diff --git a/.hgtags b/.hgtags index f0dd95d1127..fc422fbdfda 100644 --- a/.hgtags +++ b/.hgtags @@ -6,3 +6,9 @@ bf2517e15f0c0f950e5b3143c4ca11e2df73dcc1 jdk7-b25 bfe4572fd301a6fcd120373cdb2eff5d2da0c72c jdk7-b29 bee4731164a06ddece1297ae58db24aca6a1c626 jdk7-b30 cd8b8f500face60d1566d850857a7fccadbd383a jdk7-b31 +a9f1805e3ba9ca520cad199d522c84af5433e85a jdk7-b32 +6838c1a3296aaa3572364d2ce7d70826cee96286 jdk7-b33 +90cf935adb353bb0af4b46fb0677e841fd24c000 jdk7-b34 +6d909d5803e3a22850e6c4e5a75b888742ee7e20 jdk7-b35 +d718a441936196b93d8bc9f084933af9a4c2a350 jdk7-b36 +c2036bf76829c03b99108fffab52e20910a9be4f jdk7-b37 diff --git a/.hgtags-top-repo b/.hgtags-top-repo index ce58a609d1b..97e4ff1601b 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -6,3 +6,9 @@ cbc8ad9dd0e085a607427ea35411990982f19a36 jdk7-b25 31e08f70e88d77c2053f91c21b49a04296bdc59a jdk7-b29 2dab2f712e1832c92acfa63ec0337048b9422c20 jdk7-b30 3300a35a0bd56d695b92fe0b34f03ebbfc939064 jdk7-b31 +64da805be725721bf2004e7409a0d7a16fc8ddbc jdk7-b32 +bb1ef4ee3d2c8cbf43a37d372325a7952be590b9 jdk7-b33 +46a989ab932992b2084b946eeb322fa99b9fee6c jdk7-b34 +143c1abedb7d3095eff0f9ee5fec9bf48e3490fc jdk7-b35 +4b4f5fea8d7d0743f0c30d91fcd9bf9d96e5d2ad jdk7-b36 +744554f5a3290e11c71cd2ddb1aff49e431f9ed0 jdk7-b37 diff --git a/Makefile b/Makefile index 24cd12282e2..54e5a256873 100644 --- a/Makefile +++ b/Makefile @@ -49,27 +49,17 @@ ifndef JDK_MAKE_SHARED_DIR JDK_MAKE_SHARED_DIR=$(JDK_TOPDIR)/make/common/shared endif +# For start and finish echo lines +TITLE_TEXT = Control $(PLATFORM) $(ARCH) $(RELEASE) +DAYE_STAMP = `$(DATE) '+%y-%m-%d %H:%M'` +START_ECHO = echo "$(TITLE_TEXT) $@ build started: $(DATE_STAMP)" +FINISH_ECHO = echo "$(TITLE_TEXT) $@ build finished: $(DATE_STAMP)" + +default: all + include $(JDK_MAKE_SHARED_DIR)/Defs-control.gmk - include ./make/Defs-internal.gmk - -all:: - @$(ECHO) $(PLATFORM) $(ARCH) $(RELEASE) build started: `$(DATE) '+%y-%m-%d %H:%M'` - $(MKDIR) -p $(OUTPUTDIR) - -# Rules for sanity checks include ./make/sanity-rules.gmk - -dev : dev-build - -dev-build: - $(MAKE) DEV_ONLY=true all -dev-sanity: - $(MAKE) DEV_ONLY=true sanity -dev-clobber: - $(MAKE) DEV_ONLY=true clobber - -# Rules for various components include ./make/hotspot-rules.gmk include ./make/langtools-rules.gmk include ./make/corba-rules.gmk @@ -80,11 +70,205 @@ include ./make/install-rules.gmk include ./make/sponsors-rules.gmk include ./make/deploy-rules.gmk -all:: setup build +# What "all" means +all:: + @$(START_ECHO) -setup: openjdk_check +all:: openjdk_check sanity + +ifeq ($(SKIP_FASTDEBUG_BUILD), false) + all:: fastdebug_build +endif + +ifeq ($(SKIP_DEBUG_BUILD), false) + all:: debug_build +endif + +ifneq ($(SKIP_OPENJDK_BUILD), true) + all:: openjdk_build +endif + +all:: all_product_build + +all:: + @$(FINISH_ECHO) + +# Everything for a full product build +all_product_build:: + @$(START_ECHO) + +ifeq ($(SKIP_PRODUCT_BUILD), false) + + all_product_build:: product_build + + ifeq ($(BUILD_INSTALL), true) + all_product_build:: $(INSTALL) + clobber:: install-clobber + endif + + ifeq ($(BUILD_SPONSORS), true) + all_product_build:: $(SPONSORS) + clobber:: sponsors-clobber + endif + + ifneq ($(SKIP_COMPARE_IMAGES), true) + all_product_build:: compare-image + endif + +endif + +all_product_build:: + @$(FINISH_ECHO) + +# Generis build of basic repo series +generic_build_repo_series:: + $(MKDIR) -p $(OUTPUTDIR) $(MKDIR) -p $(OUTPUTDIR)/j2sdk-image +ifeq ($(BUILD_LANGTOOLS), true) + generic_build_repo_series:: langtools + clobber:: langtools-clobber +endif + +ifeq ($(BUILD_CORBA), true) + generic_build_repo_series:: corba + clobber:: corba-clobber +endif + +ifeq ($(BUILD_JAXP), true) + generic_build_repo_series:: jaxp + clobber:: jaxp-clobber +endif + +ifeq ($(BUILD_JAXWS), true) + generic_build_repo_series:: jaxws + clobber:: jaxws-clobber +endif + +ifeq ($(BUILD_HOTSPOT), true) + generic_build_repo_series:: $(HOTSPOT) + clobber:: hotspot-clobber +endif + +ifeq ($(BUILD_JDK), true) + generic_build_repo_series:: $(JDK_JAVA_EXE) + clobber:: jdk-clobber +endif + +ifeq ($(BUILD_DEPLOY), true) + generic_build_repo_series:: $(DEPLOY) + clobber:: deploy-clobber +endif + +ifeq ($(BUILD_JDK), true) + ifeq ($(BUNDLE_RULES_AVAILABLE), true) + generic_build_repo_series:: openjdk-binary-plugs-bundles + endif +endif + +# The debug build, fastdebug or debug. Needs special handling. +# Note that debug builds do NOT do INSTALL steps, but must be done +# after the product build and before the INSTALL step of the product build. +# +# DEBUG_NAME is fastdebug or debug +# ALT_OUTPUTDIR is changed to have -debug or -fastdebug suffix +# The resulting j2sdk-image is used by the install makefiles to create a +# debug install bundle jdk-*-debug-** bundle (tar or zip) +# which will install in the debug or fastdebug subdirectory of the +# normal product install area. +# The install process needs to know what the DEBUG_NAME is, so +# look for INSTALL_DEBUG_NAME in the install rules. +# + +# Location of fresh bootdir output +ABS_BOOTDIR_OUTPUTDIR=$(ABS_OUTPUTDIR)/bootjdk +FRESH_BOOTDIR=$(ABS_BOOTDIR_OUTPUTDIR)/j2sdk-image +FRESH_DEBUG_BOOTDIR=$(ABS_BOOTDIR_OUTPUTDIR)-$(DEBUG_NAME)/j2sdk-image + +create_fresh_product_bootdir: FRC + @$(START_ECHO) + $(MAKE) ALT_OUTPUTDIR=$(ABS_BOOTDIR_OUTPUTDIR) \ + NO_DOCS=true \ + BOOT_CYCLE_SETTINGS= \ + build_product_image + @$(FINISH_ECHO) + +create_fresh_debug_bootdir: FRC + @$(START_ECHO) + $(MAKE) ALT_OUTPUTDIR=$(ABS_BOOTDIR_OUTPUTDIR) \ + NO_DOCS=true \ + BOOT_CYCLE_DEBUG_SETTINGS= \ + build_debug_image + @$(FINISH_ECHO) + +create_fresh_fastdebug_bootdir: FRC + @$(START_ECHO) + $(MAKE) ALT_OUTPUTDIR=$(ABS_BOOTDIR_OUTPUTDIR) \ + NO_DOCS=true \ + BOOT_CYCLE_DEBUG_SETTINGS= \ + build_fastdebug_image + @$(FINISH_ECHO) + +# Create boot image? +ifeq ($(SKIP_BOOT_CYCLE),false) + ifneq ($(PLATFORM)$(ARCH_DATA_MODEL),solaris64) + DO_BOOT_CYCLE=true + endif +endif + +ifeq ($(DO_BOOT_CYCLE),true) + + # Create the bootdir to use in the build + product_build:: create_fresh_product_bootdir + debug_build:: create_fresh_debug_bootdir + fastdebug_build:: create_fresh_fastdebug_bootdir + + # Define variables to be used now for the boot jdk + BOOT_CYCLE_SETTINGS= \ + ALT_BOOTDIR=$(FRESH_BOOTDIR) \ + ALT_JDK_IMPORT_PATH=$(FRESH_BOOTDIR) + BOOT_CYCLE_DEBUG_SETTINGS= \ + ALT_BOOTDIR=$(FRESH_DEBUG_BOOTDIR) \ + ALT_JDK_IMPORT_PATH=$(FRESH_DEBUG_BOOTDIR) + +else + + # Use the supplied ALT_BOOTDIR as the boot + BOOT_CYCLE_SETTINGS= + BOOT_CYCLE_DEBUG_SETTINGS= + +endif + +build_product_image: + @$(START_ECHO) + $(MAKE) \ + SKIP_FASTDEBUG_BUILD=true \ + SKIP_DEBUG_BUILD=true \ + $(BOOT_CYCLE_SETTINGS) \ + generic_build_repo_series + @$(FINISH_ECHO) + +generic_debug_build: + @$(START_ECHO) + $(MAKE) \ + ALT_OUTPUTDIR=$(ABS_OUTPUTDIR)-$(DEBUG_NAME) \ + DEBUG_NAME=$(DEBUG_NAME) \ + NO_DOCS=true \ + $(BOOT_CYCLE_DEBUG_SETTINGS) \ + generic_build_repo_series + @$(FINISH_ECHO) + +build_debug_image: + $(MAKE) DEBUG_NAME=debug generic_debug_build + +build_fastdebug_image: + $(MAKE) DEBUG_NAME=fastdebug generic_debug_build + +# Build final image +product_build:: build_product_image +debug_build:: build_debug_image +fastdebug_build:: build_fastdebug_image + # Check on whether we really can build the openjdk, need source etc. openjdk_check: FRC ifneq ($(SKIP_OPENJDK_BUILD), true) @@ -101,113 +285,6 @@ ifneq ($(SKIP_OPENJDK_BUILD), true) @$(ECHO) " " endif -build:: sanity - -clobber:: - -ifeq ($(BUILD_LANGTOOLS), true) - build:: langtools - clobber:: langtools-clobber -endif - -ifeq ($(BUILD_CORBA), true) - build:: corba - clobber:: corba-clobber -endif - -ifeq ($(BUILD_JAXP), true) - build:: jaxp - clobber:: jaxp-clobber -endif - -ifeq ($(BUILD_JAXWS), true) - build:: jaxws - clobber:: jaxws-clobber -endif - -ifeq ($(BUILD_HOTSPOT), true) - build:: $(HOTSPOT) - clobber:: hotspot-clobber -endif - -ifeq ($(BUILD_JDK), true) - build:: $(JDK_JAVA_EXE) - clobber:: jdk-clobber -endif - -ifeq ($(BUILD_DEPLOY), true) - build:: $(DEPLOY) - clobber:: deploy-clobber -endif - -# -# Generic debug build, fastdebug or debug. Needs special handling. -# Note that debug builds do NOT do INSTALL steps, but must be done -# after the product build and before the INSTALL step of the product build. -# -# DEBUG_NAME is fastdebug or debug -# ALT_OUTPUTDIR is changed to have -debug or -fastdebug suffix -# The resulting j2sdk-image is used by the install makefiles to create a -# debug install bundle jdk-*-debug-** bundle (tar or zip) -# which will install in the debug or fastdebug subdirectory of the -# normal product install area. -# The install process needs to know what the DEBUG_NAME is, so -# look for INSTALL_DEBUG_NAME in the install rules. -# - -COMMON_DEBUG_FLAGS= \ - DEBUG_NAME=$(DEBUG_NAME) \ - ALT_OUTPUTDIR=$(ABS_OUTPUTDIR)-$(DEBUG_NAME) \ - NO_DOCS=true - -product_build: setup - @$(ECHO) $@ build started: `$(DATE) '+%y-%m-%d %H:%M'` - $(MAKE) SKIP_FASTDEBUG_BUILD=true SKIP_DEBUG_BUILD=true all - @$(ECHO) $@ build finished: `$(DATE) '+%y-%m-%d %H:%M'` - -generic_debug_build: - @$(ECHO) $@ build started: `$(DATE) '+%y-%m-%d %H:%M'` - $(MAKE) $(COMMON_DEBUG_FLAGS) setup build - @$(ECHO) $@ build finished: `$(DATE) '+%y-%m-%d %H:%M'` - -debug_build: setup - $(MAKE) DEBUG_NAME=debug generic_debug_build - -fastdebug_build: setup - $(MAKE) DEBUG_NAME=fastdebug generic_debug_build - -ifeq ($(SKIP_FASTDEBUG_BUILD), false) - all:: fastdebug_build -endif - -ifeq ($(SKIP_DEBUG_BUILD), false) - all:: debug_build -endif - -ifeq ($(BUILD_JDK), true) - ifeq ($(BUNDLE_RULES_AVAILABLE), true) - all:: openjdk-binary-plugs-bundles - endif -endif - -ifeq ($(BUILD_INSTALL), true) - all :: $(INSTALL) - clobber:: install-clobber -endif - -ifeq ($(BUILD_SPONSORS), true) - all :: $(SPONSORS) - clobber:: sponsors-clobber -endif - -ifneq ($(SKIP_COMPARE_IMAGES), true) - all :: compare-image -endif - -ifneq ($(SKIP_OPENJDK_BUILD), true) - all :: openjdk_build -endif - # If we have bundle rules, we have a chance here to do a complete cycle # build, of production and open build. # FIXUP: We should create the openjdk source bundle and build that? @@ -235,6 +312,7 @@ else endif openjdk_build: + @$(START_ECHO) @$(ECHO) " " @$(ECHO) "=================================================" @$(ECHO) "Starting openjdk build" @@ -245,6 +323,7 @@ openjdk_build: $(MKDIR) -p $(OPENJDK_OUTPUTDIR) ($(CD) $(OPENJDK_BUILDDIR) && $(MAKE) \ OPENJDK=true \ + NO_DOCS=true \ ALT_JDK_DEVTOOLS_DIR=$(JDK_DEVTOOLS_DIR) \ ALT_OUTPUTDIR=$(OPENJDK_OUTPUTDIR) \ ALT_BINARY_PLUGS_PATH=$(OPENJDK_PLUGS) \ @@ -261,6 +340,7 @@ openjdk_build: @$(ECHO) " Binary Bundle: $(OPENJDK_BUILD_BINARY_ZIP)" @$(ECHO) "=================================================" @$(ECHO) " " + @$(FINISH_ECHO) endif endif @@ -274,8 +354,18 @@ clobber:: clean: clobber -all:: - @$(ECHO) Control build finished: `$(DATE) '+%y-%m-%d %H:%M'` +# +# Dev builds +# + +dev : dev-build + +dev-build: + $(MAKE) DEV_ONLY=true all +dev-sanity: + $(MAKE) DEV_ONLY=true sanity +dev-clobber: + $(MAKE) DEV_ONLY=true clobber # # Quick jdk verification build @@ -460,16 +550,6 @@ ifeq ($(BUNDLE_RULES_AVAILABLE), true) include $(BUNDLE_RULES) endif -################################################################ -# Cycle build. Build the jdk, use it to build the jdk again. -################################################################ - -ABS_BOOTDIR_OUTPUTDIR=$(ABS_OUTPUTDIR)/bootjdk - -boot_cycle: - $(MAKE) ALT_OUTPUTDIR=$(ABS_BOOTDIR_OUTPUTDIR) product_build - $(MAKE) ALT_BOOTDIR=$(ABS_BOOTDIR_OUTPUTDIR)/j2sdk-image product_build - ################################################################ # JPRT rule to build ################################################################ @@ -480,9 +560,20 @@ include ./make/jprt.gmk # PHONY ################################################################ -.PHONY: all build what clobber insane \ - fastdebug_build debug_build product_build setup \ - dev dev-build dev-sanity dev-clobber +.PHONY: all \ + generic_build_repo_series \ + what clobber insane \ + dev dev-build dev-sanity dev-clobber \ + product_build \ + fastdebug_build \ + debug_build \ + build_product_image \ + build_debug_image \ + build_fastdebug_image \ + create_fresh_product_bootdir \ + create_fresh_debug_bootdir \ + create_fresh_fastdebug_bootdir \ + generic_debug_build # Force target FRC: diff --git a/README-builds.html b/README-builds.html index 37998f9c1f6..8783bf8bde2 100644 --- a/README-builds.html +++ b/README-builds.html @@ -5,7 +5,7 @@ - + +
- + @@ -141,7 +146,7 @@ See SunSolve for patch downloads. - + @@ -150,7 +155,7 @@ See SunSolve for patch downloads. - + @@ -159,7 +164,7 @@ See SunSolve for patch downloads. - + @@ -182,14 +187,64 @@ we will try to provide what information we have available to us. -

Fedora

+

Fedora 9

- TBD + After installing + Fedora 9 + you need to make sure you have + the "Software Development" bundle installed, plus the + following packages: +
+ +
+

+ Always a good idea to do a complete Software Update/Refresh + after you get all the packages installed.

-

Debian

+

CentOS 5.2

- TBD + After installing + CentOS 5.2 + you need to make sure you have + the following Development bundles installed: +
+ +
+

+ Plus the following packages: +

+ +
+

+ The freetype 2.3 packages don't seem to be available, + but the freetype 2.3 sources can be downloaded, built, + and installed easily enough from + + the freetype site. + Build and install with something like: +

+ ./configure && make && sudo -u root make install +
+

+ Mercurial packages could not be found easily, but a Google + search should find ones, and they usually include Python if + it's needed.

Ubuntu

@@ -664,8 +719,8 @@
  • Install the - Microsoft Visual Studio .NET 2003 Professional or the - Microsoft Platform SDK. + Microsoft Visual Studio .NET 2003 Professional (32bit) or the + Microsoft Platform SDK (64bit).
  • Setup all environment variables for compilers @@ -831,8 +886,8 @@
    At a minimum, the - Sun Studio 11 Compilers - (containing version 5.8 of the C and C++ compilers) is required, + Sun Studio 12 Compilers + (containing version 5.9 of the C and C++ compilers) is required, with patches from the SunSolve web site. @@ -871,6 +926,11 @@ The Microsoft Visual Studio .NET 2005 (VS2005) compiler will not work at this time due to the new runtime dll and the manifest requirements. +

    + WARNING: Make sure you check out the + CYGWIN link.exe WARNING. + The path /usr/bin must be after the path to the + Visual Studio product.

    Windows X64: Microsoft Platform SDK April 2005
    @@ -1079,6 +1139,7 @@
  • + @@ -1087,50 +1148,59 @@ - + - + - + - + + - + + - + + - + + - + + - - + + +
    OpenJDKIntroduction
  • Minimum Build Environments
  • Specific Developer Build Environments
  • +
  • Source Directory Structure
  • Build Information
      @@ -132,7 +137,7 @@ See SunSolve for patch downloads.
  • Sun Studio 11 Sun Studio 12
    Solaris SPARCV9 (64bit)Sun Studio 11Sun Studio 12
    Solaris X86 (32bit)Sun Studio 11Sun Studio 12
    Solaris X64 (64bit)Sun Studio 11Sun Studio 12
    Windows X86 (32bit)
    Binary NameCategory Package Description
    ar.exe Develbinutils: The GNU assembler, linker and binary + binutilsThe GNU assembler, linker and binary utilities
    make.exe Develmake: The GNU version of the 'make' utility
    +
    makeThe GNU version of the 'make' utility built for CYGWIN.
    NOTE: See the GNU make section
    m4.exe Interpretersm4: GNU implementation of the traditional Unix macro + m4GNU implementation of the traditional Unix macro processor
    cpio.exe Utilscpio: A program to manage archives of filescpioA program to manage archives of files
    gawk.exe Utilsawk: Pattern-directed scanning and processing languageawkPattern-directed scanning and processing language
    file.exe Utilsfile: Determines file type using 'magic' numbersfileDetermines file type using 'magic' numbers
    zip.exe Archivezip: Package and compress (archive) fileszipPackage and compress (archive) files
    unzip.exe Archiveunzip: Extract compressed files in a ZIP archiveunzipExtract compressed files in a ZIP archive
    free.exeProcpsfree: Display amount of free and used memory in the systemSystemprocpsDisplay amount of free and used memory in the system
    @@ -1144,6 +1214,13 @@ section on BLODA (applications that interfere with CYGWIN). +

    + WARNING: + Be very careful with link.exe, it will conflict + with the Visual Studio version. You need the Visual Studio + version of link.exe, not the CYGWIN one. + So it's important that the Visual Studio paths in PATH preceed + the CYGWIN path /usr/bin. Microsoft DirectX 9.0 SDK header files and libraries

    @@ -1429,7 +1506,7 @@ build output is to go. The default output directory will be build/platform. -
    ALT_SLASHJAVA
    +
    ALT_SLASH_JAVA
    The default root location for many of the ALT path locations of the following ALT variables. diff --git a/corba/.hgtags b/corba/.hgtags index 6792e20a86a..296a27ee08e 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -6,3 +6,9 @@ e84e9018bebbf3e5bafc5706e7882a15cb1c7d99 jdk7-b27 8b71960f79ce0a6fb8ddfeec03f03d400a361747 jdk7-b29 c0252adbb2abbfdd6c35595429ac6fbdd98e20ac jdk7-b30 ef6af34d75a7b44e77083f1d4ee47631fa09d3b4 jdk7-b31 +80a0f46a6203e727012bd579fe38a609b83decce jdk7-b32 +6a5b9d2f8b20de54e3bfe33cd12bd0793caedc4e jdk7-b33 +0a812b9824e5d17b073765d1505594b49ff88a10 jdk7-b34 +3867c4d14a5bfdbb37c97b4874ccb0ee5343111c jdk7-b35 +0723891eb8d1c27e67c54163af0b4cea05a4e036 jdk7-b36 +59d5848bdedebe91cc2753acce78911bcb4a66db jdk7-b37 diff --git a/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_dynamicany.jmk b/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_dynamicany.jmk index 84a8a387e5b..a3a4ffb5fdd 100644 --- a/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_dynamicany.jmk +++ b/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_dynamicany.jmk @@ -1,5 +1,5 @@ # -# Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -41,4 +41,7 @@ com_sun_corba_se_impl_dynamicany_java = \ com/sun/corba/se/impl/dynamicany/DynSequenceImpl.java \ com/sun/corba/se/impl/dynamicany/DynStructImpl.java \ com/sun/corba/se/impl/dynamicany/DynUnionImpl.java \ - com/sun/corba/se/impl/dynamicany/DynValueImpl.java + com/sun/corba/se/impl/dynamicany/DynValueImpl.java \ + com/sun/corba/se/impl/dynamicany/DynValueBoxImpl.java \ + com/sun/corba/se/impl/dynamicany/DynValueCommonImpl.java + diff --git a/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_encoding.jmk b/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_encoding.jmk index f978761790b..84f725c3353 100644 --- a/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_encoding.jmk +++ b/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_encoding.jmk @@ -1,5 +1,5 @@ # -# Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -52,6 +52,8 @@ com_sun_corba_se_impl_encoding_java = \ com/sun/corba/se/impl/encoding/CodeSetComponentInfo.java \ com/sun/corba/se/impl/encoding/EncapsInputStream.java \ com/sun/corba/se/impl/encoding/EncapsOutputStream.java \ + com/sun/corba/se/impl/encoding/IDLJavaSerializationInputStream.java \ + com/sun/corba/se/impl/encoding/IDLJavaSerializationOutputStream.java \ com/sun/corba/se/impl/encoding/MarkAndResetHandler.java \ com/sun/corba/se/impl/encoding/MarshalInputStream.java \ com/sun/corba/se/impl/encoding/MarshalOutputStream.java \ diff --git a/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_ior.jmk b/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_ior.jmk index e8cae1a5e22..c4cddea8de3 100644 --- a/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_ior.jmk +++ b/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_ior.jmk @@ -1,5 +1,5 @@ # -# Copyright 2000-2004 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -63,6 +63,7 @@ com_sun_corba_se_impl_ior_java = \ com/sun/corba/se/impl/ior/iiop/IIOPProfileImpl.java \ com/sun/corba/se/impl/ior/iiop/IIOPProfileTemplateImpl.java \ com/sun/corba/se/impl/ior/iiop/JavaCodebaseComponentImpl.java \ + com/sun/corba/se/impl/ior/iiop/JavaSerializationComponent.java \ com/sun/corba/se/impl/ior/iiop/MaxStreamFormatVersionComponentImpl.java \ com/sun/corba/se/impl/ior/iiop/RequestPartitioningComponentImpl.java \ com/sun/corba/se/impl/ior/iiop/ORBTypeComponentImpl.java diff --git a/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_orbutil.jmk b/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_orbutil.jmk index a3162fce9e4..871b48df55d 100644 --- a/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_orbutil.jmk +++ b/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_orbutil.jmk @@ -1,5 +1,5 @@ # -# Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ com_sun_corba_se_impl_orbutil_java = \ com/sun/corba/se/impl/orbutil/CacheTable.java \ com/sun/corba/se/impl/orbutil/CorbaResourceUtil.java \ com/sun/corba/se/impl/orbutil/DenseIntMapImpl.java \ + com/sun/corba/se/impl/orbutil/GetPropertyAction.java \ com/sun/corba/se/impl/orbutil/HexOutputStream.java \ com/sun/corba/se/impl/orbutil/IIOPInputStream_1_3.java \ com/sun/corba/se/impl/orbutil/IIOPInputStream_1_3_1.java \ @@ -76,6 +77,7 @@ com_sun_corba_se_impl_orbutil_java = \ com/sun/corba/se/impl/copyobject/FallbackObjectCopierImpl.java \ com/sun/corba/se/impl/copyobject/ORBStreamObjectCopierImpl.java \ com/sun/corba/se/impl/copyobject/ReferenceObjectCopierImpl.java \ + com/sun/corba/se/impl/copyobject/JavaStreamObjectCopierImpl.java \ com/sun/corba/se/impl/orbutil/graph/Node.java \ com/sun/corba/se/impl/orbutil/graph/NodeData.java \ com/sun/corba/se/impl/orbutil/graph/Graph.java \ diff --git a/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_protocol.jmk b/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_protocol.jmk index 507eac18a5b..0a6b350ae85 100644 --- a/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_protocol.jmk +++ b/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_protocol.jmk @@ -1,5 +1,5 @@ # -# Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -63,6 +63,7 @@ com_sun_corba_se_impl_protocol_java = \ com/sun/corba/se/impl/protocol/giopmsgheaders/LocateRequestMessage_1_0.java \ com/sun/corba/se/impl/protocol/giopmsgheaders/LocateRequestMessage_1_1.java \ com/sun/corba/se/impl/protocol/giopmsgheaders/LocateRequestMessage_1_2.java \ + com/sun/corba/se/impl/protocol/giopmsgheaders/LocateReplyOrReplyMessage.java \ com/sun/corba/se/impl/protocol/giopmsgheaders/Message.java \ com/sun/corba/se/impl/protocol/giopmsgheaders/MessageBase.java \ com/sun/corba/se/impl/protocol/giopmsgheaders/MessageHandler.java \ diff --git a/corba/make/com/sun/corba/minclude/com_sun_corba_se_spi_legacy_interceptor.jmk b/corba/make/com/sun/corba/minclude/com_sun_corba_se_spi_legacy_interceptor.jmk index 1c807ecb0c0..156eb299ee2 100644 --- a/corba/make/com/sun/corba/minclude/com_sun_corba_se_spi_legacy_interceptor.jmk +++ b/corba/make/com/sun/corba/minclude/com_sun_corba_se_spi_legacy_interceptor.jmk @@ -1,5 +1,5 @@ # -# Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ com_sun_corba_se_spi_legacy_interceptor_java = \ com/sun/corba/se/spi/legacy/interceptor/IORInfoExt.java \ + com/sun/corba/se/spi/legacy/interceptor/ORBInitInfoExt.java \ com/sun/corba/se/spi/legacy/interceptor/RequestInfoExt.java \ com/sun/corba/se/spi/legacy/interceptor/UnknownType.java diff --git a/corba/make/com/sun/corba/minclude/com_sun_corba_se_spi_monitoring.jmk b/corba/make/com/sun/corba/minclude/com_sun_corba_se_spi_monitoring.jmk index 49b64f0c61c..6a423c0bb9b 100644 --- a/corba/make/com/sun/corba/minclude/com_sun_corba_se_spi_monitoring.jmk +++ b/corba/make/com/sun/corba/minclude/com_sun_corba_se_spi_monitoring.jmk @@ -1,5 +1,5 @@ # -# Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -35,5 +35,6 @@ FILES_java = \ com/sun/corba/se/spi/monitoring/MonitoredObjectFactory.java \ com/sun/corba/se/spi/monitoring/MonitoredAttribute.java \ com/sun/corba/se/spi/monitoring/MonitoredAttributeInfoFactory.java \ + com/sun/corba/se/spi/monitoring/MonitoringConstants.java \ com/sun/corba/se/spi/monitoring/MonitoringManager.java \ com/sun/corba/se/spi/monitoring/MonitoringManagerFactory.java diff --git a/corba/make/com/sun/corba/minclude/com_sun_corba_se_spi_presentation_rmi.jmk b/corba/make/com/sun/corba/minclude/com_sun_corba_se_spi_presentation_rmi.jmk index 6795f9de104..d6e5e7f94dd 100644 --- a/corba/make/com/sun/corba/minclude/com_sun_corba_se_spi_presentation_rmi.jmk +++ b/corba/make/com/sun/corba/minclude/com_sun_corba_se_spi_presentation_rmi.jmk @@ -1,5 +1,5 @@ # -# Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ com_sun_corba_se_spi_presentation_rmi_java = \ com/sun/corba/se/spi/presentation/rmi/DynamicMethodMarshaller.java \ com/sun/corba/se/spi/presentation/rmi/DynamicStub.java \ com/sun/corba/se/spi/presentation/rmi/IDLNameTranslator.java \ + com/sun/corba/se/spi/presentation/rmi/PresentationDefaults.java \ com/sun/corba/se/spi/presentation/rmi/PresentationManager.java \ com/sun/corba/se/spi/presentation/rmi/StubAdapter.java diff --git a/corba/make/com/sun/corba/minclude/com_sun_corba_se_spi_transport.jmk b/corba/make/com/sun/corba/minclude/com_sun_corba_se_spi_transport.jmk index 170776d2939..68f68bae04c 100644 --- a/corba/make/com/sun/corba/minclude/com_sun_corba_se_spi_transport.jmk +++ b/corba/make/com/sun/corba/minclude/com_sun_corba_se_spi_transport.jmk @@ -1,5 +1,5 @@ # -# Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ com_sun_corba_se_spi_transport_java = \ com/sun/corba/se/spi/transport/CorbaAcceptor.java \ com/sun/corba/se/spi/transport/CorbaConnection.java \ + com/sun/corba/se/spi/transport/CorbaConnectionCache.java \ com/sun/corba/se/spi/transport/CorbaContactInfo.java \ com/sun/corba/se/spi/transport/CorbaContactInfoList.java \ com/sun/corba/se/spi/transport/CorbaContactInfoListFactory.java \ diff --git a/corba/make/com/sun/corba/minclude/org_omg_CosNaming.jmk b/corba/make/com/sun/corba/minclude/org_omg_CosNaming.jmk index 66bb8b27cae..0cff6b03d7d 100644 --- a/corba/make/com/sun/corba/minclude/org_omg_CosNaming.jmk +++ b/corba/make/com/sun/corba/minclude/org_omg_CosNaming.jmk @@ -1,5 +1,5 @@ # -# Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,7 @@ NS_GENERATED_java = \ org/omg/CosNaming/NamingContext.java \ org/omg/CosNaming/NamingContextHelper.java \ org/omg/CosNaming/NamingContextHolder.java \ + org/omg/CosNaming/NamingContextOperations.java \ org/omg/CosNaming/_NamingContextStub.java \ org/omg/CosNaming/NamingContextPackage/AlreadyBound.java \ org/omg/CosNaming/NamingContextPackage/AlreadyBoundHelper.java \ diff --git a/corba/make/com/sun/corba/minclude/org_omg_DynamicAny.jmk b/corba/make/com/sun/corba/minclude/org_omg_DynamicAny.jmk index 0a5e0550d42..d9e7c1f8ea8 100644 --- a/corba/make/com/sun/corba/minclude/org_omg_DynamicAny.jmk +++ b/corba/make/com/sun/corba/minclude/org_omg_DynamicAny.jmk @@ -1,5 +1,5 @@ # -# Copyright 2000-2002 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,10 @@ DYNANY_GENERATED_java = \ org/omg/DynamicAny/DynUnionOperations.java \ org/omg/DynamicAny/DynValue.java \ org/omg/DynamicAny/DynValueOperations.java \ + org/omg/DynamicAny/DynValueBox.java \ + org/omg/DynamicAny/DynValueBoxOperations.java \ + org/omg/DynamicAny/DynValueCommon.java \ + org/omg/DynamicAny/DynValueCommonOperations.java \ org/omg/DynamicAny/NameDynAnyPair.java \ org/omg/DynamicAny/NameValuePair.java \ org/omg/DynamicAny/DynAnyPackage/InvalidValue.java \ @@ -70,8 +74,16 @@ DYNANY_GENERATED_java = \ org/omg/DynamicAny/DynSequenceHelper.java \ org/omg/DynamicAny/NameDynAnyPairSeqHelper.java \ org/omg/DynamicAny/NameValuePairHelper.java \ - org/omg/DynamicAny/NameValuePairSeqHelper.java - + org/omg/DynamicAny/NameValuePairSeqHelper.java \ + org/omg/DynamicAny/_DynAnyFactoryStub.java \ + org/omg/DynamicAny/_DynAnyStub.java \ + org/omg/DynamicAny/_DynArrayStub.java \ + org/omg/DynamicAny/_DynEnumStub.java \ + org/omg/DynamicAny/_DynFixedStub.java \ + org/omg/DynamicAny/_DynSequenceStub.java \ + org/omg/DynamicAny/_DynStructStub.java \ + org/omg/DynamicAny/_DynUnionStub.java \ + org/omg/DynamicAny/_DynValueStub.java DYNANY_HELP_HOLD_java = \ org/omg/DynamicAny/AnySeqHolder.java \ diff --git a/corba/make/com/sun/corba/minclude/org_omg_PortableInterceptor.jmk b/corba/make/com/sun/corba/minclude/org_omg_PortableInterceptor.jmk index 3e05c552d10..5f0a661971c 100644 --- a/corba/make/com/sun/corba/minclude/org_omg_PortableInterceptor.jmk +++ b/corba/make/com/sun/corba/minclude/org_omg_PortableInterceptor.jmk @@ -1,5 +1,5 @@ # -# Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -106,6 +106,7 @@ PI_GENERATED_java = \ org/omg/IOP/CodecPackage/TypeMismatchHelper.java \ org/omg/IOP/ENCODING_CDR_ENCAPS.java \ org/omg/IOP/Encoding.java \ + org/omg/IOP/ExceptionDetailMessage.java \ org/omg/Dynamic/Parameter.java # Helper and Holder files to be removed: diff --git a/corba/make/com/sun/corba/se/sources/Makefile b/corba/make/com/sun/corba/se/sources/Makefile index 405822a201f..624661e5afa 100644 --- a/corba/make/com/sun/corba/se/sources/Makefile +++ b/corba/make/com/sun/corba/se/sources/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -46,6 +46,8 @@ CORBA_JMK_DIRECTORY=$(TOPDIR)/make/com/sun/corba/minclude/ include $(CORBA_JMK_DIRECTORY)com_sun_corba_se_PortableActivationIDL.jmk include $(CORBA_JMK_DIRECTORY)com_sun_corba_se_impl_logging.jmk +FILES_java += com/sun/corba/se/org/omg/CORBA/ORB.java + # # Dirs # diff --git a/corba/make/common/Defs-windows.gmk b/corba/make/common/Defs-windows.gmk index c5de04c03cb..aa863f64782 100644 --- a/corba/make/common/Defs-windows.gmk +++ b/corba/make/common/Defs-windows.gmk @@ -58,11 +58,24 @@ PLATFORM_INCLUDE = $(INCLUDEDIR)/$(PLATFORM_INCLUDE_NAME) # The following DLL's are considered MS runtime libraries and should # not to be REBASEd, see deploy/make/common/Release.gmk. -# msvcrt.dll, msvcr71.dll: Microsoft runtimes +# msvcrt.dll, msvcrnn.dll [msvcr71 or msvcr80 or msvcr90] : Microsoft runtimes MS_RUNTIME_LIBRARIES = msvcrt.dll +MSVCRNN_DLL = ifeq ($(ARCH_DATA_MODEL), 32) ifeq ($(COMPILER_VERSION), VS2003) - MS_RUNTIME_LIBRARIES += msvcr71.dll + MSVCRNN_DLL = msvcr71.dll + MSVCPNN_DLL = msvcp71.dll + MS_RUNTIME_LIBRARIES += $(MSVCRNN_DLL) + endif + ifeq ($(COMPILER_VERSION), VS2005) + MSVCRNN_DLL = msvcr80.dll + MSVCPNN_DLL = msvcp80.dll + MS_RUNTIME_LIBRARIES += $(MSVCRNN_DLL) + endif + ifeq ($(COMPILER_VERSION), VS2008) + MSVCRNN_DLL = msvcr90.dll + MSVCPNN_DLL = msvcp90.dll + MS_RUNTIME_LIBRARIES += $(MSVCRNN_DLL) endif endif @@ -148,6 +161,20 @@ ifeq ($(CC_VERSION),msvc) CC_LOWER_OPT = -O1 endif endif + ifeq ($(COMPILER_VERSION), VS2008) + # Automatic precompiled header option to use (if COMPILE_APPROACH=batch) + AUTOMATIC_PCH_OPTION = + GX_OPTION = -EHsc + ifeq ($(ARCH_DATA_MODEL), 32) + CC_HIGHEST_OPT = -O2 + CC_HIGHER_OPT = -O1 + CC_LOWER_OPT = -O1 + else + CC_HIGHEST_OPT = -O2 + CC_HIGHER_OPT = -O1 + CC_LOWER_OPT = -O1 + endif + endif CC_NO_OPT = -Od else # CC_VERSION # GCC not supported, but left for historical reference... @@ -179,7 +206,7 @@ endif # -MTd Use static debug version (better than -MDd, no runtime issues) # -D_DEBUG Change use of malloc/free/etc to use special debug ones (-MTd) # -# NOTE: We also will use /D _STATIC_CPPLIB so we don't need msvcp71.dll +# NOTE: We also will use /D _STATIC_CPPLIB so we don't need msvcpnn.dll # ifeq ($(MS_RUNTIME_STATIC),true) MS_RUNTIME_OPTION=-MT @@ -217,7 +244,7 @@ ifeq ($(CC_VERSION),msvc) # -YX -Fp/.../foobar.pch Use precompiled headers (try someday?) # -nologo Don't print out startup message # /D _STATIC_CPPLIB - # Use static link for the C++ runtime (so msvcp71.dll not needed) + # Use static link for the C++ runtime (so msvcpnn.dll not needed) # CFLAGS_COMMON += -Zi -nologo CFLAGS_OPT = $(POPT) diff --git a/corba/make/common/shared/Compiler-msvc.gmk b/corba/make/common/shared/Compiler-msvc.gmk index fbb8e8a5664..e42dce91a40 100644 --- a/corba/make/common/shared/Compiler-msvc.gmk +++ b/corba/make/common/shared/Compiler-msvc.gmk @@ -47,24 +47,17 @@ ifeq ($(PLATFORM), windows) # unset any GNU Make settings of MFLAGS and MAKEFLAGS which may mess up nmake NMAKE = MFLAGS= MAKEFLAGS= $(COMPILER_PATH)nmake -nologo + # Compiler version and type (Always get word after "Version") + CC_VER := $(shell $(CC) 2>&1 | $(HEAD) -n 1 | $(SED) 's/.*\(Version.*\)/\1/' | $(NAWK) '{print $$2}') + # SDK-64 and MSVC6 put REBASE.EXE in a different places - go figure... ifeq ($(ARCH_DATA_MODEL), 32) - CC_VER := $(shell $(CC) 2>&1 | $(HEAD) -n 1 | $(NAWK) '{print $$8}') LINK_VER := $(shell $(LINK) | $(HEAD) -n 1 | $(NAWK) '{print $$6}') - CC_TYPE := $(shell $(CC) 2>&1 | $(HEAD) -n 1 | $(NAWK) '{print $$5}') CC_MAJORVER :=$(call MajorVersion,$(CC_VER)) - REQUIRED_CCTYPE = Optimizing - REQUIRED_CC_VER = 13.10.3077 - REQUIRED_LINK_VER = 7.10.3077 - ifeq ($(CC_MAJORVER), 12) - # This should be: CC_VER=12.00.8168 LINK_VER=6.00.8447 - COMPILER_NAME=Visual C++ 6.0 Professional + VC6-SP 3 - COMPILER_VERSION=VC6 - REBASE = $(COMPILER_PATH)rebase - MTL = $(COMPILER_PATH)midl - endif ifeq ($(CC_MAJORVER), 13) # This should be: CC_VER=13.10.3077 LINK_VER=7.10.3077 + REQUIRED_CC_VER = 13.10.3077 + REQUIRED_LINK_VER = 7.10.3077 COMPILER_NAME=Visual Studio .NET 2003 Professional C++ COMPILER_VERSION=VS2003 REBASE = $(COMPILER_PATH)../../Common7/Tools/Bin/rebase @@ -74,9 +67,10 @@ ifeq ($(PLATFORM), windows) endif endif ifeq ($(CC_MAJORVER), 14) - # This should be: CC_VER=14.00.0000 LINK_VER=8.00.0000 - # NOTE: This compiler has not been tried yet on 32bit systems - COMPILER_NAME=Visual Studio .NET 2005 + # This should be: CC_VER=14.00.50727.42 LINK_VER=8.00.50727.42 + REQUIRED_CC_VER = 14.00.50727.42 + REQUIRED_LINK_VER = 8.00.50727.42 + COMPILER_NAME=Visual Studio 8 COMPILER_VERSION=VS2005 REBASE = $(COMPILER_PATH)../../Common8/Tools/Bin/rebase MTL = $(COMPILER_PATH)../../Common8/Tools/Bin/midl @@ -84,10 +78,22 @@ ifeq ($(PLATFORM), windows) COMPILER_PATH := $(error COMPILER_PATH cannot be empty here) endif endif + ifeq ($(CC_MAJORVER), 15) + # This should be: CC_VER=15.00.21022.08 LINK_VER=9.00.21022.08 + REQUIRED_CC_VER = 15.00.21022.08 + REQUIRED_LINK_VER = 9.00.21022.08 + COMPILER_NAME=Visual Studio 9 + COMPILER_VERSION=VS2008 + #rebase and midl moved out of Visual Studio into the SDK: + REBASE = $(MSDEVTOOLS_PATH)/rebase + MTL = $(MSDEVTOOLS_PATH)/midl.exe + ifndef COMPILER_PATH + COMPILER_PATH := $(error COMPILER_PATH cannot be empty here) + endif + endif else - CC_VER := $(shell $(CC) 2>&1 | $(HEAD) -n 1 | $(NAWK) '{print $$7}') + # else ARCH_DATA_MODEL is 64 LINK_VER := $(shell $(LINK) | $(HEAD) -n 1 | $(NAWK) '{print $$6}') - CC_TYPE := $(shell $(CC) 2>&1 | $(HEAD) -n 1 | $(NAWK) '{print $$4}') CC_MAJORVER :=$(call MajorVersion,$(CC_VER)) CC_MINORVER :=$(call MinorVersion,$(CC_VER)) CC_MICROVER :=$(call MicroVersion,$(CC_VER)) diff --git a/corba/make/common/shared/Compiler-sun.gmk b/corba/make/common/shared/Compiler-sun.gmk index 730310201c6..1dda0891d03 100644 --- a/corba/make/common/shared/Compiler-sun.gmk +++ b/corba/make/common/shared/Compiler-sun.gmk @@ -31,11 +31,8 @@ COMPILER_NAME=Sun Studio # Sun Studio Compiler settings specific to Solaris ifeq ($(PLATFORM), solaris) - # FIXUP: Change to SS12 when validated - #COMPILER_VERSION=SS12 - #REQUIRED_CC_VER=5.9 - COMPILER_VERSION=SS11 - REQUIRED_CC_VER=5.8 + COMPILER_VERSION=SS12 + REQUIRED_CC_VER=5.9 CC = $(COMPILER_PATH)cc CPP = $(COMPILER_PATH)cc -E CXX = $(COMPILER_PATH)CC diff --git a/corba/make/common/shared/Defs-utils.gmk b/corba/make/common/shared/Defs-utils.gmk index dc84d795b76..b008c5ed0f4 100644 --- a/corba/make/common/shared/Defs-utils.gmk +++ b/corba/make/common/shared/Defs-utils.gmk @@ -1,5 +1,5 @@ # -# Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -67,16 +67,6 @@ ifeq ($(PLATFORM),windows) UTILS_DEVTOOL_PATH=$(DEVTOOLS_PATH) endif -# Utilities ant and findbugs -ifndef ANT_HOME - ANT_HOME = $(JDK_DEVTOOLS_DIR)/share/ant/latest -endif -ANT = $(ANT_HOME)/bin/ant -ifndef FINDBUGS_HOME - FINDBUGS_HOME = $(JDK_DEVTOOLS_DIR)/share/findbugs/latest -endif -FINDBUGS = $(FINDBUGS_HOME)/bin/findbugs - # Utilities ADB = $(UTILS_COMMAND_PATH)adb AR = $(UTILS_CCS_BIN_PATH)ar diff --git a/corba/make/javax/xa/Makefile b/corba/make/javax/xa/Makefile index fdbdc840221..6efdbe1e4f8 100644 --- a/corba/make/javax/xa/Makefile +++ b/corba/make/javax/xa/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ include $(BUILDDIR)/common/Defs.gmk # # Files to compile # -AUTO_FILES_JAVA_DIRS = javax/transaction/xa +AUTO_FILES_JAVA_DIRS = javax/transaction # # Rules diff --git a/corba/make/jprt.config b/corba/make/jprt.config index 86e6499a156..2bff1a54c49 100644 --- a/corba/make/jprt.config +++ b/corba/make/jprt.config @@ -93,23 +93,13 @@ jdk_import="${ALT_JDK_IMPORT_PATH}" jdk_devtools="${slashjava}/devtools" share="${jdk_devtools}/share" -# Needed for langtools, maybe other parts of the build -ANT_HOME="${share}/ant/latest" -export ANT_HOME -FINDBUGS_HOME="${share}/findbugs/latest" -export FINDBUGS_HOME - # The 3 bin directories in common to all platforms sharebin="${share}/bin" -antbin="${ANT_HOME}/bin" -findbugsbin="${FINDBUGS_HOME}/bin" # Check input dirMustExist "${bootdir}" ALT_BOOTDIR dirMustExist "${slashjava}" ALT_SLASH_JAVA dirMustExist "${jdk_import}" ALT_JDK_IMPORT_PATH -dirMustExist "${ANT_HOME}" ANT_HOME -dirMustExist "${FINDBUGS_HOME}" FINDBUGS_HOME # Uses 'uname -s', but only expect SunOS or Linux, assume Windows otherwise. osname=`uname -s` @@ -127,15 +117,13 @@ if [ "${osname}" = SunOS ] ; then if [ "${JPRT_SOLARIS_COMPILER_NAME}" != "" ] ; then compiler_name=${JPRT_SOLARIS_COMPILER_NAME} else - # FIXUP: Change to SS12 when validated - #compiler_name=SS12 - compiler_name=SS11 + compiler_name=SS12 fi compiler_path=${jdk_devtools}/${solaris_arch}/SUNWspro/${compiler_name}/bin ALT_COMPILER_PATH="${compiler_path}" export ALT_COMPILER_PATH dirMustExist "${compiler_path}" ALT_COMPILER_PATH - path4sdk=${compiler_path}:${sharebin}:${antbin}:${findbugsbin} + path4sdk=${compiler_path}:${sharebin} # Add basic solaris system paths path4sdk=${path4sdk}:/usr/ccs/bin:/usr/ccs/lib:/usr/bin:/bin:/usr/sfw/bin @@ -172,7 +160,7 @@ elif [ "${osname}" = Linux ] ; then ALT_COMPILER_PATH="${compiler_path}" export ALT_COMPILER_PATH dirMustExist "${compiler_path}" ALT_COMPILER_PATH - path4sdk=${compiler_path}:${sharebin}:${antbin}:${findbugsbin} + path4sdk=${compiler_path}:${sharebin} # Add basic paths path4sdk=${path4sdk}:/usr/bin:/bin:/usr/sbin:/sbin @@ -213,7 +201,7 @@ else dosname="${mkshome}/mksnt/dosname -s" # Most unix utilities are in the mksnt directory of ROOTDIR unixcommand_path="${mkshome}/mksnt" - path4sdk="${sharebin};${antbin};${findbugsbin};${unixcommand_path}" + path4sdk="${sharebin};${unixcommand_path}" dirMustExist "${unixcommand_path}" ALT_UNIXCOMMAND_PATH devtools_path="${jdk_devtools}/win32/bin" path4sdk="${devtools_path};${path4sdk}" @@ -231,7 +219,7 @@ else dosname="/usr/bin/cygpath -a -m -s" # Most unix utilities are in the /usr/bin unixcommand_path="/usr/bin" - path4sdk="${sharebin};${antbin};${findbugsbin};${unixcommand_path}" + path4sdk="${sharebin};${unixcommand_path}" dirMustExist "${unixcommand_path}" ALT_UNIXCOMMAND_PATH # Find GNU make make="${unixcommand_path}/make.exe" diff --git a/corba/make/org/omg/CORBA/Makefile b/corba/make/org/omg/CORBA/Makefile index b57170ebc8a..110660256e4 100644 --- a/corba/make/org/omg/CORBA/Makefile +++ b/corba/make/org/omg/CORBA/Makefile @@ -1,5 +1,5 @@ # -# Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -47,8 +47,8 @@ else endif FILES_java = \ - $(ORG_OMG_SENDINGCONTEXT_java) \ - $(ORG_OMG_CORBA_2_3_java) \ + $(org_omg_SendingContext_java) \ + $(org_omg_CORBA_2_3_java) \ $(ORG_OMG_CORBA_java) # diff --git a/hotspot/.hgtags b/hotspot/.hgtags index b23c6ac9012..7cf7d998708 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -6,3 +6,9 @@ c14dab40ed9bf45ad21150bd70c9c80cdf655415 jdk7-b28 4f91c08b3e4498213a9c5a24898f7d9c38cf86fb jdk7-b29 d1605aabd0a15ecf93787c47de63073c33fba52d jdk7-b30 9c2ecc2ffb125f14fab3857fe7689598956348a0 jdk7-b31 +b727c32788a906c04839516ae7443a085185a300 jdk7-b32 +585535ec8a14adafa6bfea65d6975e29094c8cec jdk7-b33 +5251a9cd8eb8743eee647365bee1c8afdc131556 jdk7-b34 +5fa96a5a7e76da7c8dad12486293a0456c2c116c jdk7-b35 +e91159f921a58af3698e6479ea1fc5818da66d09 jdk7-b36 +9ee9cf798b59e7d51f8c0a686959f313867a55d6 jdk7-b37 diff --git a/hotspot/agent/make/Makefile b/hotspot/agent/make/Makefile index ae10cb3cb97..bdde49eec1a 100644 --- a/hotspot/agent/make/Makefile +++ b/hotspot/agent/make/Makefile @@ -32,6 +32,12 @@ else include $(GAMMADIR)/make/defs.make endif +ifeq "x$(HOTSPOT_BUILD_VERSION)" "x" +SA_BUILD_VERSION=$(HOTSPOT_RELEASE_VERSION) +else +SA_BUILD_VERSION=$(HOTSPOT_RELEASE_VERSION)-$(HOTSPOT_BUILD_VERSION) +endif + PKGLIST = \ sun.jvm.hotspot \ sun.jvm.hotspot.asm \ @@ -117,7 +123,9 @@ sun.jvm.hotspot.ui.tree \ sun.jvm.hotspot.ui.treetable \ sun.jvm.hotspot.utilities \ sun.jvm.hotspot.utilities.memo \ -sun.jvm.hotspot.utilities.soql +sun.jvm.hotspot.utilities.soql \ +com.sun.java.swing.action \ +com.sun.java.swing.ui #END PKGLIST # Generated using the build-filelist script @@ -198,7 +206,9 @@ sun/jvm/hotspot/ui/tree/*.java \ sun/jvm/hotspot/ui/treetable/*.java \ sun/jvm/hotspot/utilities/*.java \ sun/jvm/hotspot/utilities/memo/*.java \ -sun/jvm/hotspot/utilities/soql/*.java +sun/jvm/hotspot/utilities/soql/*.java \ +com/sun/java/swing/action/*.java \ +com/sun/java/swing/ui/*.java #END FILELIST ifneq "x$(ALT_BOOTDIR)" "x" @@ -220,8 +230,6 @@ else endif SRC_DIR = ../src/share/classes -LIB_DIR = ../src/share/lib -CLOSED_LIB_DIR = ../closed/src/share/lib BUILD_DIR = ../build OUTPUT_DIR = $(BUILD_DIR)/classes DOC_DIR = $(BUILD_DIR)/doc @@ -231,9 +239,9 @@ DOC_DIR = $(BUILD_DIR)/doc ALLFILES := $(patsubst %,$(SRC_DIR)/%,$(FILELIST)) ALLFILES := $(shell /bin/ls $(ALLFILES)) +# tools.jar is used by the sa-jdi binding +CLASSPATH = $(JDK_HOME)/lib/tools.jar -# tools.jar is needed by the JDI - SA binding -CLASSPATH = $(LIB_DIR)/maf-1_0.jar$(CPS)$(JDK_HOME)/lib/tools.jar CLASSPATH := $(subst \,/,$(CLASSPATH)) # FIXME: autogenerate call to rmic @@ -241,24 +249,36 @@ CLASSPATH := $(subst \,/,$(CLASSPATH)) SA_BUILD_VERSION_PROP = "sun.jvm.hotspot.runtime.VM.saBuildVersion=$(SA_BUILD_VERSION)" SA_PROPERTIES = $(OUTPUT_DIR)/sa.properties +JAVAC = $(JDK_HOME)/bin/javac +JAVADOC = $(JDK_HOME)/bin/javadoc +RMIC = $(JDK_HOME)/bin/rmic # Tagging it on because there's no reason not to run it all: filelist @mkdir -p $(OUTPUT_DIR) @echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES) - @${JDK_HOME}/bin/javac -source 1.4 -classpath $(CLASSPATH) -deprecation -sourcepath $(SRC_DIR) -g -d $(OUTPUT_DIR) @filelist - @${JDK_HOME}/bin/rmic -classpath $(OUTPUT_DIR) -d $(OUTPUT_DIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer + $(JAVAC) -source 1.4 -classpath $(CLASSPATH) -deprecation -sourcepath $(SRC_DIR) -g -d $(OUTPUT_DIR) @filelist + $(RMIC) -classpath $(OUTPUT_DIR) -d $(OUTPUT_DIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql/sa.js cp $(SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql + mkdir -p $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources + rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources/* + cp $(SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources/ + cp -r $(SRC_DIR)/images/* $(OUTPUT_DIR)/ allprof: filelist @mkdir -p $(OUTPUT_DIR) @echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES) - @${JDK_HOME}/bin/javac -source 1.4 -J-Xprof -classpath $(CLASSPATH) -deprecation -sourcepath $(SRC_DIR) -g -d $(OUTPUT_DIR) @filelist - @${JDK_HOME}/bin/rmic -classpath $(OUTPUT_DIR) -d $(OUTPUT_DIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer + $(JAVAC) -source 1.4 -J-Xprof -classpath $(CLASSPATH) -deprecation -sourcepath $(SRC_DIR) -g -d $(OUTPUT_DIR) @filelist + $(RMIC) -classpath $(OUTPUT_DIR) -d $(OUTPUT_DIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql/sa.js cp $(SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql + mkdir -p $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources + rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources/* + cp $(SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources/ + cp -r $(SRC_DIR)/images/* $(OUTPUT_DIR)/ +.PHONY: filelist filelist: $(ALLFILES) @if [ ! -f $(JDK_HOME)/lib/tools.jar ] ; then \ echo "Missing $(JDK_HOME)/lib/tools.jar file. Use 1.6.0 or later version jdk to build SA."; \ @@ -274,36 +294,23 @@ natives: .PHONY: sa-jdi.jar sa-jdi.jar: - if [ ! -f $(JDK_HOME)/lib/tools.jar ] ; then \ - echo "Missing $(JDK_HOME)/lib/tools.jar file. Use 1.6.0 or later version jdk to build SA.";\ - exit 1; \ - fi - rm -f $(BUILD_DIR)/sa-jdi.jar - rm -f $(OUTPUT_DIR)/jdi_class_files - javac -source 1.4 ClosureFinder.java -d $(OUTPUT_DIR) - cd $(OUTPUT_DIR) ; find sun/jvm/hotspot/jdi -name "*.class" > jdi_class_files - cd $(OUTPUT_DIR) ; jar cvf ../sa-jdi.jar `java ClosureFinder jdi_class_files .` - cd $(BUILD_DIR) ; jar uvf sa-jdi.jar -C $(SRC_DIR) META-INF/services/com.sun.jdi.connect.Connector - cd $(BUILD_DIR) ; jar uvf sa-jdi.jar -C $(OUTPUT_DIR) sa.properties - rm -f $(OUTPUT_DIR)/ClosureFinder.class - rm -f $(OUTPUT_DIR)/jdi_class_files + echo "sa-jdi.jar is built by a hotspot build." docs: - @javadoc -private -classpath $(CLASSPATH) -sourcepath $(SRC_DIR) -d $(DOC_DIR) $(PKGLIST) + @$(JAVADOC) -private -classpath $(CLASSPATH) -sourcepath $(SRC_DIR) -d $(DOC_DIR) $(PKGLIST) sizes: $(ALLFILES) wc -l $(ALLFILES) cscope: $(ALLFILES) + rm -f java.files echo $(ALLFILES) > java.files cscope -b -i java.files -f java.out + rm -f java.files .PHONY: sa.jar sa.jar: rm -f $(BUILD_DIR)/sa.jar - mkdir -p $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources - rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources/* - cp $(SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources/ cd $(OUTPUT_DIR) ; jar cvf ../sa.jar * clean:: diff --git a/hotspot/agent/make/bugspot.bat b/hotspot/agent/make/bugspot.bat index da0880c4da8..07f407568e8 100644 --- a/hotspot/agent/make/bugspot.bat +++ b/hotspot/agent/make/bugspot.bat @@ -1,5 +1,5 @@ REM -REM Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved. +REM Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. REM REM This code is free software; you can redistribute it and/or modify it @@ -22,4 +22,4 @@ REM have any questions. REM REM -java -showversion -cp ..\build\classes;..\src\share\lib\maf-1_0.jar;..\src\share\lib\jlfgr-1_0.jar;..\src\share\lib\js.jar;sa.jar;lib\maf-1_0.jar;lib\jlfgr-1_0.jar;lib\js.jar sun.jvm.hotspot.bugspot.Main +java -showversion -cp ..\build\classes;..\src\share\lib\js.jar;.\sa.jar;lib\js.jar sun.jvm.hotspot.bugspot.Main diff --git a/hotspot/agent/make/build-pkglist b/hotspot/agent/make/build-pkglist index 64d9a96cabb..c7cac3dfc05 100644 --- a/hotspot/agent/make/build-pkglist +++ b/hotspot/agent/make/build-pkglist @@ -8,4 +8,4 @@ FIND=$MKS_HOME/find SED=$MKS_HOME/sed SORT=$MKS_HOME/sort -$CD ../src/share/classes; $FIND sun/jvm/hotspot \( -name SCCS -prune \) -o -type d -print | $SED -e 's/\//./g' | $SORT > ../../../make/pkglist.txt +$CD ../src/share/classes; $FIND sun/jvm/hotspot com/sun/java/swing -type d -print | $SED -e 's/\//./g' | $SORT > ../../../make/pkglist.txt diff --git a/hotspot/agent/make/build.xml b/hotspot/agent/make/build.xml index ebd5d39b785..d6f407e45f4 100644 --- a/hotspot/agent/make/build.xml +++ b/hotspot/agent/make/build.xml @@ -1,6 +1,6 @@ - - - - - + + + + + + + + + + + + diff --git a/hotspot/agent/make/hsdb.bat b/hotspot/agent/make/hsdb.bat index 6b12916d998..6b5cd35dd25 100644 --- a/hotspot/agent/make/hsdb.bat +++ b/hotspot/agent/make/hsdb.bat @@ -1,5 +1,5 @@ REM -REM Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved. +REM Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. REM REM This code is free software; you can redistribute it and/or modify it @@ -22,4 +22,4 @@ REM have any questions. REM REM -java -showversion -cp ..\build\classes;..\src\share\lib\maf-1_0.jar;..\src\share\lib\jlfgr-1_0.jar;..\src\share\lib\js.jar;sa.jar;lib\maf-1_0.jar;lib\jlfgr-1_0.jar;lib\js.jar sun.jvm.hotspot.HSDB %1 %2 +java -showversion -cp ..\build\classes;..\src\share\lib\js.jar;.\sa.jar;lib\js.jar sun.jvm.hotspot.HSDB %1 %2 diff --git a/hotspot/agent/make/hsdb.sh b/hotspot/agent/make/hsdb.sh index 3e5cc2df040..3e5e8b4a499 100644 --- a/hotspot/agent/make/hsdb.sh +++ b/hotspot/agent/make/hsdb.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -29,4 +29,4 @@ if [ "x$SA_JAVA" = "x" ]; then SA_JAVA=java fi -$SA_JAVA -showversion -cp $STARTDIR/../build/classes:$STARTDIR/../src/share/lib/maf-1_0.jar:$STARTDIR/../src/share/lib/jlfgr-1_0.jar:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar:$STARTDIR/lib/maf-1_0.jar:$STARTDIR/lib/jlfgr-1_0.jar:$STARTDIR/lib/js.jar sun.jvm.hotspot.HSDB $* +$SA_JAVA -showversion -cp $STARTDIR/../build/classes:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar:$STARTDIR/lib/js.jar sun.jvm.hotspot.HSDB $* diff --git a/hotspot/agent/make/saenv.bat b/hotspot/agent/make/saenv.bat index b5342027b98..aa5b927602e 100644 --- a/hotspot/agent/make/saenv.bat +++ b/hotspot/agent/make/saenv.bat @@ -1,6 +1,6 @@ @echo off REM -REM Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. +REM Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. REM REM This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ set SA_JAVA=java :sa_java_set -set SA_CLASSPATH=..\build\classes;..\src\share\lib\maf-1_0.jar;..\src\share\lib\jlfgr-1_0.jar;..\src\share\lib\js.jar;sa.jar;lib\maf-1_0.jar;lib\jlfgr-1_0.jar;lib\js.jar +set SA_CLASSPATH=..\build\classes;..\src\share\lib\js.jar;sa.jar;lib\js.jar set SA_LIBPATH=..\src\os\win32\windbg\i386;.\win32\i386 diff --git a/hotspot/agent/make/saenv.sh b/hotspot/agent/make/saenv.sh index e5e5c485dd4..38e0f78dbfc 100644 --- a/hotspot/agent/make/saenv.sh +++ b/hotspot/agent/make/saenv.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -58,7 +58,7 @@ if [ "x$SA_DISABLE_VERS_CHK" != "x" ]; then fi -SA_CLASSPATH=$STARTDIR/../build/classes:$STARTDIR/../src/share/lib/maf-1_0.jar:$STARTDIR/../src/share/lib/jlfgr-1_0.jar:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar:$STARTDIR/lib/maf-1_0.jar:$STARTDIR/lib/jlfgr-1_0.jar:$STARTDIR/lib/js.jar +SA_CLASSPATH=$STARTDIR/../build/classes:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar:$STARTDIR/lib/js.jar OPTIONS="-Djava.system.class.loader=sun.jvm.hotspot.SALauncherLoader ${OPTIONS}" diff --git a/hotspot/agent/make/saenv64.bat b/hotspot/agent/make/saenv64.bat index 84e30c31bc2..ef16f03475f 100644 --- a/hotspot/agent/make/saenv64.bat +++ b/hotspot/agent/make/saenv64.bat @@ -1,6 +1,6 @@ @echo off REM -REM Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. +REM Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. REM REM This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ set SA_JAVA=java :sa_java_set -set SA_CLASSPATH=..\build\classes;..\src\share\lib\maf-1_0.jar;..\src\share\lib\jlfgr-1_0.jar;..\src\share\lib\js.jar;sa.jar;lib\maf-1_0.jar;lib\jlfgr-1_0.jar;lib\js.jar +set SA_CLASSPATH=..\build\classes;..\src\share\lib\js.jar;sa.jar;lib\js.jar REM For now, only AMD-64, IA-64 stack walking is not working anyway set SA_LIBPATH=.\src\os\win32\windbg\amd64;.\win32\amd64 diff --git a/hotspot/agent/make/saenv64.sh b/hotspot/agent/make/saenv64.sh index ea22420496b..a443cb127b6 100644 --- a/hotspot/agent/make/saenv64.sh +++ b/hotspot/agent/make/saenv64.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -55,7 +55,7 @@ if [ "x$SA_DISABLE_VERS_CHK" != "x" ]; then OPTIONS="-Dsun.jvm.hotspot.runtime.VM.disableVersionCheck ${OPTIONS}" fi -SA_CLASSPATH=$STARTDIR/../build/classes:$STARTDIR/../src/share/lib/maf-1_0.jar:$STARTDIR/../src/share/lib/jlfgr-1_0.jar:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar:$STARTDIR/lib/maf-1_0.jar:$STARTDIR/lib/jlfgr-1_0.jar:$STARTDIR/lib/js.jar +SA_CLASSPATH=$STARTDIR/../build/classes:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar::$STARTDIR/lib/js.jar OPTIONS="-Djava.system.class.loader=sun.jvm.hotspot.SALauncherLoader ${OPTIONS}" diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/AboutAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/AboutAction.java new file mode 100644 index 00000000000..e6d1094a145 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/AboutAction.java @@ -0,0 +1,57 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class AboutAction extends DelegateAction +{ + + public AboutAction() + { + this("general/About16.gif"); + } + + public AboutAction(String iconPath) + { + super("About...", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "about-command"); + putValue("ShortDescription", "About..."); + putValue("LongDescription", "System information and version of the application."); + putValue("MnemonicKey", VALUE_MNEMONIC); + } + + public static final String VALUE_COMMAND = "about-command"; + public static final String VALUE_NAME = "About..."; + public static final String VALUE_SMALL_ICON = "general/About16.gif"; + public static final String VALUE_LARGE_ICON = "general/About24.gif"; + public static final Integer VALUE_MNEMONIC = new Integer(65); + public static final String VALUE_SHORT_DESCRIPTION = "About..."; + public static final String VALUE_LONG_DESCRIPTION = "System information and version of the application."; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/ActionManager.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ActionManager.java new file mode 100644 index 00000000000..d73fbda2eb7 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ActionManager.java @@ -0,0 +1,95 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import java.util.HashMap; +import javax.swing.Action; +import javax.swing.ImageIcon; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, StateChangeAction, ActionUtilities + +public abstract class ActionManager +{ + + protected ActionManager() + { + actions = new HashMap(); + addActions(); + } + + public static ActionManager getInstance() + { + return manager; + } + + protected abstract void addActions(); + + protected void addAction(String cmdname, Action action) + { + actions.put(cmdname, action); + } + + public Action getAction(String key) + { + return (Action)actions.get(key); + } + + public DelegateAction getDelegateAction(String name) + { + Action a = getAction(name); + if(a instanceof DelegateAction) + return (DelegateAction)a; + else + return null; + } + + public StateChangeAction getStateChangeAction(String name) + { + Action a = getAction(name); + if(a instanceof StateChangeAction) + return (StateChangeAction)a; + else + return null; + } + + public static ImageIcon getIcon(String name) + { + return utilities.getIcon(name); + } + + public void setActionEnabled(String name, boolean enabled) + { + Action action = getAction(name); + if(action != null) + action.setEnabled(enabled); + } + + private HashMap actions; + private static ActionUtilities utilities = new ActionUtilities(); + protected static ActionManager manager; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/ActionUtilities.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ActionUtilities.java new file mode 100644 index 00000000000..67097f77b00 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ActionUtilities.java @@ -0,0 +1,49 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.ImageIcon; + +class ActionUtilities +{ + + ActionUtilities() + { + } + + public ImageIcon getIcon(String name) + { + String imagePath = "/toolbarButtonGraphics/" + name; + java.net.URL url = getClass().getResource(imagePath); + if(url != null) + return new ImageIcon(url); + else + return null; + } + + public static final String IMAGE_DIR = "/toolbarButtonGraphics/"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignCenterAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignCenterAction.java new file mode 100644 index 00000000000..5ce24155ddd --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignCenterAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// StateChangeAction, ActionManager + +public class AlignCenterAction extends StateChangeAction +{ + + public AlignCenterAction() + { + this("text/AlignCenter16.gif"); + } + + public AlignCenterAction(String iconPath) + { + super("Center", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "align-center-command"); + putValue("ShortDescription", "Center"); + putValue("LongDescription", "Adjust the placement of text to the center of the line"); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "align-center-command"; + public static final String VALUE_NAME = "Center"; + public static final String VALUE_SMALL_ICON = "text/AlignCenter16.gif"; + public static final String VALUE_LARGE_ICON = "text/AlignCenter24.gif"; + public static final Integer VALUE_MNEMONIC = new Integer(78); + public static final KeyStroke VALUE_ACCELERATOR = KeyStroke.getKeyStroke(69, 2); + public static final String VALUE_SHORT_DESCRIPTION = "Center"; + public static final String VALUE_LONG_DESCRIPTION = "Adjust the placement of text to the center of the line"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignLeftAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignLeftAction.java new file mode 100644 index 00000000000..b94f2c102f1 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignLeftAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// StateChangeAction, ActionManager + +public class AlignLeftAction extends StateChangeAction +{ + + public AlignLeftAction() + { + this("text/AlignLeft16.gif"); + } + + public AlignLeftAction(String iconPath) + { + super("Left Align", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "align-left-command"); + putValue("ShortDescription", "Left Align"); + putValue("LongDescription", "Adjust the placement of text along the left edge"); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "align-left-command"; + public static final String VALUE_NAME = "Left Align"; + public static final String VALUE_SMALL_ICON = "text/AlignLeft16.gif"; + public static final String VALUE_LARGE_ICON = "text/AlignLeft24.gif"; + public static final Integer VALUE_MNEMONIC = new Integer(76); + public static final KeyStroke VALUE_ACCELERATOR = KeyStroke.getKeyStroke(76, 2); + public static final String VALUE_SHORT_DESCRIPTION = "Left Align"; + public static final String VALUE_LONG_DESCRIPTION = "Adjust the placement of text along the left edge"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignRightAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignRightAction.java new file mode 100644 index 00000000000..46c0204bf66 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignRightAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// StateChangeAction, ActionManager + +public class AlignRightAction extends StateChangeAction +{ + + public AlignRightAction() + { + this("text/AlignRight16.gif"); + } + + public AlignRightAction(String iconPath) + { + super("Right Align", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "align-right-command"); + putValue("ShortDescription", "Right Align"); + putValue("LongDescription", "Adjust the placement of text along the right edge"); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "align-right-command"; + public static final String VALUE_NAME = "Right Align"; + public static final String VALUE_SMALL_ICON = "text/AlignRight16.gif"; + public static final String VALUE_LARGE_ICON = "text/AlignRight24.gif"; + public static final Integer VALUE_MNEMONIC = new Integer(82); + public static final KeyStroke VALUE_ACCELERATOR = KeyStroke.getKeyStroke(82, 2); + public static final String VALUE_SHORT_DESCRIPTION = "Right Align"; + public static final String VALUE_LONG_DESCRIPTION = "Adjust the placement of text along the right edge"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/ApplyAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ApplyAction.java new file mode 100644 index 00000000000..0851431c873 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ApplyAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class ApplyAction extends DelegateAction +{ + + public ApplyAction() + { + this(VALUE_SMALL_ICON); + } + + public ApplyAction(String iconPath) + { + super("Apply", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "apply-command"); + putValue("ShortDescription", "Apply the activity"); + putValue("LongDescription", "Apply the activity"); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "apply-command"; + public static final String VALUE_NAME = "Apply"; + public static final String VALUE_SMALL_ICON = null; + public static final String VALUE_LARGE_ICON = null; + public static final Integer VALUE_MNEMONIC = new Integer(65); + public static final KeyStroke VALUE_ACCELERATOR = null; + public static final String VALUE_SHORT_DESCRIPTION = "Apply the activity"; + public static final String VALUE_LONG_DESCRIPTION = "Apply the activity"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/BackAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/BackAction.java new file mode 100644 index 00000000000..d0163cc37bc --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/BackAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class BackAction extends DelegateAction +{ + + public BackAction() + { + this(VALUE_SMALL_ICON); + } + + public BackAction(String iconPath) + { + super("< Back", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "back-command"); + putValue("ShortDescription", "Select previous item"); + putValue("LongDescription", "Select previous item"); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "back-command"; + public static final String VALUE_NAME = "< Back"; + public static final String VALUE_SMALL_ICON = null; + public static final String VALUE_LARGE_ICON = null; + public static final Integer VALUE_MNEMONIC = new Integer(66); + public static final KeyStroke VALUE_ACCELERATOR = null; + public static final String VALUE_SHORT_DESCRIPTION = "Select previous item"; + public static final String VALUE_LONG_DESCRIPTION = "Select previous item"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/CancelAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/CancelAction.java new file mode 100644 index 00000000000..aa9801d588f --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/CancelAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class CancelAction extends DelegateAction +{ + + public CancelAction() + { + this(VALUE_SMALL_ICON); + } + + public CancelAction(String iconPath) + { + super("Cancel", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "cancel-command"); + putValue("ShortDescription", "Cancels the action"); + putValue("LongDescription", "Cancels the action"); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "cancel-command"; + public static final String VALUE_NAME = "Cancel"; + public static final String VALUE_SMALL_ICON = null; + public static final String VALUE_LARGE_ICON = null; + public static final Integer VALUE_MNEMONIC = new Integer(67); + public static final KeyStroke VALUE_ACCELERATOR = null; + public static final String VALUE_SHORT_DESCRIPTION = "Cancels the action"; + public static final String VALUE_LONG_DESCRIPTION = "Cancels the action"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/DelegateAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/DelegateAction.java new file mode 100644 index 00000000000..41e7ed80322 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/DelegateAction.java @@ -0,0 +1,65 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.AbstractAction; +import javax.swing.Icon; + +public abstract class DelegateAction extends AbstractAction +{ + + public DelegateAction(String name, Icon icon) + { + super(name, icon); + } + + public void addActionListener(ActionListener listener) + { + this.listener = listener; + } + + public void removeActionListener(ActionListener listener) + { + this.listener = null; + } + + public ActionListener[] getActionListeners() + { + return (new ActionListener[] { + listener + }); + } + + public void actionPerformed(ActionEvent evt) + { + if(listener != null) + listener.actionPerformed(evt); + } + + private ActionListener listener; +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/ExitAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ExitAction.java new file mode 100644 index 00000000000..79c5d31dff8 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ExitAction.java @@ -0,0 +1,55 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class ExitAction extends DelegateAction +{ + + public ExitAction() + { + super("Exit", ActionManager.getIcon(VALUE_SMALL_ICON)); + putValue("ActionCommandKey", "exit-command"); + putValue("ShortDescription", "Exits the application"); + putValue("LongDescription", "Exits the application"); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "exit-command"; + public static final String VALUE_NAME = "Exit"; + public static final String VALUE_SMALL_ICON = null; + public static final String VALUE_LARGE_ICON = null; + public static final Integer VALUE_MNEMONIC = new Integer(88); + public static final KeyStroke VALUE_ACCELERATOR = null; + public static final String VALUE_SHORT_DESCRIPTION = "Exits the application"; + public static final String VALUE_LONG_DESCRIPTION = "Exits the application"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/FileMenu.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/FileMenu.java new file mode 100644 index 00000000000..ab078b1b5e7 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/FileMenu.java @@ -0,0 +1,53 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import java.awt.event.ActionEvent; +import javax.swing.AbstractAction; + +public class FileMenu extends AbstractAction +{ + + public FileMenu() + { + super("File"); + putValue("ActionCommandKey", "file-menu-command"); + putValue("ShortDescription", "File operations"); + putValue("LongDescription", "File operations"); + putValue("MnemonicKey", VALUE_MNEMONIC); + } + + public void actionPerformed(ActionEvent actionevent) + { + } + + public static final String VALUE_COMMAND = "file-menu-command"; + public static final String VALUE_NAME = "File"; + public static final Integer VALUE_MNEMONIC = new Integer(70); + public static final String VALUE_SHORT_DESCRIPTION = "File operations"; + public static final String VALUE_LONG_DESCRIPTION = "File operations"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/FinishAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/FinishAction.java new file mode 100644 index 00000000000..1e80dc2e7fc --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/FinishAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class FinishAction extends DelegateAction +{ + + public FinishAction() + { + this(VALUE_SMALL_ICON); + } + + public FinishAction(String iconPath) + { + super("Finish", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "finish-command"); + putValue("ShortDescription", "Finish the activity"); + putValue("LongDescription", "Finish the activity"); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "finish-command"; + public static final String VALUE_NAME = "Finish"; + public static final String VALUE_SMALL_ICON = null; + public static final String VALUE_LARGE_ICON = null; + public static final Integer VALUE_MNEMONIC = new Integer(70); + public static final KeyStroke VALUE_ACCELERATOR = null; + public static final String VALUE_SHORT_DESCRIPTION = "Finish the activity"; + public static final String VALUE_LONG_DESCRIPTION = "Finish the activity"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/HelpAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/HelpAction.java new file mode 100644 index 00000000000..73cf8ec1e5b --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/HelpAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class HelpAction extends DelegateAction +{ + + public HelpAction() + { + this("general/Help16.gif"); + } + + public HelpAction(String iconPath) + { + super("Help", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "help-command"); + putValue("ShortDescription", "Help..."); + putValue("LongDescription", "Provide information which may aid the user."); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "help-command"; + public static final String VALUE_NAME = "Help"; + public static final String VALUE_SMALL_ICON = "general/Help16.gif"; + public static final String VALUE_LARGE_ICON = "general/Help24.gif"; + public static final Integer VALUE_MNEMONIC = new Integer(72); + public static final KeyStroke VALUE_ACCELERATOR = KeyStroke.getKeyStroke(112, 0); + public static final String VALUE_SHORT_DESCRIPTION = "Help..."; + public static final String VALUE_LONG_DESCRIPTION = "Provide information which may aid the user."; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/HelpMenu.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/HelpMenu.java new file mode 100644 index 00000000000..c329ab4b47e --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/HelpMenu.java @@ -0,0 +1,53 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import java.awt.event.ActionEvent; +import javax.swing.AbstractAction; + +public class HelpMenu extends AbstractAction +{ + + public HelpMenu() + { + super("Help"); + putValue("ActionCommandKey", "help-menu-command"); + putValue("ShortDescription", "Help operations"); + putValue("LongDescription", "Help operations"); + putValue("MnemonicKey", VALUE_MNEMONIC); + } + + public void actionPerformed(ActionEvent actionevent) + { + } + + public static final String VALUE_COMMAND = "help-menu-command"; + public static final String VALUE_NAME = "Help"; + public static final Integer VALUE_MNEMONIC = new Integer(72); + public static final String VALUE_SHORT_DESCRIPTION = "Help operations"; + public static final String VALUE_LONG_DESCRIPTION = "Help operations"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/NewAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/NewAction.java new file mode 100644 index 00000000000..62d4f54a3ff --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/NewAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class NewAction extends DelegateAction +{ + + public NewAction() + { + this("general/New16.gif"); + } + + public NewAction(String iconPath) + { + super("New", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "new-command"); + putValue("ShortDescription", "Create a new object."); + putValue("LongDescription", "Create a new object."); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "new-command"; + public static final String VALUE_NAME = "New"; + public static final String VALUE_SMALL_ICON = "general/New16.gif"; + public static final String VALUE_LARGE_ICON = "general/New24.gif"; + public static final Integer VALUE_MNEMONIC = new Integer(78); + public static final KeyStroke VALUE_ACCELERATOR = KeyStroke.getKeyStroke(78, 2); + public static final String VALUE_SHORT_DESCRIPTION = "Create a new object."; + public static final String VALUE_LONG_DESCRIPTION = "Create a new object."; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/NextAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/NextAction.java new file mode 100644 index 00000000000..a133198ba70 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/NextAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class NextAction extends DelegateAction +{ + + public NextAction() + { + this(VALUE_SMALL_ICON); + } + + public NextAction(String iconPath) + { + super("Next >", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "next-command"); + putValue("ShortDescription", "Select next item"); + putValue("LongDescription", "Select next item"); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "next-command"; + public static final String VALUE_NAME = "Next >"; + public static final String VALUE_SMALL_ICON = null; + public static final String VALUE_LARGE_ICON = null; + public static final Integer VALUE_MNEMONIC = new Integer(78); + public static final KeyStroke VALUE_ACCELERATOR = null; + public static final String VALUE_SHORT_DESCRIPTION = "Select next item"; + public static final String VALUE_LONG_DESCRIPTION = "Select next item"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/OkAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/OkAction.java new file mode 100644 index 00000000000..87bd03efed3 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/OkAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class OkAction extends DelegateAction +{ + + public OkAction() + { + this(VALUE_SMALL_ICON); + } + + public OkAction(String iconPath) + { + super("OK", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "ok-command"); + putValue("ShortDescription", "Acknowleges the action"); + putValue("LongDescription", "Acknowleges the action"); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "ok-command"; + public static final String VALUE_NAME = "OK"; + public static final String VALUE_SMALL_ICON = null; + public static final String VALUE_LARGE_ICON = null; + public static final Integer VALUE_MNEMONIC = new Integer(79); + public static final KeyStroke VALUE_ACCELERATOR = null; + public static final String VALUE_SHORT_DESCRIPTION = "Acknowleges the action"; + public static final String VALUE_LONG_DESCRIPTION = "Acknowleges the action"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/OpenAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/OpenAction.java new file mode 100644 index 00000000000..82609a0ecb2 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/OpenAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class OpenAction extends DelegateAction +{ + + public OpenAction() + { + this("general/Open16.gif"); + } + + public OpenAction(String iconPath) + { + super("Open...", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "open-command"); + putValue("ShortDescription", "Open the specified object."); + putValue("LongDescription", "Open the specified object."); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "open-command"; + public static final String VALUE_NAME = "Open..."; + public static final String VALUE_SMALL_ICON = "general/Open16.gif"; + public static final String VALUE_LARGE_ICON = "general/Open24.gif"; + public static final Integer VALUE_MNEMONIC = new Integer(79); + public static final KeyStroke VALUE_ACCELERATOR = KeyStroke.getKeyStroke(79, 2); + public static final String VALUE_SHORT_DESCRIPTION = "Open the specified object."; + public static final String VALUE_LONG_DESCRIPTION = "Open the specified object."; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/SaveAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/SaveAction.java new file mode 100644 index 00000000000..3255d2856d8 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/SaveAction.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import javax.swing.KeyStroke; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class SaveAction extends DelegateAction +{ + + public SaveAction() + { + this("general/Save16.gif"); + } + + public SaveAction(String iconPath) + { + super("Save", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "save-command"); + putValue("ShortDescription", "Commit changes to a permanent storage area"); + putValue("LongDescription", "Commit changes to a permanent storage area"); + putValue("MnemonicKey", VALUE_MNEMONIC); + putValue("AcceleratorKey", VALUE_ACCELERATOR); + } + + public static final String VALUE_COMMAND = "save-command"; + public static final String VALUE_NAME = "Save"; + public static final String VALUE_SMALL_ICON = "general/Save16.gif"; + public static final String VALUE_LARGE_ICON = "general/Save24.gif"; + public static final Integer VALUE_MNEMONIC = new Integer(83); + public static final KeyStroke VALUE_ACCELERATOR = KeyStroke.getKeyStroke(83, 2); + public static final String VALUE_SHORT_DESCRIPTION = "Commit changes to a permanent storage area"; + public static final String VALUE_LONG_DESCRIPTION = "Commit changes to a permanent storage area"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/SaveAsAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/SaveAsAction.java new file mode 100644 index 00000000000..385024da9df --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/SaveAsAction.java @@ -0,0 +1,57 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction, ActionManager + +public class SaveAsAction extends DelegateAction +{ + + public SaveAsAction() + { + this("general/SaveAs16.gif"); + } + + public SaveAsAction(String iconPath) + { + super("Save As", ActionManager.getIcon(iconPath)); + putValue("ActionCommandKey", "save-as-command"); + putValue("ShortDescription", "Save as a new file"); + putValue("LongDescription", "Saves the current object as another object"); + putValue("MnemonicKey", VALUE_MNEMONIC); + } + + public static final String VALUE_COMMAND = "save-as-command"; + public static final String VALUE_NAME = "Save As"; + public static final String VALUE_SMALL_ICON = "general/SaveAs16.gif"; + public static final String VALUE_LARGE_ICON = "general/SaveAs24.gif"; + public static final Integer VALUE_MNEMONIC = new Integer(65); + public static final String VALUE_SHORT_DESCRIPTION = "Save as a new file"; + public static final String VALUE_LONG_DESCRIPTION = "Saves the current object as another object"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/StateChangeAction.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/StateChangeAction.java new file mode 100644 index 00000000000..d00761feeb8 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/StateChangeAction.java @@ -0,0 +1,88 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import javax.swing.Icon; + +// Referenced classes of package com.sun.java.swing.action: +// DelegateAction + +public abstract class StateChangeAction extends DelegateAction + implements ItemListener +{ + + public StateChangeAction(String name) + { + super(name, null); + selected = false; + } + + public StateChangeAction(String name, Icon icon) + { + super(name, icon); + selected = false; + } + + public boolean isSelected() + { + return selected; + } + + public synchronized void setSelected(boolean newValue) + { + boolean oldValue = selected; + if(oldValue != newValue) + { + selected = newValue; + firePropertyChange("selected", Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); + } + } + + public void setItemListener(ItemListener listener) + { + this.listener = listener; + } + + public ItemListener getItemListener() + { + return listener; + } + + public void itemStateChanged(ItemEvent evt) + { + if(evt.getStateChange() == 1) + setSelected(true); + else + setSelected(false); + if(listener != null) + listener.itemStateChanged(evt); + } + + protected boolean selected; + private ItemListener listener; +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/action/ViewMenu.java b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ViewMenu.java new file mode 100644 index 00000000000..5501ba8fcb7 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ViewMenu.java @@ -0,0 +1,53 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.action; + +import java.awt.event.ActionEvent; +import javax.swing.AbstractAction; + +public class ViewMenu extends AbstractAction +{ + + public ViewMenu() + { + super("View"); + putValue("ActionCommandKey", "view-menu-command"); + putValue("ShortDescription", "View operations"); + putValue("LongDescription", "View operations"); + putValue("MnemonicKey", VALUE_MNEMONIC); + } + + public void actionPerformed(ActionEvent actionevent) + { + } + + public static final String VALUE_COMMAND = "view-menu-command"; + public static final String VALUE_NAME = "View"; + public static final Integer VALUE_MNEMONIC = new Integer(86); + public static final String VALUE_SHORT_DESCRIPTION = "View operations"; + public static final String VALUE_LONG_DESCRIPTION = "View operations"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonMenuBar.java b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonMenuBar.java new file mode 100644 index 00000000000..20ebbb52111 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonMenuBar.java @@ -0,0 +1,108 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.ui; + +import com.sun.java.swing.action.ActionManager; +import com.sun.java.swing.action.StateChangeAction; +import javax.swing.*; + +// Referenced classes of package com.sun.java.swing.ui: +// ToggleActionPropertyChangeListener, StatusBar + +public abstract class CommonMenuBar extends JMenuBar +{ + + protected CommonMenuBar(ActionManager manager) + { + this(manager, StatusBar.getInstance()); + } + + protected CommonMenuBar(ActionManager manager, StatusBar status) + { + this.manager = manager; + statusBar = status; + configureMenu(); + } + + protected abstract void configureMenu(); + + protected void configureToggleMenuItem(JMenuItem menuItem, Action action) + { + configureMenuItem(menuItem, action); + action.addPropertyChangeListener(new ToggleActionPropertyChangeListener(menuItem)); + } + + protected void configureMenuItem(JMenuItem menuItem, Action action) + { + menuItem.addMouseListener(statusBar); + } + + protected JMenu createMenu(String name, char mnemonic) + { + JMenu menu = new JMenu(name); + menu.setMnemonic(mnemonic); + return menu; + } + + protected void addMenuItem(JMenu menu, Action action) + { + JMenuItem menuItem = menu.add(action); + configureMenuItem(menuItem, action); + } + + protected void addCheckBoxMenuItem(JMenu menu, StateChangeAction a) + { + addCheckBoxMenuItem(menu, a, false); + } + + protected void addCheckBoxMenuItem(JMenu menu, StateChangeAction a, boolean selected) + { + JCheckBoxMenuItem mi = new JCheckBoxMenuItem(a); + mi.addItemListener(a); + mi.setSelected(selected); + menu.add(mi); + configureToggleMenuItem(mi, a); + } + + protected void addRadioButtonMenuItem(JMenu menu, ButtonGroup group, StateChangeAction a) + { + addRadioButtonMenuItem(menu, group, a, false); + } + + protected void addRadioButtonMenuItem(JMenu menu, ButtonGroup group, StateChangeAction a, boolean selected) + { + JRadioButtonMenuItem mi = new JRadioButtonMenuItem(a); + mi.addItemListener(a); + mi.setSelected(selected); + menu.add(mi); + if(group != null) + group.add(mi); + configureToggleMenuItem(mi, a); + } + + protected ActionManager manager; + private StatusBar statusBar; +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonToolBar.java b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonToolBar.java new file mode 100644 index 00000000000..d65e06e3af8 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonToolBar.java @@ -0,0 +1,95 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.ui; + +import com.sun.java.swing.action.ActionManager; +import com.sun.java.swing.action.StateChangeAction; +import java.awt.Dimension; +import java.awt.Insets; +import javax.swing.*; + +// Referenced classes of package com.sun.java.swing.ui: +// ToggleActionPropertyChangeListener, StatusBar, CommonUI + +public abstract class CommonToolBar extends JToolBar +{ + + protected CommonToolBar(ActionManager manager) + { + this(manager, StatusBar.getInstance()); + } + + protected CommonToolBar(ActionManager manager, StatusBar status) + { + this.manager = manager; + statusBar = status; + buttonSize = new Dimension(CommonUI.buttconPrefSize); + buttonInsets = new Insets(0, 0, 0, 0); + addComponents(); + } + + protected abstract void addComponents(); + + protected void addButton(Action action) + { + javax.swing.JButton button = add(action); + configureButton(button, action); + } + + protected void addToggleButton(StateChangeAction a) + { + addToggleButton(a, null); + } + + protected void addToggleButton(StateChangeAction a, ButtonGroup group) + { + JToggleButton button = new JToggleButton(a); + button.addItemListener(a); + button.setSelected(a.isSelected()); + if(group != null) + group.add(button); + add(button); + configureToggleButton(button, a); + } + + protected void configureToggleButton(JToggleButton button, Action action) + { + configureButton(button, action); + action.addPropertyChangeListener(new ToggleActionPropertyChangeListener(button)); + } + + protected void configureButton(AbstractButton button, Action action) + { + button.setToolTipText((String)action.getValue("Name")); + button.setText(""); + button.addMouseListener(statusBar); + } + + protected ActionManager manager; + private Dimension buttonSize; + private Insets buttonInsets; + private StatusBar statusBar; +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonUI.java b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonUI.java new file mode 100644 index 00000000000..6429ea0fa31 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonUI.java @@ -0,0 +1,392 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.ui; + +import java.awt.*; +import java.awt.event.ActionListener; +import java.awt.event.KeyListener; +import java.util.StringTokenizer; +import java.util.Vector; +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.text.*; + +public class CommonUI +{ + private static class NumberDocument extends PlainDocument + { + + public void insertString(int offs, String str, AttributeSet atts) + throws BadLocationException + { + if(!Character.isDigit(str.charAt(0))) + { + return; + } else + { + super.insertString(offs, str, atts); + return; + } + } + + private NumberDocument() + { + } + + } + + + public CommonUI() + { + } + + public static JLabel createLabel(String text, int mnemonic, Component comp) + { + JLabel label = new JLabel(" " + text); + label.setMinimumSize(labelPrefSize); + if(mnemonic != -1) + label.setDisplayedMnemonic(mnemonic); + if(comp != null) + label.setLabelFor(comp); + if(text.length() == 0) + label.setPreferredSize(labelPrefSize); + return label; + } + + public static JLabel createLabel(String text) + { + return createLabel(text, -1, null); + } + + public static JTextField createTextField(String text, KeyListener listener, boolean numbers) + { + JTextField field = new JTextField(text); + field.setMinimumSize(textPrefSize); + if(text.length() == 0) + field.setPreferredSize(textPrefSize); + if(listener != null) + field.addKeyListener(listener); + if(numbers) + field.setDocument(new NumberDocument()); + return field; + } + + public static JTextField createTextField(String text, boolean numbers) + { + return createTextField(text, null, numbers); + } + + public static JTextField createTextField(String text, KeyListener listener) + { + return createTextField(text, listener, false); + } + + public static JTextField createTextField(String text) + { + return createTextField(text, null, false); + } + + public static JRadioButton createRadioButton(String text, int mnemonic, ActionListener listener, boolean selected) + { + JRadioButton button = new JRadioButton(text); + button.setMnemonic(mnemonic); + button.setSelected(selected); + button.setMinimumSize(labelPrefSize); + if(listener != null) + button.addActionListener(listener); + if(text.length() == 0) + button.setPreferredSize(labelPrefSize); + return button; + } + + public static JRadioButton createRadioButton(String text, int mnemonic, boolean selected) + { + return createRadioButton(text, mnemonic, null, selected); + } + + public static JRadioButton createRadioButton(String text, int mnemonic, ActionListener listener) + { + return createRadioButton(text, mnemonic, listener, false); + } + + public static JRadioButton createRadioButton(String text, int mnemonic) + { + return createRadioButton(text, mnemonic, null, false); + } + + public static JRadioButton createRadioButton(String text) + { + return createRadioButton(text, -1, null, false); + } + + public static JCheckBox createCheckBox(String text, int mnemonic, ActionListener listener, boolean selected) + { + JCheckBox checkbox = new JCheckBox(text); + checkbox.setMinimumSize(labelPrefSize); + if(mnemonic != -1) + checkbox.setMnemonic(mnemonic); + checkbox.setSelected(selected); + if(text.length() == 0) + checkbox.setPreferredSize(labelPrefSize); + if(listener != null) + checkbox.addActionListener(listener); + return checkbox; + } + + public static JCheckBox createCheckBox(String text, int mnemonic, ActionListener listener) + { + return createCheckBox(text, mnemonic, listener, false); + } + + public static JCheckBox createCheckBox(String text, int mnemonic, boolean selected) + { + return createCheckBox(text, mnemonic, null, selected); + } + + public static JCheckBox createCheckBox(String text, int mnemonic) + { + return createCheckBox(text, mnemonic, null, false); + } + + public static JCheckBox createCheckBox(String text) + { + return createCheckBox(text, -1, null, false); + } + + public static JComboBox createComboBox(Object items[], ActionListener listener, boolean editable) + { + JComboBox comboBox = new JComboBox(items); + if(listener != null) + comboBox.addActionListener(listener); + comboBox.setEditable(editable); + return comboBox; + } + + public static JComboBox createComboBox(Object items[], boolean editable) + { + return createComboBox(items, null, editable); + } + + public static JComboBox createComboBox(Vector items, ActionListener listener, boolean editable) + { + JComboBox comboBox = new JComboBox(items); + if(listener != null) + comboBox.addActionListener(listener); + comboBox.setEditable(editable); + return comboBox; + } + + public static JComboBox createComboBox(Vector items, boolean editable) + { + return createComboBox(items, null, editable); + } + + public static JButton createButton(Action action) + { + JButton button = new JButton(action); + setButtonSize(button, buttonPrefSize); + return button; + } + + public static JButton createButton(String text, ActionListener listener, int mnemonic) + { + JButton button = new JButton(text); + if(listener != null) + button.addActionListener(listener); + if(mnemonic != -1) + button.setMnemonic(mnemonic); + setButtonSize(button, buttonPrefSize); + return button; + } + + private static void setButtonSize(JButton button, Dimension size) + { + String text = button.getText(); + button.setMinimumSize(size); + if(text.length() == 0) + { + button.setPreferredSize(size); + } else + { + Dimension psize = button.getPreferredSize(); + if(psize.width < size.width) + button.setPreferredSize(size); + } + } + + public static JButton createButton(String text, ActionListener listener) + { + return createButton(text, listener, -1); + } + + public static JButton createSmallButton(String text, ActionListener listener, int mnemonic) + { + JButton button = createButton(text, listener, mnemonic); + setButtonSize(button, smbuttonPrefSize); + return button; + } + + public static JButton createSmallButton(String text, ActionListener listener) + { + return createSmallButton(text, listener, -1); + } + + public static Border createBorder(String text) + { + Border border = BorderFactory.createEtchedBorder(); + return BorderFactory.createTitledBorder(border, text, 0, 2); + } + + public static Border createBorder() + { + return BorderFactory.createEmptyBorder(4, 4, 4, 4); + } + + public static JScrollPane createListPane(JList list, String text) + { + JScrollPane pane = new JScrollPane(list); + pane.setBorder(BorderFactory.createCompoundBorder(createBorder(text), BorderFactory.createLoweredBevelBorder())); + return pane; + } + + public static void centerComponent(Component source, Component parent) + { + Dimension dim = source.getSize(); + Rectangle rect; + if(parent != null) + { + rect = parent.getBounds(); + } else + { + Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); + rect = new Rectangle(0, 0, d.width, d.height); + } + int x = rect.x + (rect.width - dim.width) / 2; + int y = rect.y + (rect.height - dim.height) / 2; + source.setLocation(x, y); + } + + public static void centerComponent(Component source) + { + centerComponent(source, null); + } + + public static JFrame getParentFrame(Component source) + { + Container parent; + for(parent = source.getParent(); parent != null; parent = parent.getParent()) + if(parent instanceof JFrame) + break; + + if(parent == null) + return null; + else + return (JFrame)parent; + } + + public static Integer msToSec(Integer ms) + { + int value = ms.intValue(); + value /= 1000; + return new Integer(value); + } + + public static Integer secToMs(Integer sec) + { + int value = sec.intValue(); + value *= 1000; + return new Integer(value); + } + + public static String stringFromStringArray(String strings[], String delim) + { + String string = ""; + String separator; + if(delim == null || delim.equals("")) + separator = " "; + else + separator = delim; + for(int i = 0; i < strings.length; i++) + { + string = string + strings[i]; + string = string + separator; + } + + return string; + } + + public static String stringFromStringArray(String strings[]) + { + return stringFromStringArray(strings, ""); + } + + public static String[] stringArrayFromString(String string, String delim) + { + StringTokenizer st; + if(delim == null || delim.equals("")) + st = new StringTokenizer(string); + else + st = new StringTokenizer(string, delim); + int numTokens = st.countTokens(); + String strings[] = new String[numTokens]; + int index = 0; + while(st.hasMoreTokens()) + strings[index++] = st.nextToken(); + return strings; + } + + public static String[] stringArrayFromString(String string) + { + return stringArrayFromString(string, ""); + } + + public static void setWaitCursor(Component comp) + { + comp.setCursor(Cursor.getPredefinedCursor(3)); + } + + public static void setDefaultCursor(Component comp) + { + comp.setCursor(Cursor.getPredefinedCursor(0)); + } + + public static final int BUTTON_WIDTH = 100; + public static final int BUTTON_HEIGHT = 26; + public static final int BUTTCON_WIDTH = 28; + public static final int BUTTCON_HEIGHT = 28; + public static final int SM_BUTTON_WIDTH = 72; + public static final int SM_BUTTON_HEIGHT = 26; + public static final int LABEL_WIDTH = 100; + public static final int LABEL_HEIGHT = 20; + public static final int TEXT_WIDTH = 150; + public static final int TEXT_HEIGHT = 20; + public static Dimension buttonPrefSize = new Dimension(100, 26); + public static Dimension buttconPrefSize = new Dimension(28, 28); + public static Dimension smbuttonPrefSize = new Dimension(72, 26); + public static Dimension labelPrefSize = new Dimension(100, 20); + public static Dimension textPrefSize = new Dimension(150, 20); + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/ui/OkCancelButtonPanel.java b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/OkCancelButtonPanel.java new file mode 100644 index 00000000000..d89404dffd7 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/OkCancelButtonPanel.java @@ -0,0 +1,51 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.ui; + +import com.sun.java.swing.action.*; +import java.awt.event.ActionListener; +import javax.swing.JPanel; + +// Referenced classes of package com.sun.java.swing.ui: +// CommonUI + +public class OkCancelButtonPanel extends JPanel +{ + + public OkCancelButtonPanel(ActionListener listener) + { + DelegateAction okAction = new OkAction(); + okAction.addActionListener(listener); + DelegateAction cancelAction = new CancelAction(); + cancelAction.addActionListener(listener); + add(CommonUI.createButton(okAction)); + add(CommonUI.createButton(cancelAction)); + } + + public static final String OK_COMMAND = "ok-command"; + public static final String CANCEL_COMMAND = "cancel-command"; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/ui/OkCancelDialog.java b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/OkCancelDialog.java new file mode 100644 index 00000000000..619a97c4fb8 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/OkCancelDialog.java @@ -0,0 +1,82 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.ui; + +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.JDialog; +import javax.swing.JPanel; + +// Referenced classes of package com.sun.java.swing.ui: +// OkCancelButtonPanel, CommonUI + +public class OkCancelDialog extends JDialog + implements ActionListener +{ + + public OkCancelDialog(String title, JPanel panel) + { + this(title, panel, true); + } + + public OkCancelDialog(String title, JPanel panel, boolean modal) + { + setTitle(title); + setModal(modal); + Container pane = getContentPane(); + pane.setLayout(new BorderLayout()); + pane.add(panel, "Center"); + pane.add(new OkCancelButtonPanel(this), "South"); + pack(); + CommonUI.centerComponent(this); + } + + public boolean isOk() + { + return okPressed; + } + + public void actionPerformed(ActionEvent evt) + { + String command = evt.getActionCommand(); + if(command.equals("ok-command")) + { + okPressed = true; + setVisible(false); + dispose(); + } else + if(command.equals("cancel-command")) + { + okPressed = false; + setVisible(false); + dispose(); + } + } + + private boolean okPressed; +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/ui/SplashScreen.java b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/SplashScreen.java new file mode 100644 index 00000000000..4f575f9cc03 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/SplashScreen.java @@ -0,0 +1,85 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.ui; + +import java.awt.*; +import javax.swing.ImageIcon; + +public class SplashScreen extends Window +{ + + public SplashScreen(Frame f) + { + super(f); + setBackground(Color.white); + java.net.URL url = getClass().getResource("/images/SplashScreen.jpg"); + if(url != null) + { + screen = new ImageIcon(url); + MediaTracker mt = new MediaTracker(this); + mt.addImage(screen.getImage(), 0); + try + { + mt.waitForAll(); + } + catch(Exception ex) { } + } + } + + public void setVisible(boolean val) + { + if(screen == null) + return; + if(val) + { + setSize(screen.getIconWidth(), screen.getIconHeight()); + setLocation(-500, -500); + super.setVisible(true); + Dimension d = getToolkit().getScreenSize(); + Insets i = getInsets(); + int w = screen.getIconWidth() + i.left + i.right; + int h = screen.getIconHeight() + i.top + i.bottom; + setSize(w, h); + setLocation(d.width / 2 - w / 2, d.height / 2 - h / 2); + } else + { + super.setVisible(false); + } + } + + public void paint(Graphics g) + { + if(screen != null) + { + Dimension d = getSize(); + g.setColor(Color.black); + g.drawRect(0, 0, d.width - 1, d.height - 1); + g.drawImage(screen.getImage(), 1, 1, this); + } + } + + private ImageIcon screen; +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/ui/StatusBar.java b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/StatusBar.java new file mode 100644 index 00000000000..dd041974216 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/StatusBar.java @@ -0,0 +1,178 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.ui; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +public class StatusBar extends JPanel + implements ActionListener, MouseListener +{ + + public StatusBar() + { + setLayout(new FlowLayout(0)); + setBorder(BorderFactory.createEtchedBorder()); + progressBar = new JProgressBar(0, 0, 100); + progressBar.setPreferredSize(new Dimension(60, progressBar.getPreferredSize().height + 2)); + progressBar.setVisible(false); + label = new JLabel(" "); + preferredSize = new Dimension(getWidth(label.getText()), 2 * getFontHeight()); + add(progressBar); + add(label); + } + + public static StatusBar getInstance() + { + if(statusBar == null) + statusBar = new StatusBar(); + return statusBar; + } + + public static void setInstance(StatusBar sb) + { + statusBar = sb; + } + + protected int getWidth(String s) + { + FontMetrics fm = getFontMetrics(getFont()); + if(fm == null) + return 0; + else + return fm.stringWidth(s); + } + + protected int getFontHeight() + { + FontMetrics fm = getFontMetrics(getFont()); + if(fm == null) + return 0; + else + return fm.getHeight(); + } + + public Dimension getPreferredSize() + { + return preferredSize; + } + + public void setMessage(String message) + { + label.setText(message); + label.repaint(); + } + + public void startBusyBar() + { + forward = true; + if(timer == null) + { + setMessage(""); + progressBar.setVisible(true); + timer = new Timer(15, this); + timer.start(); + } + } + + public void stopBusyBar() + { + if(timer != null) + { + timer.stop(); + timer = null; + } + setMessage(""); + progressBar.setVisible(false); + progressBar.setValue(0); + } + + public void actionPerformed(ActionEvent evt) + { + int value = progressBar.getValue(); + if(forward) + { + if(value < 100) + { + progressBar.setValue(value + 1); + } else + { + forward = false; + progressBar.setValue(value - 1); + } + } else + if(value > 0) + { + progressBar.setValue(value - 1); + } else + { + forward = true; + progressBar.setValue(value + 1); + } + } + + public void mouseClicked(MouseEvent mouseevent) + { + } + + public void mousePressed(MouseEvent mouseevent) + { + } + + public void mouseReleased(MouseEvent mouseevent) + { + } + + public void mouseExited(MouseEvent evt) + { + setMessage(""); + } + + public void mouseEntered(MouseEvent evt) + { + if(evt.getSource() instanceof AbstractButton) + { + AbstractButton button = (AbstractButton)evt.getSource(); + Action action = button.getAction(); + if(action != null) + { + String message = (String)action.getValue("LongDescription"); + setMessage(message); + } + } + } + + private static final int PROGRESS_MAX = 100; + private static final int PROGRESS_MIN = 0; + private JLabel label; + private Dimension preferredSize; + private JProgressBar progressBar; + private Timer timer; + private boolean forward; + private static StatusBar statusBar; + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/ui/TabsDlg.java b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/TabsDlg.java new file mode 100644 index 00000000000..bace0097ef6 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/TabsDlg.java @@ -0,0 +1,221 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.ui; + +import com.sun.java.swing.action.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Vector; +import javax.swing.*; + +// Referenced classes of package com.sun.java.swing.ui: +// CommonUI + +public class TabsDlg extends JDialog +{ + private class ApplyListener + implements ActionListener + { + + public void actionPerformed(ActionEvent evt) + { + if(applyListener != null) + { + applyListener.actionPerformed(evt); + enableApplyButton(false); + } + } + + private ApplyListener() + { + } + + } + + private class CancelListener + implements ActionListener + { + + public void actionPerformed(ActionEvent evt) + { + if(cancelListener != null) + cancelListener.actionPerformed(evt); + setVisible(false); + } + + private CancelListener() + { + } + + } + + private class OkListener + implements ActionListener + { + + public void actionPerformed(ActionEvent evt) + { + if(okListener != null) + okListener.actionPerformed(evt); + setVisible(false); + } + + private OkListener() + { + } + + } + + + public TabsDlg(String title, Vector panels) + { + super(new JFrame(), title, true); + okListener = null; + cancelListener = null; + applyListener = null; + Container pane = getContentPane(); + pane.setLayout(new BorderLayout()); + tabsPanel = new JTabbedPane(); + int numPanels = panels.size(); + for(int i = 0; i < numPanels; i++) + { + JPanel panel = (JPanel)panels.elementAt(i); + tabsPanel.addTab(panel.getName(), panel); + } + + pane.add(tabsPanel, "Center"); + pane.add(createButtonPanel(), "South"); + pack(); + CommonUI.centerComponent(this); + } + + public static void main(String args[]) + { + JPanel p1 = new JPanel(); + p1.add(new JButton("One")); + p1.setName("One"); + JPanel p2 = new JPanel(); + p2.add(new JButton("Two")); + p2.setName("Two"); + JPanel p3 = new JPanel(); + p3.add(new JButton("Three")); + p3.setName("Three"); + JPanel p4 = new JPanel(); + p4.add(new JButton("Four")); + p4.setName("Four"); + Vector panels = new Vector(); + panels.addElement(p1); + panels.addElement(p2); + panels.addElement(p3); + panels.addElement(p4); + tabsDlg = new TabsDlg("Test Dialog", panels); + tabsDlg.addOkListener(new ActionListener() { + + public void actionPerformed(ActionEvent evt) + { + System.exit(0); + } + + } +); + tabsDlg.addCancelListener(new ActionListener() { + + public void actionPerformed(ActionEvent evt) + { + System.exit(0); + } + + } +); + tabsDlg.setVisible(true); + } + + private JPanel createButtonPanel() + { + JPanel panel = new JPanel(); + okAction = new OkAction(); + cancelAction = new CancelAction(); + applyAction = new ApplyAction(); + okAction.addActionListener(new OkListener()); + cancelAction.addActionListener(new CancelListener()); + applyAction.addActionListener(new ApplyListener()); + panel.add(CommonUI.createButton(okAction)); + panel.add(CommonUI.createButton(cancelAction)); + panel.add(CommonUI.createButton(applyAction)); + JPanel p2 = new JPanel(new BorderLayout()); + p2.add(panel, "Center"); + p2.add(new JSeparator(), "North"); + return p2; + } + + public void enableApplyButton(boolean enabled) + { + applyAction.setEnabled(enabled); + } + + public synchronized void addOkListener(ActionListener l) + { + okListener = AWTEventMulticaster.add(okListener, l); + } + + public synchronized void removeOkListener(ActionListener l) + { + okListener = AWTEventMulticaster.remove(okListener, l); + } + + public synchronized void addCancelListener(ActionListener l) + { + cancelListener = AWTEventMulticaster.add(cancelListener, l); + } + + public synchronized void removeCancelListener(ActionListener l) + { + cancelListener = AWTEventMulticaster.remove(cancelListener, l); + } + + public synchronized void addApplyListener(ActionListener l) + { + applyListener = AWTEventMulticaster.add(applyListener, l); + } + + public synchronized void removeApplyListener(ActionListener l) + { + applyListener = AWTEventMulticaster.remove(applyListener, l); + } + + private JTabbedPane tabsPanel; + private DelegateAction okAction; + private DelegateAction cancelAction; + private DelegateAction applyAction; + private ActionListener okListener; + private ActionListener cancelListener; + private ActionListener applyListener; + private static TabsDlg tabsDlg; + + + +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/ui/ToggleActionPropertyChangeListener.java b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/ToggleActionPropertyChangeListener.java new file mode 100644 index 00000000000..afeeece4960 --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/ToggleActionPropertyChangeListener.java @@ -0,0 +1,52 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.ui; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.AbstractButton; + +public class ToggleActionPropertyChangeListener + implements PropertyChangeListener +{ + + public ToggleActionPropertyChangeListener(AbstractButton button) + { + this.button = button; + } + + public void propertyChange(PropertyChangeEvent evt) + { + String propertyName = evt.getPropertyName(); + if(propertyName.equals("selected")) + { + Boolean selected = (Boolean)evt.getNewValue(); + button.setSelected(selected.booleanValue()); + } + } + + private AbstractButton button; +} diff --git a/hotspot/agent/src/share/classes/com/sun/java/swing/ui/WizardDlg.java b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/WizardDlg.java new file mode 100644 index 00000000000..cd2a696b19a --- /dev/null +++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/WizardDlg.java @@ -0,0 +1,336 @@ +/* + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +package com.sun.java.swing.ui; + +import com.sun.java.swing.action.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Vector; +import javax.swing.*; + +// Referenced classes of package com.sun.java.swing.ui: +// CommonUI + +public class WizardDlg extends JDialog +{ + private class CancelListener + implements ActionListener + { + + public void actionPerformed(ActionEvent evt) + { + if(cancelListener != null) + cancelListener.actionPerformed(evt); + setVisible(false); + } + + private CancelListener() + { + } + + } + + private class FinishListener + implements ActionListener + { + + public void actionPerformed(ActionEvent evt) + { + if(finishListener != null) + finishListener.actionPerformed(evt); + setVisible(false); + } + + private FinishListener() + { + } + + } + + private class NextListener + implements ActionListener + { + + public void actionPerformed(ActionEvent evt) + { + cardShowing++; + if(cardShowing > numCards) + cardShowing = numCards; + else + panesLayout.next(panesPanel); + if(nextListener != null) + nextListener.actionPerformed(evt); + enableBackNextButtons(); + } + + private NextListener() + { + } + + } + + private class BackListener + implements ActionListener + { + + public void actionPerformed(ActionEvent evt) + { + cardShowing--; + if(cardShowing < 1) + cardShowing = 1; + else + panesLayout.previous(panesPanel); + if(backListener != null) + backListener.actionPerformed(evt); + enableBackNextButtons(); + } + + private BackListener() + { + } + + } + + + public WizardDlg(JFrame frame, String title, Vector panels, Vector images) + { + super(frame, title, true); + this.title = title; + this.images = images; + Container pane = getContentPane(); + pane.setLayout(new BorderLayout()); + panesLayout = new CardLayout(); + panesPanel = new JPanel(panesLayout); + pane.add(panesPanel, "Center"); + pane.add(createButtonPanel(), "South"); + setPanels(panels); + pack(); + CommonUI.centerComponent(this); + } + + public WizardDlg(JFrame frame, String title, Vector panels) + { + this(frame, title, panels, null); + } + + public WizardDlg(String title, Vector panels) + { + this(new JFrame(), title, panels, null); + } + + public void setPanels(Vector panels) + { + numCards = panels.size(); + cardShowing = 1; + this.panels = panels; + panesPanel.removeAll(); + for(int i = 0; i < numCards; i++) + panesPanel.add((JPanel)panels.elementAt(i), (new Integer(i)).toString()); + + validate(); + enableBackNextButtons(); + } + + public void reset() + { + cardShowing = 1; + panesLayout.first(panesPanel); + enableBackNextButtons(); + } + + public void setWestPanel(JPanel panel) + { + Container pane = getContentPane(); + pane.add(panel, "West"); + } + + public static void main(String args[]) + { + JPanel p1 = new JPanel(); + p1.add(new JButton("One")); + JPanel p2 = new JPanel(); + p2.add(new JButton("Two")); + JPanel p3 = new JPanel(); + p3.add(new JButton("Three")); + JPanel p4 = new JPanel(); + p4.add(new JButton("Four")); + Vector panels = new Vector(); + panels.addElement(p1); + panels.addElement(p2); + panels.addElement(p3); + panels.addElement(p4); + wizardDlg = new WizardDlg("Test Dialog", panels); + wizardDlg.addFinishListener(new ActionListener() { + + public void actionPerformed(ActionEvent evt) + { + System.exit(0); + } + + } +); + wizardDlg.addCancelListener(new ActionListener() { + + public void actionPerformed(ActionEvent evt) + { + System.exit(0); + } + + } +); + wizardDlg.setVisible(true); + } + + private JPanel createButtonPanel() + { + JPanel panel = new JPanel(); + backAction = new BackAction(); + nextAction = new NextAction(); + finishAction = new FinishAction(); + cancelAction = new CancelAction(); + backAction.setEnabled(false); + finishAction.setEnabled(false); + backAction.addActionListener(new BackListener()); + nextAction.addActionListener(new NextListener()); + finishAction.addActionListener(new FinishListener()); + cancelAction.addActionListener(new CancelListener()); + panel.add(CommonUI.createButton(backAction)); + panel.add(CommonUI.createButton(nextAction)); + panel.add(CommonUI.createButton(finishAction)); + panel.add(CommonUI.createButton(cancelAction)); + JPanel p2 = new JPanel(new BorderLayout()); + p2.add(panel, "Center"); + p2.add(new JSeparator(), "North"); + return p2; + } + + private void enableBackNextButtons() + { + if(cardShowing == 1) + { + backAction.setEnabled(false); + finishAction.setEnabled(false); + if(numCards > 1) + { + nextAction.setEnabled(true); + } else + { + finishAction.setEnabled(true); + nextAction.setEnabled(false); + } + } else + if(cardShowing == numCards) + { + nextAction.setEnabled(false); + finishAction.setEnabled(true); + if(numCards > 1) + backAction.setEnabled(true); + else + backAction.setEnabled(false); + } else + { + backAction.setEnabled(true); + nextAction.setEnabled(true); + finishAction.setEnabled(false); + } + setTitle(); + } + + private void setTitle() + { + JPanel panel = (JPanel)panels.elementAt(cardShowing - 1); + String newTitle = title; + String panelTitle = panel.getName(); + if(panelTitle != null && panelTitle.equals("")) + { + newTitle = newTitle + " - "; + newTitle = newTitle + panelTitle; + } + super.setTitle(newTitle); + } + + public synchronized void addFinishListener(ActionListener l) + { + finishListener = AWTEventMulticaster.add(finishListener, l); + } + + public synchronized void removeFinishListener(ActionListener l) + { + finishListener = AWTEventMulticaster.remove(finishListener, l); + } + + public synchronized void addCancelListener(ActionListener l) + { + cancelListener = AWTEventMulticaster.add(cancelListener, l); + } + + public synchronized void removeCancelListener(ActionListener l) + { + cancelListener = AWTEventMulticaster.remove(cancelListener, l); + } + + public synchronized void addNextListener(ActionListener l) + { + nextListener = AWTEventMulticaster.add(nextListener, l); + } + + public synchronized void removeNextListener(ActionListener l) + { + nextListener = AWTEventMulticaster.remove(nextListener, l); + } + + public synchronized void addBackListener(ActionListener l) + { + backListener = AWTEventMulticaster.add(backListener, l); + } + + public synchronized void removeBackListener(ActionListener l) + { + backListener = AWTEventMulticaster.remove(backListener, l); + } + + private CardLayout panesLayout; + private JPanel panesPanel; + private DelegateAction backAction; + private DelegateAction nextAction; + private DelegateAction finishAction; + private DelegateAction cancelAction; + private ActionListener finishListener; + private ActionListener cancelListener; + private ActionListener nextListener; + private ActionListener backListener; + private int numCards; + private int cardShowing; + private String title; + private Vector panels; + private Vector images; + private static WizardDlg wizardDlg; + + + + +} diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/development/Server16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/development/Server16.gif new file mode 100644 index 00000000000..4e76682efa3 Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/development/Server16.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/development/Server24.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/development/Server24.gif new file mode 100644 index 00000000000..8a5092450b4 Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/development/Server24.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/About16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/About16.gif new file mode 100644 index 00000000000..04da95eb831 Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/About16.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/About24.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/About24.gif new file mode 100644 index 00000000000..9e1168954af Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/About24.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Delete16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Delete16.gif new file mode 100644 index 00000000000..d9d1a338f4d Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Delete16.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Delete24.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Delete24.gif new file mode 100644 index 00000000000..96d799a0af0 Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Delete24.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Find16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Find16.gif new file mode 100644 index 00000000000..abafbe28cfa Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Find16.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Help16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Help16.gif new file mode 100644 index 00000000000..dc5c2d310de Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Help16.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Help24.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Help24.gif new file mode 100644 index 00000000000..a2848d880e7 Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Help24.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/History16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/History16.gif new file mode 100644 index 00000000000..bc278f9ae9b Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/History16.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/History24.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/History24.gif new file mode 100644 index 00000000000..0bd250fb577 Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/History24.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Information16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Information16.gif new file mode 100644 index 00000000000..5748e325f15 Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Information16.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Information24.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Information24.gif new file mode 100644 index 00000000000..16cb3def157 Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Information24.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/New16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/New16.gif new file mode 100644 index 00000000000..3513dfddbb9 Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/New16.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/New24.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/New24.gif new file mode 100644 index 00000000000..1cc488d4524 Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/New24.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Open16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Open16.gif new file mode 100644 index 00000000000..fabd5676f96 Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Open16.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Open24.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Open24.gif new file mode 100644 index 00000000000..2086bc29630 Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Open24.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Save16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Save16.gif new file mode 100644 index 00000000000..954f1accde6 Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Save16.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Save24.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Save24.gif new file mode 100644 index 00000000000..bfa98a8df0a Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Save24.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/SaveAs16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/SaveAs16.gif new file mode 100644 index 00000000000..8d3929c8aa7 Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/SaveAs16.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/SaveAs24.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/SaveAs24.gif new file mode 100644 index 00000000000..97eb6fa30d3 Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/SaveAs24.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Zoom16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Zoom16.gif new file mode 100644 index 00000000000..9e488969a62 Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Zoom16.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/ZoomIn16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/ZoomIn16.gif new file mode 100644 index 00000000000..2329426e481 Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/ZoomIn16.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/ZoomIn24.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/ZoomIn24.gif new file mode 100644 index 00000000000..dbd44778a3d Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/ZoomIn24.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/navigation/Down16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/navigation/Down16.gif new file mode 100644 index 00000000000..39849181f1d Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/navigation/Down16.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/navigation/Up16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/navigation/Up16.gif new file mode 100644 index 00000000000..cebe60d956c Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/navigation/Up16.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignCenter16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignCenter16.gif new file mode 100644 index 00000000000..34c09f34d2a Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignCenter16.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignCenter24.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignCenter24.gif new file mode 100644 index 00000000000..d4baf4ef07f Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignCenter24.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignLeft16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignLeft16.gif new file mode 100644 index 00000000000..235e780fbca Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignLeft16.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignLeft24.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignLeft24.gif new file mode 100644 index 00000000000..85631ca5b01 Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignLeft24.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignRight16.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignRight16.gif new file mode 100644 index 00000000000..9c06d30c456 Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignRight16.gif differ diff --git a/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignRight24.gif b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignRight24.gif new file mode 100644 index 00000000000..25a77d35a81 Binary files /dev/null and b/hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignRight24.gif differ diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/Location.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/Location.java index 160712104af..47d25fb6210 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/Location.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/Location.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,9 +39,9 @@ import sun.jvm.hotspot.utilities.*;

    Encoding:

         bits:
    -    Where:  [15]
    -    Type:   [14..12]
    -    Offset: [11..0]
    +    Type:   [3..0]
    +    Where:  [4]
    +    Offset: [31..5]
         
    */ @@ -69,6 +69,7 @@ public class Location { // Location::Type constants TYPE_NORMAL = db.lookupIntConstant("Location::normal").intValue(); TYPE_OOP = db.lookupIntConstant("Location::oop").intValue(); + TYPE_NARROWOOP = db.lookupIntConstant("Location::narrowoop").intValue(); TYPE_INT_IN_LONG = db.lookupIntConstant("Location::int_in_long").intValue(); TYPE_LNG = db.lookupIntConstant("Location::lng").intValue(); TYPE_FLOAT_IN_DBL = db.lookupIntConstant("Location::float_in_dbl").intValue(); @@ -115,6 +116,8 @@ public class Location { public static final Type NORMAL = new Type("normal"); /** Oop (please GC me!) */ public static final Type OOP = new Type("oop"); + /** NarrowOop (please GC me!) */ + public static final Type NARROWOOP = new Type("narrowoop"); /** Long held in one register */ public static final Type INT_IN_LONG = new Type("int_in_long"); /** Long held in one register */ @@ -142,6 +145,8 @@ public class Location { return TYPE_NORMAL; } else if (this == OOP) { return TYPE_OOP; + } else if (this == NARROWOOP) { + return TYPE_NARROWOOP; } else if (this == INT_IN_LONG) { return TYPE_INT_IN_LONG; } else if (this == LNG) { @@ -170,6 +175,7 @@ public class Location { // constants in Type enum private static int TYPE_NORMAL; private static int TYPE_OOP; + private static int TYPE_NARROWOOP; private static int TYPE_INT_IN_LONG; private static int TYPE_LNG; private static int TYPE_FLOAT_IN_DBL; @@ -185,7 +191,7 @@ public class Location { Location(Where where, Type type, int offset) { setWhere(where); setType(type); - setOffset(offset & 0x0000FFFF); + setOffset(offset); } public Where getWhere() { @@ -205,6 +211,8 @@ public class Location { return Type.NORMAL; } else if (type == TYPE_OOP) { return Type.OOP; + } else if (type == TYPE_NARROWOOP) { + return Type.NARROWOOP; } else if (type == TYPE_INT_IN_LONG) { return Type.INT_IN_LONG; } else if (type == TYPE_LNG) { @@ -238,6 +246,10 @@ public class Location { return getType() == Type.OOP; } + public boolean holdsNarrowOop() { + return getType() == Type.NARROWOOP; + } + public boolean holdsInt() { return getType() == Type.INT_IN_LONG; } @@ -266,7 +278,7 @@ public class Location { if (Assert.ASSERTS_ENABLED) { Assert.that(getWhere() == Where.ON_STACK, "wrong Where"); } - return getOffset() << VM.getVM().getLogAddressSize(); + return getOffset() * (int)VM.getVM().getIntSize(); } public int getRegisterNumber() { @@ -296,6 +308,8 @@ public class Location { if (type == Type.NORMAL) { } else if (type == Type.OOP) { tty.print(",oop"); + } else if (type == Type.NARROWOOP) { + tty.print(",narrowoop"); } else if (type == Type.INT_IN_LONG) { tty.print(",int"); } else if (type == Type.LNG) { @@ -314,26 +328,26 @@ public class Location { /** Serialization of debugging information */ public Location(DebugInfoReadStream stream) { - value = (0x0000FFFF & stream.readInt()); + value = stream.readInt(); } // FIXME: not yet implementable // void write_on(DebugInfoWriteStream* stream); - //-------------------------------------------------------------------------------- + //----------------------------------------------------------------------------- // Internals only below this point // private void setWhere(Where where) { - value |= (where.getValue() << WHERE_SHIFT); + value |= ((where.getValue() << WHERE_SHIFT) & WHERE_MASK); } private void setType(Type type) { - value |= (type.getValue() << TYPE_SHIFT); + value |= ((type.getValue() << TYPE_SHIFT) & TYPE_MASK); } private void setOffset(int offset) { - value |= (offset << OFFSET_SHIFT); + value |= ((offset << OFFSET_SHIFT) & OFFSET_MASK); } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/CompiledVFrame.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/CompiledVFrame.java index fc12a0abbd1..1642fefe2cb 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/CompiledVFrame.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/CompiledVFrame.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -206,6 +206,16 @@ public class CompiledVFrame extends JavaVFrame { Assert.that( loc.isRegister(), "ints always saved to stack in 1 word" ); } return new StackValue(valueAddr.getJLongAt(0) & 0xFFFFFFFF); + } else if (loc.holdsNarrowOop()) { // Holds an narrow oop? + if (loc.isRegister() && VM.getVM().isBigEndian()) { + // The callee has no clue whether the register holds an narrow oop, + // long or is unused. He always saves a long. Here we know + // a long was saved, but we only want an narrow oop back. Narrow the + // saved long to the narrow oop that the JVM wants. + return new StackValue(valueAddr.getCompOopHandleAt(VM.getVM().getIntSize())); + } else { + return new StackValue(valueAddr.getCompOopHandleAt(0)); + } } else if( loc.holdsOop() ) { // Holds an oop? return new StackValue(valueAddr.getOopHandleAt(0)); } else if( loc.holdsDouble() ) { diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java index e1ed4b97f2b..0272c069352 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java @@ -621,6 +621,11 @@ public class VM { return bytes; } + /** Returns true if this is a isBigEndian, false otherwise */ + public boolean isBigEndian() { + return isBigEndian; + } + /** Returns true if this is a "core" build, false if either C1 or C2 is present */ public boolean isCore() { diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java index 039fc37e027..5419b2c20a8 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -193,8 +193,12 @@ public class HeapSummary extends Tool { private static final double FACTOR = 1024*1024; private void printValMB(String title, long value) { - double mb = value / FACTOR; - System.out.println(alignment + title + value + " (" + mb + "MB)"); + if (value < 0) { + System.out.println(alignment + title + (value >>> 20) + " MB"); + } else { + double mb = value/FACTOR; + System.out.println(alignment + title + value + " (" + mb + "MB)"); + } } private void printValue(String title, long value) { diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PermStat.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PermStat.java index 1808babf2cc..159e2f66ac2 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PermStat.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PermStat.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -266,46 +266,52 @@ public class PermStat extends Tool { out.println(); } + private static long objectSize(Oop oop) { + return oop == null ? 0L : oop.getObjectSize(); + } + + // Don't count the shared empty arrays + private static long arraySize(Array arr) { + return arr.getLength() != 0L ? arr.getObjectSize() : 0L; + } + private long computeSize(InstanceKlass k) { long size = 0L; - // InstanceKlass object size + // the InstanceKlass object itself size += k.getObjectSize(); - // add ConstantPool size - size += k.getConstants().getObjectSize(); + // Constant pool + ConstantPool cp = k.getConstants(); + size += cp.getObjectSize(); + size += objectSize(cp.getCache()); + size += objectSize(cp.getTags()); - // add ConstantPoolCache, if any - ConstantPoolCache cpCache = k.getConstants().getCache(); - if (cpCache != null) { - size += cpCache.getObjectSize(); - } + // Interfaces + size += arraySize(k.getLocalInterfaces()); + size += arraySize(k.getTransitiveInterfaces()); - // add interfaces size - ObjArray interfaces = k.getLocalInterfaces(); - size += (interfaces.getLength() != 0L)? interfaces.getObjectSize() : 0L; - ObjArray transitiveInterfaces = k.getTransitiveInterfaces(); - size += (transitiveInterfaces.getLength() != 0L)? transitiveInterfaces.getObjectSize() : 0L; + // Inner classes + size += objectSize(k.getInnerClasses()); - // add inner classes size - TypeArray innerClasses = k.getInnerClasses(); - size += innerClasses.getObjectSize(); + // Fields + size += objectSize(k.getFields()); - // add fields size - size += k.getFields().getObjectSize(); - - // add methods size + // Methods ObjArray methods = k.getMethods(); - size += (methods.getLength() != 0L)? methods.getObjectSize() : 0L; - TypeArray methodOrdering = k.getMethodOrdering(); - size += (methodOrdering.getLength() != 0L)? methodOrdering.getObjectSize() : 0; - - // add each method's size - int numMethods = (int) methods.getLength(); - for (int i = 0; i < numMethods; i++) { - Method m = (Method) methods.getObjAt(i); - size += m.getObjectSize(); + int nmethods = (int) methods.getLength(); + if (nmethods != 0L) { + size += methods.getObjectSize(); + for (int i = 0; i < nmethods; ++i) { + Method m = (Method) methods.getObjAt(i); + size += m.getObjectSize(); + size += objectSize(m.getConstMethod()); + } } + // MethodOrdering - an int array that records the original + // ordering of methods in the class file + size += arraySize(k.getMethodOrdering()); + return size; } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java index d9b8f5bbced..0be7fad5ab6 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java @@ -1135,6 +1135,8 @@ public class HTMLGenerator implements /* imports */ ClassConstants { buf.append("normal"); } else if (type == Location.Type.OOP) { buf.append("oop"); + } else if (type == Location.Type.NARROWOOP) { + buf.append("narrowoop"); } else if (type == Location.Type.INT_IN_LONG) { buf.append("int"); } else if (type == Location.Type.LNG) { diff --git a/hotspot/agent/src/share/lib/jlfgr-1_0.jar b/hotspot/agent/src/share/lib/jlfgr-1_0.jar deleted file mode 100644 index 0a63e06972d..00000000000 Binary files a/hotspot/agent/src/share/lib/jlfgr-1_0.jar and /dev/null differ diff --git a/hotspot/agent/src/share/lib/maf-1_0.jar b/hotspot/agent/src/share/lib/maf-1_0.jar deleted file mode 100644 index 5c8aafa5ea2..00000000000 Binary files a/hotspot/agent/src/share/lib/maf-1_0.jar and /dev/null differ diff --git a/hotspot/make/hotspot_distro b/hotspot/make/hotspot_distro index bae47300e58..ab698d37c4e 100644 --- a/hotspot/make/hotspot_distro +++ b/hotspot/make/hotspot_distro @@ -1,6 +1,24 @@ -# -# Copyright 2006-2008 Sun Microsystems, Inc. All rights reserved. -# SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. +# +# Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. # # diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version index b30abbb8928..061bd9ebc32 100644 --- a/hotspot/make/hotspot_version +++ b/hotspot/make/hotspot_version @@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2008 HS_MAJOR_VER=14 HS_MINOR_VER=0 -HS_BUILD_NUMBER=01 +HS_BUILD_NUMBER=05 JDK_MAJOR_VER=1 JDK_MINOR_VER=7 diff --git a/hotspot/make/jprt.config b/hotspot/make/jprt.config index dd9940763c2..02fdbc0c51b 100644 --- a/hotspot/make/jprt.config +++ b/hotspot/make/jprt.config @@ -77,9 +77,7 @@ if [ "${osname}" = SunOS ] ; then # All jdk6 builds use SS11 compiler_name=SS11 else - # FIXUP: Change to SS12 once it has been validated. - #compiler_name=SS12 - compiler_name=SS11 + compiler_name=SS12 fi fi diff --git a/hotspot/make/jprt.properties b/hotspot/make/jprt.properties index 459867eae08..012015262ae 100644 --- a/hotspot/make/jprt.properties +++ b/hotspot/make/jprt.properties @@ -295,3 +295,9 @@ jprt.test.targets = \ ${jprt.my.windows.i586.test.targets}, \ ${jprt.my.windows.x64.test.targets} +# The default test/Makefile targets that should be run + +# Example: +# jprt.make.rule.test.targets=*-*-*-packtest +#jprt.make.rule.test.targets=*-product-*-packtest + diff --git a/hotspot/make/linux/makefiles/sa.make b/hotspot/make/linux/makefiles/sa.make index 94463d6a049..eca293bb8c0 100644 --- a/hotspot/make/linux/makefiles/sa.make +++ b/hotspot/make/linux/makefiles/sa.make @@ -41,8 +41,9 @@ GENERATED = $(TOPDIR)/../generated SA_CLASSPATH = $(BOOT_JAVA_HOME)/lib/tools.jar # gnumake 3.78.1 does not accept the *s that -# are in AGENT_ALLFILES, so use the shell to expand them -AGENT_ALLFILES := $(shell /usr/bin/test -d $(AGENT_DIR) && /bin/ls $(AGENT_ALLFILES)) +# are in AGENT_FILES1 and AGENT_FILES2, so use the shell to expand them +AGENT_FILES1 := $(shell /usr/bin/test -d $(AGENT_DIR) && /bin/ls $(AGENT_FILES1)) +AGENT_FILES2 := $(shell /usr/bin/test -d $(AGENT_DIR) && /bin/ls $(AGENT_FILES2)) SA_CLASSDIR = $(GENERATED)/saclasses @@ -58,7 +59,7 @@ all: $(MAKE) -f sa.make $(GENERATED)/sa-jdi.jar; \ fi -$(GENERATED)/sa-jdi.jar: $(AGENT_ALLFILES) +$(GENERATED)/sa-jdi.jar: $(AGENT_FILES1) $(AGENT_FILES2) $(QUIETLY) echo "Making $@" $(QUIETLY) if [ "$(BOOT_JAVA_HOME)" = "" ]; then \ echo "ALT_BOOTDIR, BOOTDIR or JAVA_HOME needs to be defined to build SA"; \ @@ -72,9 +73,18 @@ $(GENERATED)/sa-jdi.jar: $(AGENT_ALLFILES) $(QUIETLY) if [ ! -d $(SA_CLASSDIR) ] ; then \ mkdir -p $(SA_CLASSDIR); \ fi - $(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -g -d $(SA_CLASSDIR) $(AGENT_ALLFILES) + + $(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES1) + $(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES2) + $(QUIETLY) $(REMOTE) $(COMPILE.RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer $(QUIETLY) echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES) + $(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js + $(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql + $(QUIETLY) mkdir -p $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources + $(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources/* + $(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources/ + $(QUIETLY) cp -r $(AGENT_SRC_DIR)/images/* $(SA_CLASSDIR)/ $(QUIETLY) $(REMOTE) $(RUN.JAR) cf $@ -C $(SA_CLASSDIR)/ . $(QUIETLY) $(REMOTE) $(RUN.JAR) uf $@ -C $(AGENT_SRC_DIR) META-INF/services/com.sun.jdi.connect.Connector $(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.x86.X86ThreadContext diff --git a/hotspot/make/linux/makefiles/vm.make b/hotspot/make/linux/makefiles/vm.make index 73caaf9a534..dc09e17b6ca 100644 --- a/hotspot/make/linux/makefiles/vm.make +++ b/hotspot/make/linux/makefiles/vm.make @@ -195,7 +195,7 @@ $(LIBJVM): $(LIBJVM.o) $(LIBJVM_MAPFILE) $(LD_SCRIPT) if [ $$? = 0 ] ; then \ /usr/bin/chcon -t textrel_shlib_t $@; \ if [ $$? != 0 ]; then \ - echo "ERROR: Cannot chcon $@"; exit 1; \ + echo "ERROR: Cannot chcon $@"; \ fi \ fi \ fi \ diff --git a/hotspot/make/sa.files b/hotspot/make/sa.files index 6f76f9d8faa..7040cf517e7 100644 --- a/hotspot/make/sa.files +++ b/hotspot/make/sa.files @@ -33,40 +33,23 @@ AGENT_SRC_DIR = $(AGENT_DIR)/src/share/classes -AGENT_ALLFILES = \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/DebugServer.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/HelloWorld.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/HotSpotAgent.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/HotSpotSolarisVtblAccess.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/HotSpotTypeDataBase.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/LinuxVtblAccess.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/ObjectHistogram.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/RMIHelper.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/StackTrace.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/TestDebugger.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/Win32VtblAccess.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/Immediate.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/ImmediateOrRegister.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/Operand.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/Register.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/amd64/AMD64Register.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/amd64/AMD64Registers.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/ia64/IA64Register.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/ia64/IA64Registers.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/sparc/SPARCArgument.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/sparc/SPARCRegister.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/sparc/SPARCRegisterType.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/sparc/SPARCRegisters.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/x86/X86Register.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/x86/X86RegisterPart.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/x86/X86Registers.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/x86/X86SegmentRegister.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/x86/X86SegmentRegisters.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/bugspot/BugSpotAgent.java \ +# Splitted the set of files into two sets because on linux plaform +# listing or compiling all the files results in 'Argument list too long' error. + +AGENT_FILES1 = \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/amd64/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/ia64/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/sparc/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/x86/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/bugspot/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/bugspot/tree/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/c1/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/code/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/compiler/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/amd64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/cdbg/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/cdbg/basic/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/cdbg/basic/x86/*.java \ @@ -75,7 +58,6 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/dbx/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/dbx/sparc/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/dbx/x86/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/dummy/*.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/amd64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/ia64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/amd64/*.java \ @@ -107,7 +89,10 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/interpreter/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/jdi/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/livejvm/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/memory/*.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/oops/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/oops/*.java + + +AGENT_FILES2 = \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/amd64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/ia64/*.java \ @@ -127,7 +112,17 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/win32_x86/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/x86/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/tools/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/tools/jcore/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/tools/soql/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/types/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/types/basic/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/utilities/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/utilities/memo/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/utilities/soql/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/action/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/classbrowser/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/table/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/tree/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/treetable/*.java \ +$(AGENT_SRC_DIR)/com/sun/java/swing/action/*.java \ +$(AGENT_SRC_DIR)/com/sun/java/swing/ui/*.java diff --git a/hotspot/make/solaris/makefiles/fastdebug.make b/hotspot/make/solaris/makefiles/fastdebug.make index 62eaeb8f968..3ac2ae212b1 100644 --- a/hotspot/make/solaris/makefiles/fastdebug.make +++ b/hotspot/make/solaris/makefiles/fastdebug.make @@ -38,6 +38,8 @@ OPT_CFLAGS/SLOWER = -xO2 # Problem with SS12 compiler, dtrace doesn't like the .o files (bug 6693876) ifeq ($(COMPILER_REV), 5.9) + # To avoid jvm98 crash + OPT_CFLAGS/instanceKlass.o = $(OPT_CFLAGS/SLOWER) # Not clear this workaround could be skipped in some cases. OPT_CFLAGS/vmGCOperations.o = $(OPT_CFLAGS/SLOWER) OPT_CFLAGS/java.o = $(OPT_CFLAGS/SLOWER) diff --git a/hotspot/make/solaris/makefiles/reorder_COMPILER1_amd64 b/hotspot/make/solaris/makefiles/reorder_COMPILER1_amd64 new file mode 100644 index 00000000000..fdc435bbf27 --- /dev/null +++ b/hotspot/make/solaris/makefiles/reorder_COMPILER1_amd64 @@ -0,0 +1,5450 @@ +data = R0x2000; +text = LOAD ?RXO; + + +# Test Null +text: .text%__cplus_fini_at_exit: CCrti.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: arguments.o; +text: .text%__1cQAgentLibraryList2t6M_v_: arguments.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_AllocTable.o; +text: .text%__1cFRInfo2t6M_v_: c1_AllocTable.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_AllocTable_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_AllocTable_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CacheLocals.o; +text: .text%__1cFRInfo2t6M_v_: c1_CacheLocals.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CacheLocals_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_CacheLocals_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Canonicalizer.o; +text: .text%__1cFRInfo2t6M_v_: c1_Canonicalizer.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CodeGenerator.o; +text: .text%__1cFRInfo2t6M_v_: c1_CodeGenerator.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CodeGenerator_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_CodeGenerator_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CodeStubs_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_CodeStubs_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Compilation.o; +text: .text%__1cFRInfo2t6M_v_: c1_Compilation.o; +text: .text%__1cMelapsedTimer2t6M_v_: c1_Compilation.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Compiler.o; +text: .text%__1cFRInfo2t6M_v_: c1_Compiler.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_FrameMap.o; +text: .text%__1cFRInfo2t6M_v_: c1_FrameMap.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_FrameMap_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_FrameMap_x86.o; +text: .text%__1cKc1_RegMask2t6M_v_: c1_FrameMap_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_GraphBuilder.o; +text: .text%__1cFRInfo2t6M_v_: c1_GraphBuilder.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_IR.o; +text: .text%__1cFRInfo2t6M_v_: c1_IR.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Instruction.o; +text: .text%__1cFRInfo2t6M_v_: c1_Instruction.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_InstructionPrinter.o; +text: .text%__1cFRInfo2t6M_v_: c1_InstructionPrinter.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Items.o; +text: .text%__1cFRInfo2t6M_v_: c1_Items.o; +text: .text%__1cIHintItem2t6MpnJValueType_i_v_: c1_Items.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Items_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_Items_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIR.o; +text: .text%__1cFRInfo2t6M_v_: c1_LIR.o; +text: .text%__1cLLIR_OprFactHillegal6F_pnLLIR_OprDesc__: c1_LIR.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIRAssembler.o; +text: .text%__1cFRInfo2t6M_v_: c1_LIRAssembler.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIRAssembler_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_LIRAssembler_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIREmitter.o; +text: .text%__1cFRInfo2t6M_v_: c1_LIREmitter.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIREmitter_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_LIREmitter_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIROptimizer.o; +text: .text%__1cFRInfo2t6M_v_: c1_LIROptimizer.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Loops.o; +text: .text%__1cFRInfo2t6M_v_: c1_Loops.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_MacroAssembler_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_MacroAssembler_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Optimizer.o; +text: .text%__1cFRInfo2t6M_v_: c1_Optimizer.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_RInfo.o; +text: .text%__1cFRInfo2t6M_v_: c1_RInfo.o; +text: .text%__1cKc1_RegMask2t6M_v_: c1_RInfo.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_RInfo_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_RInfo_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_RegAlloc.o; +text: .text%__1cFRInfo2t6M_v_: c1_RegAlloc.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_RegAlloc_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_RegAlloc_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Runtime1.o; +text: .text%__1cFRInfo2t6M_v_: c1_Runtime1.o; +text: .text%__1cIiEntries2t6M_v_; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Runtime1_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_Runtime1_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_ScanBlocks.o; +text: .text%__1cFRInfo2t6M_v_: c1_ScanBlocks.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_ValueMap.o; +text: .text%__1cFRInfo2t6M_v_: c1_ValueMap.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_ValueSet.o; +text: .text%__1cFRInfo2t6M_v_: c1_ValueSet.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_ValueStack.o; +text: .text%__1cFRInfo2t6M_v_: c1_ValueStack.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: codeBlob.o; +text: .text%__1cFRInfo2t6M_v_: codeBlob.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: codeCache.o; +text: .text%__1cICHeapObj2n6FI_pv_; +text: .text%__1cCosGmalloc6FI_pv_; +text: .text%__1cICodeHeap2t6M_v_; +text: .text%__1cMVirtualSpace2t6M_v_; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: compilationPolicy.o; +text: .text%__1cMelapsedTimer2t6M_v_: compilationPolicy.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: compileBroker.o; +text: .text%__1cMelapsedTimer2t6M_v_: compileBroker.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: compiledIC.o; +text: .text%__1cFRInfo2t6M_v_: compiledIC.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: deoptimization.o; +text: .text%__1cFRInfo2t6M_v_: deoptimization.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: fprofiler.o; +text: .text%__1cMelapsedTimer2t6M_v_: fprofiler.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: frame.o; +text: .text%__1cFRInfo2t6M_v_: frame.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: frame_x86.o; +text: .text%__1cFRInfo2t6M_v_: frame_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: genCollectedHeap.o; +text: .text%__1cTAssertIsPermClosure2t6M_v_: genCollectedHeap.o; +text: .text%__1cRAlwaysTrueClosure2t6M_v_: genCollectedHeap.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: generateOopMap.o; +text: .text%__1cNCellTypeStateLmake_bottom6F_0_: generateOopMap.o; +text: .text%__1cNCellTypeStateImake_any6Fi_0_: generateOopMap.o; +text: .text%__1cNCellTypeStateImake_top6F_0_: generateOopMap.o; +text: .text%__1cMelapsedTimer2t6M_v_: generateOopMap.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: interpreter.o; +text: .text%__1cKEntryPoint2t6M_v_; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: interpreter_x86.o; +text: .text%__1cFRInfo2t6M_v_: interpreter_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: java.o; +text: .text%__1cFRInfo2t6M_v_: java.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: jvmtiEnvBase.o; +text: .text%__1cWNonPrintingResourceObj2n6FInLResourceObjPallocation_type__pv_: jvmtiEnvBase.o; +text: .text%__1cLResourceObj2n6FIn0APallocation_type__pv_; +text: .text%__1cNGrowableArray4CpnMJvmtiEnvBase__2t6Mii_v_: jvmtiEnvBase.o; +text: .text%__1cUGenericGrowableArray2t6Mii_v_; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: jvmtiEventController.o; +text: .text%__1cRJvmtiEventEnabled2t6M_v_; +text: .text%__1cRJvmtiEventEnabledFclear6M_v_; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: jvmtiImpl.o; +text: .text%__1cWNonPrintingResourceObj2n6FInLResourceObjPallocation_type__pv_: jvmtiImpl.o; +text: .text%__1cNGrowableArray4CpnPJvmtiRawMonitor__2t6Mii_v_: jvmtiImpl.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: jvmtiTagMap.o; +text: .text%__1cJMemRegion2t6M_v_: jvmtiTagMap.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: klassVtable.o; +text: .text%__1cFRInfo2t6M_v_: klassVtable.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: management.o; +text: .text%__1cJTimeStamp2t6M_v_: management.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: markSweep.o; +text: .text%__1cJMarkSweepSMarkAndPushClosure2t6M_v_: markSweep.o; +text: .text%__1cJMarkSweepRFollowRootClosure2t6M_v_: markSweep.o; +text: .text%__1cJMarkSweepSFollowStackClosure2t6M_v_: markSweep.o; +text: .text%__1cJMarkSweepUAdjustPointerClosure2t6Mi_v_: markSweep.o; +text: .text%__1cJMarkSweepOIsAliveClosure2t6M_v_: markSweep.o; +text: .text%__1cJMarkSweepQKeepAliveClosure2t6M_v_: markSweep.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: memoryService.o; +text: .text%__1cWNonPrintingResourceObj2n6FInLResourceObjPallocation_type__pv_: memoryService.o; +text: .text%__1cNGrowableArray4CpnKMemoryPool__2t6Mii_v_: memoryService.o; +text: .text%__1cNGrowableArray4CpnNMemoryManager__2t6Mii_v_: memoryService.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: methodOop.o; +text: .text%__1cFRInfo2t6M_v_: methodOop.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: nativeInst_x86.o; +text: .text%__1cFRInfo2t6M_v_: nativeInst_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: nmethod.o; +text: .text%__1cFRInfo2t6M_v_: nmethod.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: oopMap.o; +text: .text%__1cQDoNothingClosure2t6M_v_: oopMap.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: os_solaris.o; +text: .text%__1cFRInfo2t6M_v_: os_solaris.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: os_solaris_x86.o; +text: .text%__1cFRInfo2t6M_v_: os_solaris_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: parGCAllocBuffer.o; +text: .text%__1cMarrayOopDescLheader_size6FnJBasicType__i_: parGCAllocBuffer.o; +text: .text%__1cRalign_object_size6Fi_i_: parGCAllocBuffer.o; +text: .text%__1cHoopDescLheader_size6F_i_: parGCAllocBuffer.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: psAdaptiveSizePolicy.o; +text: .text%__1cMelapsedTimer2t6M_v_: psAdaptiveSizePolicy.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: psMarkSweep.o; +text: .text%__1cMelapsedTimer2t6M_v_: psMarkSweep.o; +text: .text%__1cTPSAlwaysTrueClosure2t6M_v_: psMarkSweep.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: psPromotionLAB.o; +text: .text%__1cMarrayOopDescLheader_size6FnJBasicType__i_: psPromotionLAB.o; +text: .text%__1cRalign_object_size6Fi_i_: psPromotionLAB.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: psScavenge.o; +text: .text%__1cMelapsedTimer2t6M_v_: psScavenge.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: relocInfo.o; +text: .text%__1cQRelocationHolder2t6M_v_: relocInfo.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: runtimeService.o; +text: .text%__1cJTimeStamp2t6M_v_: runtimeService.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: safepoint.o; +text: .text%__1cFRInfo2t6M_v_: safepoint.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: safepoint_solaris_x86.o; +text: .text%__1cFRInfo2t6M_v_: safepoint_solaris_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: sharedHeap.o; +text: .text%__1cTAssertIsPermClosure2t6M_v_: sharedHeap.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: sharedRuntime.o; +text: .text%__1cFRInfo2t6M_v_: sharedRuntime.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: tenuredGeneration.o; +text: .text%__1cRCardTableModRefBSbCpar_chunk_heapword_alignment6F_I_: tenuredGeneration.o; +text: .text%__1cEMIN24CI_6FTA0_0_: tenuredGeneration.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: vframeArray.o; +text: .text%__1cFRInfo2t6M_v_: vframeArray.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: vmStructs.o; +text: .text%__1cFRInfo2t6M_v_: vmStructs.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: vm_version.o; +text: .text%__1cTAbstract_VM_VersionKvm_release6F_pkc_; +text: .text%__1cTAbstract_VM_VersionXinternal_vm_info_string6F_pkc_; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: vtableStubs_x86.o; +text: .text%__1cFRInfo2t6M_v_: vtableStubs_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIROptimizer_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_LIROptimizer_x86.o; +text: .text%JNI_CreateJavaVM; +text: .text%__1cCosVatomic_xchg_bootstrap6Fipoi_i_; +text: .text%__1cHThreadsJcreate_vm6FpnOJavaVMInitArgs_pi_i_; +text: .text%__1cHThreadsYis_supported_jni_version6Fi_C_; +text: .text%__1cMostream_init6F_v_; +text: .text%__1cMoutputStream2t6Mi_v_; +text: .text%__1cCosEinit6F_v_; +text: .text%__1cCosLinit_random6Fl_v_; +text: .text%__1cCosHSolarisWinitialize_system_info6F_v_; +text: .text%__1cOThreadCriticalKinitialize6F_v_; +text: .text%__1cCosMvm_page_size6F_i_; +text: .text%__1cJArgumentsWinit_system_properties6F_v_; +text: .text%__1cJArgumentsQPropertyList_add6FppnOSystemProperty_2_v_; +text: .text%__1cTAbstract_VM_VersionHvm_name6F_pkc_; +text: .text%__1cTAbstract_VM_VersionJvm_vendor6F_pkc_; +text: .text%__1cTAbstract_VM_VersionOvm_info_string6F_pkc_; +text: .text%__1cCosbDinit_system_properties_values6F_v_; +text: .text%__1cCosIjvm_path6Fpci_v_; +text: .text%__1cCosNset_boot_path6Fcc_i_; +text: .text%__1cJArgumentsFparse6FpknOJavaVMInitArgs__i_; +text: .text%__1cMmatch_option6FpknMJavaVMOption_pkcp4_i_: arguments.o; +text: .text%__1cJArgumentsVprocess_settings_file6Fpkcii_i_; +text: .text%__1cJArgumentsSparse_vm_init_args6FpknOJavaVMInitArgs__i_; +text: .text%__1cMSysClassPath2t6Mpkc_v_; +text: .text%__1cJArgumentsbSparse_java_tool_options_environment_variable6FpnMSysClassPath_pi_i_; +text: .text%__1cCosGgetenv6Fpkcpci_i_; +text: .text%__1cJArgumentsWparse_each_vm_init_arg6FpknOJavaVMInitArgs_pnMSysClassPath_pi_i_; +text: .text%__1cMmatch_option6FpknMJavaVMOption_ppkc5i_i_: arguments.o; +text: .text%__1cJArgumentsMadd_property6Fpkc_i_; +text: .text%__1cJArgumentsXPropertyList_unique_add6FppnOSystemProperty_pkcpc_v_; +text: .text%__1cCosEfree6Fpv_v_; +text: .text%__1cJArgumentsbNparse_java_options_environment_variable6FpnMSysClassPath_pi_i_; +text: .text%__1cJArgumentsVfinalize_vm_init_args6FpnMSysClassPath_i_i_; +text: .text%__1cMSysClassPathPexpand_endorsed6M_v_; +text: .text%__1cJArgumentsMget_property6Fpkc_2_; +text: .text%__1cJArgumentsWPropertyList_get_value6FpnOSystemProperty_pkc_4_; +text: .text%__1cMSysClassPathQadd_jars_to_path6Fpcpkc_1_; +text: .text%__1cJArgumentsZcheck_vm_args_consistency6F_i_; +text: .text%__1cJArgumentsRverify_percentage6FIpkc_i_; +text: .text%__1cMSysClassPath2T6M_v_; +text: .text%__1cMSysClassPathNreset_item_at6Mi_v_: arguments.o; +text: .text%__1cJArgumentsbOparse_java_compiler_environment_variable6F_v_; +text: .text%__1cJArgumentsVset_parallel_gc_flags6F_v_; +text: .text%__1cJArgumentsbBset_cms_and_parnew_gc_flags6F_v_; +text: .text%__1cJArgumentsTset_parnew_gc_flags6F_v_; +text: .text%__1cSCommandLineFlagsExKis_default6FnPCommandLineFlag__i_; +text: .text%__1cJArgumentsUset_ergonomics_flags6F_v_; +text: .text%__1cCosXis_server_class_machine6F_i_; +text: .text%__1cJTimeStampJupdate_to6Mx_v_; +text: .text%__1cCosOjavaTimeMillis6F_x_; +text: .text%__1cJTraceTime2t6MpkciipnMoutputStream__v_; +text: .text%__1cCosGinit_26F_i_; +text: .text%__1cCosHSolarisKmmap_chunk6FpcIii_2_; +text: .text%__1cCosXnon_memory_address_word6F_pc_; +text: .text%__1cCosHSolarisRmpss_sanity_check6F_v_; +text: .text%__1cCosHSolarisOset_mpss_range6FpcII_i_; +text: .text%__1cCosPuncommit_memory6FpcI_i_; +text: .text%__1cCosHSolarisOlibthread_init6F_v_; +text: .text%__1cOisT2_libthread6F_i_; +text: .text%__1cRlwp_priocntl_init6F_i_: os_solaris.o; +text: .text%__1cNpriocntl_stub6FinGidtype_lipc_l_: os_solaris.o; +text: .text%__1cOresolve_symbol6Fpkc_pC_: os_solaris.o; +text: .text%__1cCosHSolarisQsignal_sets_init6F_v_; +text: .text%__1cCosHSolarisOis_sig_ignored6Fi_i_; +text: .text%__1cCosHSolarisPinit_signal_mem6F_v_; +text: .text%__1cCosHSolarisXinstall_signal_handlers6F_v_; +text: .text%__1cCosHSolarisSset_signal_handler6Fiii_v_; +text: .text%__1cCosHSolarisUsynchronization_init6F_v_; +text: .text%__1cDhpiKinitialize6F_i_; +text: .text%__1cDhpiYinitialize_get_interface6FpnIvm_calls__v_; +text: .text%__1cQostream_init_log6F_v_; +text: .text%__1cNdefaultStreamMhas_log_file6M_i_; +text: .text%__1cRis_error_reported6F_i_; +text: .text%__1cNdefaultStreamEinit6M_v_; +text: .text%__1cSThreadLocalStorageEinit6F_v_; +text: .text%__1cSThreadLocalStorageHpd_init6F_v_; +text: .text%__1cCosbDallocate_thread_local_storage6F_i_; +text: .text%__1cSThreadLocalStoragebCgenerate_code_for_get_thread6F_v_; +text: .text%__1cRAllocateTLSOffset6F_v_: threadLS_solaris_x86.o; +text: .text%__1cPvm_init_globals6F_v_; +text: .text%__1cScheck_ThreadShadow6F_v_; +text: .text%__1cRcheck_basic_types6F_v_; +text: .text%__1cNeventlog_init6F_v_; +text: .text%__1cKmutex_init6F_v_; +text: .text%__1cFMutex2t6Mipkci_v_; +text: .text%lwp_cond_init: os_solaris.o; +text: .text%lwp_mutex_init: os_solaris.o; +text: .text%__1cHMonitor2t6Mipkci_v_; +text: .text%__1cOchunkpool_init6F_v_; +text: .text%__1cPperfMemory_init6F_v_; +text: .text%__1cKPerfMemoryKinitialize6F_v_; +text: .text%__1cCosZvm_allocation_granularity6F_i_; +text: .text%__1cKPerfMemoryUcreate_memory_region6FI_v_; +text: .text%__1cUcreate_shared_memory6FI_pc_: perfMemory_solaris.o; +text: .text%__1cSmmap_create_shared6FI_pc_: perfMemory_solaris.o; +text: .text%__1cCosScurrent_process_id6F_i_; +text: .text%__1cNget_user_name6Fl_pc_: perfMemory_solaris.o; +text: .text%__1cQget_user_tmp_dir6Fpkc_pc_: perfMemory_solaris.o; +text: .text%__1cCosSget_temp_directory6F_pkc_; +text: .text%__1cWget_sharedmem_filename6Fpkci_pc_: perfMemory_solaris.o; +text: .text%__1cbBcleanup_sharedmem_resources6Fpkc_v_: perfMemory_solaris.o; +text: .text%__1cTis_directory_secure6Fpkc_i_: perfMemory_solaris.o; +text: .text%lstat: perfMemory_solaris.o; +text: .text%__1cPfilename_to_pid6Fpkc_l_: perfMemory_solaris.o; +text: .text%__1cbAcreate_sharedmem_resources6Fpkc1I_i_: perfMemory_solaris.o; +text: .text%__1cRmake_user_tmp_dir6Fpkc_i_: perfMemory_solaris.o; +text: .text%__1cKJavaThread2t6M_v_; +text: .text%__1cGThread2t6M_v_; +text: .text%__1cFArena2t6M_v_; +text: .text%__1cFChunk2n6FII_pv_; +text: .text%__1cOThreadCritical2t6M_v_; +text: .text%__1cOThreadCritical2T6M_v_; +text: .text%__1cFChunk2t6MI_v_; +text: .text%__1cKHandleMarkKinitialize6MpnGThread__v_; +text: .text%__1cKJavaThreadKinitialize6M_v_; +text: .text%__1cNjni_functions6F_pknTJNINativeInterface___; +text: .text%__1cQThreadStatistics2t6M_v_; +text: .text%__1cGParker2t6M_v_; +text: .text%__1cWThreadLocalAllocBufferKinitialize6M_v_; +text: .text%__1cWThreadLocalAllocBufferKinitialize6MpnIHeapWord_22_v_; +text: .text%__1cWThreadLocalAllocBufferMinitial_size6F_I_; +text: .text%__1cWThreadLocalAllocBufferVinitialize_statistics6M_v_; +text: .text%__1cMFlatProfilerJis_active6F_i_; +text: .text%__1cUThreadSafepointStateGcreate6FpnKJavaThread__v_; +text: .text%__1cUThreadSafepointState2t6MpnKJavaThread__v_; +text: .text%__1cGThreadbArecord_stack_base_and_size6M_v_; +text: .text%__1cCosScurrent_stack_base6F_pC_; +text: .text%__1cCosScurrent_stack_size6F_I_; +text: .text%__1cGThreadbFinitialize_thread_local_storage6M_v_; +text: .text%__1cSThreadLocalStorageKset_thread6FpnGThread__v_; +text: .text%__1cSThreadLocalStorageNpd_set_thread6FpnGThread__v_; +text: .text%__1cCosbBthread_local_storage_at_put6Fipv_v_; +text: .text%__1cSThreadLocalStorageSset_thread_in_slot6FpnGThread__v_; +text: .text%get_thread; +text: .text%__1cSThreadLocalStoragebBget_thread_via_cache_slowly6FIi_pnGThread__; +text: .text%__1cSThreadLocalStoragePget_thread_slow6F_pnGThread__; +text: .text%__1cCosXthread_local_storage_at6Fi_pv_; +text: .text%__1cCosVcurrent_stack_pointer6F_pC_; +text: .text%__1cCosRinitialize_thread6F_v_; +text: .text%__1cNReservedSpaceUpage_align_size_down6FI_I_; +text: .text%__1cCosHSolarisVinit_thread_fpu_state6F_v_; +text: .text%__1cOJNIHandleBlockOallocate_block6FpnGThread__p0_; +text: .text%__1cFMutexbClock_without_safepoint_check6M_v_; +text: .text%__1cFMutexGunlock6M_v_; +text: .text%__1cGThreadWset_as_starting_thread6M_i_; +text: .text%__1cCosScreate_main_thread6FpnGThread__i_; +text: .text%__1cQcreate_os_thread6FpnGThread_I_pnIOSThread__: os_solaris.o; +text: .text%__1cIOSThread2t6MpFpv_i1_v_; +text: .text%__1cIOSThreadNpd_initialize6M_v_; +text: .text%__1cCosHSolarisPhotspot_sigmask6FpnGThread__v_; +text: .text%__1cCosHSolarisRunblocked_signals6F_pnIsigset_t__; +text: .text%__1cGThreadMis_VM_thread6kM_i_: thread.o; +text: .text%__1cCosHSolarisKvm_signals6F_pnIsigset_t__; +text: .text%__1cKJavaThreadYcreate_stack_guard_pages6M_v_; +text: .text%__1cCosNcommit_memory6FpcI_i_; +text: .text%__1cCosMguard_memory6FpcI_i_; +text: .text%__1cMinit_globals6F_i_; +text: .text%__1cPmanagement_init6F_v_; +text: .text%__1cKManagementEinit6F_v_; +text: .text%__1cNExceptionMark2t6MrpnGThread__v_; +text: .text%__1cPPerfDataManagerUcreate_long_variable6FnJCounterNS_pkcnIPerfDataFUnits_xpnGThread__pnQPerfLongVariable__; +text: .text%__1cIPerfLong2t6MnJCounterNS_pkcnIPerfDataFUnits_n0CLVariability__v_; +text: .text%__1cIPerfData2t6MnJCounterNS_pkcn0AFUnits_n0ALVariability__v_; +text: .text%__1cIPerfDataMcreate_entry6MnJBasicType_II_v_; +text: .text%__1cKPerfMemoryFalloc6FI_pc_; +text: .text%__1cFMutexElock6M_v_; +text: .text%__1cFMutexElock6MpnGThread__v_; +text: .text%__1cKPerfMemoryMmark_updated6F_v_; +text: .text%__1cCosLelapsedTime6F_d_; +text: .text%__1cMgetTimeNanos6F_x_: os_solaris.o; +text: .text%__1cPoldgetTimeNanos6F_x_: os_solaris.o; +text: .text%__1cPPerfDataManagerIadd_item6FpnIPerfData_i_v_; +text: .text%__1cMPerfDataList2t6Mi_v_; +text: .text%__1cCosbCis_thread_cpu_time_supported6F_i_; +text: .text%__1cNExceptionMark2T6M_v_; +text: .text%__1cNThreadServiceEinit6F_v_; +text: .text%__1cPPerfDataManagerTcreate_long_counter6FnJCounterNS_pkcnIPerfDataFUnits_xpnGThread__pnPPerfLongCounter__; +text: .text%__1cORuntimeServiceEinit6F_v_; +text: .text%__1cTClassLoadingServiceEinit6F_v_; +text: .text%__1cKvtune_init6F_v_; +text: .text%__1cObytecodes_init6F_v_; +text: .text%__1cJBytecodesKinitialize6F_v_; +text: .text%__1cJBytecodesDdef6Fn0AECode_pkc33nJBasicType_iii_v_; +text: .text%__1cJBytecodesDdef6Fn0AECode_pkc33nJBasicType_ii1i_v_; +text: .text%__1cJBytecodesNpd_initialize6F_v_; +text: .text%__1cQclassLoader_init6F_v_; +text: .text%__1cLClassLoaderKinitialize6F_v_; +text: .text%__1cLClassLoaderQload_zip_library6F_v_; +text: .text%__1cCosTnative_java_library6F_pv_; +text: .text%JVM_GetInterfaceVersion; +text: .text%__1cHThreadsbMis_supported_jni_version_including_1_16Fi_C_; +text: .text%__1cKHandleMark2T6M_v_; +text: .text%__1cLClassLoaderbBsetup_bootstrap_search_path6F_v_; +text: .text%__1cCosGstrdup6Fpkc_pc_; +text: .text%__1cLClassLoaderbCupdate_class_path_entry_list6Fpkc_v_; +text: .text%__1cCosEstat6FpkcpnEstat__i_; +text: .text%stat: os_solaris.o; +text: .text%__1cLClassLoaderXcreate_class_path_entry6FpcnEstat_ppnOClassPathEntry__v_; +text: .text%__1cLClassLoaderSget_canonical_path6Fpc1i_i_; +text: .text%JVM_RawMonitorCreate; +text: .text%JVM_NativePath; +text: .text%JVM_RawMonitorEnter; +text: .text%__1cFMutexMjvm_raw_lock6M_v_; +text: .text%JVM_RawMonitorExit; +text: .text%__1cFMutexOjvm_raw_unlock6M_v_; +text: .text%JVM_Open; +text: .text%JVM_Lseek; +text: .text%JVM_Close; +text: .text%__1cDhpiFclose6Fi_i_: jvm.o; +text: .text%__1cRClassPathZipEntry2t6Mppvpc_v_; +text: .text%__1cOClassPathEntry2t6M_v_; +text: .text%__1cLClassLoaderLadd_to_list6FpnOClassPathEntry__v_; +text: .text%__1cOcodeCache_init6F_v_; +text: .text%__1cJCodeCacheKinitialize6F_v_; +text: .text%__1cICodeHeapHreserve6MIII_i_; +text: .text%__1cLlog2_intptr6Fi_i_: heap.o; +text: .text%__1cYalign_to_allocation_size6FI_I_: heap.o; +text: .text%__1cNReservedSpace2t6MI_v_; +text: .text%__1cNReservedSpaceKinitialize6MIIipc_v_; +text: .text%__1cCosOreserve_memory6FIpc_1_; +text: .text%__1cMVirtualSpaceKinitialize6MnNReservedSpace_I_i_; +text: .text%__1cMVirtualSpaceJexpand_by6MI_i_; +text: .text%__1cMVirtualSpaceQuncommitted_size6kM_I_; +text: .text%__1cMVirtualSpaceNreserved_size6kM_I_; +text: .text%__1cMVirtualSpaceOcommitted_size6kM_I_; +text: .text%__1cCosNcommit_memory6FpcII_i_; +text: .text%__1cSalign_to_page_size6FI_I_: heap.o; +text: .text%__1cICodeHeapFclear6M_v_; +text: .text%__1cICodeHeapTmark_segmap_as_free6MII_v_; +text: .text%__1cNMemoryServiceZadd_code_heap_memory_pool6FpnICodeHeap__v_; +text: .text%__1cMCodeHeapPool2t6MpnICodeHeap_pkci_v_; +text: .text%__1cICodeHeapIcapacity6kM_I_; +text: .text%__1cICodeHeapMmax_capacity6kM_I_; +text: .text%__1cKMemoryPool2t6Mpkcn0AIPoolType_IIii_v_; +text: .text%__1cNMemoryManagerbDget_code_cache_memory_manager6F_p0_; +text: .text%__1cNMemoryManager2t6M_v_; +text: .text%__1cNMemoryManagerIadd_pool6MpnKMemoryPool__v_; +text: .text%__1cKMemoryPoolLadd_manager6MpnNMemoryManager__v_; +text: .text%__1cLicache_init6F_v_; +text: .text%__1cPVM_Version_init6F_v_; +text: .text%__1cKVM_VersionKinitialize6F_v_; +text: .text%__1cKBufferBlobGcreate6Fpkci_p0_; +text: .text%__1cKJavaThreadOis_Java_thread6kM_i_: thread.o; +text: .text%__1cRalign_code_offset6Fi_I_; +text: .text%__1cICodeHeapLheader_size6F_I_; +text: .text%__1cKBufferBlob2n6FII_pv_; +text: .text%__1cJCodeCacheIallocate6Fi_pnICodeBlob__; +text: .text%__1cICodeHeapIallocate6MI_pv_; +text: .text%__1cICodeHeapPsearch_freelist6MI_pnJFreeBlock__; +text: .text%__1cICodeHeapTmark_segmap_as_used6MII_v_; +text: .text%__1cKBufferBlob2t6Mpkci_v_; +text: .text%__1cICodeBlob2t6Mpkcii_v_; +text: .text%__1cICodeBlobMset_oop_maps6MpnJOopMapSet__v_; +text: .text%__1cNMemoryServiceXtrack_memory_pool_usage6FpnKMemoryPool__v_; +text: .text%__1cKMemoryPoolYrecord_peak_memory_usage6M_v_; +text: .text%__1cMCodeHeapPoolQget_memory_usage6M_nLMemoryUsage__; +text: .text%__1cMCodeHeapPoolNused_in_bytes6M_I_: memoryPool.o; +text: .text%__1cICodeHeapSallocated_capacity6kM_I_; +text: .text%__1cKMemoryPoolImax_size6kM_I_: memoryPool.o; +text: .text%__1cXresource_allocate_bytes6FI_pc_; +text: .text%__1cKCodeBuffer2t6MpCi_v_; +text: .text%__1cRAbstractAssembler2t6MpnKCodeBuffer__v_; +text: .text%__1cYVM_Version_StubGeneratorTgenerate_getPsrInfo6M_pC_: vm_version_x86.o; +text: .text%__1cMStubCodeMark2t6MpnRStubCodeGenerator_pkc4_v_; +text: .text%__1cRStubCodeGeneratorLstub_prolog6MpnMStubCodeDesc__v_; +text: .text%__1cJAssemblerFpushl6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerEmovl6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerGpushfd6M_v_; +text: .text%__1cJAssemblerEpopl6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerExorl6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerKemit_arith6MiipnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerExorl6MpnMRegisterImpl_i_v_; +text: .text%__1cJAssemblerKemit_arith6MiipnMRegisterImpl_i_v_; +text: .text%__1cJAssemblerFpopfd6M_v_; +text: .text%__1cJAssemblerEcmpl6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerDjcc6Mn0AJCondition_rnFLabel_nJrelocInfoJrelocType__v_; +text: .text%__1cJAssemblerFcpuid6M_v_; +text: .text%__1cJAssemblerDorl6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerEmovl6MpnMRegisterImpl_i_v_; +text: .text%__1cJAssemblerDjmp6MrnFLabel_nJrelocInfoJrelocType__v_; +text: .text%__1cRAbstractAssemblerEbind6MrnFLabel__v_; +text: .text%__1cRAbstractAssemblerHbind_to6MrnFLabel_i_v_; +text: .text%__1cMDisplacementEbind6MrnFLabel_ipnRAbstractAssembler__v_; +text: .text%__1cJAssemblerEmovl6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cJAssemblerMemit_operand6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cJAssemblerMemit_operand6MpnMRegisterImpl_22nHAddressLScaleFactor_irknQRelocationHolder__v_; +text: .text%__1cKRelocationEtype6M_nJrelocInfoJrelocType__: relocInfo.o; +text: .text%__1cJAssemblerEmovl6MnHAddress_pnMRegisterImpl__v_; +text: .text%__1cJAssemblerDret6Mi_v_; +text: .text%__1cMStubCodeMark2T6M_v_; +text: .text%__1cRAbstractAssemblerFflush6M_v_; +text: .text%__1cRStubCodeGeneratorLstub_epilog6MpnMStubCodeDesc__v_; +text: .text%__1cFVTuneNregister_stub6FpkcpC3_v_; +text: .text%__1cFForteNregister_stub6FpkcpC3_v_; +text: .text%__1cKVM_VersionWget_processor_features6F_v_; +text: .text%__1cCosMsupports_sse6F_i_; +text: .text%__1cVcheck_for_sse_support6F_v_: os_solaris_x86.o; +text: .text%jio_snprintf; +text: .text%jio_vsnprintf; +text: .text%__1cPlocal_vsnprintf6FpcIpkcpv_i_; +text: .text%__1cSstubRoutines_init16F_v_; +text: .text%__1cMStubRoutinesLinitialize16F_v_; +text: .text%__1cWStubGenerator_generate6FpnKCodeBuffer_i_v_; +text: .text%__1cNStubGeneratorbAgenerate_forward_exception6M_pC_: stubGenerator_x86.o; +text: .text%__1cOMacroAssemblerMcall_VM_leaf6MpCpnMRegisterImpl__v_; +text: .text%__1cOMacroAssemblerMcall_VM_leaf6MpCi_v_; +text: .text%__1cOMacroAssemblerRcall_VM_leaf_base6MpCi_v_; +text: .text%__1cJAssemblerEcall6MpCnJrelocInfoJrelocType__v_; +text: .text%__1cJAssemblerJemit_data6MinJrelocInfoJrelocType_i_v_; +text: .text%__1cKRelocationLspec_simple6FnJrelocInfoJrelocType__nQRelocationHolder__; +text: .text%__1cPBoundRelocationLunpack_data6MnJrelocInfoJrelocType__v_: relocInfo.o; +text: .text%__1cKRelocationLunpack_data6M_v_: codeBlob.o; +text: .text%__1cJAssemblerJemit_data6MirknQRelocationHolder_i_v_; +text: .text%__1cKCodeBufferIrelocate6MpCrknQRelocationHolder_i_v_; +text: .text%__1cXruntime_call_RelocationEtype6M_nJrelocInfoJrelocType__: codeBlob.o; +text: .text%__1cOMacroAssemblerJincrement6MpnMRegisterImpl_i_v_; +text: .text%__1cJAssemblerEaddl6MpnMRegisterImpl_i_v_; +text: .text%__1cOMacroAssemblerKget_thread6MpnMRegisterImpl__v_; +text: .text%__1cSThreadLocalStorageTpd_getTlsAccessMode6F_n0AQpd_tlsAccessMode__; +text: .text%__1cJAssemblerFpushl6Mi_v_; +text: .text%__1cJAssemblerEleal6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cJAssemblerEmovl6MnHAddress_i_v_; +text: .text%__1cOMacroAssemblerKverify_oop6MpnMRegisterImpl_pkc_v_; +text: .text%__1cJAssemblerDjmp6MpnMRegisterImpl_nJrelocInfoJrelocType__v_; +text: .text%__1cNStubGeneratorSgenerate_call_stub6MrpC_1_: stubGenerator_x86.o; +text: .text%__1cOMacroAssemblerFenter6M_v_; +text: .text%__1cJAssemblerEsubl6MpnMRegisterImpl_i_v_; +text: .text%__1cJAssemblerFtestl6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerEdecl6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerEcall6MpnMRegisterImpl_nJrelocInfoJrelocType__v_; +text: .text%__1cJAssemblerEcmpl6MpnMRegisterImpl_i_v_; +text: .text%__1cJAssemblerGfstp_s6MnHAddress__v_; +text: .text%__1cJAssemblerGfstp_d6MnHAddress__v_; +text: .text%__1cNStubGeneratorYgenerate_catch_exception6M_pC_: stubGenerator_x86.o; +text: .text%__1cJAssemblerDjmp6MpCnJrelocInfoJrelocType__v_; +text: .text%__1cNStubGeneratorUgenerate_atomic_xchg6M_pC_: stubGenerator_x86.o; +text: .text%__1cJAssemblerExchg6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cJAssemblerGpushad6M_v_; +text: .text%__1cJAssemblerFpopad6M_v_; +text: .text%__1cNStubGeneratorYgenerate_get_previous_fp6M_pC_: stubGenerator_x86.o; +text: .text%__1cNStubGeneratorUgenerate_d2i_wrapper6MpC_1_: stubGenerator_x86.o; +text: .text%__1cOMacroAssemblerOpush_FPU_state6M_v_; +text: .text%__1cJAssemblerGfnsave6MnHAddress__v_; +text: .text%__1cJAssemblerFfwait6M_v_; +text: .text%__1cJAssemblerFfld_d6MnHAddress__v_; +text: .text%__1cJAssemblerFfst_d6MnHAddress__v_; +text: .text%__1cOMacroAssemblerPempty_FPU_stack6M_v_; +text: .text%__1cJAssemblerFffree6Mi_v_; +text: .text%__1cJAssemblerLemit_farith6Miii_v_; +text: .text%__1cOMacroAssemblerNpop_FPU_state6M_v_; +text: .text%__1cJAssemblerGfrstor6MnHAddress__v_; +text: .text%__1cNStubGeneratorUcreate_control_words6M_v_: stubGenerator_x86.o; +text: .text%__1cJTraceTime2T6M_v_; +text: .text%__1cNcarSpace_init6F_v_; +text: .text%__1cICarSpaceEinit6F_v_; +text: .text%__1cNuniverse_init6F_i_; +text: .text%__1cLJavaClassesbAcompute_hard_coded_offsets6F_v_; +text: .text%__1cLFileMapInfoKinitialize6M_i_; +text: .text%__1cLFileMapInfoNfail_continue6MpkcE_v_; +text: .text%__1cLFileMapInfoFclose6M_v_; +text: .text%__1cIUniversePinitialize_heap6F_i_; +text: .text%__1cPMarkSweepPolicy2t6M_v_; +text: .text%__1cbCTwoGenerationCollectorPolicyQinitialize_flags6M_v_; +text: .text%__1cbCTwoGenerationCollectorPolicyMrem_set_name6M_nJGenRemSetEName__: collectorPolicy.o; +text: .text%__1cJGenRemSetYmax_alignment_constraint6Fn0AEName__I_; +text: .text%__1cRCardTableModRefBSbBct_max_alignment_constraint6F_I_; +text: .text%__1cbCTwoGenerationCollectorPolicyUinitialize_size_info6M_v_; +text: .text%__1cPMarkSweepPolicyWinitialize_generations6M_v_; +text: .text%__1cbCTwoGenerationCollectorPolicyVnumber_of_generations6M_i_: collectorPolicy.o; +text: .text%__1cXPermanentGenerationSpec2t6MnHPermGenEName_IIIIII_v_; +text: .text%__1cQGCPolicyCounters2t6Mpkcii_v_; +text: .text%__1cPPerfDataManagerMcounter_name6Fpkc2_pc_; +text: .text%__1cPPerfDataManagerWcreate_string_constant6FnJCounterNS_pkc3pnGThread__pnSPerfStringConstant__; +text: .text%__1cSPerfStringConstant2t6MnJCounterNS_pkc3_v_; +text: .text%__1cNPerfByteArray2t6MnJCounterNS_pkcnIPerfDataFUnits_n0CLVariability_i_v_; +text: .text%__1cKPerfStringKset_string6Mpkc_v_; +text: .text%__1cPPerfDataManagerUcreate_long_constant6FnJCounterNS_pkcnIPerfDataFUnits_xpnGThread__pnQPerfLongConstant__; +text: .text%__1cQGenCollectedHeap2t6MpnPCollectorPolicy__v_; +text: .text%__1cKSharedHeap2t6MpnPCollectorPolicy__v_; +text: .text%__1cNCollectedHeap2t6M_v_; +text: .text%__1cHGCCauseJto_string6Fn0AFCause__pkc_; +text: .text%__1cPPerfDataManagerWcreate_string_variable6FnJCounterNS_pkci3pnGThread__pnSPerfStringVariable__; +text: .text%__1cMSubTasksDone2t6Mi_v_; +text: .text%__1cMSubTasksDoneFclear6M_v_; +text: .text%__1cMSubTasksDoneFvalid6M_i_; +text: .text%__1cQGenCollectedHeapKinitialize6M_i_; +text: .text%__1cPCollectorPolicyLgenerations6M_ppnOGenerationSpec__: collectorPolicy.o; +text: .text%__1cPCollectorPolicyUpermanent_generation6M_pnXPermanentGenerationSpec__: collectorPolicy.o; +text: .text%__1cXPermanentGenerationSpecFalign6MI_v_; +text: .text%__1cQGenCollectedHeapIallocate6MIpnXPermanentGenerationSpec_pIpipnNReservedSpace__pc_; +text: .text%__1cOGenerationSpecRn_covered_regions6kM_i_: collectorPolicy.o; +text: .text%__1cNReservedSpace2t6MIIipc_v_; +text: .text%__1cPCollectorPolicyOcreate_rem_set6MnJMemRegion_i_pnJGenRemSet__; +text: .text%__1cbCTwoGenerationCollectorPolicyQbarrier_set_name6M_nKBarrierSetEName__: collectorPolicy.o; +text: .text%__1cLCardTableRS2t6MnJMemRegion_i_v_; +text: .text%__1cRCardTableModRefBS2t6MnJMemRegion_i_v_; +text: .text%__1cNReservedSpaceYallocation_align_size_up6FI_I_; +text: .text%__1cJMemRegion2t6M_v_: cardTableModRefBS.o; +text: .text%__1cKSharedHeapPset_barrier_set6MpnKBarrierSet__v_; +text: .text%__1cNReservedSpaceKfirst_part6MIii_0_; +text: .text%__1cNReservedSpace2t6MpcI_v_; +text: .text%__1cOGenerationSpecEinit6MnNReservedSpace_ipnJGenRemSet__pnKGeneration__; +text: .text%__1cQDefNewGeneration2t6MnNReservedSpace_Iipkc_v_; +text: .text%__1cKGeneration2t6MnNReservedSpace_Ii_v_; +text: .text%__1cIageTable2t6Mi_v_; +text: .text%__1cIageTableFclear6M_v_; +text: .text%__1cFArenaEgrow6MI_pv_; +text: .text%__1cFChunkJnext_chop6M_v_; +text: .text%__1cFChunkEchop6M_v_; +text: .text%__1cFChunk2k6Fpv_v_; +text: .text%__1cRCardTableModRefBSVresize_covered_region6MnJMemRegion__v_; +text: .text%__1cRCardTableModRefBSbCfind_covering_region_by_base6MpnIHeapWord__i_; +text: .text%__1cRCardTableModRefBSbAlargest_prev_committed_end6kMi_pnIHeapWord__; +text: .text%__1cWSequentialSubTasksDoneFclear6M_v_; +text: .text%__1cSGenerationCounters2t6MpkciipnMVirtualSpace__v_; +text: .text%__1cPPerfDataManagerKname_space6Fpkci_pc_; +text: .text%__1cRCollectorCounters2t6Mpkci_v_; +text: .text%__1cOCSpaceCounters2t6MpkciIpnPContiguousSpace_pnSGenerationCounters__v_; +text: .text%__1cPPerfDataManagerKname_space6Fpkc2i_pc_; +text: .text%__1cPPerfDataManagerUcreate_long_variable6FnJCounterNS_pkcnIPerfDataFUnits_pnUPerfLongSampleHelper_pnGThread__pnQPerfLongVariable__; +text: .text%__1cPPerfLongVariant2t6MnJCounterNS_pkcnIPerfDataFUnits_n0CLVariability_pnUPerfLongSampleHelper__v_; +text: .text%__1cPPerfLongVariantGsample6M_v_; +text: .text%__1cZContiguousSpaceUsedHelperLtake_sample6M_x_: cSpaceCounters.o; +text: .text%__1cPContiguousSpaceEused6kM_I_: space.o; +text: .text%__1cQDefNewGenerationYcompute_space_boundaries6MI_v_; +text: .text%__1cQCompactibleSpaceKinitialize6MnJMemRegion_i_v_; +text: .text%__1cFSpaceKinitialize6MnJMemRegion_i_v_; +text: .text%__1cFSpaceKset_bottom6MpnIHeapWord__v_: space.o; +text: .text%__1cJEdenSpaceHset_end6MpnIHeapWord__v_: space.o; +text: .text%__1cJEdenSpaceFclear6M_v_; +text: .text%__1cPContiguousSpaceFclear6M_v_; +text: .text%__1cFSpaceFclear6M_v_; +text: .text%__1cFSpaceHset_end6MpnIHeapWord__v_: space.o; +text: .text%__1cQDefNewGenerationPupdate_counters6M_v_; +text: .text%__1cSGenerationCountersKupdate_all6M_v_: generationCounters.o; +text: .text%__1cNReservedSpaceJlast_part6MI_0_; +text: .text%__1cRTenuredGeneration2t6MnNReservedSpace_IipnJGenRemSet__v_; +text: .text%__1cOCardGeneration2t6MnNReservedSpace_IipnJGenRemSet__v_; +text: .text%__1cWBlockOffsetSharedArray2t6MnJMemRegion_I_v_; +text: .text%__1cWBlockOffsetSharedArrayGresize6MI_v_; +text: .text%__1cNReservedSpaceSpage_align_size_up6FI_I_; +text: .text%__1cLCardTableRSVresize_covered_region6MnJMemRegion__v_; +text: .text%__1cLCardTableRSKis_aligned6MpnIHeapWord__i_: cardTableRS.o; +text: .text%__1cHGCStats2t6M_v_; +text: .text%__1cWOffsetTableContigSpace2t6MpnWBlockOffsetSharedArray_nJMemRegion__v_; +text: .text%__1cQBlockOffsetArray2t6MpnWBlockOffsetSharedArray_nJMemRegion_i_v_; +text: .text%__1cWOffsetTableContigSpaceKset_bottom6MpnIHeapWord__v_; +text: .text%__1cQBlockOffsetArrayGresize6MI_v_: blockOffsetTable.o; +text: .text%__1cWOffsetTableContigSpaceHset_end6MpnIHeapWord__v_; +text: .text%__1cWOffsetTableContigSpaceFclear6M_v_; +text: .text%__1cbBBlockOffsetArrayContigSpaceUinitialize_threshold6M_pnIHeapWord__; +text: .text%__1cUGenericGrowableArrayEgrow6Mi_v_; +text: .text%__1cXPermanentGenerationSpecEinit6MnNReservedSpace_IpnJGenRemSet__pnHPermGen__; +text: .text%__1cRCompactingPermGen2t6MnNReservedSpace_1IpnJGenRemSet_pnXPermanentGenerationSpec__v_; +text: .text%__1cUCompactingPermGenGen2t6MnNReservedSpace_1IipnJGenRemSet_pnPContiguousSpace_pnXPermanentGenerationSpec__v_; +text: .text%__1cUCompactingPermGenGenbFinitialize_performance_counters6M_v_; +text: .text%__1cbCOneContigSpaceCardGenerationIcapacity6kM_I_; +text: .text%__1cPCollectorPolicybFis_concurrent_mark_sweep_policy6M_i_: collectorPolicy.o; +text: .text%__1cWThreadLocalAllocBufferWstartup_initialization6F_v_; +text: .text%__1cPGlobalTLABStats2t6M_v_; +text: .text%__1cPGlobalTLABStatsKinitialize6M_v_; +text: .text%__1cXAdaptiveWeightedAverageGsample6Mf_v_; +text: .text%__1cXAdaptiveWeightedAverageYcompute_adaptive_average6Mff_f_; +text: .text%__1cQGenCollectedHeapNtlab_capacity6kM_I_; +text: .text%__1cQDefNewGenerationYsupports_tlab_allocation6kM_i_: defNewGeneration.o; +text: .text%__1cQDefNewGenerationNtlab_capacity6kM_I_: defNewGeneration.o; +text: .text%__1cKGenerationYsupports_tlab_allocation6kM_i_: tenuredGeneration.o; +text: .text%__1cWThreadLocalAllocBufferImax_size6F_I_; +text: .text%__1cOBasicHashtable2t6Mii_v_: universe.o; +text: .text%__1cLClassLoaderZcreate_package_info_table6F_v_; +text: .text%__1cOBasicHashtable2t6Mii_v_: classLoader.o; +text: .text%__1cQinterpreter_init6F_v_; +text: .text%__1cTAbstractInterpreterKinitialize6F_v_; +text: .text%__1cNTemplateTableKinitialize6F_v_; +text: .text%__1cNTemplateTableDdef6FnJBytecodesECode_inITosState_3pF_vc_v_; +text: .text%__1cNTemplateTableDdef6FnJBytecodesECode_inITosState_3pFi_vi_v_; +text: .text%__1cITemplateKinitialize6MinITosState_1pFi_vi_v_; +text: .text%__1cNTemplateTableDdef6FnJBytecodesECode_inITosState_3pFn0AJOperation__v4_v_; +text: .text%__1cNTemplateTableDdef6FnJBytecodesECode_inITosState_3pFn0AJCondition__v4_v_; +text: .text%__1cNTemplateTableDdef6FnJBytecodesECode_inITosState_3pF3_v3_v_; +text: .text%__1cNTemplateTableNpd_initialize6F_v_; +text: .text%__1cRInvocationCounterMreinitialize6Fi_v_; +text: .text%__1cRInvocationCounterDdef6Fn0AFState_ipFnMmethodHandle_pnGThread__pC_v_; +text: .text%__1cJStubQdDueue2t6MpnNStubInterface_ipnFMutex_pkc_v_; +text: .text%__1cICodeHeapJexpand_by6MI_i_; +text: .text%__1cJStubQdDueueOregister_queue6Fp0_v_; +text: .text%__1cUInterpreterGenerator2t6MpnJStubQdDueue__v_; +text: .text%__1cbCAbstractInterpreterGenerator2t6MpnJStubQdDueue__v_; +text: .text%__1cbCAbstractInterpreterGeneratorMgenerate_all6M_v_; +text: .text%__1cLCodeletMark2t6MrpnZInterpreterMacroAssembler_pkcinJBytecodesECode__v_: interpreter.o; +text: .text%__1cJStubQdDueueHrequest6Mi_pnEStub__; +text: .text%__1cbBInterpreterCodeletInterfaceRcode_size_to_size6kMi_i_: interpreter.o; +text: .text%__1cbBInterpreterCodeletInterfaceKinitialize6MpnEStub_i_v_: interpreter.o; +text: .text%__1cSInterpreterCodeletKinitialize6MpkcinJBytecodesECode__v_; +text: .text%__1cbCAbstractInterpreterGeneratorTgenerate_error_exit6Mpkc_pC_; +text: .text%__1cOMacroAssemblerEstop6Mpkc_v_; +text: .text%__1cJAssemblerEcall6MrnFLabel_nJrelocInfoJrelocType__v_; +text: .text%__1cJAssemblerDhlt6M_v_; +text: .text%__1cOMacroAssemblerFalign6Mi_v_; +text: .text%__1cJAssemblerDnop6M_v_; +text: .text%__1cJStubQdDueueGcommit6Mi_v_; +text: .text%__1cbCAbstractInterpreterGeneratorZgenerate_return_entry_for6MnITosState_i_pC_; +text: .text%__1cZInterpreterMacroAssemblerbAget_cache_and_index_at_bcp6MpnMRegisterImpl_2i_v_; +text: .text%__1cOMacroAssemblerSload_unsigned_word6MpnMRegisterImpl_nHAddress__i_; +text: .text%__1cJAssemblerGmovzxw6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cJAssemblerEshll6MpnMRegisterImpl_i_v_; +text: .text%__1cJAssemblerEandl6MpnMRegisterImpl_i_v_; +text: .text%__1cZInterpreterMacroAssemblerNdispatch_next6MnITosState_i_v_; +text: .text%__1cOMacroAssemblerSload_unsigned_byte6MpnMRegisterImpl_nHAddress__i_; +text: .text%__1cJAssemblerGmovzxb6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cZInterpreterMacroAssemblerNdispatch_base6MnITosState_ppCi_v_; +text: .text%__1cZInterpreterMacroAssemblerKverify_FPU6MinITosState__v_; +text: .text%__1cZInterpreterMacroAssemblerKverify_oop6MpnMRegisterImpl_nITosState__v_; +text: .text%__1cJAssemblerDjmp6MnHAddress__v_; +text: .text%__1cOMacroAssemblerKverify_FPU6Mipkc_v_; +text: .text%__1cKEntryPoint2t6MpC11111111_v_; +text: .text%__1cJAssemblerEincl6MpnMRegisterImpl__v_; +text: .text%__1cbCAbstractInterpreterGeneratorYgenerate_deopt_entry_for6MnITosState_i_pC_; +text: .text%__1cJAssemblerEcmpl6MnHAddress_i_v_; +text: .text%__1cOMacroAssemblerHcall_VM6MpnMRegisterImpl_pCi_v_; +text: .text%__1cOMacroAssemblerOcall_VM_helper6MpnMRegisterImpl_pCii_v_; +text: .text%__1cZInterpreterMacroAssemblerMcall_VM_base6MpnMRegisterImpl_22pCii_v_; +text: .text%__1cOMacroAssemblerMcall_VM_base6MpnMRegisterImpl_22pCii_v_; +text: .text%__1cZInterpreterMacroAssemblerZcheck_and_handle_popframe6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerDjcc6Mn0AJCondition_pCnJrelocInfoJrelocType__v_; +text: .text%__1cTAbstractInterpreterSBasicType_as_index6FnJBasicType__i_; +text: .text%__1cbCAbstractInterpreterGeneratorbBgenerate_result_handler_for6MnJBasicType__pC_; +text: .text%__1cOMacroAssemblerGc2bool6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerEsetb6Mn0AJCondition_pnMRegisterImpl__v_; +text: .text%__1cOMacroAssemblerQsign_extend_byte6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerGmovsxb6MpnMRegisterImpl_2_v_; +text: .text%__1cOMacroAssemblerRsign_extend_short6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerGmovsxw6MpnMRegisterImpl_2_v_; +text: .text%__1cSInterpreterRuntimeZSignatureHandlerGeneratorEtemp6F_pnMRegisterImpl__; +text: .text%__1cZInterpreterMacroAssemblerDpop6MnITosState__v_; +text: .text%__1cbCAbstractInterpreterGeneratorbFgenerate_slow_signature_handler6M_pC_; +text: .text%__1cOMacroAssemblerHcall_VM6MpnMRegisterImpl_pC222i_v_; +text: .text%__1cTAbstractInterpreterRTosState_as_index6FnITosState__i_; +text: .text%__1cTAbstractInterpreterMreturn_entry6FnITosState_i_pC_; +text: .text%__1cKEntryPointFentry6kMnITosState__pC_; +text: .text%__1cbCAbstractInterpreterGeneratorZgenerate_continuation_for6MnITosState__pC_; +text: .text%__1cbCAbstractInterpreterGeneratorZgenerate_safept_entry_for6MnITosState_pC_2_; +text: .text%__1cZInterpreterMacroAssemblerEpush6MnITosState__v_; +text: .text%__1cZInterpreterMacroAssemblerMdispatch_via6MnITosState_ppC_v_; +text: .text%__1cbCAbstractInterpreterGeneratorYgenerate_throw_exception6M_v_; +text: .text%__1cOMacroAssemblerHcall_VM6MpnMRegisterImpl_pC2i_v_; +text: .text%__1cJAssemblerDorl6MpnMRegisterImpl_i_v_; +text: .text%__1cZInterpreterMacroAssemblerSsuper_call_VM_leaf6MpCpnMRegisterImpl__v_; +text: .text%__1cJAssemblerEsubl6MpnMRegisterImpl_2_v_; +text: .text%__1cZInterpreterMacroAssemblerSsuper_call_VM_leaf6MpCpnMRegisterImpl_33_v_; +text: .text%__1cZInterpreterMacroAssemblerRremove_activation6MnITosState_pnMRegisterImpl_iii_v_; +text: .text%__1cJAssemblerFtestl6MpnMRegisterImpl_i_v_; +text: .text%__1cZInterpreterMacroAssemblerNunlock_object6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerElock6M_v_; +text: .text%__1cJAssemblerHcmpxchg6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cHAddress2t6MinJrelocInfoJrelocType__v_; +text: .text%__1cOMacroAssemblerFleave6M_v_; +text: .text%__1cbCAbstractInterpreterGeneratorbMgenerate_ArrayIndexOutOfBounds_handler6Mpkc_pC_; +text: .text%__1cOMacroAssemblerHcall_VM6MpnMRegisterImpl_pC22i_v_; +text: .text%__1cbCAbstractInterpreterGeneratorbHgenerate_exception_handler_common6Mpkc2i_pC_; +text: .text%__1cbCAbstractInterpreterGeneratorbJgenerate_StackOverflowError_handler6M_pC_; +text: .text%__1cbCAbstractInterpreterGeneratorVgenerate_method_entry6MnTAbstractInterpreterKMethodKind__pC_; +text: .text%__1cUInterpreterGeneratorbEgenerate_asm_interpreter_entry6Mi_pC_; +text: .text%__1cUInterpreterGeneratorXcheck_for_compiled_code6MrnFLabel__v_; +text: .text%__1cUInterpreterGeneratorbDgenerate_stack_overflow_check6M_v_; +text: .text%__1cJAssemblerEaddl6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cJAssemblerEsubl6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cUInterpreterGeneratorUgenerate_fixed_frame6Mi_v_; +text: .text%__1cUInterpreterGeneratorVgenerate_counter_incr6MpnFLabel_22_v_; +text: .text%__1cJAssemblerEaddl6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerEcmpl6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cbCAbstractInterpreterGeneratorXbang_stack_shadow_pages6Mi_v_; +text: .text%__1cOMacroAssemblerWbang_stack_with_offset6Mi_v_: interp_masm_x86.o; +text: .text%__1cZInterpreterMacroAssemblerTnotify_method_entry6M_v_; +text: .text%__1cUInterpreterGeneratorZgenerate_counter_overflow6MpC_v_; +text: .text%__1cJAssemblerEnegl6MpnMRegisterImpl__v_; +text: .text%__1cUInterpreterGeneratorbAgenerate_run_compiled_code6M_v_; +text: .text%__1cZInterpreterMacroAssemblerNsuper_call_VM6MpnMRegisterImpl_2pC22_v_; +text: .text%__1cUInterpreterGeneratorLlock_method6M_v_; +text: .text%__1cZInterpreterMacroAssemblerLlock_object6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerDorl6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cUInterpreterGeneratorUgenerate_empty_entry6M_pC_; +text: .text%__1cUInterpreterGeneratorXgenerate_accessor_entry6M_pC_; +text: .text%__1cJAssemblerEshrl6MpnMRegisterImpl_i_v_; +text: .text%__1cLlog2_intptr6Fi_i_: interpreter_x86.o; +text: .text%__1cOMacroAssemblerQload_signed_byte6MpnMRegisterImpl_nHAddress__i_; +text: .text%__1cJAssemblerGmovsxb6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cOMacroAssemblerQload_signed_word6MpnMRegisterImpl_nHAddress__i_; +text: .text%__1cJAssemblerGmovsxw6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cUInterpreterGeneratorXgenerate_abstract_entry6M_pC_; +text: .text%__1cUInterpreterGeneratorTgenerate_math_entry6MnTAbstractInterpreterKMethodKind__pC_; +text: .text%__1cOMacroAssemblerGsincos6Miii_v_; +text: .text%__1cJAssemblerFfld_s6Mi_v_; +text: .text%__1cJAssemblerEfabs6M_v_; +text: .text%__1cOMacroAssemblerEfcmp6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerHfucomip6Mi_v_; +text: .text%__1cOMacroAssemblerEfpop6M_v_; +text: .text%__1cJAssemblerHfincstp6M_v_; +text: .text%__1cJAssemblerEfsin6M_v_; +text: .text%__1cJAssemblerEfcos6M_v_; +text: .text%__1cJAssemblerFfsqrt6M_v_; +text: .text%__1cUInterpreterGeneratorVgenerate_native_entry6Mi_pC_; +text: .text%__1cNSharedRuntimebWnative_method_throw_unsatisfied_link_error_entry6F_pC_; +text: .text%__1cJAssemblerGmembar6M_v_; +text: .text%__1cJAssemblerEaddl6MnHAddress_i_v_; +text: .text%__1cJAssemblerSemit_arith_operand6MipnMRegisterImpl_nHAddress_i_v_; +text: .text%__1cZInterpreterMacroAssemblerSnotify_method_exit6MnITosState__v_; +text: .text%__1cbCAbstractInterpreterGeneratorbEset_entry_points_for_all_bytes6M_v_; +text: .text%__1cbCAbstractInterpreterGeneratorQset_entry_points6MnJBytecodesECode__v_; +text: .text%__1cbCAbstractInterpreterGeneratorWset_short_entry_points6MpnITemplate_rpC44444444_v_; +text: .text%__1cbCAbstractInterpreterGeneratorVset_vtos_entry_points6MpnITemplate_rpC44444444_v_; +text: .text%__1cbCAbstractInterpreterGeneratorVgenerate_and_dispatch6MpnITemplate_nITosState__v_; +text: .text%__1cITemplateIbytecode6kM_nJBytecodesECode__; +text: .text%__1cZInterpreterMacroAssemblerPdispatch_prolog6MnITosState_i_v_; +text: .text%__1cITemplateIgenerate6MpnZInterpreterMacroAssembler__v_; +text: .text%__1cNTemplateTableDnop6F_v_; +text: .text%__1cNTemplateTableKtransition6FnITosState_1_v_; +text: .text%__1cZInterpreterMacroAssemblerPdispatch_epilog6MnITosState_i_v_; +text: .text%__1cNDispatchTableJset_entry6MirnKEntryPoint__v_; +text: .text%__1cNTemplateTableLaconst_null6F_v_; +text: .text%__1cNTemplateTableGiconst6Fi_v_; +text: .text%__1cNTemplateTableGlconst6Fi_v_; +text: .text%__1cNTemplateTableGfconst6Fi_v_; +text: .text%__1cJAssemblerEfldz6M_v_; +text: .text%__1cJAssemblerEfld16M_v_; +text: .text%__1cJAssemblerFfaddp6Mi_v_; +text: .text%__1cNTemplateTableGdconst6Fi_v_; +text: .text%__1cNTemplateTableGbipush6F_v_; +text: .text%__1cNTemplateTableGsipush6F_v_; +text: .text%__1cJAssemblerFbswap6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerEsarl6MpnMRegisterImpl_i_v_; +text: .text%__1cNTemplateTableDldc6Fi_v_; +text: .text%__1cJAssemblerEmovb6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cNTemplateTableHcall_VM6FpnMRegisterImpl_pC2_v_; +text: .text%__1cJAssemblerFfld_s6MnHAddress__v_; +text: .text%__1cZInterpreterMacroAssemblerbGget_unsigned_2_byte_index_at_bcp6MpnMRegisterImpl_i_v_; +text: .text%__1cNTemplateTableGldc2_w6F_v_; +text: .text%__1cJAssemblerEcmpb6MnHAddress_i_v_; +text: .text%__1cNTemplateTableFiload6F_v_; +text: .text%__1cNTemplateTableMlocals_index6FpnMRegisterImpl_i_v_; +text: .text%__1cbCAbstractInterpreterGeneratorUset_wide_entry_point6MpnITemplate_rpC_v_; +text: .text%__1cNTemplateTableKwide_iload6F_v_; +text: .text%__1cNTemplateTableRlocals_index_wide6FpnMRegisterImpl__v_; +text: .text%__1cNTemplateTableFlload6F_v_; +text: .text%__1cNTemplateTableKwide_lload6F_v_; +text: .text%__1cNTemplateTableFfload6F_v_; +text: .text%__1cNTemplateTableKwide_fload6F_v_; +text: .text%__1cNTemplateTableFdload6F_v_; +text: .text%__1cNTemplateTableKwide_dload6F_v_; +text: .text%__1cNTemplateTableFaload6F_v_; +text: .text%__1cNTemplateTableKwide_aload6F_v_; +text: .text%__1cNTemplateTableFiload6Fi_v_; +text: .text%__1cNTemplateTableFlload6Fi_v_; +text: .text%__1cNTemplateTableFfload6Fi_v_; +text: .text%__1cNTemplateTableFdload6Fi_v_; +text: .text%__1cNTemplateTableHaload_06F_v_; +text: .text%__1cNTemplateTableFaload6Fi_v_; +text: .text%__1cNTemplateTableGiaload6F_v_; +text: .text%__1cNTemplateTableLindex_check6FpnMRegisterImpl_2_v_; +text: .text%__1cOMacroAssemblerKnull_check6MpnMRegisterImpl_i_v_; +text: .text%__1cOMacroAssemblerZneeds_explicit_null_check6Fi_i_; +text: .text%__1cNTemplateTableGlaload6F_v_; +text: .text%__1cNTemplateTableGfaload6F_v_; +text: .text%__1cNTemplateTableGdaload6F_v_; +text: .text%__1cNTemplateTableGaaload6F_v_; +text: .text%__1cNTemplateTableGbaload6F_v_; +text: .text%__1cNTemplateTableGcaload6F_v_; +text: .text%__1cNTemplateTableGsaload6F_v_; +text: .text%__1cNTemplateTableGistore6F_v_; +text: .text%__1cNTemplateTableLwide_istore6F_v_; +text: .text%__1cNTemplateTableGlstore6F_v_; +text: .text%__1cNTemplateTableLwide_lstore6F_v_; +text: .text%__1cNTemplateTableGfstore6F_v_; +text: .text%__1cNTemplateTableLwide_fstore6F_v_; +text: .text%__1cNTemplateTableGdstore6F_v_; +text: .text%__1cNTemplateTableLwide_dstore6F_v_; +text: .text%__1cNTemplateTableGastore6F_v_; +text: .text%__1cNTemplateTableLwide_astore6F_v_; +text: .text%__1cNTemplateTableGistore6Fi_v_; +text: .text%__1cNTemplateTableGlstore6Fi_v_; +text: .text%__1cNTemplateTableGfstore6Fi_v_; +text: .text%__1cNTemplateTableGdstore6Fi_v_; +text: .text%__1cNTemplateTableGastore6Fi_v_; +text: .text%__1cNTemplateTableHiastore6F_v_; +text: .text%__1cNTemplateTableHlastore6F_v_; +text: .text%__1cNTemplateTableHfastore6F_v_; +text: .text%__1cNTemplateTableHdastore6F_v_; +text: .text%__1cNTemplateTableHaastore6F_v_; +text: .text%__1cZInterpreterMacroAssemblerRprofile_checkcast6MipnMRegisterImpl__v_; +text: .text%__1cZInterpreterMacroAssemblerRgen_subtype_check6MpnMRegisterImpl_rnFLabel__v_; +text: .text%__1cJAssemblerKrepne_scan6M_v_; +text: .text%__1cOMacroAssemblerLstore_check6MpnMRegisterImpl__v_; +text: .text%__1cOMacroAssemblerSstore_check_part_16MpnMRegisterImpl__v_; +text: .text%__1cOMacroAssemblerSstore_check_part_26MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerEmovb6MnHAddress_i_v_; +text: .text%__1cNTemplateTableHbastore6F_v_; +text: .text%__1cJAssemblerEmovb6MnHAddress_pnMRegisterImpl__v_; +text: .text%__1cNTemplateTableHcastore6F_v_; +text: .text%__1cJAssemblerEmovw6MnHAddress_pnMRegisterImpl__v_; +text: .text%__1cNTemplateTableHsastore6F_v_; +text: .text%__1cNTemplateTableDpop6F_v_; +text: .text%__1cNTemplateTableEpop26F_v_; +text: .text%__1cNTemplateTableDdup6F_v_; +text: .text%__1cJAssemblerFpushl6MnHAddress__v_; +text: .text%__1cNTemplateTableGdup_x16F_v_; +text: .text%__1cNTemplateTableGdup_x26F_v_; +text: .text%__1cNTemplateTableEdup26F_v_; +text: .text%__1cNTemplateTableHdup2_x16F_v_; +text: .text%__1cNTemplateTableHdup2_x26F_v_; +text: .text%__1cNTemplateTableEswap6F_v_; +text: .text%__1cNTemplateTableEiop26Fn0AJOperation__v_; +text: .text%__1cNTemplateTableElop26Fn0AJOperation__v_; +text: .text%__1cJAssemblerEadcl6MpnMRegisterImpl_2_v_; +text: .text%__1cNTemplateTableEfop26Fn0AJOperation__v_; +text: .text%__1cJAssemblerGfadd_s6MnHAddress__v_; +text: .text%__1cZInterpreterMacroAssemblerGf2ieee6M_v_; +text: .text%__1cNTemplateTableEdop26Fn0AJOperation__v_; +text: .text%__1cJAssemblerGfadd_d6MnHAddress__v_; +text: .text%__1cZInterpreterMacroAssemblerGd2ieee6M_v_; +text: .text%__1cJAssemblerEsbbl6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerHfsubr_s6MnHAddress__v_; +text: .text%__1cJAssemblerHfsubr_d6MnHAddress__v_; +text: .text%__1cJAssemblerFimull6MpnMRegisterImpl_2_v_; +text: .text%__1cNTemplateTableElmul6F_v_; +text: .text%__1cOMacroAssemblerElmul6Mii_v_; +text: .text%__1cJAssemblerEmull6MnHAddress__v_; +text: .text%__1cJAssemblerEmull6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerGfmul_s6MnHAddress__v_; +text: .text%__1cJAssemblerGfmul_d6MnHAddress__v_; +text: .text%__1cJAssemblerFfld_x6MnHAddress__v_; +text: .text%__1cJAssemblerFfmulp6Mi_v_; +text: .text%__1cNTemplateTableEidiv6F_v_; +text: .text%__1cOMacroAssemblerPcorrected_idivl6MpnMRegisterImpl__i_; +text: .text%__1cJAssemblerEcdql6M_v_; +text: .text%__1cJAssemblerFidivl6MpnMRegisterImpl__v_; +text: .text%__1cNTemplateTableEldiv6F_v_; +text: .text%__1cZInterpreterMacroAssemblerRcall_VM_leaf_base6MpCi_v_; +text: .text%__1cJAssemblerHfdivr_s6MnHAddress__v_; +text: .text%__1cJAssemblerHfdivr_d6MnHAddress__v_; +text: .text%__1cJAssemblerGfdivrp6Mi_v_; +text: .text%__1cNTemplateTableEirem6F_v_; +text: .text%__1cNTemplateTableElrem6F_v_; +text: .text%__1cOMacroAssemblerFfremr6MpnMRegisterImpl__v_; +text: .text%__1cOMacroAssemblerIsave_eax6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerFfprem6M_v_; +text: .text%__1cJAssemblerJfnstsw_ax6M_v_; +text: .text%__1cJAssemblerEsahf6M_v_; +text: .text%__1cOMacroAssemblerLrestore_eax6MpnMRegisterImpl__v_; +text: .text%__1cJAssemblerEfxch6Mi_v_; +text: .text%__1cNTemplateTableEineg6F_v_; +text: .text%__1cNTemplateTableElneg6F_v_; +text: .text%__1cOMacroAssemblerElneg6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerEadcl6MpnMRegisterImpl_i_v_; +text: .text%__1cNTemplateTableEfneg6F_v_; +text: .text%__1cJAssemblerEfchs6M_v_; +text: .text%__1cNTemplateTableEdneg6F_v_; +text: .text%__1cJAssemblerEshll6MpnMRegisterImpl__v_; +text: .text%__1cNTemplateTableElshl6F_v_; +text: .text%__1cOMacroAssemblerElshl6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerFshldl6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerEsarl6MpnMRegisterImpl__v_; +text: .text%__1cNTemplateTableElshr6F_v_; +text: .text%__1cOMacroAssemblerElshr6MpnMRegisterImpl_2i_v_; +text: .text%__1cJAssemblerFshrdl6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerEshrl6MpnMRegisterImpl__v_; +text: .text%__1cNTemplateTableFlushr6F_v_; +text: .text%__1cJAssemblerEandl6MpnMRegisterImpl_2_v_; +text: .text%__1cNTemplateTableEiinc6F_v_; +text: .text%__1cJAssemblerEaddl6MnHAddress_pnMRegisterImpl__v_; +text: .text%__1cNTemplateTableJwide_iinc6F_v_; +text: .text%__1cNTemplateTableHconvert6F_v_; +text: .text%__1cOMacroAssemblerLextend_sign6MpnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerGfild_s6MnHAddress__v_; +text: .text%__1cJAssemblerGfild_d6MnHAddress__v_; +text: .text%__1cNTemplateTableElcmp6F_v_; +text: .text%__1cOMacroAssemblerIlcmp2int6MpnMRegisterImpl_222_v_; +text: .text%__1cNTemplateTableJfloat_cmp6Fi_v_; +text: .text%__1cNTemplateTableJfloat_cmp6Fii_v_; +text: .text%__1cOMacroAssemblerIfcmp2int6MpnMRegisterImpl_i_v_; +text: .text%__1cNTemplateTableKdouble_cmp6Fi_v_; +text: .text%__1cNTemplateTableHif_0cmp6Fn0AJCondition__v_; +text: .text%__1cFj_not6FnNTemplateTableJCondition__nJAssemblerJCondition__: templateTable_x86.o; +text: .text%__1cNTemplateTableGbranch6Fii_v_; +text: .text%__1cZInterpreterMacroAssemblerUprofile_taken_branch6MpnMRegisterImpl_2_v_; +text: .text%__1cZInterpreterMacroAssemblerNdispatch_only6MnITosState__v_; +text: .text%__1cZInterpreterMacroAssemblerYprofile_not_taken_branch6MpnMRegisterImpl__v_; +text: .text%__1cNTemplateTableHif_icmp6Fn0AJCondition__v_; +text: .text%__1cNTemplateTableHif_acmp6Fn0AJCondition__v_; +text: .text%__1cNTemplateTableF_goto6F_v_; +text: .text%__1cNTemplateTableDjsr6F_v_; +text: .text%__1cZInterpreterMacroAssemblerWdispatch_only_noverify6MnITosState__v_; +text: .text%__1cNTemplateTableDret6F_v_; +text: .text%__1cZInterpreterMacroAssemblerLprofile_ret6MpnMRegisterImpl_2_v_; +text: .text%__1cNTemplateTableIwide_ret6F_v_; +text: .text%__1cNTemplateTableLtableswitch6F_v_; +text: .text%__1cZInterpreterMacroAssemblerTprofile_switch_case6MpnMRegisterImpl_22_v_; +text: .text%__1cZInterpreterMacroAssemblerWprofile_switch_default6MpnMRegisterImpl__v_; +text: .text%__1cNTemplateTableMlookupswitch6F_v_; +text: .text%__1cNTemplateTableH_return6FnITosState__v_; +text: .text%__1cNTemplateTableJgetstatic6Fi_v_; +text: .text%__1cNTemplateTableSgetfield_or_static6Fii_v_; +text: .text%__1cNTemplateTableZload_field_cp_cache_entry6FipnMRegisterImpl_22i_v_; +text: .text%__1cNTemplateTableXresolve_cache_and_index6FipnMRegisterImpl_2_v_; +text: .text%__1cJAssemblerHfistp_d6MnHAddress__v_; +text: .text%__1cNTemplateTableJputstatic6Fi_v_; +text: .text%__1cNTemplateTableSputfield_or_static6Fii_v_; +text: .text%__1cNTemplateTableUjvmti_post_field_mod6Fii_v_; +text: .text%__1cOMacroAssemblerLstore_check6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cNTemplateTableQvolatile_barrier6F_v_; +text: .text%__1cNTemplateTableIgetfield6Fi_v_; +text: .text%__1cNTemplateTableOpatch_bytecode6FnJBytecodesECode_pnMRegisterImpl_4i_v_; +text: .text%__1cNTemplateTableIputfield6Fi_v_; +text: .text%__1cNTemplateTableNinvokevirtual6Fi_v_; +text: .text%__1cNTemplateTableOprepare_invoke6FpnMRegisterImpl_2inJBytecodesECode__v_; +text: .text%__1cNTemplateTablebAload_invoke_cp_cache_entry6FipnMRegisterImpl_22ii_v_; +text: .text%__1cNTemplateTableUinvokevirtual_helper6FpnMRegisterImpl_22_v_; +text: .text%__1cZInterpreterMacroAssemblerSprofile_final_call6MpnMRegisterImpl__v_; +text: .text%__1cZInterpreterMacroAssemblerUprofile_virtual_call6MpnMRegisterImpl_22_v_; +text: .text%__1cNTemplateTableNinvokespecial6Fi_v_; +text: .text%__1cZInterpreterMacroAssemblerMprofile_call6MpnMRegisterImpl__v_; +text: .text%__1cNTemplateTableMinvokestatic6Fi_v_; +text: .text%__1cNTemplateTablePinvokeinterface6Fi_v_; +text: .text%__1cOMacroAssemblerIround_to6MpnMRegisterImpl_i_v_; +text: .text%__1cbCAbstractInterpreterGeneratorRset_unimplemented6Mi_v_; +text: .text%__1cNTemplateTableE_new6F_v_; +text: .text%__1cQGenCollectedHeapItop_addr6kM_ppnIHeapWord__; +text: .text%__1cQDefNewGenerationItop_addr6kM_ppnIHeapWord__; +text: .text%__1cQGenCollectedHeapIend_addr6kM_ppnIHeapWord__; +text: .text%__1cQDefNewGenerationIend_addr6kM_ppnIHeapWord__; +text: .text%__1cOMacroAssemblerJdecrement6MpnMRegisterImpl_i_v_; +text: .text%__1cNTemplateTableHcall_VM6FpnMRegisterImpl_pC22_v_; +text: .text%__1cNTemplateTableInewarray6F_v_; +text: .text%__1cNTemplateTableJanewarray6F_v_; +text: .text%__1cNTemplateTableHcall_VM6FpnMRegisterImpl_pC222_v_; +text: .text%__1cNTemplateTableLarraylength6F_v_; +text: .text%__1cNTemplateTableGathrow6F_v_; +text: .text%__1cNTemplateTableJcheckcast6F_v_; +text: .text%__1cNTemplateTableHcall_VM6FpnMRegisterImpl_pC_v_; +text: .text%__1cNTemplateTableKinstanceof6F_v_; +text: .text%__1cNTemplateTableMmonitorenter6F_v_; +text: .text%__1cJAssemblerFcmovl6Mn0AJCondition_pnMRegisterImpl_3_v_; +text: .text%__1cNTemplateTableLmonitorexit6F_v_; +text: .text%__1cNTemplateTableEwide6F_v_; +text: .text%__1cNTemplateTableOmultianewarray6F_v_; +text: .text%__1cNTemplateTableKif_nullcmp6Fn0AJCondition__v_; +text: .text%__1cNTemplateTableGgoto_w6F_v_; +text: .text%__1cNTemplateTableFjsr_w6F_v_; +text: .text%__1cNTemplateTableL_breakpoint6F_v_; +text: .text%__1cZInterpreterMacroAssemblerUdispatch_only_normal6MnITosState__v_; +text: .text%__1cNTemplateTableQfast_accessfield6FnITosState__v_; +text: .text%__1cNTemplateTablePfast_storefield6FnITosState__v_; +text: .text%__1cNTemplateTableZjvmti_post_fast_field_mod6F_v_; +text: .text%__1cNTemplateTableMfast_xaccess6FnITosState__v_; +text: .text%__1cNTemplateTableKfast_iload6F_v_; +text: .text%__1cNTemplateTableLfast_iload26F_v_; +text: .text%__1cNTemplateTableMfast_icaload6F_v_; +text: .text%__1cNTemplateTableRfast_invokevfinal6Fi_v_; +text: .text%__1cNTemplateTableRfast_linearswitch6F_v_; +text: .text%__1cNTemplateTableRfast_binaryswitch6F_v_; +text: .text%__1cNTemplateTableSshouldnotreachhere6F_v_; +text: .text%__1cbCAbstractInterpreterGeneratorbCset_safepoints_for_all_bytes6M_v_; +text: .text%__1cWinvocationCounter_init6F_v_; +text: .text%__1cOmarksweep_init6F_v_; +text: .text%__1cQaccessFlags_init6F_v_; +text: .text%__1cStemplateTable_init6F_v_; +text: .text%__1cVInterfaceSupport_init6F_v_; +text: .text%__1cOuniverse2_init6F_v_; +text: .text%__1cIUniverseHgenesis6FpnGThread__v_; +text: .text%__1cIUniverseYcompute_base_vtable_size6F_v_; +text: .text%__1cLClassLoaderVcompute_Object_vtable6F_i_; +text: .text%__1cKklassKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cFKlassVbase_create_klass_oop6FrnLKlassHandle_irknKKlass_vtbl_pnGThread__pnMklassOopDesc__; +text: .text%__1cKklassKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: klassKlass.o; +text: .text%__1cKKlass_vtbl2n6FIrnLKlassHandle_ipnGThread__pv_; +text: .text%__1cNCollectedHeapWpermanent_obj_allocate6FnLKlassHandle_ipnGThread__pnHoopDesc__: klass.o; +text: .text%__1cKSharedHeapWpermanent_mem_allocate6MI_pnIHeapWord__: genCollectedHeap.o; +text: .text%__1cRCompactingPermGenMmem_allocate6MI_pnIHeapWord__; +text: .text%__1cbCOneContigSpaceCardGenerationIallocate6MIii_pnIHeapWord__: compactingPermGenGen.o; +text: .text%__1cWOffsetTableContigSpaceIallocate6MI_pnIHeapWord__: space.o; +text: .text%__1cPContiguousSpaceIallocate6MI_pnIHeapWord__; +text: .text%__1cbBBlockOffsetArrayContigSpaceLalloc_block6MpnIHeapWord_2_v_: blockOffsetTable.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: klass.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: klass.o; +text: .text%__1cRCardTableModRefBSEkind6M_nKBarrierSetEName__: cardTableModRefBS.o; +text: .text%__1cFKlassMset_subklass6MpnMklassOopDesc__v_; +text: .text%__1cFKlassQset_next_sibling6MpnMklassOopDesc__v_; +text: .text%__1cKklassKlassOset_alloc_size6MI_v_: klassKlass.o; +text: .text%__1cParrayKlassKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cFKlassRbase_create_klass6FrnLKlassHandle_irknKKlass_vtbl_pnGThread__1_; +text: .text%__1cParrayKlassKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: arrayKlassKlass.o; +text: .text%__1cKklassKlassOset_alloc_size6MI_v_: arrayKlassKlass.o; +text: .text%__1cPjava_lang_ClassNcreate_mirror6FnLKlassHandle_pnGThread__pnHoopDesc__; +text: .text%__1cFKlassWcompute_modifier_flags6kMpnGThread__i_; +text: .text%__1cSobjArrayKlassKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cSobjArrayKlassKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: objArrayKlassKlass.o; +text: .text%__1cKklassKlassOset_alloc_size6MI_v_: objArrayKlassKlass.o; +text: .text%__1cSinstanceKlassKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cSinstanceKlassKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: instanceKlassKlass.o; +text: .text%__1cKklassKlassOset_alloc_size6MI_v_: instanceKlassKlass.o; +text: .text%__1cTtypeArrayKlassKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cTtypeArrayKlassKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: typeArrayKlassKlass.o; +text: .text%__1cbBBlockOffsetArrayContigSpaceQalloc_block_work6MpnIHeapWord_2_v_; +text: .text%__1cKklassKlassOset_alloc_size6MI_v_: typeArrayKlassKlass.o; +text: .text%__1cLsymbolKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cLsymbolKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: symbolKlass.o; +text: .text%__1cLsymbolKlassOset_alloc_size6MI_v_: symbolKlass.o; +text: .text%__1cKoopFactoryKnew_symbol6FpkcipnGThread__pnNsymbolOopDesc__; +text: .text%__1cLSymbolTableGlookup6FpkcipnGThread__pnNsymbolOopDesc__; +text: .text%__1cJHashtableLhash_symbol6Fpkci_I_: symbolTable.o; +text: .text%__1cLSymbolTableGlookup6MipkciI_pnNsymbolOopDesc__; +text: .text%__1cLSymbolTableJbasic_add6MipCiIpnGThread__pnNsymbolOopDesc__; +text: .text%__1cLsymbolKlassPallocate_symbol6MpCipnGThread__pnNsymbolOopDesc__; +text: .text%__1cNCollectedHeapWpermanent_obj_allocate6FnLKlassHandle_ipnGThread__pnHoopDesc__: symbolKlass.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: symbolKlass.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: symbolKlass.o; +text: .text%__1cJHashtableJnew_entry6MIpnHoopDesc__pnOHashtableEntry__; +text: .text%__1cOBasicHashtableJnew_entry6MI_pnTBasicHashtableEntry__; +text: .text%__1cOtypeArrayKlassMcreate_klass6FnJBasicType_ipnGThread__pnMklassOopDesc__; +text: .text%__1cOtypeArrayKlassNexternal_name6FnJBasicType__pkc_; +text: .text%__1cKarrayKlassXbase_create_array_klass6FrknKKlass_vtbl_inLKlassHandle_pnGThread__nQarrayKlassHandle__; +text: .text%__1cOtypeArrayKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: typeArrayKlass.o; +text: .text%__1cKarrayKlassOset_alloc_size6MI_v_: typeArrayKlass.o; +text: .text%__1cLAccessFlagsPatomic_set_bits6Mi_v_; +text: .text%__1cLlog2_intptr6Fi_i_: typeArrayKlass.o; +text: .text%__1cKarrayKlassbBcomplete_create_array_klass6FnQarrayKlassHandle_nLKlassHandle_pnGThread__v_; +text: .text%__1cFKlassRinitialize_supers6MpnMklassOopDesc_pnGThread__v_; +text: .text%__1cKarrayKlassYcompute_secondary_supers6MipnGThread__pnPobjArrayOopDesc__; +text: .text%__1cKarrayKlassGvtable6kM_pnLklassVtable__; +text: .text%__1cLklassVtableRinitialize_vtable6MpnGThread__v_; +text: .text%__1cKarrayKlassKjava_super6kM_pnMklassOopDesc__; +text: .text%__1cKarrayKlassWcompute_modifier_flags6kMpnGThread__i_; +text: .text%__1cLmethodKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cLmethodKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: methodKlass.o; +text: .text%__1cLmethodKlassOset_alloc_size6MI_v_: methodKlass.o; +text: .text%__1cQconstMethodKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cQconstMethodKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: constMethodKlass.o; +text: .text%__1cQconstMethodKlassOset_alloc_size6MI_v_: constMethodKlass.o; +text: .text%__1cPmethodDataKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cPmethodDataKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: methodDataKlass.o; +text: .text%__1cPmethodDataKlassOset_alloc_size6MI_v_: methodDataKlass.o; +text: .text%__1cRconstantPoolKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cRconstantPoolKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: constantPoolKlass.o; +text: .text%__1cKarrayKlassOset_alloc_size6MI_v_: constantPoolKlass.o; +text: .text%__1cWconstantPoolCacheKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cWconstantPoolCacheKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: cpCacheKlass.o; +text: .text%__1cKarrayKlassOset_alloc_size6MI_v_: cpCacheKlass.o; +text: .text%__1cVcompiledICHolderKlassMcreate_klass6FpnGThread__pnMklassOopDesc__; +text: .text%__1cVcompiledICHolderKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: compiledICHolderKlass.o; +text: .text%__1cVcompiledICHolderKlassOset_alloc_size6MI_v_: compiledICHolderKlass.o; +text: .text%__1cSobjArrayKlassKlassbEallocate_system_objArray_klass6MpnGThread__pnMklassOopDesc__; +text: .text%__1cSobjArrayKlassKlassXallocate_objArray_klass6MinLKlassHandle_pnGThread__pnMklassOopDesc__; +text: .text%__1cSobjArrayKlassKlassbCallocate_objArray_klass_impl6FnYobjArrayKlassKlassHandle_inLKlassHandle_pnGThread__pnMklassOopDesc__; +text: .text%__1cFKlassNoop_is_symbol6kM_i_: typeArrayKlass.o; +text: .text%__1cNsymbolOopDescLas_C_string6kM_pc_; +text: .text%__1cNsymbolOopDescLas_C_string6kMpci_1_; +text: .text%__1cFKlassPoop_is_instance6kM_i_: typeArrayKlass.o; +text: .text%__1cNobjArrayKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: objArrayKlass.o; +text: .text%__1cKarrayKlassOset_alloc_size6MI_v_: objArrayKlass.o; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: typeArrayKlass.o; +text: .text%__1cLlog2_intptr6Fi_i_: objArrayKlassKlass.o; +text: .text%__1cNobjArrayKlassYcompute_secondary_supers6MipnGThread__pnPobjArrayOopDesc__; +text: .text%__1cNobjArrayKlassWcompute_modifier_flags6kMpnGThread__i_; +text: .text%__1cKoopFactoryXnew_permanent_byteArray6FipnGThread__pnQtypeArrayOopDesc__; +text: .text%__1cOtypeArrayKlassSallocate_permanent6MipnGThread__pnQtypeArrayOopDesc__; +text: .text%__1cNCollectedHeapYpermanent_array_allocate6FnLKlassHandle_iipnGThread__pnHoopDesc__: typeArrayKlass.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: typeArrayKlass.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: typeArrayKlass.o; +text: .text%__1cKoopFactoryYnew_permanent_shortArray6FipnGThread__pnQtypeArrayOopDesc__; +text: .text%__1cKoopFactoryWnew_permanent_intArray6FipnGThread__pnQtypeArrayOopDesc__; +text: .text%__1cKoopFactoryTnew_system_objArray6FipnGThread__pnPobjArrayOopDesc__; +text: .text%__1cNCollectedHeapYpermanent_array_allocate6FnLKlassHandle_iipnGThread__pnHoopDesc__: oopFactory.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: oopFactory.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: oopFactory.o; +text: .text%__1cJvmSymbolsKinitialize6FpnGThread__v_; +text: .text%__1cNsymbolOopDescGequals6kMpkci_i_; +text: .text%__1cQSystemDictionaryKinitialize6FpnGThread__v_; +text: .text%__1cKDictionary2t6Mi_v_; +text: .text%__1cOBasicHashtable2t6Mii_v_: dictionary.o; +text: .text%__1cQPlaceholderTable2t6Mi_v_; +text: .text%__1cOBasicHashtable2t6Mii_v_: placeholders.o; +text: .text%__1cVLoaderConstraintTable2t6Mi_v_; +text: .text%__1cOBasicHashtable2t6Mii_v_: loaderConstraints.o; +text: .text%__1cQSystemDictionarybCinitialize_preloaded_classes6FpnGThread__v_; +text: .text%__1cQSystemDictionaryPresolve_or_fail6FnMsymbolHandle_ipnGThread__pnMklassOopDesc__; +text: .text%__1cQSystemDictionaryPresolve_or_fail6FnMsymbolHandle_nGHandle_2ipnGThread__pnMklassOopDesc__; +text: .text%__1cQSystemDictionaryPresolve_or_null6FnMsymbolHandle_nGHandle_2pnGThread__pnMklassOopDesc__; +text: .text%__1cQSystemDictionarybEresolve_instance_class_or_null6FnMsymbolHandle_nGHandle_2pnGThread__pnMklassOopDesc__; +text: .text%__1cVjava_lang_ClassLoaderbBnon_reflection_class_loader6FpnHoopDesc__2_; +text: .text%__1cPTwoOopHashtableMcompute_hash6MnMsymbolHandle_nGHandle__I_: systemDictionary.o; +text: .text%__1cHoopDescSslow_identity_hash6M_i_; +text: .text%__1cSObjectSynchronizerXidentity_hash_value_for6FnGHandle__i_; +text: .text%__1cNget_next_hash6F_i_: synchronizer.o; +text: .text%__1cCosGrandom6F_l_; +text: .text%__1cKDictionaryEfind6MiInMsymbolHandle_nGHandle_2pnGThread__pnMklassOopDesc__; +text: .text%__1cKDictionaryJget_entry6MiInMsymbolHandle_nGHandle__pnPDictionaryEntry__; +text: .text%__1cQSystemDictionarybAcompute_loader_lock_object6FnGHandle_pnGThread__1_; +text: .text%__1cMObjectLocker2t6MnGHandle_pnGThread__v_; +text: .text%__1cSObjectSynchronizerKfast_enter6FnGHandle_pnJBasicLock_pnGThread__v_; +text: .text%__1cQSystemDictionaryKfind_class6FiInMsymbolHandle_nGHandle__pnMklassOopDesc__; +text: .text%__1cKDictionaryKfind_class6MiInMsymbolHandle_nGHandle__pnMklassOopDesc__; +text: .text%__1cQPlaceholderTableKfind_entry6MiInMsymbolHandle_nGHandle__pnNsymbolOopDesc__; +text: .text%__1cQPlaceholderTableJadd_entry6MiInMsymbolHandle_nGHandle__v_; +text: .text%__1cQPlaceholderTableJnew_entry6MipnNsymbolOopDesc_pnHoopDesc__pnQPlaceholderEntry__; +text: .text%__1cQSystemDictionaryTload_instance_class6FnMsymbolHandle_nGHandle_pnGThread__nTinstanceKlassHandle__; +text: .text%__1cQSystemDictionaryRload_shared_class6FnMsymbolHandle_nGHandle_pnGThread__nTinstanceKlassHandle__; +text: .text%__1cQSystemDictionaryRfind_shared_class6FnMsymbolHandle__pnMklassOopDesc__; +text: .text%__1cQSystemDictionaryRload_shared_class6FnTinstanceKlassHandle_nGHandle_pnGThread__1_; +text: .text%__1cLClassLoaderOload_classfile6FnMsymbolHandle_pnGThread__nTinstanceKlassHandle__; +text: .text%__1cFVTuneQstart_class_load6F_v_; +text: .text%__1cJEventMark2t6MpkcE_v_: classLoader.o; +text: .text%__1cSThreadProfilerMark2t6Mn0AGRegion__v_; +text: .text%__1cMstringStream2t6MI_v_; +text: .text%__1cMstringStreamFwrite6MpkcI_v_; +text: .text%__1cMoutputStreamPupdate_position6MpkcI_v_; +text: .text%__1cMstringStreamJas_string6M_pc_; +text: .text%__1cMelapsedTimerFstart6M_v_; +text: .text%__1cCosPelapsed_counter6F_x_; +text: .text%__1cRClassPathZipEntryLopen_stream6Mpkc_pnPClassFileStream__; +text: .text%__1cPClassFileStream2t6MpCipc_v_; +text: .text%__1cMelapsedTimerEstop6M_v_; +text: .text%__1cPClassFileParserOparseClassFile6MnMsymbolHandle_nGHandle_2r1pnGThread__nTinstanceKlassHandle__; +text: .text%__1cIVerifierRshould_verify_for6FpnHoopDesc__i_; +text: .text%__1cPClassFileStreamGget_u46MpnGThread__I_; +text: .text%__1cPClassFileStreamGget_u26MpnGThread__H_; +text: .text%__1cIVerifierQrelax_verify_for6FpnHoopDesc__i_; +text: .text%__1cVjava_lang_ClassLoaderRis_trusted_loader6FpnHoopDesc__i_; +text: .text%__1cQSystemDictionarySjava_system_loader6F_pnHoopDesc__; +text: .text%__1cPClassFileParserTparse_constant_pool6MpnGThread__nSconstantPoolHandle__; +text: .text%__1cPClassFileParserOcheck_property6MipkcipnGThread__v_; +text: .text%__1cKoopFactoryQnew_constantPool6FipnGThread__pnTconstantPoolOopDesc__; +text: .text%__1cRconstantPoolKlassIallocate6MipnGThread__pnTconstantPoolOopDesc__; +text: .text%__1cNCollectedHeapYpermanent_array_allocate6FnLKlassHandle_iipnGThread__pnHoopDesc__: constantPoolKlass.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: constantPoolKlass.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: constantPoolKlass.o; +text: .text%__1cPClassFileParserbBparse_constant_pool_entries6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cPClassFileStreamGget_u16MpnGThread__C_; +text: .text%__1cPClassFileParserbFparse_constant_pool_class_entry6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cPClassFileParserbJparse_constant_pool_methodref_entry6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cPClassFileParserbGparse_constant_pool_string_entry6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cPClassFileParserbHparse_constant_pool_integer_entry6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cPClassFileParserbEparse_constant_pool_utf8_entry6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cPClassFileParserRverify_legal_utf86MpkCipnGThread__v_; +text: .text%__1cPClassFileStreamHskip_u16MipnGThread__v_; +text: .text%__1cPClassFileParserbLparse_constant_pool_nameandtype_entry6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cTconstantPoolOopDescSklass_ref_index_at6Mi_i_; +text: .text%__1cTconstantPoolOopDescbAname_and_type_ref_index_at6Mi_i_; +text: .text%__1cTconstantPoolOopDescRname_ref_index_at6Mi_i_; +text: .text%__1cTconstantPoolOopDescWsignature_ref_index_at6Mi_i_; +text: .text%__1cPClassFileParserbCverify_legal_class_modifiers6MipnGThread__v_; +text: .text%__1cPClassFileParserQparse_interfaces6MnSconstantPoolHandle_nGHandle_2pnGThread__nOobjArrayHandle__; +text: .text%__1cPClassFileParserMparse_fields6MnSconstantPoolHandle_ipnUFieldAllocationCount_pnOobjArrayHandle_pnGThread__nPtypeArrayHandle__; +text: .text%__1cUinitialize_hashtable6FppnLNameSigHash__v_; +text: .text%__1cPclear_hashtable6FppnLNameSigHash__v_; +text: .text%__1cPClassFileParserNparse_methods6MnSconstantPoolHandle_ipnLAccessFlags_ppnPobjArrayOopDesc_66pnGThread__nOobjArrayHandle__; +text: .text%__1cPClassFileParserMparse_method6MnSconstantPoolHandle_ipnLAccessFlags_pnPtypeArrayHandle_55pnGThread__nMmethodHandle__; +text: .text%__1cPClassFileParserYverify_legal_method_name6MnMsymbolHandle_pnGThread__v_; +text: .text%__1cPClassFileParserbDverify_legal_method_modifiers6MiinMsymbolHandle_pnGThread__v_; +text: .text%__1cPClassFileParserWparse_linenumber_table6MIIpipnGThread__pC_; +text: .text%__1cbFCompressedLineNumberWriteStream2t6Mi_v_; +text: .text%__1cVCompressedWriteStream2t6Mi_v_; +text: .text%__1cQCompressedStream2t6MpCi_v_; +text: .text%__1cbFCompressedLineNumberWriteStreamKwrite_pair6Mii_v_; +text: .text%__1cVCompressedWriteStreamJwrite_int6Mi_v_: methodOop.o; +text: .text%__1cKoopFactoryKnew_method6FinLAccessFlags_iiipnGThread__pnNmethodOopDesc__; +text: .text%__1cKoopFactoryPnew_constMethod6FiiiipnGThread__pnSconstMethodOopDesc__; +text: .text%__1cQconstMethodKlassIallocate6MiiiipnGThread__pnSconstMethodOopDesc__; +text: .text%__1cSconstMethodOopDescLobject_size6Fiiii_i_; +text: .text%__1cNCollectedHeapWpermanent_obj_allocate6FnLKlassHandle_ipnGThread__pnHoopDesc__: constMethodKlass.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: constMethodKlass.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: constMethodKlass.o; +text: .text%__1cSconstMethodOopDescZset_inlined_tables_length6Miii_v_; +text: .text%__1cLmethodKlassIallocate6MnRconstMethodHandle_nLAccessFlags_pnGThread__pnNmethodOopDesc__; +text: .text%__1cNmethodOopDescLobject_size6Fi_i_; +text: .text%__1cNCollectedHeapWpermanent_obj_allocate6FnLKlassHandle_ipnGThread__pnHoopDesc__: methodKlass.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: methodKlass.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: methodKlass.o; +text: .text%__1cNmethodOopDescJinit_code6M_v_; +text: .text%__1cRInvocationCounterEinit6M_v_; +text: .text%__1cRInvocationCounterFreset6M_v_; +text: .text%__1cRInvocationCounterJset_state6Mn0AFState__v_; +text: .text%__1cLmethodKlassIoop_size6kMpnHoopDesc__i_; +text: .text%__1cNmethodOopDescbAcompute_size_of_parameters6MpnGThread__v_; +text: .text%__1cRSignatureIterator2t6MnMsymbolHandle__v_; +text: .text%__1cRSignatureIteratorSiterate_parameters6M_v_; +text: .text%__1cRSignatureIteratorGexpect6Mc_v_; +text: .text%__1cSconstMethodOopDescbBcompressed_linenumber_table6kM_pC_; +text: .text%__1cPClassFileParserUassemble_annotations6MpCi1ipnGThread__nPtypeArrayHandle__; +text: .text%__1cNmethodOopDescVclear_native_function6M_v_; +text: .text%__1cNmethodOopDescTset_native_function6MpC_v_; +text: .text%__1cNmethodOopDescVset_signature_handler6MpC_v_; +text: .text%__1cVCompressedWriteStreamEgrow6M_v_; +text: .text%__1cRSignatureIteratorKparse_type6M_i_; +text: .text%__1cNSignatureInfoJdo_object6Mii_v_: frame.o; +text: .text%__1cUArgumentSizeComputerDset6MinJBasicType__v_: frame.o; +text: .text%__1cPClassFileParserYparse_checked_exceptions6MpHInSconstantPoolHandle_pnGThread__1_; +text: .text%__1cPClassFileStreamHskip_u26MipnGThread__v_; +text: .text%__1cSconstMethodOopDescbEchecked_exceptions_length_addr6kM_pH_; +text: .text%__1cSconstMethodOopDescYchecked_exceptions_start6kM_pnXCheckedExceptionElement__; +text: .text%__1cXcopy_u2_with_conversion6FpH0i_v_: classFileParser.o; +text: .text%__1cNSignatureInfoHdo_long6M_v_: frame.o; +text: .text%__1cNSignatureInfoGdo_int6M_v_: frame.o; +text: .text%__1cPClassFileParserbDcompute_transitive_interfaces6MnTinstanceKlassHandle_nOobjArrayHandle_pnGThread__2_; +text: .text%__1cPClassFileParserMsort_methods6MnOobjArrayHandle_111pnGThread__nPtypeArrayHandle__; +text: .text%__1cNmethodOopDescMsort_methods6FpnPobjArrayOopDesc_222_v_; +text: .text%method_compare: methodOop.o; +text: .text%__1cLklassVtablebKcompute_vtable_size_and_num_mirandas6Fri1pnMklassOopDesc_pnPobjArrayOopDesc_nLAccessFlags_pnHoopDesc_pnNsymbolOopDesc_5_v_; +text: .text%__1cLklassVtableWneeds_new_vtable_entry6FpnNmethodOopDesc_pnMklassOopDesc_pnHoopDesc_pnNsymbolOopDesc_nLAccessFlags__i_; +text: .text%__1cLklassVtableQget_num_mirandas6FpnMklassOopDesc_pnPobjArrayOopDesc_4_i_; +text: .text%__1cLklassVtableMget_mirandas6FpnNGrowableArray4CpnNmethodOopDesc___pnMklassOopDesc_pnPobjArrayOopDesc_8_v_; +text: .text%__1cLklassItableTcompute_itable_size6FnOobjArrayHandle__i_; +text: .text%__1cUvisit_all_interfaces6FpnPobjArrayOopDesc_pnXInterfaceVisiterClosure__v_; +text: .text%__1cPClassFileParserUcompute_oop_map_size6MnTinstanceKlassHandle_ii_i_; +text: .text%__1cKoopFactoryRnew_instanceKlass6FiiiinNReferenceType_pnGThread__pnMklassOopDesc__; +text: .text%__1cSinstanceKlassKlassXallocate_instance_klass6MiiiinNReferenceType_pnGThread__pnMklassOopDesc__; +text: .text%__1cNinstanceKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: instanceKlass.o; +text: .text%__1cNinstanceKlassOset_alloc_size6MI_v_: instanceKlass.o; +text: .text%__1cNinstanceKlassQinit_implementor6M_v_; +text: .text%__1cNinstanceKlassWcompute_modifier_flags6kMpnGThread__i_; +text: .text%__1cTconstantPoolOopDescNklass_name_at6Mi_pnNsymbolOopDesc__; +text: .text%__1cFKlassMoop_is_klass6kM_i_: symbolKlass.o; +text: .text%__1cPClassFileParserbAparse_classfile_attributes6MnSconstantPoolHandle_nTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cPClassFileParserbKparse_classfile_sourcefile_attribute6MnSconstantPoolHandle_nTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cNinstanceKlassWdo_local_static_fields6MpFpnPfieldDescriptor_pnGThread__v4_v_; +text: .text%__1cNinstanceKlassbBdo_local_static_fields_impl6FnTinstanceKlassHandle_pFpnPfieldDescriptor_pnGThread__v5_v_; +text: .text%__1cNinstanceKlassYcompute_secondary_supers6MipnGThread__pnPobjArrayOopDesc__; +text: .text%__1cLklassItableZsetup_itable_offset_table6FnTinstanceKlassHandle__v_; +text: .text%__1cPClassFileParserNfill_oop_maps6MnTinstanceKlassHandle_ii_v_; +text: .text%__1cFKlassKsuperklass6kM_pnNinstanceKlass__; +text: .text%__1cPClassFileParserVset_precomputed_flags6MnTinstanceKlassHandle__v_; +text: .text%__1cFKlassNlookup_method6kMpnNsymbolOopDesc_2_pnNmethodOopDesc__; +text: .text%__1cNinstanceKlassWuncached_lookup_method6kMpnNsymbolOopDesc_2_pnNmethodOopDesc__; +text: .text%__1cNinstanceKlassLfind_method6kMpnNsymbolOopDesc_2_pnNmethodOopDesc__; +text: .text%__1cNinstanceKlassLfind_method6FpnPobjArrayOopDesc_pnNsymbolOopDesc_4_pnNmethodOopDesc__; +text: .text%__1cNmethodOopDescPis_empty_method6kM_i_; +text: .text%__1cPClassFileParserYcheck_super_class_access6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cPClassFileParserbCcheck_super_interface_access6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cPClassFileParserbBcheck_final_method_override6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cTClassLoadingServiceTnotify_class_loaded6FpnNinstanceKlass_i_v_; +text: .text%__1cTClassLoadingServiceScompute_class_size6FpnNinstanceKlass__I_; +text: .text%__1cSinstanceKlassKlassIoop_size6kMpnHoopDesc__i_; +text: .text%__1cNinstanceKlassPoop_is_instance6kM_i_: instanceKlass.o; +text: .text%__1cRconstantPoolKlassIoop_size6kMpnHoopDesc__i_; +text: .text%__1cLClassLoaderLadd_package6Fpkci_i_; +text: .text%__1cLClassLoaderOlookup_package6Fpkc_pnLPackageInfo__; +text: .text%__1cQPackageHashtableMcompute_hash6Mpkci_I_: classLoader.o; +text: .text%__1cQPackageHashtableJget_entry6MiIpkcI_pnLPackageInfo__: classLoader.o; +text: .text%__1cMstringStream2T6M_v_; +text: .text%__1cSThreadProfilerMark2T6M_v_; +text: .text%__1cFVTuneOend_class_load6F_v_; +text: .text%__1cQSystemDictionaryVdefine_instance_class6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cQSystemDictionaryRcheck_constraints6FiInTinstanceKlassHandle_nGHandle_pnGThread__v_; +text: .text%__1cVLoaderConstraintTablePcheck_or_update6MnTinstanceKlassHandle_nGHandle_nMsymbolHandle__pkc_; +text: .text%__1cVLoaderConstraintTableWfind_loader_constraint6MnMsymbolHandle_nGHandle__ppnVLoaderConstraintEntry__; +text: .text%__1cQSystemDictionaryQadd_to_hierarchy6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cFKlassWappend_to_sibling_list6M_v_; +text: .text%__1cNinstanceKlassSprocess_interfaces6MpnGThread__v_; +text: .text%__1cIUniverseTflush_dependents_on6FnTinstanceKlassHandle__v_; +text: .text%__1cJCodeCachebKnumber_of_nmethods_with_dependencies6F_i_; +text: .text%__1cQSystemDictionaryRupdate_dictionary6FiIiInTinstanceKlassHandle_nGHandle_pnGThread__v_; +text: .text%__1cQSystemDictionaryQfind_placeholder6FiInMsymbolHandle_nGHandle__pnNsymbolOopDesc__; +text: .text%__1cQPlaceholderTableMremove_entry6MiInMsymbolHandle_nGHandle__v_; +text: .text%__1cKDictionaryJadd_klass6MnMsymbolHandle_nGHandle_nLKlassHandle__v_; +text: .text%__1cPTwoOopHashtableMcompute_hash6MnMsymbolHandle_nGHandle__I_: dictionary.o; +text: .text%__1cKDictionaryJnew_entry6MIpnMklassOopDesc_pnHoopDesc__pnPDictionaryEntry__; +text: .text%__1cNinstanceKlassQeager_initialize6MpnGThread__v_; +text: .text%__1cMObjectLocker2T6M_v_; +text: .text%__1cSObjectSynchronizerJfast_exit6FpnHoopDesc_pnJBasicLock_pnGThread__v_; +text: .text%__1cPClassFileParserbIparse_constant_pool_fieldref_entry6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cPClassFileParserbSparse_constant_pool_interfacemethodref_entry6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cPClassFileParserbEparse_constant_pool_long_entry6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cPClassFileStreamGget_u86MpnGThread__X_; +text: .text%__1cSObjectSynchronizerKslow_enter6FnGHandle_pnJBasicLock_pnGThread__v_; +text: .text%__1cKJavaThreadNis_lock_owned6kMpC_i_; +text: .text%__1cGThreadLis_in_stack6kMpC_i_; +text: .text%__1cQSystemDictionaryVresolve_super_or_fail6FnMsymbolHandle_1nGHandle_2pnGThread__pnMklassOopDesc__; +text: .text%__1cNinstanceKlassZcan_be_primary_super_slow6kM_i_; +text: .text%__1cKReflectionTverify_class_access6FpnMklassOopDesc_2i_i_; +text: .text%__1cPClassFileParserbBcheck_illegal_static_method6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cPClassFileParserbJparse_classfile_signature_attribute6MnSconstantPoolHandle_nTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cPClassFileParserbCverify_legal_field_modifiers6MiipnGThread__v_; +text: .text%__1cPClassFileParserXverify_legal_field_name6MnMsymbolHandle_pnGThread__v_; +text: .text%__1cPClassFileParserbCverify_legal_field_signature6MnMsymbolHandle_1pnGThread__v_; +text: .text%__1cPClassFileParserWparse_field_attributes6MnSconstantPoolHandle_iHpHpi2pnPtypeArrayHandle_pnGThread__v_; +text: .text%__1cTconstantPoolOopDescbBbasic_type_for_signature_at6Mi_nJBasicType__; +text: .text%__1cJFieldTypeKbasic_type6FpnNsymbolOopDesc__nJBasicType__; +text: .text%__1cJchar2type6Fc_nJBasicType__: fieldType.o; +text: .text%__1cRSignatureIteratorSskip_optional_size6M_v_; +text: .text%__1cNSignatureInfoIdo_array6Mii_v_: frame.o; +text: .text%__1cPClassFileParserVparse_exception_table6MIInSconstantPoolHandle_pnGThread__nPtypeArrayHandle__; +text: .text%__1cNSignatureInfoHdo_bool6M_v_: frame.o; +text: .text%__1cNSignatureInfoHdo_char6M_v_: frame.o; +text: .text%__1cNSignatureInfoIdo_float6M_v_: frame.o; +text: .text%__1cNSignatureInfoJdo_double6M_v_: frame.o; +text: .text%__1cbDreorder_based_on_method_index6FpnPobjArrayOopDesc_1ppnHoopDesc__v_: methodOop.o; +text: .text%__1cLklassVtableYadd_new_mirandas_to_list6FpnNGrowableArray4CpnNmethodOopDesc___pnPobjArrayOopDesc_6pnMklassOopDesc__v_; +text: .text%__1cLklassVtableKis_miranda6FpnNmethodOopDesc_pnPobjArrayOopDesc_pnMklassOopDesc__i_; +text: .text%__1cWCountInterfacesClosureEdoit6MpnMklassOopDesc_i_v_: klassVtable.o; +text: .text%__1cPClassFileParserbNparse_classfile_inner_classes_attribute6MnSconstantPoolHandle_nTinstanceKlassHandle_pnGThread__H_; +text: .text%__1cPfieldDescriptorKinitialize6MpnMklassOopDesc_i_v_; +text: .text%__1cXinitialize_static_field6FpnPfieldDescriptor_pnGThread__v_: classFileParser.o; +text: .text%__1cPfieldDescriptorSlong_initial_value6kM_x_; +text: .text%__1cFKlassZcan_be_primary_super_slow6kM_i_; +text: .text%__1cSSetupItableClosureEdoit6MpnMklassOopDesc_i_v_: klassVtable.o; +text: .text%__1cNmethodOopDescWis_vanilla_constructor6kM_i_; +text: .text%__1cNinstanceKlassPadd_implementor6MpnMklassOopDesc__v_; +text: .text%__1cPClassFileParserXjava_lang_Class_fix_pre6MpnOobjArrayHandle_pnUFieldAllocationCount_pnGThread__v_; +text: .text%__1cPClassFileParserYjava_lang_Class_fix_post6Mpi_v_; +text: .text%__1cPfieldDescriptorRint_initial_value6kM_i_; +text: .text%__1cIUniverseNfixup_mirrors6FpnGThread__v_; +text: .text%__1cKSharedHeapYpermanent_object_iterate6MpnNObjectClosure__v_: genCollectedHeap.o; +text: .text%__1cHPermGenOobject_iterate6MpnNObjectClosure__v_: permGen.o; +text: .text%__1cRCompactingPermGenGas_gen6kM_pnKGeneration__: permGen.o; +text: .text%__1cbCOneContigSpaceCardGenerationOobject_iterate6MpnNObjectClosure__v_; +text: .text%__1cPContiguousSpaceOobject_iterate6MpnNObjectClosure__v_; +text: .text%__1cPContiguousSpaceTobject_iterate_from6MnJWaterMark_pnNObjectClosure__v_; +text: .text%__1cSFixupMirrorClosureJdo_object6MpnHoopDesc__v_: universe.o; +text: .text%__1cKklassKlassMoop_is_klass6kM_i_: klassKlass.o; +text: .text%__1cNinstanceKlassbBallocate_permanent_instance6MpnGThread__pnPinstanceOopDesc__; +text: .text%__1cNCollectedHeapWpermanent_obj_allocate6FnLKlassHandle_ipnGThread__pnHoopDesc__: instanceKlass.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: instanceKlass.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: instanceKlass.o; +text: .text%__1cKklassKlassIoop_size6kMpnHoopDesc__i_; +text: .text%__1cKklassKlassOklass_oop_size6kM_i_: klassKlass.o; +text: .text%__1cKklassKlassOklass_oop_size6kM_i_: arrayKlassKlass.o; +text: .text%__1cSobjArrayKlassKlassOklass_oop_size6kM_i_: objArrayKlassKlass.o; +text: .text%__1cSinstanceKlassKlassOklass_oop_size6kM_i_: instanceKlassKlass.o; +text: .text%__1cTtypeArrayKlassKlassOklass_oop_size6kM_i_: typeArrayKlassKlass.o; +text: .text%__1cLsymbolKlassOklass_oop_size6kM_i_: symbolKlass.o; +text: .text%__1cLsymbolKlassIoop_size6kMpnHoopDesc__i_; +text: .text%__1cKklassKlassMoop_is_klass6kM_i_: typeArrayKlassKlass.o; +text: .text%__1cTtypeArrayKlassKlassIoop_size6kMpnHoopDesc__i_: typeArrayKlassKlass.o; +text: .text%__1cKarrayKlassLobject_size6kMi_i_; +text: .text%__1cLmethodKlassOklass_oop_size6kM_i_: methodKlass.o; +text: .text%__1cQconstMethodKlassOklass_oop_size6kM_i_: constMethodKlass.o; +text: .text%__1cPmethodDataKlassOklass_oop_size6kM_i_: methodDataKlass.o; +text: .text%__1cKklassKlassMoop_is_klass6kM_i_: arrayKlassKlass.o; +text: .text%__1cRconstantPoolKlassOklass_oop_size6kM_i_: constantPoolKlass.o; +text: .text%__1cWconstantPoolCacheKlassOklass_oop_size6kM_i_: cpCacheKlass.o; +text: .text%__1cVcompiledICHolderKlassOklass_oop_size6kM_i_: compiledICHolderKlass.o; +text: .text%__1cKklassKlassMoop_is_klass6kM_i_: objArrayKlassKlass.o; +text: .text%__1cSobjArrayKlassKlassIoop_size6kMpnHoopDesc__i_: objArrayKlassKlass.o; +text: .text%__1cFKlassMoop_is_klass6kM_i_: typeArrayKlass.o; +text: .text%__1cFKlassMoop_is_klass6kM_i_: objArrayKlass.o; +text: .text%__1cFKlassMoop_is_klass6kM_i_: constantPoolKlass.o; +text: .text%__1cFKlassMoop_is_klass6kM_i_: constMethodKlass.o; +text: .text%__1cQconstMethodKlassIoop_size6kMpnHoopDesc__i_; +text: .text%__1cFKlassMoop_is_klass6kM_i_: methodKlass.o; +text: .text%__1cSinstanceKlassKlassMoop_is_klass6kM_i_: instanceKlassKlass.o; +text: .text%__1cFKlassMoop_is_klass6kM_i_: instanceKlass.o; +text: .text%__1cFKlassXsearch_secondary_supers6kMpnMklassOopDesc__i_; +text: .text%__1cPClassFileParserbFjava_lang_ref_Reference_fix_pre6MpnPtypeArrayHandle_nSconstantPoolHandle_pnUFieldAllocationCount_pnGThread__v_; +text: .text%__1cQinstanceRefKlassZupdate_nonstatic_oop_maps6FpnMklassOopDesc__v_; +text: .text%__1cQinstanceRefKlassSallocate_permanent6kMrnLKlassHandle_ipnGThread__pv_: instanceRefKlass.o; +text: .text%__1cNinstanceKlassOset_alloc_size6MI_v_: instanceRefKlass.o; +text: .text%__1cNinstanceKlassPoop_is_instance6kM_i_: instanceRefKlass.o; +text: .text%__1cKReflectionVis_same_class_package6FpnMklassOopDesc_2_i_; +text: .text%__1cNinstanceKlassVis_same_class_package6MpnMklassOopDesc__i_; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: instanceRefKlass.o; +text: .text%__1cNinstanceKlassVis_same_class_package6FpnHoopDesc_pnNsymbolOopDesc_24_i_; +text: .text%__1cEUTF8Hstrrchr6FpWiW_1_; +text: .text%__1cEUTF8Fequal6FpWi1i_i_; +text: .text%__1cPClassFileParserbFparse_constant_pool_float_entry6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cNSignatureInfoHdo_byte6M_v_: frame.o; +text: .text%__1cNSignatureInfoIdo_short6M_v_: frame.o; +text: .text%__1cRappend_interfaces6FnOobjArrayHandle_ripnPobjArrayOopDesc__v_; +text: .text%__1cQSystemDictionaryPresolve_or_null6FnMsymbolHandle_pnGThread__pnMklassOopDesc__; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: instanceKlass.o; +text: .text%__1cPfieldDescriptorTfloat_initial_value6kM_f_; +text: .text%__1cPClassFileParserbGparse_constant_pool_double_entry6MnSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cPfieldDescriptorUdouble_initial_value6kM_d_; +text: .text%__1cQSystemDictionarybDinitialize_basic_type_mirrors6FpnGThread__v_; +text: .text%__1cPjava_lang_ClassYcreate_basic_type_mirror6FpkcpnGThread__pnHoopDesc__; +text: .text%__1cNobjArrayKlassZcan_be_primary_super_slow6kM_i_; +text: .text%__1cXreferenceProcessor_init6F_v_; +text: .text%__1cSReferenceProcessorMinit_statics6F_v_; +text: .text%__1cbBjava_lang_ref_SoftReferenceJset_clock6Fx_v_; +text: .text%__1cQjni_handles_init6F_v_; +text: .text%__1cKJNIHandlesKinitialize6F_v_; +text: .text%__1cOvmStructs_init6F_v_; +text: .text%__1cVverificationType_init6F_v_; +text: .text%__1cQVerificationTypeKinitialize6F_v_; +text: .text%__1cOcompiler1_init6F_v_; +text: .text%__1cKSharedInfoKset_stack06Fi_v_; +text: .text%__1cKSharedInfoLset_regName6F_v_; +text: .text%__1cIRegAllocYinit_register_allocation6F_v_; +text: .text%__1cIFrameMapEinit6F_v_; +text: .text%__1cKc1_RegMaskKinit_masks6Fi_v_; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_FrameMap_x86.o; +text: .text%__1cNc1_AllocTableLinit_tables6F_v_; +text: .text%__1cIFrameMapOfirst_register6F_pnMRegisterImpl__; +text: .text%__1cIFrameMapLcpu_reg2rnr6FpnMRegisterImpl__i_; +text: .text%__1cIFrameMapLcpu_rnr2reg6Fi_pnMRegisterImpl__; +text: .text%__1cIRuntime1Kinitialize6F_v_; +text: .text%__1cKCodeBufferRinsts_memory_size6Fi_i_; +text: .text%__1cKCodeBufferQlocs_memory_size6Fi_i_; +text: .text%__1cIRuntime1Ninitialize_pd6F_v_; +text: .text%__1cNSharedRuntimeTgenerate_deopt_blob6F_v_; +text: .text%__1cKCodeBuffer2t6MiiiiiipnKBufferBlob_pnJrelocInfo_pnORelocateBuffer_ipnLOopRecorder_pkcii_v_; +text: .text%__1cKCodeBufferQalloc_relocation6MI_v_; +text: .text%__1cJOopMapSet2t6M_v_; +text: .text%__1cJAssemblerEsubl6MnHAddress_i_v_; +text: .text%__1cTsave_live_registers6FpnOMacroAssembler_i_pnGOopMap__: c1_Runtime1_x86.o; +text: .text%__1cJAssemblerGfldenv6MnHAddress__v_; +text: .text%__1cGOopMap2t6Mii_v_; +text: .text%__1cGOopMapQset_callee_saved6MnHOptoRegEName_ii2_v_; +text: .text%__1cGOopMapHset_xxx6MnHOptoRegEName_nLOopMapValueJoop_types_ii2_v_; +text: .text%__1cGOopMapbEmap_compiler_reg_to_oopmap_reg6MnHOptoRegEName_ii_nFVMRegEName__; +text: .text%__1cVCompressedWriteStreamJwrite_int6Mi_v_: oopMap.o; +text: .text%__1cIFrameMapRfpu_stack_regname6Fi_nHOptoRegEName__; +text: .text%__1cKRelocationJpack_data6M_i_: codeBlob.o; +text: .text%__1cJrelocInfoNfinish_prefix6Mph_p0_; +text: .text%__1cJrelocInfo2t6Mn0AJrelocType_ii_v_; +text: .text%__1cOMacroAssemblerTset_last_Java_frame6MpnMRegisterImpl_22pC_v_; +text: .text%__1cJOopMapSetKadd_gc_map6MiipnGOopMap__v_; +text: .text%__1cOMacroAssemblerVreset_last_Java_frame6MpnMRegisterImpl_i_v_; +text: .text%__1cJAssemblerEdecl6MnHAddress__v_; +text: .text%__1cSDeoptimizationBlobGcreate6FpnKCodeBuffer_pnJOopMapSet_iiii_p0_; +text: .text%__1cICodeBlobPallocation_size6FpnKCodeBuffer_ii_I_; +text: .text%__1cNRelocIteratorTlocs_and_index_size6Fii_i_; +text: .text%__1cSDeoptimizationBlob2n6FII_pv_; +text: .text%__1cSDeoptimizationBlob2t6MpnKCodeBuffer_ipnJOopMapSet_iiii_v_; +text: .text%__1cICodeBlob2t6MpkcpnKCodeBuffer_iiipnJOopMapSet_i_v_; +text: .text%__1cKCodeBufferPcopy_relocation6MpnICodeBlob__v_; +text: .text%__1cNRelocIteratorMcreate_index6FpnKCodeBuffer_pnJrelocInfo_4_4_; +text: .text%__1cKCodeBufferJcopy_code6MpnICodeBlob__v_; +text: .text%__1cRAbstractAssemblerOcode_fill_byte6F_i_; +text: .text%__1cICodeBlobWfix_relocation_at_move6Mi_v_; +text: .text%__1cNRelocIteratorKinitialize6MipnICodeBlob_pC3_v_; +text: .text%__1cNRelocIteratorKset_limits6MpC1_v_; +text: .text%__1cVPatchingRelocIteratorHprepass6M_v_; +text: .text%__1cNRelocIteratorEnext6M_i_: relocInfo.o; +text: .text%__1cNRelocIteratorEnext6M_i_: codeBlob.o; +text: .text%__1cNRelocIteratorFreloc6M_pnKRelocation__; +text: .text%__1cOCallRelocationWfix_relocation_at_move6Mi_v_; +text: .text%__1cOCallRelocationFvalue6M_pC_: codeBlob.o; +text: .text%__1cKRelocationTpd_call_destination6M_pC_; +text: .text%__1cKNativeCallLdestination6kM_pC_; +text: .text%__1cOCallRelocationPset_destination6MpCi_v_; +text: .text%__1cKRelocationXpd_set_call_destination6MpCi_v_; +text: .text%__1cRNativeInstructionFwrote6Mi_v_; +text: .text%__1cKRelocationLunpack_data6M_v_: relocInfo.o; +text: .text%__1cKRelocationWfix_relocation_at_move6Mi_v_: relocInfo.o; +text: .text%__1cVPatchingRelocIteratorIpostpass6M_v_; +text: .text%__1cJOopMapSetJheap_size6kM_i_; +text: .text%__1cGOopMapJheap_size6kM_i_; +text: .text%__1cJOopMapSetHcopy_to6MpC_v_; +text: .text%__1cGOopMapHcopy_to6MpC_v_; +text: .text%__1cIRuntime1Rgenerate_blob_for6Fn0AGStubID__v_; +text: .text%__1cIRuntime1Pnew_code_buffer6F_pnKCodeBuffer__; +text: .text%__1cLOopRecorder2t6MpnFArena__v_; +text: .text%__1cNStubAssembler2t6MpnKCodeBuffer__v_; +text: .text%__1cIRuntime1Rgenerate_code_for6Fn0AGStubID_pnNStubAssembler_pi_pnJOopMapSet__; +text: .text%__1cIRuntime1Iname_for6Fn0AGStubID__pkc_; +text: .text%__1cLRuntimeStubQnew_runtime_stub6FpkcpnKCodeBuffer_ipnJOopMapSet_i_p0_; +text: .text%__1cLRuntimeStub2n6FII_pv_; +text: .text%__1cLRuntimeStub2t6MpkcpnKCodeBuffer_iipnJOopMapSet_i_v_; +text: .text%__1cJStubFrame2t6MpnNStubAssembler_pkci_v_; +text: .text%__1cNStubAssemblerIset_info6Mpkci_v_; +text: .text%__1cNStubAssemblerHcall_RT6MpnMRegisterImpl_2pC2_i_; +text: .text%__1cNStubAssemblerHcall_RT6MpnMRegisterImpl_2pCi_i_; +text: .text%__1cJStubFrame2T6M_v_; +text: .text%__1cIRuntime1Ygenerate_exception_throw6FpnNStubAssembler_pCpnMRegisterImpl__pnJOopMapSet__; +text: .text%__1cOMacroAssemblerLtlab_refill6MrnFLabel_22_v_; +text: .text%__1cLlog2_intptr6Fi_i_: assembler_x86.o; +text: .text%__1cOMacroAssemblerNeden_allocate6MpnMRegisterImpl_2i2rnFLabel__v_; +text: .text%__1cOMacroAssemblerLverify_tlab6M_v_; +text: .text%__1cLlog2_intptr6Fi_i_: c1_Runtime1_x86.o; +text: .text%__1cOMacroAssemblerNtlab_allocate6MpnMRegisterImpl_2i22rnFLabel__v_; +text: .text%__1cRC1_MacroAssemblerRinitialize_object6MpnMRegisterImpl_22i22_v_; +text: .text%__1cRC1_MacroAssemblerRinitialize_header6MpnMRegisterImpl_22_v_; +text: .text%__1cRC1_MacroAssemblerPinitialize_body6MpnMRegisterImpl_2i2_v_; +text: .text%__1cNStubAssemblerHcall_RT6MpnMRegisterImpl_2pC22_i_; +text: .text%__1cNStubAssemblerHcall_RT6MpnMRegisterImpl_2pC222_i_; +text: .text%__1cIRuntime1Iblob_for6Fn0AGStubID__pnICodeBlob__; +text: .text%__1cJStubFrame2t6MpnNStubAssembler_pkcipnMRegisterImpl_6_v_; +text: .text%__1cJStubFrame2t6MpnNStubAssembler_pkcipnMRegisterImpl__v_; +text: .text%__1cIiEntries2t6Miiii_v_; +text: .text%__1cRNativeGeneralJumpQjump_destination6kM_pC_; +text: .text%__1cJAssemblerOlocate_operand6FpCn0AMWhichOperand__1_; +text: .text%__1cIRuntime1Rgenerate_patching6FpnNStubAssembler_pC_pnJOopMapSet__; +text: .text%__1cWrestore_live_registers6FpnOMacroAssembler__v_: c1_Runtime1_x86.o; +text: .text%__1cNSafepointBlobGcreate6FpnKCodeBuffer_pnJOopMapSet_i_p0_; +text: .text%__1cNSafepointBlob2n6FII_pv_; +text: .text%__1cNSafepointBlob2t6MpnKCodeBuffer_ipnJOopMapSet_i_v_; +text: .text%__1cJAssemblerFfldcw6MnHAddress__v_; +text: .text%__1cJAssemblerGfnstcw6MnHAddress__v_; +text: .text%__1cJAssemblerHfcomp_d6MnHAddress__v_; +text: .text%__1cIiEntriesIset_base6MpC_v_; +text: .text%__1cQvtableStubs_init6F_v_; +text: .text%__1cLVtableStubsKinitialize6F_v_; +text: .text%__1cWInlineCacheBuffer_init6F_v_; +text: .text%__1cRInlineCacheBufferKinitialize6F_v_; +text: .text%__1cRInlineCacheBufferOinit_next_stub6F_v_; +text: .text%__1cRInlineCacheBufferRic_stub_code_size6F_i_; +text: .text%__1cJStubQdDueueRrequest_committed6Mi_pnEStub__; +text: .text%__1cPICStubInterfaceRcode_size_to_size6kMi_i_: icBuffer.o; +text: .text%__1cPICStubInterfaceKinitialize6MpnEStub_i_v_: icBuffer.o; +text: .text%__1cTcompilerOracle_init6F_v_; +text: .text%__1cOCompilerOracleRparse_from_string6Fpkc_v_; +text: .text%__1cOCompilerOracleOread_from_line6Fpc_v_; +text: .text%__1cOCompilerOraclePparse_from_file6F_v_; +text: .text%__1cHcc_file6F_pkc_: compilerOracle.o; +text: .text%__1cXonStackReplacement_init6F_v_; +text: .text%__1cSOnStackReplacementKinitialize6F_v_; +text: .text%__1cUGenericGrowableArrayPraw_at_put_grow6MipknEGrET_3_v_; +text: .text%__1cWcompilationPolicy_init6F_v_; +text: .text%__1cSuniverse_post_init6F_v_; +text: .text%__1cIUniverseWreinitialize_vtable_of6FpnFKlass_pnGThread__v_; +text: .text%__1cNinstanceKlassGvtable6kM_pnLklassVtable__; +text: .text%__1cNinstanceKlassKjava_super6kM_pnMklassOopDesc__: instanceKlass.o; +text: .text%__1cLklassVtableVinitialize_from_super6MnLKlassHandle__i_; +text: .text%__1cFKlassMoop_is_array6kM_i_: instanceKlass.o; +text: .text%__1cLklassVtableTupdate_super_vtable6MpnNinstanceKlass_pnNmethodOopDesc_i_i_; +text: .text%__1cLklassVtableNput_method_at6MpnNmethodOopDesc_i_v_; +text: .text%__1cLklassVtableQfill_in_mirandas6Mri_v_; +text: .text%__1cFKlassIsubklass6kM_p0_; +text: .text%__1cLklassVtableOcopy_vtable_to6MpnLvtableEntry__v_; +text: .text%__1cLklassVtableXvtable_accessibility_at6Mi_n0AKAccessType__; +text: .text%__1cFKlassMnext_sibling6kM_p0_; +text: .text%__1cKarrayKlassMoop_is_array6kM_i_: objArrayKlass.o; +text: .text%__1cFKlassPoop_is_instance6kM_i_: objArrayKlass.o; +text: .text%__1cKarrayKlassMoop_is_array6kM_i_: constantPoolKlass.o; +text: .text%__1cFKlassPoop_is_instance6kM_i_: constantPoolKlass.o; +text: .text%__1cKarrayKlassMoop_is_array6kM_i_: typeArrayKlass.o; +text: .text%__1cNinstanceKlassKjava_super6kM_pnMklassOopDesc__: instanceRefKlass.o; +text: .text%__1cFKlassMoop_is_array6kM_i_: instanceRefKlass.o; +text: .text%__1cIUniverseUreinitialize_itables6F_v_; +text: .text%__1cQSystemDictionaryKclasses_do6FpFpnMklassOopDesc__v_v_; +text: .text%__1cKDictionaryKclasses_do6MpFpnMklassOopDesc__v_v_; +text: .text%__1cbBinitialize_itable_for_klass6FpnMklassOopDesc__v_; +text: .text%__1cNinstanceKlassGitable6kM_pnLklassItable__; +text: .text%__1cLklassItable2t6MnTinstanceKlassHandle__v_; +text: .text%__1cLklassItableRinitialize_itable6M_v_; +text: .text%__1cLklassItablebFinitialize_itable_for_interface6MpnMklassOopDesc_pnRitableMethodEntry__v_; +text: .text%__1cRitableMethodEntryKinitialize6MpnNmethodOopDesc__v_; +text: .text%__1cKoopFactoryMnew_objArray6FpnMklassOopDesc_ipnGThread__pnPobjArrayOopDesc__; +text: .text%__1cNinstanceKlassRallocate_objArray6MiipnGThread__pnPobjArrayOopDesc__; +text: .text%__1cNinstanceKlassQarray_klass_impl6MiipnGThread__pnMklassOopDesc__; +text: .text%__1cNinstanceKlassQarray_klass_impl6FnTinstanceKlassHandle_iipnGThread__pnMklassOopDesc__; +text: .text%__1cFKlassTarray_klass_or_null6M_pnMklassOopDesc__; +text: .text%__1cNinstanceKlassQarray_klass_impl6MipnGThread__pnMklassOopDesc__; +text: .text%__1cFKlassNoop_is_symbol6kM_i_: instanceKlass.o; +text: .text%__1cNobjArrayKlassQarray_klass_impl6MiipnGThread__pnMklassOopDesc__; +text: .text%__1cNobjArrayKlassQarray_klass_impl6FnTobjArrayKlassHandle_iipnGThread__pnMklassOopDesc__; +text: .text%__1cFKlassTarray_klass_or_null6Mi_pnMklassOopDesc__; +text: .text%__1cNCollectedHeapOarray_allocate6FnLKlassHandle_iipnGThread__pnHoopDesc__: instanceKlass.o; +text: .text%__1cNCollectedHeapYcommon_mem_allocate_init6FIipnGThread__pnIHeapWord__: instanceKlass.o; +text: .text%__1cNCollectedHeapXallocate_from_tlab_slow6FpnGThread_I_pnIHeapWord__; +text: .text%__1cQGenCollectedHeapVunsafe_max_tlab_alloc6kM_I_; +text: .text%__1cQDefNewGenerationVunsafe_max_tlab_alloc6kM_I_: defNewGeneration.o; +text: .text%__1cQDefNewGenerationVunsafe_max_alloc_nogc6kM_I_; +text: .text%__1cPContiguousSpaceEfree6kM_I_: space.o; +text: .text%__1cWThreadLocalAllocBufferXclear_before_allocation6M_v_; +text: .text%__1cWThreadLocalAllocBufferFreset6M_v_; +text: .text%__1cQGenCollectedHeapRallocate_new_tlab6MI_pnIHeapWord__; +text: .text%__1cQGenCollectedHeapMmem_allocate6MIii_pnIHeapWord__; +text: .text%__1cbCTwoGenerationCollectorPolicyRmem_allocate_work6MIii_pnIHeapWord__; +text: .text%__1cQGenCollectedHeapEheap6F_p0_; +text: .text%__1cQDefNewGenerationPshould_allocate6MIii_i_: defNewGeneration.o; +text: .text%__1cQDefNewGenerationMpar_allocate6MIii_pnIHeapWord__: defNewGeneration.o; +text: .text%__1cJEdenSpaceMpar_allocate6MI_pnIHeapWord__; +text: .text%__1cPContiguousSpaceRpar_allocate_impl6MIkpnIHeapWord__2_: space.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: collectedHeap.o; +text: .text%__1cWThreadLocalAllocBufferEfill6MpnIHeapWord_2I_v_; +text: .text%__1cQjava_lang_StringPcreate_from_str6FpkcpnGThread__nGHandle__; +text: .text%__1cQjava_lang_StringTcreate_oop_from_str6FpkcpnGThread__pnHoopDesc__; +text: .text%__1cKoopFactoryNnew_charArray6FpkcpnGThread__pnQtypeArrayOopDesc__; +text: .text%__1cEUTF8Ounicode_length6Fpkc_i_; +text: .text%__1cEUTF8Enext6FpkcpH_pc_; +text: .text%__1cOtypeArrayKlassIallocate6MipnGThread__pnQtypeArrayOopDesc__; +text: .text%__1cQGenCollectedHeapVlarge_typearray_limit6M_I_; +text: .text%__1cbCTwoGenerationCollectorPolicyYis_two_generation_policy6M_i_: collectorPolicy.o; +text: .text%__1cbCTwoGenerationCollectorPolicyVlarge_typearray_limit6M_I_; +text: .text%__1cNCollectedHeapOarray_allocate6FnLKlassHandle_iipnGThread__pnHoopDesc__: typeArrayKlass.o; +text: .text%__1cNCollectedHeapYcommon_mem_allocate_init6FIipnGThread__pnIHeapWord__: typeArrayKlass.o; +text: .text%__1cEUTF8Sconvert_to_unicode6FpkcpHi_v_; +text: .text%__1cQjava_lang_StringQbasic_create_oop6FpnQtypeArrayOopDesc_ipnGThread__pnHoopDesc__; +text: .text%__1cNinstanceKlassRallocate_instance6MpnGThread__pnPinstanceOopDesc__; +text: .text%__1cNCollectedHeapMobj_allocate6FnLKlassHandle_ipnGThread__pnHoopDesc__: instanceKlass.o; +text: .text%__1cTjava_lang_ThrowableLset_message6FpnHoopDesc_2_v_; +text: .text%__1cNinstanceKlassKlink_class6MpnGThread__v_; +text: .text%__1cNinstanceKlassPlink_class_impl6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cNinstanceKlassLverify_code6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cIVerifierRverify_byte_codes6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cNinstanceKlassWadd_loader_constraints6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cNinstanceKlassNrewrite_class6MpnGThread__v_; +text: .text%__1cIRewriterHrewrite6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cIRewriterScompute_index_maps6FnSconstantPoolHandle_rpnIintArray_rpnIintStack__v_; +text: .text%__1cIintArray2t6Mki1_v_: rewriter.o; +text: .text%__1cIRewriterXnew_constant_pool_cache6FrnIintArray_pnGThread__nXconstantPoolCacheHandle__; +text: .text%__1cKoopFactoryVnew_constantPoolCache6FipnGThread__pnYconstantPoolCacheOopDesc__; +text: .text%__1cWconstantPoolCacheKlassIallocate6MipnGThread__pnYconstantPoolCacheOopDesc__; +text: .text%__1cNCollectedHeapYpermanent_array_allocate6FnLKlassHandle_iipnGThread__pnHoopDesc__: cpCacheKlass.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: cpCacheKlass.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: cpCacheKlass.o; +text: .text%__1cYconstantPoolCacheOopDescKinitialize6MrnIintArray__v_; +text: .text%__1cWConstantPoolCacheEntryRset_initial_state6Mi_v_; +text: .text%__1cIRewriterOrewrite_method6FnMmethodHandle_rnIintArray_pnGThread__1_; +text: .text%__1cNmethodOopDescLlink_method6FnMmethodHandle__v_; +text: .text%__1cTAbstractInterpreterLmethod_kind6FnMmethodHandle__n0AKMethodKind__; +text: .text%__1cNmethodOopDescbGupdate_compiled_code_entry_point6Mi_v_; +text: .text%__1cIRuntime1Mientries_for6FnMmethodHandle__pnIiEntries__; +text: .text%__1cNmethodOopDescLis_accessor6kM_i_; +text: .text%__1cNmethodOopDescMintrinsic_id6kM_n0ALIntrinsicId__; +text: .text%__1cQSystemDictionaryXcheck_signature_loaders6FnMsymbolHandle_nGHandle_2ipnGThread__v_; +text: .text%__1cNSharedRuntimebIinitialize_StrictMath_entry_points6F_v_; +text: .text%__1cNSharedRuntimeUlookup_function_DD_D6FrpFpnHJNIEnv__pnH_jclass_dd_dpkc_v_; +text: .text%__1cMNativeLookupTbase_library_lookup6Fpkc22_pC_; +text: .text%__1cMNativeLookupGlookup6FnMmethodHandle_ripnGThread__pC_; +text: .text%__1cNmethodOopDescThas_native_function6kM_i_; +text: .text%__1cMNativeLookupLlookup_base6FnMmethodHandle_ripnGThread__pC_; +text: .text%__1cMNativeLookupNpure_jni_name6FnMmethodHandle__pc_; +text: .text%__1cMoutputStreamFprint6MpkcE_v_; +text: .text%__1cMoutputStreamMdo_vsnprintf6FpcIpkcpvirI_3_; +text: .text%__1cNmethodOopDescKklass_name6kM_pnNsymbolOopDesc__; +text: .text%__1cOmangle_name_on6FpnMoutputStream_pnNsymbolOopDesc__v_: nativeLookup.o; +text: .text%__1cOmangle_name_on6FpnMoutputStream_pnNsymbolOopDesc_ii_v_: nativeLookup.o; +text: .text%__1cMoutputStreamDput6Mc_v_; +text: .text%__1cMNativeLookupMlookup_style6FnMmethodHandle_pcpkciiripnGThread__pC_; +text: .text%__1cCosYprint_jni_name_prefix_on6FpnMoutputStream_i_v_; +text: .text%__1cCosYprint_jni_name_suffix_on6FpnMoutputStream_i_v_; +text: .text%__1cVlookup_special_native6Fpc_pC_: nativeLookup.o; +text: .text%__1cbEinitialize_converter_functions6F_v_; +text: .text%__1cIUniverseWupdate_heap_info_at_gc6F_v_; +text: .text%__1cQGenCollectedHeapIcapacity6kM_I_; +text: .text%__1cQDefNewGenerationIcapacity6kM_I_; +text: .text%__1cQGenCollectedHeapEused6kM_I_; +text: .text%__1cQDefNewGenerationEused6kM_I_; +text: .text%__1cbCOneContigSpaceCardGenerationEused6kM_I_; +text: .text%__1cQGenCollectedHeapPpost_initialize6M_v_; +text: .text%__1cQGenCollectedHeapTref_processing_init6M_v_; +text: .text%__1cKSharedHeapTref_processing_init6M_v_; +text: .text%__1cKGenerationSref_processor_init6M_v_; +text: .text%__1cKGenerationYrefs_discovery_is_atomic6kM_i_: compactingPermGenGen.o; +text: .text%__1cKGenerationUrefs_discovery_is_mt6kM_i_: compactingPermGenGen.o; +text: .text%__1cSReferenceProcessor2t6MnJMemRegion_iii_v_; +text: .text%__1cKGenerationYrefs_discovery_is_atomic6kM_i_: defNewGeneration.o; +text: .text%__1cKGenerationUrefs_discovery_is_mt6kM_i_: defNewGeneration.o; +text: .text%__1cKGenerationYrefs_discovery_is_atomic6kM_i_: tenuredGeneration.o; +text: .text%__1cKGenerationUrefs_discovery_is_mt6kM_i_: tenuredGeneration.o; +text: .text%__1cNMemoryServiceRset_universe_heap6FpnNCollectedHeap__v_; +text: .text%__1cQGenCollectedHeapEkind6M_nNCollectedHeapEName__: genCollectedHeap.o; +text: .text%__1cNMemoryServicebBadd_gen_collected_heap_info6FpnQGenCollectedHeap__v_; +text: .text%__1cPMarkSweepPolicyUis_mark_sweep_policy6M_i_: collectorPolicy.o; +text: .text%__1cNMemoryManagerXget_copy_memory_manager6F_pnPGCMemoryManager__; +text: .text%__1cPGCMemoryManager2t6M_v_; +text: .text%__1cNMemoryManagerWget_msc_memory_manager6F_pnPGCMemoryManager__; +text: .text%__1cNMemoryServicebAadd_generation_memory_pool6FpnKGeneration_pnNMemoryManager_4_v_; +text: .text%__1cQDefNewGenerationEkind6M_nKGenerationEName__: defNewGeneration.o; +text: .text%__1cNMemoryServiceJadd_space6FpnPContiguousSpace_pkciIi_pnKMemoryPool__; +text: .text%__1cTContiguousSpacePool2t6MpnPContiguousSpace_pkcnKMemoryPoolIPoolType_Ii_v_; +text: .text%__1cNMemoryServiceTadd_survivor_spaces6FpnQDefNewGeneration_pkciIi_pnKMemoryPool__; +text: .text%__1cbBSurvivorContiguousSpacePool2t6MpnQDefNewGeneration_pkcnKMemoryPoolIPoolType_Ii_v_; +text: .text%__1cRTenuredGenerationEkind6M_nKGenerationEName__: tenuredGeneration.o; +text: .text%__1cNMemoryServiceHadd_gen6FpnKGeneration_pkcii_pnKMemoryPool__; +text: .text%__1cOGenerationPool2t6MpnKGeneration_pkcnKMemoryPoolIPoolType_i_v_; +text: .text%__1cKGenerationMmax_capacity6kM_I_; +text: .text%__1cNMemoryServicebGadd_compact_perm_gen_memory_pool6FpnUCompactingPermGenGen_pnNMemoryManager__v_; +text: .text%__1cQGenCollectedHeapNgc_threads_do6kMpnNThreadClosure__v_; +text: .text%__1cPGCMemoryManagerXinitialize_gc_stat_info6M_v_; +text: .text%__1cKGCStatInfo2t6Mi_v_; +text: .text%__1cQjavaClasses_init6F_v_; +text: .text%__1cLJavaClassesPcompute_offsets6F_v_; +text: .text%__1cQjava_lang_SystemPcompute_offsets6F_v_; +text: .text%__1cQjava_lang_ThreadPcompute_offsets6F_v_; +text: .text%__1cNinstanceKlassQfind_local_field6kMpnNsymbolOopDesc_2pnPfieldDescriptor__i_; +text: .text%__1cVjava_lang_ThreadGroupPcompute_offsets6F_v_; +text: .text%__1cbIjava_security_AccessControlContextPcompute_offsets6F_v_; +text: .text%__1cbIjava_lang_reflect_AccessibleObjectPcompute_offsets6F_v_; +text: .text%__1cYjava_lang_reflect_MethodPcompute_offsets6F_v_; +text: .text%__1cbDjava_lang_reflect_ConstructorPcompute_offsets6F_v_; +text: .text%__1cXjava_lang_reflect_FieldPcompute_offsets6F_v_; +text: .text%__1cPjava_nio_BufferPcompute_offsets6F_v_; +text: .text%__1cYsun_reflect_ConstantPoolPcompute_offsets6F_v_; +text: .text%__1cZsun_misc_AtomicLongCSImplPcompute_offsets6F_v_; +text: .text%__1cSstubRoutines_init26F_v_; +text: .text%__1cMStubRoutinesLinitialize26F_v_; +text: .text%__1cNStubGeneratorYgenerate_throw_exception6MpkcpCi_3_: stubGenerator_x86.o; +text: .text%__1cNStubGeneratorTgenerate_verify_oop6M_pC_: stubGenerator_x86.o; +text: .text%__1cJAssemblerEincl6MnHAddress__v_; +text: .text%__1cHThreadsDadd6FpnKJavaThread_i_v_; +text: .text%__1cNThreadServiceKadd_thread6FpnKJavaThread_i_v_; +text: .text%__1cGThreadbCis_hidden_from_external_view6kM_i_: thread.o; +text: .text%__1cGThreadVis_jvmti_agent_thread6kM_i_: thread.o; +text: .text%__1cGEventsDlog6FpkcE_v_: thread.o; +text: .text%__1cLJvmtiExportbMtransition_pending_onload_raw_monitors6F_v_; +text: .text%__1cUJvmtiPendingMonitorsXtransition_raw_monitors6F_v_; +text: .text%__1cUGenericGrowableArrayUclear_and_deallocate6M_v_; +text: .text%__1cIVMThreadGcreate6F_v_; +text: .text%__1cIVMThread2t6M_v_; +text: .text%__1cQVMOperationQdDueue2t6M_v_; +text: .text%__1cCosNcreate_thread6FpnGThread_n0AKThreadType_I_i_; +text: .text%__1cCosMstart_thread6FpnGThread__v_; +text: .text%__1cCosPpd_start_thread6FpnGThread__v_; +text: .text%__1cHMonitorEwait6Mil_i_; +text: .text%_start: os_solaris.o; +text: .text%__1cCosTset_native_priority6FpnGThread_i_nIOSReturn__; +text: .text%__1cQset_lwp_priority6Fiii_i_; +text: .text%__1cVscale_to_lwp_priority6Fiii_i_: os_solaris.o; +text: .text%__1cIVMThreadMis_VM_thread6kM_i_: vmThread.o; +text: .text%__1cIVMThreadDrun6M_v_; +text: .text%__1cHMonitorGnotify6M_i_; +text: .text%__1cIVMThreadEloop6M_v_; +text: .text%__1cQVMOperationQdDueueLremove_next6M_pnMVM_Operation__; +text: .text%__1cQVMOperationQdDueueLqueue_empty6Mi_i_; +text: .text%__1cQVMOperationQdDueueSqueue_remove_front6Mi_pnMVM_Operation__; +text: .text%__1cLJvmtiExportRenter_start_phase6F_v_; +text: .text%__1cLJvmtiExportNpost_vm_start6F_v_; +text: .text%__1cUJvmtiEventControllerIvm_start6F_v_; +text: .text%__1cQinitialize_class6FnMsymbolHandle_pnGThread__v_: thread.o; +text: .text%__1cNinstanceKlassKinitialize6MpnGThread__v_; +text: .text%__1cNinstanceKlassVshould_be_initialized6kM_i_; +text: .text%__1cNinstanceKlassPinitialize_impl6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cNinstanceKlassWcall_class_initializer6MpnGThread__v_; +text: .text%__1cNinstanceKlassbBcall_class_initializer_impl6FnTinstanceKlassHandle_pnGThread__v_; +text: .text%__1cNinstanceKlassRclass_initializer6M_pnNmethodOopDesc__; +text: .text%__1cJJavaCallsEcall6FpnJJavaValue_nMmethodHandle_pnRJavaCallArguments_pnGThread__v_; +text: .text%__1cCosUos_exception_wrapper6FpFpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v2468_v_; +text: .text%__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v_; +text: .text%__1cRCompilationPolicyOmustBeCompiled6FnMmethodHandle__i_; +text: .text%__1cRCompilationPolicyNcanBeCompiled6FnMmethodHandle__i_; +text: .text%__1cNmethodOopDescRis_not_compilable6kMi_i_; +text: .text%__1cRruntime_type_from6FpnJJavaValue__nJBasicType__: javaCalls.o; +text: .text%__1cCosbCstack_shadow_pages_available6FpnGThread_nMmethodHandle__i_; +text: .text%__1cTAbstractInterpreterbFsize_top_interpreter_activation6FpnNmethodOopDesc__i_; +text: .text%__1cPJavaCallWrapper2t6MnMmethodHandle_nGHandle_pnJJavaValue_pnGThread__v_; +text: .text%__1cGThreadSis_Compiler_thread6kM_i_: thread.o; +text: .text%__1cGThreadXclear_pending_exception6M_v_; +text: .text%__1cRJavaCallArgumentsKparameters6M_pi_; +text: .text%__1cSInterpreterRuntimeOresolve_invoke6FpnKJavaThread_nJBytecodesECode__v_; +text: .text%__1cKJavaThreadPcook_last_frame6MnFframe__1_; +text: .text%__1cFframeYinterpreter_frame_method6kM_pnNmethodOopDesc__; +text: .text%__1cFframeVinterpreter_frame_bcp6kM_pC_; +text: .text%__1cMLinkResolverOresolve_invoke6FrnICallInfo_nGHandle_nSconstantPoolHandle_inJBytecodesECode_pnGThread__v_; +text: .text%__1cMLinkResolverUresolve_invokestatic6FrnICallInfo_nSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cMLinkResolverMresolve_pool6FrnLKlassHandle_rnMsymbolHandle_42nSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cMLinkResolverNresolve_klass6FrnLKlassHandle_nSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cTconstantPoolOopDescMklass_ref_at6MipnGThread__pnMklassOopDesc__; +text: .text%__1cTconstantPoolOopDescNklass_at_impl6FnSconstantPoolHandle_ipnGThread__pnMklassOopDesc__; +text: .text%__1cNinstanceKlassRprotection_domain6M_pnHoopDesc__: instanceKlass.o; +text: .text%__1cTconstantPoolOopDescbCverify_constant_pool_resolve6FnSconstantPoolHandle_nLKlassHandle_pnGThread__v_; +text: .text%__1cMLinkResolverZcheck_klass_accessability6FnLKlassHandle_1pnGThread__v_; +text: .text%__1cTconstantPoolOopDescMklass_at_put6MipnMklassOopDesc__v_: constantPoolOop.o; +text: .text%__1cTconstantPoolOopDescLname_ref_at6Mi_pnNsymbolOopDesc__; +text: .text%__1cTconstantPoolOopDescQsignature_ref_at6Mi_pnNsymbolOopDesc__; +text: .text%__1cMLinkResolverTresolve_static_call6FrnICallInfo_rnLKlassHandle_nMsymbolHandle_53iipnGThread__v_; +text: .text%__1cMLinkResolverbElinktime_resolve_static_method6FrnMmethodHandle_nLKlassHandle_nMsymbolHandle_43ipnGThread__v_; +text: .text%__1cMLinkResolverOresolve_method6FrnMmethodHandle_nLKlassHandle_nMsymbolHandle_43ipnGThread__v_; +text: .text%__1cMLinkResolverYlookup_method_in_klasses6FrnMmethodHandle_nLKlassHandle_nMsymbolHandle_4pnGThread__v_; +text: .text%__1cMLinkResolverbAcheck_method_accessability6FnLKlassHandle_11nMmethodHandle_pnGThread__v_; +text: .text%__1cKReflectionTverify_field_access6FpnMklassOopDesc_22nLAccessFlags_ii_i_; +text: .text%__1cICallInfoDset6MnLKlassHandle_nMmethodHandle_pnGThread__v_; +text: .text%__1cICallInfoDset6MnLKlassHandle_1nMmethodHandle_2ipnGThread__v_; +text: .text%__1cSInterpreterRuntimeLcache_entry6FpnKJavaThread__pnWConstantPoolCacheEntry__: interpreterRuntime.o; +text: .text%__1cWConstantPoolCacheEntryLis_resolved6kMnJBytecodesECode__i_: interpreterRuntime.o; +text: .text%__1cWConstantPoolCacheEntryPbytecode_number6FnJBytecodesECode__i_: interpreterRuntime.o; +text: .text%__1cWConstantPoolCacheEntryKset_method6MnJBytecodesECode_nMmethodHandle_i_v_; +text: .text%__1cNmethodOopDescLresult_type6kM_nJBasicType__; +text: .text%__1cRSignatureIteratorSiterate_returntype6M_v_; +text: .text%__1cNSignatureInfoHdo_void6M_v_: bytecode.o; +text: .text%__1cQResultTypeFinderDset6MinJBasicType__v_: bytecode.o; +text: .text%__1cRSignatureIteratorTcheck_signature_end6M_v_; +text: .text%__1cLas_TosState6FnJBasicType__nITosState__: cpCacheOop.o; +text: .text%__1cNmethodOopDescPis_final_method6kM_i_; +text: .text%__1cWConstantPoolCacheEntryIas_flags6MnITosState_iiiii_i_; +text: .text%__1cWConstantPoolCacheEntryOset_bytecode_16MnJBytecodesECode__v_; +text: .text%__1cWConstantPoolCacheEntryGverify6kMpnMoutputStream__v_; +text: .text%__1cSInterpreterRuntimeTprepare_native_call6FpnKJavaThread_pnNmethodOopDesc__v_; +text: .text%__1cXSignatureHandlerLibraryDadd6FnMmethodHandle__v_; +text: .text%__1cXSignatureHandlerLibraryKinitialize6F_v_; +text: .text%__1cXSignatureHandlerLibraryQset_handler_blob6F_pC_; +text: .text%__1cRSignatureIterator2t6MpnNsymbolOopDesc__v_; +text: .text%__1cNFingerprinterLfingerprint6M_X_: interpreterRuntime.o; +text: .text%__1cNGrowableArray4CX_Efind6kMkX_i_: interpreterRuntime.o; +text: .text%__1cSInterpreterRuntimeZSignatureHandlerGeneratorIgenerate6MX_v_; +text: .text%__1cRSignatureIteratorSiterate_parameters6MX_v_; +text: .text%__1cXSignatureHandlerLibraryLset_handler6FpnKCodeBuffer__pC_; +text: .text%__1cXSignatureHandlerLibraryOpd_set_handler6FpC_v_; +text: .text%jni_RegisterNatives: jni.o; +text: .text%__1cPjava_lang_ClassLas_klassOop6FpnHoopDesc__pnMklassOopDesc__; +text: .text%__1cLSymbolTableFprobe6Fpkci_pnNsymbolOopDesc__; +text: .text%__1cPregister_native6FnLKlassHandle_nMsymbolHandle_1pCpnGThread__i_: jni.o; +text: .text%__1cPJavaCallWrapper2T6M_v_; +text: .text%__1cOJNIHandleBlockNrelease_block6Fp0pnGThread__v_; +text: .text%__1cNinstanceKlassbJset_initialization_state_and_notify6Mn0AKClassState_pnGThread__v_; +text: .text%__1cNinstanceKlassbOset_initialization_state_and_notify_impl6FnTinstanceKlassHandle_n0AKClassState_pnGThread__v_; +text: .text%__1cSObjectSynchronizerJnotifyall6FnGHandle_pnGThread__v_; +text: .text%__1cSInterpreterRuntimeJanewarray6FpnKJavaThread_pnTconstantPoolOopDesc_ii_v_; +text: .text%__1cSInterpreterRuntimePresolve_get_put6FpnKJavaThread_nJBytecodesECode__v_; +text: .text%__1cMLinkResolverNresolve_field6FrnPFieldAccessInfo_nSconstantPoolHandle_inJBytecodesECode_ipnGThread__v_; +text: .text%__1cMLinkResolverNresolve_field6FrnPFieldAccessInfo_nSconstantPoolHandle_inJBytecodesECode_iipnGThread__v_; +text: .text%__1cNinstanceKlassKfind_field6kMpnNsymbolOopDesc_2pnPfieldDescriptor__pnMklassOopDesc__; +text: .text%__1cMLinkResolverZcheck_field_accessability6FnLKlassHandle_11rnPfieldDescriptor_pnGThread__v_; +text: .text%__1cPFieldAccessInfoDset6MnLKlassHandle_nMsymbolHandle_iinJBasicType_nLAccessFlags__v_; +text: .text%__1cLas_TosState6FnJBasicType__nITosState__: interpreterRuntime.o; +text: .text%__1cWConstantPoolCacheEntryJset_field6MnJBytecodesECode_2nLKlassHandle_iinITosState_ii_v_; +text: .text%__1cWConstantPoolCacheEntryOset_bytecode_26MnJBytecodesECode__v_; +text: .text%__1cSInterpreterRuntimeE_new6FpnKJavaThread_pnTconstantPoolOopDesc_i_v_; +text: .text%__1cNinstanceKlassbDcheck_valid_for_instantiation6MipnGThread__v_; +text: .text%__1cMLinkResolverVresolve_invokespecial6FrnICallInfo_nSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cMLinkResolverUresolve_special_call6FrnICallInfo_nLKlassHandle_nMsymbolHandle_43ipnGThread__v_; +text: .text%__1cMLinkResolverbFlinktime_resolve_special_method6FrnMmethodHandle_nLKlassHandle_nMsymbolHandle_43ipnGThread__v_; +text: .text%__1cMLinkResolverbEruntime_resolve_special_method6FrnICallInfo_nMmethodHandle_nLKlassHandle_4ipnGThread__v_; +text: .text%__1cWConstantPoolCacheEntryLis_resolved6kMnJBytecodesECode__i_: cpCacheOop.o; +text: .text%__1cWConstantPoolCacheEntryPbytecode_number6FnJBytecodesECode__i_: cpCacheOop.o; +text: .text%__1cNSignatureInfoJdo_object6Mii_v_: bytecode.o; +text: .text%__1cNSignatureInfoHdo_long6M_v_: bytecode.o; +text: .text%JVM_CurrentTimeMillis; +text: .text%__1cbBcreate_initial_thread_group6FpnGThread__nGHandle__: thread.o; +text: .text%__1cJJavaCallsMcall_special6FpnJJavaValue_nGHandle_nLKlassHandle_nMsymbolHandle_5pnGThread__v_; +text: .text%__1cJJavaCallsMcall_special6FpnJJavaValue_nLKlassHandle_nMsymbolHandle_4pnRJavaCallArguments_pnGThread__v_; +text: .text%__1cSInterpreterRuntimeDldc6FpnKJavaThread_i_v_; +text: .text%__1cTconstantPoolOopDescOstring_at_impl6FnSconstantPoolHandle_ipnGThread__pnHoopDesc__; +text: .text%__1cLsymbolKlassNoop_is_symbol6kM_i_: symbolKlass.o; +text: .text%__1cLStringTableGintern6FpnNsymbolOopDesc_pnGThread__pnHoopDesc__; +text: .text%__1cNsymbolOopDescKas_unicode6kMri_pH_; +text: .text%__1cEUTF8Ounicode_length6Fpkci_i_; +text: .text%__1cLStringTableGintern6FnGHandle_pHipnGThread__pnHoopDesc__; +text: .text%__1cLStringTableLhash_string6FpHi_i_; +text: .text%__1cLStringTableGlookup6MipHiI_pnHoopDesc__; +text: .text%__1cLStringTableJbasic_add6MinGHandle_pHiIpnGThread__pnHoopDesc__; +text: .text%__1cQjava_lang_StringbBcreate_tenured_from_unicode6FpHipnGThread__nGHandle__; +text: .text%__1cKoopFactoryXnew_permanent_charArray6FipnGThread__pnQtypeArrayOopDesc__; +text: .text%__1cQjava_lang_StringMbasic_create6FpnQtypeArrayOopDesc_ipnGThread__nGHandle__; +text: .text%__1cJJavaCallsMcall_special6FpnJJavaValue_nGHandle_nLKlassHandle_nMsymbolHandle_533pnGThread__v_; +text: .text%__1cNmethodOopDescIbci_from6kMpC_i_; +text: .text%__1cPBytecode_invokeJsignature6kM_pnNsymbolOopDesc__; +text: .text%__1cPBytecode_invokeFindex6kM_i_; +text: .text%__1cNmethodOopDescIbcp_from6kMi_pC_; +text: .text%__1cFframebGinterpreter_callee_receiver_addr6MnMsymbolHandle__ppnHoopDesc__; +text: .text%__1cMLinkResolverVresolve_invokevirtual6FrnICallInfo_nGHandle_nSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cMLinkResolverUresolve_virtual_call6FrnICallInfo_nGHandle_nLKlassHandle_4nMsymbolHandle_54iipnGThread__v_; +text: .text%__1cMLinkResolverbFlinktime_resolve_virtual_method6FrnMmethodHandle_nLKlassHandle_nMsymbolHandle_43ipnGThread__v_; +text: .text%__1cMLinkResolverbEruntime_resolve_virtual_method6FrnICallInfo_nMmethodHandle_nLKlassHandle_nGHandle_4ipnGThread__v_; +text: .text%__1cFKlassXcan_be_statically_bound6FpnNmethodOopDesc__i_; +text: .text%__1cNSignatureInfoGdo_int6M_v_: bytecode.o; +text: .text%__1cNSignatureInfoHdo_char6M_v_: bytecode.o; +text: .text%__1cFKlassOis_subclass_of6kMpnMklassOopDesc__i_; +text: .text%__1cNinstanceKlassVis_same_class_package6MpnHoopDesc_pnNsymbolOopDesc__i_; +text: .text%__1cJBytecodesRspecial_length_at6FpC_i_; +text: .text%__1cJJavaCallsLcall_static6FpnJJavaValue_nLKlassHandle_nMsymbolHandle_4nGHandle_5pnGThread__v_; +text: .text%__1cJJavaCallsLcall_static6FpnJJavaValue_nLKlassHandle_nMsymbolHandle_4pnRJavaCallArguments_pnGThread__v_; +text: .text%__1cLklassVtableIindex_of6kMpnNmethodOopDesc_i_i_; +text: .text%__1cMNativeLookupNlong_jni_name6FnMmethodHandle__pc_; +text: .text%__1cNFingerprinterJdo_object6Mii_v_: dump.o; +text: .text%__1cXNativeSignatureIteratorJdo_object6Mii_v_: interpreterRuntime.o; +text: .text%__1cSInterpreterRuntimeZSignatureHandlerGeneratorLpass_object6M_v_: interpreterRuntime.o; +text: .text%__1cSInterpreterRuntimeZSignatureHandlerGeneratorDbox6Mii_v_; +text: .text%__1cSInterpreterRuntimeZSignatureHandlerGeneratorEfrom6F_pnMRegisterImpl__; +text: .text%__1cSInterpreterRuntimeZSignatureHandlerGeneratorCto6F_pnMRegisterImpl__; +text: .text%JVM_DoPrivileged; +text: .text%__1cLmethodKlassNoop_is_method6kM_i_: methodKlass.o; +text: .text%__1cMvframeStream2t6MpnKJavaThread_i_v_; +text: .text%__1cLRegisterMap2t6MpnKJavaThread_i_v_; +text: .text%__1cLRegisterMapFclear6Mpi_v_; +text: .text%__1cSvframeStreamCommonPfill_from_frame6M_i_; +text: .text%__1cFframeUis_interpreted_frame6kM_i_; +text: .text%__1cSvframeStreamCommonbBfill_from_interpreter_frame6M_v_; +text: .text%__1cSvframeStreamCommonZsecurity_get_caller_frame6Mi_v_; +text: .text%__1cSvframeStreamCommonbHskip_method_invoke_and_aux_frames6M_v_; +text: .text%__1cSvframeStreamCommonEnext6M_v_; +text: .text%__1cFframeGsender6kMpnLRegisterMap_pnICodeBlob__0_; +text: .text%__1cFframeOis_entry_frame6kM_i_; +text: .text%__1cRPrivilegedElementKinitialize6MpnMvframeStream_pnHoopDesc_p0pnGThread__v_; +text: .text%__1cKJNIHandlesKmake_local6FpnHJNIEnv__pnHoopDesc__pnI_jobject__; +text: .text%__1cOJNIHandleBlockPallocate_handle6MpnHoopDesc__pnI_jobject__; +text: .text%__1cSInterpreterRuntimeNquicken_io_cc6FpnKJavaThread__v_; +text: .text%__1cNSignatureInfoHdo_bool6M_v_: bytecode.o; +text: .text%__1cNSharedRuntimeDf2i6Ff_i_; +text: .text%jni_FindClass: jni.o; +text: .text%__1cKJavaThreadZsecurity_get_caller_class6Mi_pnMklassOopDesc__; +text: .text%__1cbCfind_class_from_class_loader6FpnHJNIEnv__nMsymbolHandle_CnGHandle_3CpnGThread__pnH_jclass__; +text: .text%__1cRCompilationPolicyUcompleted_vm_startup6F_v_; +text: .text%jni_NewGlobalRef: jni.o; +text: .text%__1cKJNIHandlesLmake_global6FnGHandle_i_pnI_jobject__; +text: .text%jni_GetStringUTFChars: jni.o; +text: .text%__1cQjava_lang_StringOas_utf8_string6FpnHoopDesc__pc_; +text: .text%__1cHUNICODEHas_utf86FpHi_pc_; +text: .text%__1cHUNICODELutf8_length6FpHi_i_; +text: .text%__1cKutf8_write6FpCH_0_: utf8.o; +text: .text%JVM_FindPrimitiveClass; +text: .text%__1cJname2type6Fpkc_nJBasicType__; +text: .text%jni_ReleaseStringUTFChars; +text: .text%__1cVcreate_initial_thread6FnGHandle_pnKJavaThread_pnGThread__pnHoopDesc__: thread.o; +text: .text%__1cQjava_lang_ThreadKset_thread6FpnHoopDesc_pnKJavaThread__v_; +text: .text%__1cQjava_lang_ThreadMset_priority6FpnHoopDesc_nOThreadPriority__v_; +text: .text%JVM_CurrentThread; +text: .text%__1cNSignatureInfoIdo_array6Mii_v_: bytecode.o; +text: .text%__1cSInterpreterRuntimeInewarray6FpnKJavaThread_nJBasicType_i_v_; +text: .text%__1cKoopFactoryNnew_typeArray6FnJBasicType_ipnGThread__pnQtypeArrayOopDesc__; +text: .text%__1cNFingerprinterGdo_int6M_v_: dump.o; +text: .text%__1cXNativeSignatureIteratorGdo_int6M_v_: interpreterRuntime.o; +text: .text%__1cSInterpreterRuntimeZSignatureHandlerGeneratorIpass_int6M_v_: interpreterRuntime.o; +text: .text%__1cSInterpreterRuntimeZSignatureHandlerGeneratorEmove6Mii_v_; +text: .text%JVM_ArrayCopy; +text: .text%__1cOtypeArrayKlassKcopy_array6MpnMarrayOopDesc_i2iipnGThread__v_; +text: .text%__1cOtypeArrayKlassQoop_is_typeArray6kM_i_: typeArrayKlass.o; +text: .text%JVM_GetStackAccessControlContext; +text: .text%__1cbGJvmtiVMObjectAllocEventCollector2t6M_v_; +text: .text%__1cJCodeCacheJfind_blob6Fpv_pnICodeBlob__; +text: .text%__1cJCodeCacheQfind_blob_unsafe6Fpv_pnICodeBlob__; +text: .text%__1cICodeHeapKfind_start6kMpv_1_; +text: .text%__1cICodeBlobJis_zombie6kM_i_: codeBlob.o; +text: .text%__1cICodeBlobKis_nmethod6kM_i_: codeBlob.o; +text: .text%__1cFframeOis_first_frame6kM_i_; +text: .text%__1cFframeUentry_frame_is_first6kM_i_; +text: .text%__1cbIjava_security_AccessControlContextGcreate6FnOobjArrayHandle_inGHandle_pnGThread__pnHoopDesc__; +text: .text%__1cbGJvmtiVMObjectAllocEventCollector2T6M_v_; +text: .text%__1cTJvmtiEventCollectorYunset_jvmti_thread_state6M_v_; +text: .text%JVM_GetInheritedAccessControlContext; +text: .text%__1cQjava_lang_ThreadbGinherited_access_control_context6FpnHoopDesc__2_; +text: .text%JVM_SetThreadPriority; +text: .text%__1cQjava_lang_ThreadGthread6FpnHoopDesc__pnKJavaThread__; +text: .text%__1cGThreadMset_priority6Fp0nOThreadPriority__v_; +text: .text%__1cCosMset_priority6FpnGThread_nOThreadPriority__nIOSReturn__; +text: .text%__1cQjava_lang_ThreadRset_thread_status6FpnHoopDesc_n0AMThreadStatus__v_; +text: .text%JVM_IsThreadAlive; +text: .text%__1cQjava_lang_ThreadIis_alive6FpnHoopDesc__i_; +text: .text%JVM_StartThread; +text: .text%__1cQjava_lang_ThreadMis_stillborn6FpnHoopDesc__i_; +text: .text%__1cQjava_lang_ThreadJstackSize6FpnHoopDesc__x_; +text: .text%__1cKJavaThread2t6MpFp0pnGThread__vI_v_; +text: .text%__1cKJavaThreadHprepare6MpnI_jobject_nOThreadPriority__v_; +text: .text%__1cQjava_lang_ThreadIpriority6FpnHoopDesc__nOThreadPriority__; +text: .text%__1cQjava_lang_ThreadJis_daemon6FpnHoopDesc__i_; +text: .text%__1cGThreadFstart6Fp0_v_; +text: .text%__1cNinstanceKlassRprotection_domain6M_pnHoopDesc__: instanceRefKlass.o; +text: .text%__1cbAcall_initializeSystemClass6FpnGThread__v_: thread.o; +text: .text%__1cJJavaCallsLcall_static6FpnJJavaValue_nLKlassHandle_nMsymbolHandle_4pnGThread__v_; +text: .text%__1cKJavaThreadDrun6M_v_; +text: .text%__1cKJavaThreadRthread_main_inner6M_v_; +text: .text%__1cMthread_entry6FpnKJavaThread_pnGThread__v_: jvm.o; +text: .text%__1cJJavaCallsMcall_virtual6FpnJJavaValue_nGHandle_nLKlassHandle_nMsymbolHandle_5pnGThread__v_; +text: .text%__1cJJavaCallsMcall_virtual6FpnJJavaValue_nLKlassHandle_nMsymbolHandle_4pnRJavaCallArguments_pnGThread__v_; +text: .text%__1cIBytecodeIset_code6MnJBytecodesECode__v_; +text: .text%__1cNFingerprinterHdo_long6M_v_: dump.o; +text: .text%__1cXNativeSignatureIteratorHdo_long6M_v_: interpreterRuntime.o; +text: .text%__1cSInterpreterRuntimeZSignatureHandlerGeneratorJpass_long6M_v_: interpreterRuntime.o; +text: .text%JVM_MonitorWait; +text: .text%__1cQjava_lang_ThreadRget_thread_status6FpnHoopDesc__n0AMThreadStatus__; +text: .text%__1cSObjectSynchronizerEwait6FnGHandle_xpnGThread__v_; +text: .text%__1cSObjectSynchronizerHinflate6FpnHoopDesc__pnNObjectMonitor__; +text: .text%__1cNObjectMonitor2t6M_v_; +text: .text%__1cNObjectMonitorHRecycle6M_v_; +text: .text%__1cNObjectMonitorEwait6MxipnGThread__v_; +text: .text%__1cGThreadOis_interrupted6Fp0i_i_; +text: .text%__1cCosOis_interrupted6FpnGThread_i_i_; +text: .text%__1cNObjectMonitorEexit6MpnGThread__v_; +text: .text%__1cCosHSolarisFEventEpark6M_v_: objectMonitor_solaris.o; +text: .text%jni_GetObjectClass: jni.o; +text: .text%jni_GetMethodID: jni.o; +text: .text%__1cNget_method_id6FpnHJNIEnv__pnH_jclass_pkc5ipnGThread__pnK_jmethodID__: jni.o; +text: .text%__1cPjava_lang_ClassMis_primitive6FpnHoopDesc__i_; +text: .text%__1cNmethodOopDescKjmethod_id6M_pnK_jmethodID__; +text: .text%__1cMjniIdSupportNto_jmethod_id6FpnNmethodOopDesc__pnK_jmethodID__; +text: .text%__1cMjniIdPrivateGid_for6FnTinstanceKlassHandle_i_i_: jniId.o; +text: .text%__1cIjniIdMapGcreate6FnTinstanceKlassHandle__p0_; +text: .text%__1cIjniIdMapRcompute_index_cnt6FnTinstanceKlassHandle__i_; +text: .text%__1cIjniIdMap2t6MpnMklassOopDesc_i_v_; +text: .text%__1cLjniIdBucket2t6MpnIjniIdMap_p0_v_; +text: .text%jni_NewStringUTF: jni.o; +text: .text%jni_CallObjectMethod: jni.o; +text: .text%__1cMjniIdSupportNto_method_oop6FpnK_jmethodID__pnNmethodOopDesc__; +text: .text%__1cRSignatureIterator2t6MpnGThread_pnNsymbolOopDesc__v_; +text: .text%__1cUjni_invoke_nonstatic6FpnHJNIEnv__pnJJavaValue_pnI_jobject_nLJNICallType_pnK_jmethodID_pnSJNI_ArgumentPusher_pnGThread__v_: jni.o; +text: .text%__1cNFingerprinterLfingerprint6M_X_: jni.o; +text: .text%__1cXJNI_ArgumentPusherVaArgHiterate6MX_v_: jni.o; +text: .text%__1cXJNI_ArgumentPusherVaArgKget_object6M_v_: jni.o; +text: .text%jni_ExceptionOccurred: jni.o; +text: .text%__1cbAjni_check_async_exceptions6FpnKJavaThread__v_: jni.o; +text: .text%__1cKJavaThreadbHcheck_and_handle_async_exceptions6Mi_v_; +text: .text%jni_DeleteLocalRef: jni.o; +text: .text%__1cOJNIHandleBlockRrebuild_free_list6M_v_; +text: .text%jni_EnsureLocalCapacity; +text: .text%jni_GetStaticMethodID: jni.o; +text: .text%jni_CallStaticObjectMethodV: jni.o; +text: .text%__1cRjni_invoke_static6FpnHJNIEnv__pnJJavaValue_pnI_jobject_nLJNICallType_pnK_jmethodID_pnSJNI_ArgumentPusher_pnGThread__v_: jni.o; +text: .text%__1cMLinkResolverbHlookup_instance_method_in_klasses6FrnMmethodHandle_nLKlassHandle_nMsymbolHandle_4pnGThread__v_; +text: .text%jni_ExceptionCheck: jni.o; +text: .text%jni_NewString: jni.o; +text: .text%__1cQjava_lang_StringXcreate_oop_from_unicode6FpHipnGThread__pnHoopDesc__; +text: .text%JVM_InitProperties; +text: .text%__1cMset_property6FnGHandle_pkc2pnGThread__v_: jvm.o; +text: .text%__1cQjava_lang_StringbHcreate_from_platform_depended_str6FpkcpnGThread__nGHandle__; +text: .text%__1cJJavaCallsMcall_virtual6FpnJJavaValue_nGHandle_nLKlassHandle_nMsymbolHandle_533pnGThread__v_; +text: .text%__1cKSharedHeapXfill_region_with_object6FnJMemRegion__v_; +text: .text%__1cYNoJvmtiVMObjectAllocMark2t6M_v_; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: sharedHeap.o; +text: .text%__1cYNoJvmtiVMObjectAllocMark2T6M_v_; +text: .text%__1cPfieldDescriptorUstring_initial_value6kMpnGThread__pnHoopDesc__; +text: .text%jni_GetFieldID: jni.o; +text: .text%__1cNinstanceKlassKfind_field6kMpnNsymbolOopDesc_2ipnPfieldDescriptor__pnMklassOopDesc__; +text: .text%__1cNinstanceKlassSregister_finalizer6FpnPinstanceOopDesc_pnGThread__2_; +text: .text%__1cJFieldTypeYis_valid_array_signature6FpnNsymbolOopDesc__i_; +text: .text%__1cQSystemDictionarybBresolve_array_class_or_null6FnMsymbolHandle_nGHandle_2pnGThread__pnMklassOopDesc__; +text: .text%__1cJFieldTypeOget_array_info6FpnNsymbolOopDesc_pip2pnGThread__nJBasicType__; +text: .text%__1cJFieldTypeSskip_optional_size6FpnNsymbolOopDesc_pi_v_; +text: .text%__1cOtypeArrayKlassQarray_klass_impl6MiipnGThread__pnMklassOopDesc__; +text: .text%__1cOtypeArrayKlassQarray_klass_impl6FnUtypeArrayKlassHandle_iipnGThread__pnMklassOopDesc__; +text: .text%JVM_RegisterUnsafeMethods; +text: .text%JVM_IsArrayClass; +text: .text%JVM_GetComponentType; +text: .text%__1cKReflectionUarray_component_type6FpnHoopDesc_pnGThread__2_; +text: .text%__1cKReflectionbFbasic_type_arrayklass_to_mirror6FpnMklassOopDesc_pnGThread__pnHoopDesc__; +text: .text%JVM_IsPrimitiveClass; +text: .text%JVM_GetClassLoader; +text: .text%JVM_DesiredAssertionStatus; +text: .text%__1cOJavaAssertionsHenabled6Fpkci_i_; +text: .text%__1cOJavaAssertionsLmatch_class6Fpkc_pn0AKOptionList__: javaAssertions.o; +text: .text%__1cOJavaAssertionsNmatch_package6Fpkc_pn0AKOptionList__; +text: .text%__1cNinstanceKlassUfind_interface_field6kMpnNsymbolOopDesc_2pnPfieldDescriptor__pnMklassOopDesc__; +text: .text%JVM_InternString; +text: .text%__1cLStringTableGintern6FpnHoopDesc_pnGThread__2_; +text: .text%__1cQjava_lang_StringRas_unicode_string6FpnHoopDesc_ri_pH_; +text: .text%__1cKSharedHeapPis_in_permanent6kMpkv_i_: genCollectedHeap.o; +text: .text%__1cQjava_lang_StringGequals6FpnHoopDesc_pHi_i_; +text: .text%JVM_NanoTime; +text: .text%__1cCosNjavaTimeNanos6F_x_; +text: .text%JVM_GetCallerClass; +text: .text%JVM_SupportsCX8; +text: .text%__1cNFingerprinterHdo_bool6M_v_: dump.o; +text: .text%__1cXNativeSignatureIteratorHdo_bool6M_v_: interpreterRuntime.o; +text: .text%JVM_GetClassDeclaredFields; +text: .text%__1cKReflectionJnew_field6FpnPfieldDescriptor_ipnGThread__pnHoopDesc__; +text: .text%__1cKReflectionInew_type6FnMsymbolHandle_nLKlassHandle_pnGThread__nGHandle__; +text: .text%__1cJvmSymbolsOsignature_type6FpnNsymbolOopDesc__nJBasicType__; +text: .text%__1cXjava_lang_reflect_FieldGcreate6FpnGThread__nGHandle__; +text: .text%__1cXjava_lang_reflect_FieldJset_clazz6FpnHoopDesc_2_v_; +text: .text%__1cXjava_lang_reflect_FieldIset_slot6FpnHoopDesc_i_v_; +text: .text%__1cXjava_lang_reflect_FieldIset_name6FpnHoopDesc_2_v_; +text: .text%__1cXjava_lang_reflect_FieldIset_type6FpnHoopDesc_2_v_; +text: .text%__1cXjava_lang_reflect_FieldNset_modifiers6FpnHoopDesc_i_v_; +text: .text%__1cbIjava_lang_reflect_AccessibleObjectMset_override6FpnHoopDesc_C_v_; +text: .text%__1cXjava_lang_reflect_FieldThas_signature_field6F_i_; +text: .text%__1cXjava_lang_reflect_FieldVhas_annotations_field6F_i_; +text: .text%__1cPfieldDescriptorLannotations6kM_pnQtypeArrayOopDesc__; +text: .text%__1cXjava_lang_reflect_FieldPset_annotations6FpnHoopDesc_2_v_; +text: .text%__1cMLinkResolverXresolve_invokeinterface6FrnICallInfo_nGHandle_nSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cMLinkResolverWresolve_interface_call6FrnICallInfo_nGHandle_nLKlassHandle_4nMsymbolHandle_54iipnGThread__v_; +text: .text%__1cMLinkResolverbHlinktime_resolve_interface_method6FrnMmethodHandle_nLKlassHandle_nMsymbolHandle_43ipnGThread__v_; +text: .text%__1cMLinkResolverYresolve_interface_method6FrnMmethodHandle_nLKlassHandle_nMsymbolHandle_43ipnGThread__v_; +text: .text%__1cMLinkResolverbGruntime_resolve_interface_method6FrnICallInfo_nMmethodHandle_nLKlassHandle_nGHandle_4ipnGThread__v_; +text: .text%__1cICallInfoDset6MnLKlassHandle_1nMmethodHandle_2pnGThread__v_; +text: .text%__1cLklassItableUcompute_itable_index6FpnNmethodOopDesc__i_; +text: .text%__1cWConstantPoolCacheEntrySset_interface_call6MnMmethodHandle_i_v_; +text: .text%Unsafe_ObjectFieldOffset; +text: .text%__1cRfind_field_offset6FpnI_jobject_ipnGThread__i_; +text: .text%__1cXjava_lang_reflect_FieldFclazz6FpnHoopDesc__2_; +text: .text%__1cXjava_lang_reflect_FieldEslot6FpnHoopDesc__i_; +text: .text%__1cXjava_lang_reflect_FieldJmodifiers6FpnHoopDesc__i_; +text: .text%__1cQjava_lang_StringScreate_from_symbol6FnMsymbolHandle_pnGThread__nGHandle__; +text: .text%__1cXjava_lang_reflect_FieldNset_signature6FpnHoopDesc_2_v_; +text: .text%JVM_IHashCode; +text: .text%jni_GetStaticFieldID: jni.o; +text: .text%__1cNinstanceKlassKjni_id_for6Mi_pnFJNIid__; +text: .text%__1cNinstanceKlassPjni_id_for_impl6FnTinstanceKlassHandle_i_pnFJNIid__; +text: .text%__1cFJNIid2t6MpnMklassOopDesc_ip0_v_; +text: .text%jni_SetStaticObjectField: jni.o; +text: .text%__1cFKlassNoop_is_symbol6kM_i_: instanceRefKlass.o; +text: .text%__1cNobjArrayKlassPoop_is_objArray6kM_i_: objArrayKlass.o; +text: .text%__1cKarrayKlassTallocate_arrayArray6MiipnGThread__pnPobjArrayOopDesc__; +text: .text%__1cNobjArrayKlassQarray_klass_impl6MipnGThread__pnMklassOopDesc__; +text: .text%__1cFKlassNoop_is_symbol6kM_i_: objArrayKlass.o; +text: .text%__1cNCollectedHeapOarray_allocate6FnLKlassHandle_iipnGThread__pnHoopDesc__: arrayKlass.o; +text: .text%__1cNCollectedHeapYcommon_mem_allocate_init6FIipnGThread__pnIHeapWord__: arrayKlass.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: arrayKlass.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: arrayKlass.o; +text: .text%jni_GetStringUTFLength: jni.o; +text: .text%__1cQjava_lang_StringLutf8_length6FpnHoopDesc__i_; +text: .text%jni_GetStringLength: jni.o; +text: .text%__1cQjava_lang_StringGlength6FpnHoopDesc__i_; +text: .text%jni_GetStringUTFRegion: jni.o; +text: .text%__1cQjava_lang_StringOas_utf8_string6FpnHoopDesc_ii_pc_; +text: .text%JVM_FindClassFromClassLoader; +text: .text%JVM_IsInterface; +text: .text%JVM_GetClassDeclaredConstructors; +text: .text%__1cNmethodOopDescOis_initializer6kM_i_; +text: .text%__1cKReflectionPnew_constructor6FnMmethodHandle_pnGThread__pnHoopDesc__; +text: .text%__1cNinstanceKlassQmethod_index_for6kMpnNmethodOopDesc_pnGThread__i_; +text: .text%__1cKReflectionTget_parameter_types6FnMmethodHandle_ippnHoopDesc_pnGThread__nOobjArrayHandle__; +text: .text%__1cPSignatureStream2t6MnMsymbolHandle_i_v_; +text: .text%__1cPSignatureStreamEnext6M_v_; +text: .text%__1cKReflectionTget_exception_types6FnMmethodHandle_pnGThread__nOobjArrayHandle__; +text: .text%__1cNmethodOopDescbGresolved_checked_exceptions_impl6Fp0pnGThread__nOobjArrayHandle__; +text: .text%__1cSconstMethodOopDescZchecked_exceptions_length6kM_i_; +text: .text%__1cbDjava_lang_reflect_ConstructorGcreate6FpnGThread__nGHandle__; +text: .text%__1cbDjava_lang_reflect_ConstructorJset_clazz6FpnHoopDesc_2_v_; +text: .text%__1cbDjava_lang_reflect_ConstructorIset_slot6FpnHoopDesc_i_v_; +text: .text%__1cbDjava_lang_reflect_ConstructorTset_parameter_types6FpnHoopDesc_2_v_; +text: .text%__1cbDjava_lang_reflect_ConstructorTset_exception_types6FpnHoopDesc_2_v_; +text: .text%__1cbDjava_lang_reflect_ConstructorNset_modifiers6FpnHoopDesc_i_v_; +text: .text%__1cbDjava_lang_reflect_ConstructorThas_signature_field6F_i_; +text: .text%__1cbDjava_lang_reflect_ConstructorVhas_annotations_field6F_i_; +text: .text%__1cNmethodOopDescLannotations6kM_pnQtypeArrayOopDesc__; +text: .text%__1cbDjava_lang_reflect_ConstructorPset_annotations6FpnHoopDesc_2_v_; +text: .text%__1cbDjava_lang_reflect_ConstructorbFhas_parameter_annotations_field6F_i_; +text: .text%__1cNmethodOopDescVparameter_annotations6kM_pnQtypeArrayOopDesc__; +text: .text%__1cbDjava_lang_reflect_ConstructorZset_parameter_annotations6FpnHoopDesc_2_v_; +text: .text%__1cKarrayKlassWuncached_lookup_method6kMpnNsymbolOopDesc_2_pnNmethodOopDesc__; +text: .text%JVM_Clone; +text: .text%__1cNCollectedHeapOarray_allocate6FnLKlassHandle_iipnGThread__pnHoopDesc__: jvm.o; +text: .text%__1cNCollectedHeapYcommon_mem_allocate_init6FIipnGThread__pnIHeapWord__: jvm.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: jvm.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: jvm.o; +text: .text%__1cRCardTableModRefBSPdirty_MemRegion6MnJMemRegion__v_; +text: .text%JVM_GetClassAccessFlags; +text: .text%JVM_GetClassName; +text: .text%__1cFKlassNexternal_name6kM_pkc_; +text: .text%__1cNsymbolOopDescWas_klass_external_name6kM_pkc_; +text: .text%__1cLStringTableGintern6FpkcpnGThread__pnHoopDesc__; +text: .text%JVM_GetClassModifiers; +text: .text%jni_GetSuperclass: jni.o; +text: .text%__1cKJNIHandlesKmake_local6FpnHoopDesc__pnI_jobject__; +text: .text%__1cNFingerprinterIdo_array6Mii_v_: dump.o; +text: .text%JVM_NewInstanceFromConstructor; +text: .text%__1cKReflectionSinvoke_constructor6FpnHoopDesc_nOobjArrayHandle_pnGThread__2_; +text: .text%__1cbDjava_lang_reflect_ConstructorFclazz6FpnHoopDesc__2_; +text: .text%__1cbDjava_lang_reflect_ConstructorEslot6FpnHoopDesc__i_; +text: .text%__1cbIjava_lang_reflect_AccessibleObjectIoverride6FpnHoopDesc__C_; +text: .text%__1cbDjava_lang_reflect_ConstructorPparameter_types6FpnHoopDesc__2_; +text: .text%__1cKReflectionGinvoke6FnTinstanceKlassHandle_nMmethodHandle_nGHandle_inOobjArrayHandle_nJBasicType_4ipnGThread__pnHoopDesc__; +text: .text%__1cKReflectionDbox6FpnGjvalue_nJBasicType_pnGThread__pnHoopDesc__; +text: .text%JVM_MaxMemory; +text: .text%__1cQGenCollectedHeapMmax_capacity6kM_I_; +text: .text%__1cQDefNewGenerationMmax_capacity6kM_I_; +text: .text%Unsafe_AllocateMemory; +text: .text%Unsafe_SetNativeLong; +text: .text%__1cNSignatureInfoHdo_byte6M_v_: bytecode.o; +text: .text%Unsafe_GetNativeByte; +text: .text%Unsafe_FreeMemory; +text: .text%__1cNSignatureInfoIdo_float6M_v_: bytecode.o; +text: .text%__1cFJNIidEfind6Mi_p0_; +text: .text%jni_NewObjectV: jni.o; +text: .text%__1cMalloc_object6FpnH_jclass_pnGThread__pnPinstanceOopDesc__: jni.o; +text: .text%jni_GetStringRegion: jni.o; +text: .text%__1cQjava_lang_StringGoffset6FpnHoopDesc__i_; +text: .text%__1cQjava_lang_StringFvalue6FpnHoopDesc__pnQtypeArrayOopDesc__; +text: .text%jni_GetObjectField: jni.o; +text: .text%jni_GetStringCritical: jni.o; +text: .text%__1cJGC_lockerNlock_critical6FpnKJavaThread__v_: jni.o; +text: .text%jni_ReleaseStringCritical: jni.o; +text: .text%JVM_LoadLibrary; +text: .text%JVM_FindLibraryEntry; +text: .text%jni_GetJavaVM; +text: .text%JVM_IsSupportedJNIVersion; +text: .text%jni_SetIntField: jni.o; +text: .text%jni_SetLongField: jni.o; +text: .text%JVM_FindSignal; +text: .text%JVM_RegisterSignal; +text: .text%__1cCosMuser_handler6F_pv_; +text: .text%__1cCosGsignal6Fipv_1_; +text: .text%__1cWreset_vm_info_property6FpnGThread__v_: thread.o; +text: .text%__1cVquicken_jni_functions6F_v_; +text: .text%__1cQJNI_FastGetFieldbFgenerate_fast_get_boolean_field6F_pC_; +text: .text%__1cQJNI_FastGetFieldbCgenerate_fast_get_int_field06FnJBasicType__pC_; +text: .text%__1cJAssemblerFtestb6MpnMRegisterImpl_i_v_; +text: .text%__1cJAssemblerMemit_arith_b6MiipnMRegisterImpl_i_v_; +text: .text%__1cYjni_GetBooleanField_addr6F_pC_; +text: .text%__1cQJNI_FastGetFieldbCgenerate_fast_get_byte_field6F_pC_; +text: .text%__1cVjni_GetByteField_addr6F_pC_; +text: .text%__1cQJNI_FastGetFieldbCgenerate_fast_get_char_field6F_pC_; +text: .text%__1cVjni_GetCharField_addr6F_pC_; +text: .text%__1cQJNI_FastGetFieldbDgenerate_fast_get_short_field6F_pC_; +text: .text%__1cWjni_GetShortField_addr6F_pC_; +text: .text%__1cQJNI_FastGetFieldbBgenerate_fast_get_int_field6F_pC_; +text: .text%__1cUjni_GetIntField_addr6F_pC_; +text: .text%__1cQJNI_FastGetFieldbCgenerate_fast_get_long_field6F_pC_; +text: .text%__1cVjni_GetLongField_addr6F_pC_; +text: .text%__1cQJNI_FastGetFieldbDgenerate_fast_get_float_field6F_pC_; +text: .text%__1cQJNI_FastGetFieldbEgenerate_fast_get_float_field06FnJBasicType__pC_; +text: .text%__1cJAssemblerFfst_s6MnHAddress__v_; +text: .text%__1cJAssemblerGfstp_d6Mi_v_; +text: .text%__1cWjni_GetFloatField_addr6F_pC_; +text: .text%__1cQJNI_FastGetFieldbEgenerate_fast_get_double_field6F_pC_; +text: .text%__1cXjni_GetDoubleField_addr6F_pC_; +text: .text%__1cSset_init_completed6F_v_; +text: .text%__1cJTimeStampGupdate6M_v_; +text: .text%__1cQSystemDictionarybAcompute_java_system_loader6FpnGThread__v_; +text: .text%jni_NewObjectArray: jni.o; +text: .text%__1cNobjArrayKlassKinitialize6MpnGThread__v_; +text: .text%__1cNobjArrayKlassIallocate6MipnGThread__pnPobjArrayOopDesc__; +text: .text%__1cNCollectedHeapOarray_allocate6FnLKlassHandle_iipnGThread__pnHoopDesc__: objArrayKlass.o; +text: .text%__1cNCollectedHeapYcommon_mem_allocate_init6FIipnGThread__pnIHeapWord__: objArrayKlass.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: objArrayKlass.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: objArrayKlass.o; +text: .text%jni_SetObjectArrayElement: jni.o; +text: .text%jni_GetObjectArrayElement: jni.o; +text: .text%__1cSInterpreterRuntimebAfrequency_counter_overflow6FpnKJavaThread_pC_x_; +text: .text%__1cQSimpleCompPolicyXmethod_invocation_event6MnMmethodHandle_pnGThread__v_; +text: .text%__1cRCompilationPolicybIreset_counter_for_invocation_event6MnMmethodHandle__v_; +text: .text%__1cRInvocationCounterJset_carry6M_v_; +text: .text%__1cNCompileBrokerOcompile_method6FnMmethodHandle_i1ipkcpnGThread__pnHnmethod__; +text: .text%__1cQSimpleCompPolicyRcompilation_level6MnMmethodHandle_i_i_; +text: .text%__1cNCompileBrokerTcompile_method_base6FnMmethodHandle_ii1ipkcpnGThread__pnHnmethod__; +text: .text%__1cNobjArrayKlassKcopy_array6MpnMarrayOopDesc_i2iipnGThread__v_; +text: .text%__1cLJvmtiExportQenter_live_phase6F_v_; +text: .text%__1cLJvmtiExportTpost_vm_initialized6F_v_; +text: .text%__1cUJvmtiEventControllerHvm_init6F_v_; +text: .text%__1cHMonitorKnotify_all6M_i_; +text: .text%__1cFChunkbDstart_chunk_pool_cleaner_task6F_v_; +text: .text%__1cMPeriodicTask2t6MI_v_; +text: .text%__1cMPeriodicTaskGenroll6M_v_; +text: .text%__1cURecompilationMonitorbGstart_recompilation_monitor_task6F_v_; +text: .text%__1cCosLsignal_init6F_v_; +text: .text%__1cJJavaCallsMcall_special6FpnJJavaValue_nGHandle_nLKlassHandle_nMsymbolHandle_53pnGThread__v_; +text: .text%__1cCosOsignal_init_pd6F_v_; +text: .text%__1cQjava_lang_ThreadKset_daemon6FpnHoopDesc__v_; +text: .text%__1cICompiler2t6M_v_; +text: .text%__1cNCompileBrokerQcompilation_init6FpnQAbstractCompiler__v_; +text: .text%__1cNCompileBrokerVinit_compiler_threads6Fi_v_; +text: .text%__1cICompilerOneeds_adapters6M_i_: c1_Compiler.o; +text: .text%__1cQCompilerCounters2t6MpkcipnGThread__v_; +text: .text%__1cNCompileBrokerUmake_compiler_thread6FpkcpnMCompileQdDueue_pnQCompilerCounters_pnGThread__pnOCompilerThread__; +text: .text%__1cOCompilerThread2t6MpnMCompileQdDueue_pnQCompilerCounters__v_; +text: .text%__1cOCompilerThreadbCis_hidden_from_external_view6kM_i_: thread.o; +text: .text%__1cCosFyield6F_v_; +text: .text%__1cCosFsleep6FpnGThread_xi_i_; +text: .text%__1cGThreadRis_Watcher_thread6kM_i_: thread.o; +text: .text%__1cTsignal_thread_entry6FpnKJavaThread_pnGThread__v_: os.o; +text: .text%__1cCosLsignal_wait6F_i_; +text: .text%__1cVcheck_pending_signals6Fi_i_: os_solaris.o; +text: .text%__1cVcompiler_thread_entry6FpnKJavaThread_pnGThread__v_: thread.o; +text: .text%__1cNCompileBrokerUcompiler_thread_loop6F_v_; +text: .text%__1cICompilerKinitialize6M_v_; +text: .text%__1cMCompileQdDueueDget6M_pnLCompileTask__; +text: .text%__1cKManagementKinitialize6FpnGThread__v_; +text: .text%__1cRLowMemoryDetectorKinitialize6F_v_; +text: .text%__1cXLowMemoryDetectorThreadbCis_hidden_from_external_view6kM_i_: lowMemoryDetector.o; +text: .text%__1cKJavaThreadOis_Java_thread6kM_i_: lowMemoryDetector.o; +text: .text%__1cLStatSamplerGengage6F_v_; +text: .text%__1cLStatSamplerKinitialize6F_v_; +text: .text%__1cLStatSamplerUcreate_misc_perfdata6F_v_; +text: .text%__1cCosRelapsed_frequency6F_x_; +text: .text%__1cLStatSamplerbMcreate_system_property_instrumentation6FpnGThread__v_; +text: .text%__1cLStatSamplerTget_system_property6FpkcpnGThread__2_; +text: .text%__1cJJavaCallsLcall_static6FpnJJavaValue_nLKlassHandle_nMsymbolHandle_4nGHandle_pnGThread__v_; +text: .text%__1cLStatSamplerXcreate_sampled_perfdata6F_v_; +text: .text%__1cPPerfDataManagerTcreate_long_counter6FnJCounterNS_pkcnIPerfDataFUnits_pnUPerfLongSampleHelper_pnGThread__pnPPerfLongCounter__; +text: .text%__1cSHighResTimeSamplerLtake_sample6M_x_: statSampler.o; +text: .text%__1cPPerfDataManagerHsampled6F_pnMPerfDataList__; +text: .text%__1cMPerfDataListFclone6M_p0_; +text: .text%__1cMPerfDataList2t6Mp0_v_; +text: .text%__1cUGenericGrowableArrayNraw_appendAll6Mpk0_v_; +text: .text%__1cNWatcherThreadFstart6F_v_; +text: .text%__1cNWatcherThread2t6M_v_; +text: .text%__1cJTimeStampMmilliseconds6kM_x_; +text: .text%__1cKManagementWrecord_vm_startup_time6Fxx_v_; +text: .text%__1cORuntimeServiceYrecord_application_start6F_v_; +text: .text%__1cNWatcherThreadDrun6M_v_; +text: .text%__1cMPeriodicTaskMtime_to_wait6F_I_: thread.o; +text: .text%__1cNWatcherThreadRis_Watcher_thread6kM_i_: thread.o; +text: .text%__1cIos_sleep6Fxi_i_: os_solaris.o; +text: .text%__1cNgetTimeMillis6F_x_; +text: .text%__1cQjava_lang_StringOchar_converter6FnGHandle_HHpnGThread__1_; +text: .text%JVM_FindLoadedClass; +text: .text%__1cQSystemDictionarybCfind_instance_or_array_klass6FnMsymbolHandle_nGHandle_2pnGThread__pnMklassOopDesc__; +text: .text%__1cQSystemDictionaryEfind6FnMsymbolHandle_nGHandle_2pnGThread__pnMklassOopDesc__; +text: .text%__1cSInterpreterRuntimeLmonitorexit6FpnKJavaThread_pnPBasicObjectLock__v_; +text: .text%__1cSObjectSynchronizerJslow_exit6FpnHoopDesc_pnJBasicLock_pnGThread__v_; +text: .text%jni_CallStaticObjectMethod: jni.o; +text: .text%jni_NewByteArray: jni.o; +text: .text%jni_SetByteArrayRegion: jni.o; +text: .text%__1cSInterpreterRuntimeMmonitorenter6FpnKJavaThread_pnPBasicObjectLock__v_; +text: .text%__1cNObjectMonitorFenter6MpnGThread__v_; +text: .text%jni_NewObject: jni.o; +text: .text%__1cGThreadMis_VM_thread6kM_i_: lowMemoryDetector.o; +text: .text%__1cRLowMemoryDetectorbGlow_memory_detector_thread_entry6FpnKJavaThread_pnGThread__v_; +text: .text%__1cRLowMemoryDetectorUhas_pending_requests6F_i_; +text: .text%__1cVjava_lang_ClassLoaderGparent6FpnHoopDesc__2_; +text: .text%__1cKExceptionsK_throw_msg6FpnGThread_pkcipnNsymbolOopDesc_4_v_; +text: .text%__1cKExceptionsK_throw_msg6FpnGThread_pkcinMsymbolHandle_4nGHandle_6_v_; +text: .text%__1cKExceptionsRspecial_exception6FpnGThread_pkcinMsymbolHandle_4_i_; +text: .text%__1cKExceptionsNnew_exception6FpnGThread_nMsymbolHandle_pkcnGHandle_6_6_; +text: .text%__1cKExceptionsNnew_exception6FpnGThread_nMsymbolHandle_3pnRJavaCallArguments_nGHandle_6_6_; +text: .text%JVM_FillInStackTrace; +text: .text%__1cTjava_lang_ThrowableTfill_in_stack_trace6FnGHandle__v_; +text: .text%__1cIUniverseWis_out_of_memory_error6FnGHandle__i_; +text: .text%__1cVPreserveExceptionMark2t6MrpnGThread__v_; +text: .text%__1cKJavaThreadGactive6F_p0_; +text: .text%__1cTjava_lang_ThrowableTfill_in_stack_trace6FnGHandle_pnGThread__v_; +text: .text%__1cTjava_lang_ThrowableNset_backtrace6FpnHoopDesc_2_v_; +text: .text%__1cTjava_lang_ThrowableQclear_stacktrace6FpnHoopDesc__v_; +text: .text%__1cVPreserveExceptionMark2T6M_v_; +text: .text%__1cKExceptionsG_throw6FpnGThread_pkcinGHandle__v_; +text: .text%__1cKExceptionsRspecial_exception6FpnGThread_pkcinGHandle__i_; +text: .text%__1cGThreadVset_pending_exception6MpnHoopDesc_pkci_v_; +text: .text%__1cGEventsDlog6FpkcE_v_: exceptions.o; +text: .text%__1cSInterpreterRuntimeXthrow_pending_exception6FpnKJavaThread__v_; +text: .text%__1cNSharedRuntimebKexception_handler_for_return_address6FpC_1_; +text: .text%__1cNSharedRuntimebOraw_exception_handler_for_return_address6FpC_1_; +text: .text%__1cSInterpreterRuntimebFexception_handler_for_exception6FpnKJavaThread_pnHoopDesc__pC_; +text: .text%__1cNmethodOopDescbEfast_exception_handler_bci_for6MnLKlassHandle_ipnGThread__i_; +text: .text%__1cKJavaThreadNreguard_stack6MpC_i_; +text: .text%__1cSInterpreterRuntimePset_bcp_and_mdp6FpCpnKJavaThread__v_; +text: .text%__1cFframeZinterpreter_frame_set_bcp6MpC_v_; +text: .text%__1cFframeZinterpreter_frame_set_bcx6Mi_v_; +text: .text%__1cNCompileBrokerYcheck_compilation_result6FnMmethodHandle_iippnHnmethod__i_; +text: .text%__1cNCompileBrokerXcompilation_is_in_queue6FnMmethodHandle_i_i_; +text: .text%__1cNCompileBrokerZcompilation_is_prohibited6FnMmethodHandle_i_i_; +text: .text%__1cNCompileBrokerTis_not_compile_only6FnMmethodHandle__i_; +text: .text%__1cOCompilerOracleOshould_exclude6FnMmethodHandle__i_; +text: .text%__1cNCompileBrokerRassign_compile_id6FnMmethodHandle_i_I_; +text: .text%__1cNCompileBrokerTis_compile_blocking6FnMmethodHandle_i_i_; +text: .text%__1cNCompileBrokerTcreate_compile_task6FpnMCompileQdDueue_inMmethodHandle_i3ipkcii_pnLCompileTask__; +text: .text%__1cNCompileBrokerNallocate_task6F_pnLCompileTask__; +text: .text%__1cLCompileTaskKinitialize6MinMmethodHandle_i1ipkcii_v_; +text: .text%__1cMCompileQdDueueDadd6MpnLCompileTask__v_; +text: .text%__1cNCompileBrokerTwait_for_completion6FpnLCompileTask__pnHnmethod__; +text: .text%__1cCosPhint_no_preempt6F_v_; +text: .text%__1cSCompileTaskWrapper2t6MpnLCompileTask__v_; +text: .text%__1cNCompileBrokerZinvoke_compiler_on_method6FpnLCompileTask__v_; +text: .text%__1cNCompileBrokerQset_last_compile6FpnOCompilerThread_nMmethodHandle_ii_v_; +text: .text%__1cNCompileBrokerVpush_jni_handle_block6F_v_; +text: .text%__1cNCompileBrokerOcheck_break_at6FnMmethodHandle_iii_i_; +text: .text%__1cOCompilerOraclePshould_break_at6FnMmethodHandle__i_; +text: .text%__1cFciEnv2t6MpnHJNIEnv__iii_v_; +text: .text%__1cPciObjectFactory2t6MpnFArena_i_v_; +text: .text%__1cPciObjectFactoryTinit_shared_objects6M_v_; +text: .text%__1cUGenericGrowableArray2t6MpnFArena_iipnEGrET__v_; +text: .text%__1cIciSymbol2t6MnMsymbolHandle__v_; +text: .text%__1cIciObject2t6MnGHandle__v_; +text: .text%__1cPciObjectFactoryEfind6MpnHoopDesc_pnNGrowableArray4CpnIciObject____i_; +text: .text%__1cPciObjectFactoryLis_found_at6MipnHoopDesc_pnNGrowableArray4CpnIciObject____i_; +text: .text%__1cPciObjectFactoryNinit_ident_of6MpnIciObject__v_; +text: .text%__1cIciObjectJset_ident6MI_v_; +text: .text%__1cPciObjectFactoryGinsert6MipnIciObject_pnNGrowableArray4C2___v_; +text: .text%__1cGciType2t6MnJBasicType__v_; +text: .text%__1cIciObject2t6M_v_; +text: .text%__1cPciObjectFactoryDget6MpnHoopDesc__pnIciObject__; +text: .text%__1cPciObjectFactoryNfind_non_perm6MpnHoopDesc__rpn0ANNonPermObject__; +text: .text%__1cFKlassNoop_is_symbol6kM_i_: klassKlass.o; +text: .text%__1cPciObjectFactoryRcreate_new_object6MpnHoopDesc__pnIciObject__; +text: .text%__1cFKlassPoop_is_instance6kM_i_: methodKlass.o; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: methodKlass.o; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: methodKlass.o; +text: .text%__1cIciSymbolEmake6Fpkc_p0_; +text: .text%__1cFciEnvIis_in_vm6F_i_; +text: .text%__1cIciSymbolJmake_impl6Fpkc_p0_; +text: .text%__1cHciKlass2t6MnLKlassHandle_pnIciSymbol__v_; +text: .text%__1cGciType2t6MnLKlassHandle__v_; +text: .text%__1cFKlassMoop_is_array6kM_i_: methodKlass.o; +text: .text%__1cFKlassPoop_is_instance6kM_i_: symbolKlass.o; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: symbolKlass.o; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: symbolKlass.o; +text: .text%__1cFKlassNoop_is_method6kM_i_: symbolKlass.o; +text: .text%__1cFKlassMoop_is_array6kM_i_: symbolKlass.o; +text: .text%__1cFKlassPoop_is_instance6kM_i_: klassKlass.o; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: klassKlass.o; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: klassKlass.o; +text: .text%__1cFKlassNoop_is_method6kM_i_: klassKlass.o; +text: .text%__1cFKlassUoop_is_objArrayKlass6kM_i_: klassKlass.o; +text: .text%__1cFKlassVoop_is_typeArrayKlass6kM_i_: klassKlass.o; +text: .text%__1cFKlassUoop_is_instanceKlass6kM_i_: klassKlass.o; +text: .text%__1cFKlassMoop_is_array6kM_i_: klassKlass.o; +text: .text%__1cFKlassPoop_is_instance6kM_i_: instanceKlassKlass.o; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: instanceKlassKlass.o; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: instanceKlassKlass.o; +text: .text%__1cFKlassNoop_is_method6kM_i_: instanceKlassKlass.o; +text: .text%__1cFKlassNoop_is_symbol6kM_i_: instanceKlassKlass.o; +text: .text%__1cFKlassUoop_is_objArrayKlass6kM_i_: instanceKlassKlass.o; +text: .text%__1cFKlassVoop_is_typeArrayKlass6kM_i_: instanceKlassKlass.o; +text: .text%__1cSinstanceKlassKlassUoop_is_instanceKlass6kM_i_: instanceKlassKlass.o; +text: .text%__1cFKlassMoop_is_array6kM_i_: instanceKlassKlass.o; +text: .text%__1cFKlassPoop_is_instance6kM_i_: typeArrayKlassKlass.o; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: typeArrayKlassKlass.o; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: typeArrayKlassKlass.o; +text: .text%__1cFKlassNoop_is_method6kM_i_: typeArrayKlassKlass.o; +text: .text%__1cFKlassNoop_is_symbol6kM_i_: typeArrayKlassKlass.o; +text: .text%__1cFKlassUoop_is_objArrayKlass6kM_i_: typeArrayKlassKlass.o; +text: .text%__1cTtypeArrayKlassKlassVoop_is_typeArrayKlass6kM_i_: typeArrayKlassKlass.o; +text: .text%__1cFKlassMoop_is_array6kM_i_: typeArrayKlassKlass.o; +text: .text%__1cFKlassPoop_is_instance6kM_i_: objArrayKlassKlass.o; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: objArrayKlassKlass.o; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: objArrayKlassKlass.o; +text: .text%__1cFKlassNoop_is_method6kM_i_: objArrayKlassKlass.o; +text: .text%__1cFKlassNoop_is_symbol6kM_i_: objArrayKlassKlass.o; +text: .text%__1cSobjArrayKlassKlassUoop_is_objArrayKlass6kM_i_: objArrayKlassKlass.o; +text: .text%__1cFKlassMoop_is_array6kM_i_: objArrayKlassKlass.o; +text: .text%__1cPciInstanceKlass2t6MnLKlassHandle__v_; +text: .text%__1cHciKlass2t6MnLKlassHandle__v_; +text: .text%__1cPciInstanceKlassFsuper6M_p0_; +text: .text%__1cPciInstanceKlassTis_java_lang_Object6M_i_; +text: .text%__1cIciObjectGequals6Mp0_i_; +text: .text%__1cPciInstanceKlassLjava_mirror6M_pnKciInstance__; +text: .text%__1cHciKlassLjava_mirror6M_pnKciInstance__; +text: .text%__1cFKlassNoop_is_method6kM_i_: instanceKlass.o; +text: .text%__1cFKlassRoop_is_methodData6kM_i_: instanceKlass.o; +text: .text%__1cUciInstanceKlassKlassEmake6F_p0_; +text: .text%__1cHciKlass2t6MpnIciSymbol_p0_v_; +text: .text%__1cGciType2t6MpnHciKlass__v_; +text: .text%__1cIciObject2t6MpnHciKlass__v_; +text: .text%__1cIciObjectUis_array_klass_klass6M_i_: ciObjectFactory.o; +text: .text%__1cPciObjArrayKlass2t6MpnIciSymbol_pnHciKlass_i_v_; +text: .text%__1cUciObjArrayKlassKlassEmake6F_p0_; +text: .text%__1cMciArrayKlass2t6MpnIciSymbol_ipnHciKlass__v_; +text: .text%__1cRciArrayKlassKlassUis_array_klass_klass6M_i_: ciObjectFactory.o; +text: .text%__1cQciTypeArrayKlass2t6MnLKlassHandle__v_; +text: .text%__1cMciArrayKlass2t6MnLKlassHandle__v_; +text: .text%__1cFciEnvWget_method_from_handle6MpnI_jobject__pnIciMethod__; +text: .text%__1cFKlassNoop_is_symbol6kM_i_: methodKlass.o; +text: .text%__1cIciMethod2t6MnMmethodHandle__v_; +text: .text%__1cLciSignature2t6MpnHciKlass_pnIciSymbol__v_; +text: .text%__1cPSignatureStreamJis_object6kM_i_; +text: .text%__1cGciTypeEmake6FnJBasicType__p0_; +text: .text%__1cJTraceTime2t6MpkcpnMelapsedTimer_iipnMoutputStream__v_; +text: .text%__1cICompilerOcompile_method6MpnFciEnv_pnIciMethod_i_v_; +text: .text%__1cLCompilation2t6MpnQAbstractCompiler_pnFciEnv_pnIciMethod_ipnRC1_MacroAssembler__v_; +text: .text%__1cTExceptionRangeTable2t6Mi_v_; +text: .text%__1cWImplicitExceptionTableIset_size6MI_v_; +text: .text%__1cLCompilationOcompile_method6M_v_; +text: .text%__1cLCompilationKinitialize6M_v_; +text: .text%__1cLCompilationEcode6kM_pnKCodeBuffer__; +text: .text%__1cYDebugInformationRecorder2t6MpnLOopRecorder__v_; +text: .text%__1cUDebugInfoWriteStream2t6MpnYDebugInformationRecorder_i_v_; +text: .text%__1cLCompilationTdebug_info_recorder6kM_pnYDebugInformationRecorder__; +text: .text%__1cLCompilationbBis_optimized_library_method6kM_i_; +text: .text%__1cLCompilationTcompile_java_method6MpnLCodeOffsets__i_; +text: .text%__1cLCompilationTinitialize_oop_maps6M_v_; +text: .text%__1cIciMethodMall_oop_maps6M_pnKciLocalMap__; +text: .text%__1cSciGenerateLocalMap2t6MpnFArena_nMmethodHandle__v_; +text: .text%__1cOGenerateOopMap2t6MnMmethodHandle__v_; +text: .text%__1cSciGenerateLocalMapWfind_jsr_return_points6MnMmethodHandle__v_; +text: .text%__1cRRawBytecodeStream2t6MnMmethodHandle__v_; +text: .text%__1cRRawBytecodeStreamMset_interval6Mii_v_; +text: .text%__1cOBytecodeStreamEnext6M_nJBytecodesECode__: ciOopMap.o; +text: .text%__1cOGenerateOopMapLcompute_map6MpnGThread__v_; +text: .text%__1cIRetTableRcompute_ret_table6MnMmethodHandle__v_; +text: .text%__1cOBytecodeStreamEnext6M_nJBytecodesECode__: generateOopMap.o; +text: .text%__1cOGenerateOopMapbImark_bbheaders_and_count_gc_points6M_v_; +text: .text%__1cOGenerateOopMapNinitialize_bb6M_v_; +text: .text%__1cOGenerateOopMapLbb_mark_fct6Fp0ipi_v_; +text: .text%__1cOGenerateOopMapOset_bbmark_bit6Mi_v_; +text: .text%__1cOGenerateOopMapPjump_targets_do6MpnOBytecodeStream_pFp0ipi_v4_i_; +text: .text%__1cSciGenerateLocalMapRpossible_gc_point6MpnOBytecodeStream__i_; +text: .text%__1cSciGenerateLocalMapUbytecode_is_gc_point6FnJBytecodesECode_ii_i_; +text: .text%__1cOGenerateOopMapRdo_interpretation6M_v_; +text: .text%__1cOGenerateOopMapRinit_basic_blocks6M_v_; +text: .text%__1cOGenerateOopMapKinit_state6M_v_; +text: .text%__1cOGenerateOopMapTmark_reachable_code6M_v_; +text: .text%__1cOGenerateOopMapUreachable_basicblock6Fp0ipi_v_; +text: .text%__1cOGenerateOopMapSget_basic_block_at6kMi_pnKBasicBlock__; +text: .text%__1cOGenerateOopMapbAget_basic_block_containing6kMi_pnKBasicBlock__; +text: .text%__1cOGenerateOopMapYsetup_method_entry_state6M_v_; +text: .text%__1cOGenerateOopMapbAmake_context_uninitialized6M_v_; +text: .text%__1cOGenerateOopMapTmethodsig_to_effect6MpnNsymbolOopDesc_ipnNCellTypeState__i_; +text: .text%__1cOGenerateOopMapPinitialize_vars6M_v_; +text: .text%__1cOGenerateOopMapTmerge_state_into_bb6MpnKBasicBlock__v_; +text: .text%__1cOGenerateOopMapKcopy_state6MpnNCellTypeState_2_v_; +text: .text%__1cOGenerateOopMapKinterp_all6M_v_; +text: .text%__1cOGenerateOopMapJinterp_bb6MpnKBasicBlock__v_; +text: .text%__1cOGenerateOopMapNrestore_state6MpnKBasicBlock__v_; +text: .text%__1cOGenerateOopMapQnext_bb_start_pc6MpnKBasicBlock__i_; +text: .text%__1cOGenerateOopMapHinterp16MpnOBytecodeStream__v_; +text: .text%__1cOGenerateOopMapGppload6MpnNCellTypeState_i_v_; +text: .text%__1cOGenerateOopMapHget_var6Mi_nNCellTypeState__; +text: .text%__1cOGenerateOopMapEpush6MnNCellTypeState__v_; +text: .text%__1cOGenerateOopMapIdo_field6Miiii_v_; +text: .text%__1cOGenerateOopMapRsigchar_to_effect6McipnNCellTypeState__2_; +text: .text%__1cOGenerateOopMapCpp6MpnNCellTypeState_2_v_; +text: .text%__1cOGenerateOopMapEppop6MpnNCellTypeState__v_; +text: .text%__1cOGenerateOopMapFppop16MnNCellTypeState__v_; +text: .text%__1cOGenerateOopMapDpop6M_nNCellTypeState__; +text: .text%__1cOGenerateOopMapKcheck_type6MnNCellTypeState_1_v_; +text: .text%__1cOGenerateOopMapFppush6MpnNCellTypeState__v_; +text: .text%__1cOGenerateOopMapGppush16MnNCellTypeState__v_; +text: .text%__1cOGenerateOopMapHppstore6MpnNCellTypeState_i_v_; +text: .text%__1cOGenerateOopMapHset_var6MinNCellTypeState__v_; +text: .text%__1cOGenerateOopMapLmerge_state6Fp0ipi_v_; +text: .text%__1cOGenerateOopMapJdo_astore6Mi_v_; +text: .text%__1cOGenerateOopMapTmerge_state_vectors6MpnNCellTypeState_2_i_; +text: .text%__1cNCellTypeStateFmerge6kM0i_0_; +text: .text%__1cOGenerateOopMapIcopy_cts6MpnNCellTypeState_2_i_; +text: .text%__1cOGenerateOopMapXdo_return_monitor_check6M_v_; +text: .text%__1cOGenerateOopMapYrewrite_refval_conflicts6M_v_; +text: .text%__1cSciGenerateLocalMapOreport_results6kM_i_: ciOopMap.o; +text: .text%__1cOGenerateOopMapNreport_result6M_v_; +text: .text%__1cSciGenerateLocalMapUfill_stackmap_prolog6Mi_v_; +text: .text%__1cSciGenerateLocalMapZfill_stackmap_for_opcodes6MpnOBytecodeStream_pnNCellTypeState_4i_v_; +text: .text%__1cKciLocalMap2t6MpnFArena_iii_v_; +text: .text%__1cKciLocalMapRset_bci_for_index6Mii_v_; +text: .text%__1cSciGenerateLocalMapUfill_stackmap_epilog6M_v_: ciOopMap.o; +text: .text%__1cSciGenerateLocalMapOfill_init_vars6MpnNGrowableArray4Ci___v_; +text: .text%__1cKciLocalMapSset_nof_initialize6Mi_v_; +text: .text%__1cLCompilationJbuild_hir6M_v_; +text: .text%__1cCIR2t6MpnLCompilation_pnIciMethod_i_v_; +text: .text%__1cJValueTypeKinitialize6F_v_; +text: .text%__1cMciNullObjectEmake6F_p0_; +text: .text%__1cMGraphBuilderKinitialize6F_v_; +text: .text%__1cHIRScope2t6MpnLCompilation_p0ipnIciMethod_ii_v_; +text: .text%__1cOLocalSlotArray2t6MkikpnJLocalSlot__v_: c1_IR.o; +text: .text%__1cGBitMap2t6MI_v_; +text: .text%__1cGBitMapGresize6MI_v_; +text: .text%__1cNWordSizeArray2t6Mki1_v_: c1_IR.o; +text: .text%__1cJXHandlers2t6MpnIciMethod__v_; +text: .text%__1cIciMethodJload_code6M_v_; +text: .text%__1cIciMethodVhas_balanced_monitors6M_i_; +text: .text%__1cHIRScopeLbuild_graph6MpnLCompilation_i_pnKBlockBegin__; +text: .text%__1cQBlockListBuilder2t6MpnHIRScope_ii_v_; +text: .text%__1cPBlockBeginArray2t6MkikpnKBlockBegin__v_: c1_GraphBuilder.o; +text: .text%__1cQBlockListBuilderLset_leaders6M_v_; +text: .text%__1cQciBytecodeStream2t6MpnIciMethod__v_; +text: .text%__1cQciBytecodeStreamMset_interval6Mii_v_; +text: .text%__1cQBlockListBuilderMnew_block_at6MinKBlockBeginEFlag__p1_; +text: .text%__1cQBlockListBuilderUset_xhandler_entries6M_v_; +text: .text%__1cKValueStack2t6MpnHIRScope_ii_v_; +text: .text%__1cKValueArray2t6MkikpnLInstruction__v_: c1_ValueStack.o; +text: .text%__1cJLocalSlot2t6M_v_; +text: .text%__1cJLocalSlotIfor_type6MpnJValueType_ii_pnFLocal__: c1_IR.o; +text: .text%__1cKObjectTypeDtag6kM_nIValueTag__: c1_ValueType.o; +text: .text%__1cMGraphBuilder2t6MpnLCompilation_pnHIRScope_pnJBlockList_pnKBlockBegin__v_; +text: .text%__1cMGraphBuilderPpush_root_scope6MpnHIRScope_pnJBlockList_pnKBlockBegin__v_; +text: .text%__1cMGraphBuilderJScopeData2t6Mp1i_v_; +text: .text%__1cMGraphBuilderJScopeDataJset_scope6MpnHIRScope__v_; +text: .text%__1cMGraphBuilderUpush_exception_scope6M_v_; +text: .text%__1cOExceptionScope2t6M_v_; +text: .text%__1cOExceptionScopeEinit6M_v_; +text: .text%__1cIValueMap2t6M_v_; +text: .text%__1cMGraphBuilderJScopeDataQadd_to_work_list6MpnKBlockBegin__v_; +text: .text%__1cNResourceArrayGexpand6MIiri_v_; +text: .text%__1cMGraphBuilderSiterate_all_blocks6Mi_v_; +text: .text%__1cMGraphBuilderJScopeDataVremove_from_work_list6M_pnKBlockBegin__; +text: .text%__1cMGraphBuilderJScopeDataSis_work_list_empty6kM_i_; +text: .text%__1cMGraphBuilderOconnect_to_end6MpnKBlockBegin__pnIBlockEnd__; +text: .text%__1cIValueMapIkill_all6M_v_; +text: .text%__1cIValueMapRnumber_of_buckets6kM_i_; +text: .text%__1cIValueMapJbucket_at6Mi_pnGBucket__; +text: .text%__1cGBucketIkill_all6M_v_; +text: .text%__1cKValueStackEcopy6M_p0_; +text: .text%__1cGValuesIpush_all6Mpk0_v_: c1_ValueStack.o; +text: .text%__1cMGraphBuilderbBiterate_bytecodes_for_block6Mi_pnIBlockEnd__; +text: .text%__1cLInstructionLas_BlockEnd6M_pnIBlockEnd__: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderJScopeDataIblock_at6Mi_pnKBlockBegin__; +text: .text%__1cMGraphBuilderKload_local6MpnJValueType_i_v_; +text: .text%__1cJLocalSlotIfor_type6MpnJValueType_ii_pnFLocal__: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderGappend6MpnLInstruction__2_; +text: .text%__1cMGraphBuilderLappend_base6MpnLInstruction__2_; +text: .text%__1cJLoadLocalFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerMdo_LoadLocal6MpnJLoadLocal__v_; +text: .text%__1cIValueMapEfind6MpnLInstruction__2_; +text: .text%__1cLInstructionOas_AccessField6M_pnLAccessField__: c1_GraphBuilder.o; +text: .text%__1cLInstructionLas_UnsafeOp6M_pnIUnsafeOp__: c1_GraphBuilder.o; +text: .text%__1cLInstructionMas_Intrinsic6M_pnJIntrinsic__: c1_GraphBuilder.o; +text: .text%__1cLInstructionEhash6kM_i_: c1_GraphBuilder.o; +text: .text%__1cLInstructionNas_StateSplit6M_pnKStateSplit__: c1_GraphBuilder.o; +text: .text%__1cLInstructionIcan_trap6kM_i_: c1_GraphBuilder.o; +text: .text%__1cKValueStackLclear_store6Mi_v_; +text: .text%__1cKValueStackEpush6MpnJValueType_pnLInstruction__v_: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderMaccess_field6MnJBytecodesECode__v_; +text: .text%__1cQciBytecodeStreamJget_field6kM_pnHciField__; +text: .text%__1cQciBytecodeStreamPget_field_index6kM_i_; +text: .text%__1cFciEnvSget_field_by_index6MpnPciInstanceKlass_i_pnHciField__; +text: .text%__1cFciEnvXget_field_by_index_impl6MpnPciInstanceKlass_i_pnHciField__; +text: .text%__1cPciInstanceKlassLfield_cache6M_pnTciConstantPoolCache__; +text: .text%__1cHciField2t6MpnPciInstanceKlass_i_v_; +text: .text%__1cFciEnvSget_klass_by_index6MpnPciInstanceKlass_iri_pnHciKlass__; +text: .text%__1cFciEnvXget_klass_by_index_impl6MpnPciInstanceKlass_iri_pnHciKlass__; +text: .text%__1cTconstantPoolOopDescSklass_at_if_loaded6FnSconstantPoolHandle_i_pnMklassOopDesc__; +text: .text%__1cPciObjectFactorySget_unloaded_klass6MpnHciKlass_pnIciSymbol_i_2_; +text: .text%__1cPciInstanceKlassGloader6M_pnHoopDesc__; +text: .text%__1cPciInstanceKlassRprotection_domain6M_pnHoopDesc__; +text: .text%__1cHciFieldPinitialize_from6MpnPfieldDescriptor__v_; +text: .text%__1cMas_ValueType6FnJBasicType__pnJValueType__; +text: .text%__1cHciFieldJwill_link6MpnPciInstanceKlass_nJBytecodesECode__i_; +text: .text%__1cMLinkResolverXresolve_klass_no_update6FrnLKlassHandle_nSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cTconstantPoolOopDescbCklass_ref_at_if_loaded_check6FnSconstantPoolHandle_ipnGThread__pnMklassOopDesc__; +text: .text%__1cMGraphBuilderKlock_stack6M_pnKValueStack__; +text: .text%__1cKValueStackKcopy_locks6M_p0_; +text: .text%__1cJLoadFieldFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cNCanonicalizerMdo_LoadField6MpnJLoadField__v_; +text: .text%__1cLAccessFieldOas_AccessField6M_p0_: c1_Instruction.o; +text: .text%__1cJLoadFieldEhash6kM_i_: c1_Instruction.o; +text: .text%__1cJLoadFieldEname6kM_pkc_: c1_Instruction.o; +text: .text%__1cIValueMapNlookup_bucket6Mi_pnGBucket__; +text: .text%__1cGBucketEfind6MpnLInstruction_i_2_; +text: .text%__1cGBucketGappend6MpnLInstruction_i_v_; +text: .text%__1cLInstructionNas_StateSplit6M_pnKStateSplit__: c1_Instruction.o; +text: .text%__1cLInstructionLas_BlockEnd6M_pnIBlockEnd__: c1_Instruction.o; +text: .text%__1cLAccessFieldIcan_trap6kM_i_: c1_Instruction.o; +text: .text%__1cOExceptionScopeEcopy6M_p0_; +text: .text%__1cOExceptionScopeGlength6kM_i_; +text: .text%__1cHIntTypeDtag6kM_nIValueTag__: c1_ValueType.o; +text: .text%__1cMGraphBuilderLstore_local6MpnJValueType_i_v_; +text: .text%__1cKValueStackDpop6MpnJValueType__pnLInstruction__: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderLstore_local6MpnKValueStack_pnLInstruction_pnJValueType_ii_v_; +text: .text%__1cJValueTypeNas_ObjectType6M_pnKObjectType__: c1_ValueType.o; +text: .text%__1cKStoreLocalFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerNdo_StoreLocal6MpnKStoreLocal__v_; +text: .text%__1cKValueStackLstore_local6MpnKStoreLocal_i_v_; +text: .text%__1cKValueStackQpin_stack_locals6Mi_v_; +text: .text%__1cKValueStackNpin_stack_all6MnLInstructionJPinReason__v_; +text: .text%__1cHIntTypeEsize6kM_i_: c1_ValueType.o; +text: .text%__1cMGraphBuilderHif_zero6MpnJValueType_nLInstructionJCondition__v_; +text: .text%__1cIConstantFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cNCanonicalizerLdo_Constant6MpnIConstant__v_; +text: .text%__1cLInstructionOas_AccessField6M_pnLAccessField__: c1_Instruction.o; +text: .text%__1cLInstructionLas_UnsafeOp6M_pnIUnsafeOp__: c1_Instruction.o; +text: .text%__1cLInstructionMas_Intrinsic6M_pnJIntrinsic__: c1_Instruction.o; +text: .text%__1cIConstantEhash6kM_i_; +text: .text%__1cHIntTypeDtag6kM_nIValueTag__: c1_Canonicalizer.o; +text: .text%__1cLIntConstantOas_IntConstant6M_p0_: c1_Canonicalizer.o; +text: .text%__1cIConstantEname6kM_pkc_: c1_Instruction.o; +text: .text%__1cIConstantIcan_trap6kM_i_: c1_Instruction.o; +text: .text%__1cMGraphBuilderHif_node6MpnLInstruction_n0BJCondition_2pnKValueStack__v_; +text: .text%__1cCIf2t6MpnLInstruction_n0BJCondition_i2pnKBlockBegin_5pnKValueStack_i_v_: c1_GraphBuilder.o; +text: .text%__1cCIfFvisit6MpnSInstructionVisitor__v_: c1_Canonicalizer.o; +text: .text%__1cNCanonicalizerFdo_If6MpnCIf__v_; +text: .text%__1cJValueTypeLis_constant6kM_i_: c1_ValueType.o; +text: .text%__1cLInstructionMas_CompareOp6M_pnJCompareOp__: c1_Instruction.o; +text: .text%__1cLInstructionNas_InstanceOf6M_pnKInstanceOf__: c1_Instruction.o; +text: .text%__1cLInstructionOas_AccessField6M_pnLAccessField__: c1_Canonicalizer.o; +text: .text%__1cLInstructionLas_UnsafeOp6M_pnIUnsafeOp__: c1_Canonicalizer.o; +text: .text%__1cLInstructionMas_Intrinsic6M_pnJIntrinsic__: c1_Canonicalizer.o; +text: .text%__1cLInstructionEhash6kM_i_: c1_Canonicalizer.o; +text: .text%__1cKStateSplitNas_StateSplit6M_p0_: c1_Canonicalizer.o; +text: .text%__1cIBlockEndLas_BlockEnd6M_p0_: c1_Canonicalizer.o; +text: .text%__1cLInstructionIcan_trap6kM_i_: c1_Canonicalizer.o; +text: .text%__1cLInstructionJas_Return6M_pnGReturn__: c1_Canonicalizer.o; +text: .text%__1cLInstructionIas_Throw6M_pnFThrow__: c1_Canonicalizer.o; +text: .text%__1cKBlockBeginItry_join6MpnKValueStack__i_; +text: .text%__1cKValueStack2t6Mp0_v_; +text: .text%__1cKValueStackEinit6Mp0_v_; +text: .text%__1cMGraphBuilderNmethod_return6MpnLInstruction__v_; +text: .text%__1cGReturnFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerJdo_Return6MpnGReturn__v_; +text: .text%__1cKStateSplitNas_StateSplit6M_p0_: c1_GraphBuilder.o; +text: .text%__1cIBlockEndLas_BlockEnd6M_p0_: c1_GraphBuilder.o; +text: .text%__1cGReturnJas_Return6M_p0_: c1_GraphBuilder.o; +text: .text%__1cKValueStackbAeliminate_all_scope_stores6Mi_v_; +text: .text%__1cKValueStackQeliminate_stores6Mi_v_; +text: .text%__1cKValueStackMcaller_state6kM_p0_; +text: .text%__1cFciEnvWget_klass_by_name_impl6MpnHciKlass_pnIciSymbol_i_2_; +text: .text%__1cQSystemDictionarybOfind_constrained_instance_or_array_klass6FnMsymbolHandle_nGHandle_pnGThread__pnMklassOopDesc__; +text: .text%__1cHciKlassGloader6M_pnHoopDesc__: ciTypeArrayKlass.o; +text: .text%__1cFciEnvZcheck_klass_accessibility6MpnHciKlass_pnMklassOopDesc__i_; +text: .text%__1cIciObjectMis_obj_array6M_i_: ciInstanceKlass.o; +text: .text%__1cPciInstanceKlassRis_instance_klass6M_i_: ciInstanceKlass.o; +text: .text%__1cKObjectTypeNas_ObjectType6M_p0_: c1_ValueType.o; +text: .text%__1cJValueTypeOas_AddressType6M_pnLAddressType__: c1_ValueType.o; +text: .text%__1cKObjectTypeEsize6kM_i_: c1_ValueType.o; +text: .text%__1cMGraphBuilderHif_same6MpnJValueType_nLInstructionJCondition__v_; +text: .text%__1cJValueTypeOas_IntConstant6M_pnLIntConstant__: c1_ValueType.o; +text: .text%__1cKStoreFieldFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerNdo_StoreField6MpnKStoreField__v_; +text: .text%__1cLAccessFieldOas_AccessField6M_p0_: c1_GraphBuilder.o; +text: .text%__1cLAccessFieldIcan_trap6kM_i_: c1_GraphBuilder.o; +text: .text%__1cIValueMapKkill_field6MpnHciField__v_; +text: .text%__1cGBucketKkill_field6MpnHciField__v_; +text: .text%__1cKValueStackQpin_stack_fields6MpnHciField__v_; +text: .text%__1cKValueStackVis_same_across_scopes6Mp0_i_; +text: .text%__1cMGraphBuilderNarithmetic_op6MpnJValueType_nJBytecodesECode_pnKValueStack__v_; +text: .text%__1cJValueTypeEmeet6kMp0_1_; +text: .text%__1cHIntTypeEbase6kM_pnJValueType__: c1_Canonicalizer.o; +text: .text%__1cMArithmeticOpIcan_trap6kM_i_; +text: .text%__1cMArithmeticOpFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cNCanonicalizerPdo_ArithmeticOp6MpnMArithmeticOp__v_; +text: .text%__1cNCanonicalizerGdo_Op26MpnDOp2__v_; +text: .text%__1cLIntConstantLis_constant6kM_i_: c1_Canonicalizer.o; +text: .text%__1cNCanonicalizerTmove_const_to_right6MpnDOp2__v_; +text: .text%__1cMArithmeticOpOis_commutative6kM_i_; +text: .text%__1cMArithmeticOpEhash6kM_i_: c1_Instruction.o; +text: .text%__1cMArithmeticOpEname6kM_pkc_: c1_Instruction.o; +text: .text%__1cMGraphBuilderJincrement6M_v_; +text: .text%__1cHIntTypeEbase6kM_pnJValueType__: c1_ValueType.o; +text: .text%__1cMGraphBuilderMload_indexed6MnJBasicType__v_; +text: .text%__1cLLoadIndexedFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cNCanonicalizerOdo_LoadIndexed6MpnLLoadIndexed__v_; +text: .text%__1cLLoadIndexedEhash6kM_i_: c1_Instruction.o; +text: .text%__1cLLoadIndexedEname6kM_pkc_: c1_Instruction.o; +text: .text%__1cLAccessArrayIcan_trap6kM_i_: c1_Instruction.o; +text: .text%__1cIConstantIis_equal6kMpnLInstruction__i_; +text: .text%__1cIConstantLas_Constant6M_p0_: c1_Instruction.o; +text: .text%__1cEGotoFvisit6MpnSInstructionVisitor__v_: c1_Canonicalizer.o; +text: .text%__1cNCanonicalizerHdo_Goto6MpnEGoto__v_; +text: .text%__1cHIRScopeMheader_block6MpnKBlockBegin_n0BEFlag__2_; +text: .text%__1cCIRIoptimize6M_v_; +text: .text%__1cJOptimizer2t6MpnCIR__v_; +text: .text%__1cJOptimizerbHeliminate_conditional_expressions6M_v_; +text: .text%__1cCIRQiterate_preorder6MpnMBlockClosure__v_; +text: .text%__1cKBlockBeginQiterate_preorder6MpnMBlockClosure__v_; +text: .text%__1cJboolArray2t6Mki1_v_: c1_Instruction.o; +text: .text%__1cKBlockBeginQiterate_preorder6MrnJboolArray_pnMBlockClosure__v_; +text: .text%__1cNCE_EliminatorIblock_do6MpnKBlockBegin__v_: c1_Optimizer.o; +text: .text%__1cLInstructionFas_If6M_pnCIf__: c1_IR.o; +text: .text%__1cLInstructionFas_If6M_pnCIf__: c1_Canonicalizer.o; +text: .text%__1cCIfFas_If6M_p0_: c1_Canonicalizer.o; +text: .text%__1cHIntTypeKas_IntType6M_p0_: c1_ValueType.o; +text: .text%__1cNCE_EliminatorRsimple_value_copy6MpnLInstruction__2_: c1_Optimizer.o; +text: .text%__1cLInstructionLas_Constant6M_pnIConstant__: c1_GraphBuilder.o; +text: .text%__1cJLoadLocalMas_LoadLocal6M_p0_: c1_GraphBuilder.o; +text: .text%__1cLInstructionHas_Goto6M_pnEGoto__: c1_GraphBuilder.o; +text: .text%__1cLInstructionFas_If6M_pnCIf__: c1_GraphBuilder.o; +text: .text%__1cJOptimizerQeliminate_blocks6M_v_; +text: .text%__1cUGenericGrowableArray2t6MiipnEGrET_i_v_; +text: .text%__1cSPredecessorCounterIblock_do6MpnKBlockBegin__v_: c1_Optimizer.o; +text: .text%__1cLBlockMergerIblock_do6MpnKBlockBegin__v_: c1_Optimizer.o; +text: .text%__1cLBlockMergerJtry_merge6MpnKBlockBegin__i_: c1_Optimizer.o; +text: .text%__1cLInstructionHas_Goto6M_pnEGoto__: c1_IR.o; +text: .text%__1cEGotoHas_Goto6M_p0_: c1_Canonicalizer.o; +text: .text%__1cLInstructionHas_Goto6M_pnEGoto__: c1_Canonicalizer.o; +text: .text%__1cJOptimizerVeliminate_null_checks6M_v_; +text: .text%__1cGBitMapFclear6M_v_; +text: .text%__1cGBitMapUclear_range_of_words6MII_v_: bitMap.o; +text: .text%__1cNValueSetArray2t6MkikpnIValueSet__v_: c1_Optimizer.o; +text: .text%__1cTNullCheckEliminatorHiterate6MpnKBlockBegin__v_; +text: .text%__1cTNullCheckEliminatorLiterate_all6M_v_; +text: .text%__1cTNullCheckEliminatorLiterate_one6MpnKBlockBegin__v_; +text: .text%__1cJLocalSlotIfor_type6MpnJValueType_ii_pnFLocal__: c1_Optimizer.o; +text: .text%__1cGBitMapIset_from6M0_v_; +text: .text%__1cKStateSplitPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cKBlockBeginFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorNdo_BlockBegin6MpnKBlockBegin__v_; +text: .text%__1cKStateSplitPinput_values_do6MpFppnLInstruction__v_v_: c1_IR.o; +text: .text%__1cEBaseFvisit6MpnSInstructionVisitor__v_: c1_IR.o; +text: .text%__1cQNullCheckVisitorHdo_Base6MpnEBase__v_; +text: .text%__1cTNullCheckEliminatorPmerge_state_for6MpnKBlockBegin_pnKValueStack_pnIValueSet__i_; +text: .text%__1cPBlockBeginArrayIindex_of6kMkpnKBlockBegin__i_: c1_Optimizer.o; +text: .text%__1cKStateSplitPinput_values_do6MpFppnLInstruction__v_v_: c1_Canonicalizer.o; +text: .text%__1cQNullCheckVisitorHdo_Goto6MpnEGoto__v_; +text: .text%__1cLInstructionMas_NullCheck6M_pnJNullCheck__: c1_GraphBuilder.o; +text: .text%__1cLInstructionMas_NullCheck6M_pnJNullCheck__: c1_Instruction.o; +text: .text%__1cKStoreLocalPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cTNullCheckEliminatorIdo_value6FppnLInstruction__v_; +text: .text%__1cFLocalPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cFLocalFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorIdo_Local6MpnFLocal__v_; +text: .text%__1cLAccessFieldPinput_values_do6MpFppnLInstruction__v_v_: c1_Instruction.o; +text: .text%__1cLAccessLocalPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorMdo_LoadLocal6MpnJLoadLocal__v_; +text: .text%__1cTNullCheckEliminatorQhandle_LoadLocal6MpnJLoadLocal__v_; +text: .text%__1cQNullCheckVisitorMdo_LoadField6MpnJLoadField__v_; +text: .text%__1cTNullCheckEliminatorShandle_AccessField6MpnLAccessField__v_; +text: .text%__1cQNullCheckVisitorNdo_StoreLocal6MpnKStoreLocal__v_; +text: .text%__1cTNullCheckEliminatorRhandle_StoreLocal6MpnKStoreLocal__v_; +text: .text%__1cCIfPinput_values_do6MpFppnLInstruction__v_v_: c1_Canonicalizer.o; +text: .text%__1cIConstantPinput_values_do6MpFppnLInstruction__v_v_: c1_Instruction.o; +text: .text%__1cQNullCheckVisitorLdo_Constant6MpnIConstant__v_; +text: .text%__1cQNullCheckVisitorFdo_If6MpnCIf__v_; +text: .text%__1cDOp2Pinput_values_do6MpFppnLInstruction__v_v_: c1_Instruction.o; +text: .text%__1cQNullCheckVisitorPdo_ArithmeticOp6MpnMArithmeticOp__v_; +text: .text%__1cNAccessIndexedPinput_values_do6MpFppnLInstruction__v_v_: c1_Instruction.o; +text: .text%__1cQNullCheckVisitorOdo_LoadIndexed6MpnLLoadIndexed__v_; +text: .text%__1cTNullCheckEliminatorShandle_LoadIndexed6MpnLLoadIndexed__v_; +text: .text%__1cGBitMapbCset_intersection_with_result6M0_i_; +text: .text%__1cKStoreFieldPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorNdo_StoreField6MpnKStoreField__v_; +text: .text%__1cGReturnPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorJdo_Return6MpnGReturn__v_; +text: .text%__1cJboolArray2t6Mki1_v_: c1_Optimizer.o; +text: .text%__1cCIRTcompute_locals_size6M_v_; +text: .text%__1cHIRScopePallocate_locals6MipnMWordSizeList__i_; +text: .text%__1cHIRScopeGlocals6M_pnJLocalList__; +text: .text%__1cJLocalSlotOcollect_locals6MpnJLocalList__v_; +text: .text%__1cHIRScopePargument_locals6M_pnJLocalList__; +text: .text%__1cJLocalSlotXcollect_argument_locals6MpnJLocalList__v_; +text: .text%__1cCIRTallocate_local_name6M_i_; +text: .text%__1cMWordSizeListEgrow6Mki1_v_: c1_IR.o; +text: .text%__1cCIRSnotice_used_offset6Mi_v_; +text: .text%__1cCIRNcompute_loops6M_v_; +text: .text%__1cIciMethodJhas_loops6kM_i_; +text: .text%__1cNmethodOopDescWcompute_has_loops_flag6M_i_; +text: .text%__1cOBytecodeStreamEnext6M_nJBytecodesECode__: methodOop.o; +text: .text%__1cKLoopFinder2t6MpnCIR_i_v_; +text: .text%__1cSBlockLoopInfoArray2t6MkikpnNBlockLoopInfo__v_: c1_Loops.o; +text: .text%__1cKLoopFinderNcompute_loops6Mi_pnILoopList__; +text: .text%__1cJboolArray2t6Mki1_v_: c1_Loops.o; +text: .text%__1cKLoopFinderScompute_dominators6MpnJboolArray__v_; +text: .text%__1cGBitMapGat_put6MIi_v_; +text: .text%__1cRCreateInfoClosureIblock_do6MpnKBlockBegin__v_: c1_Loops.o; +text: .text%__1cNBlockLoopInfo2t6MpnKBlockBegin_i_v_; +text: .text%__1cPSetPredsClosureIblock_do6MpnKBlockBegin__v_: c1_Loops.o; +text: .text%__1cKLoopFinderSdominator_walk_sux6MpnKBlockBegin_pnJboolArray__v_; +text: .text%__1cGBitMapQset_intersection6M0_v_; +text: .text%__1cGBitMapHis_same6M0_i_; +text: .text%__1cKLoopFinderOfind_backedges6MpnJboolArray__pnILoopList__; +text: .text%__1cELoop2t6MpnKBlockBegin_2_v_: c1_Loops.o; +text: .text%__1cKLoopFinderSgather_loop_blocks6MpnILoopList__v_; +text: .text%__1cPBlockBeginArrayIindex_of6kMkpnKBlockBegin__i_: c1_Loops.o; +text: .text%__1cKLoopFinderKfind_loops6MpnILoopList_i_2_; +text: .text%__1cKScanBlocks2t6MpnJBlockList__v_; +text: .text%__1cIintStack2t6M_v_: c1_ScanBlocks.o; +text: .text%__1cKScanBlocksEscan6MpnKScanResult_i_v_; +text: .text%__1cKScanBlocksKscan_block6MpnKBlockBegin_pnKScanResult_i_v_; +text: .text%__1cLIllegalTypeDtag6kM_nIValueTag__: c1_ValueType.o; +text: .text%__1cLInstructionJas_Invoke6M_pnGInvoke__: c1_GraphBuilder.o; +text: .text%__1cLInstructionLas_NewArray6M_pnINewArray__: c1_GraphBuilder.o; +text: .text%__1cLInstructionOas_NewInstance6M_pnLNewInstance__: c1_GraphBuilder.o; +text: .text%__1cLInstructionQas_AccessMonitor6M_pnNAccessMonitor__: c1_GraphBuilder.o; +text: .text%__1cLInstructionOas_AccessLocal6M_pnLAccessLocal__: c1_Instruction.o; +text: .text%__1cLAccessLocalOas_AccessLocal6M_p0_: c1_GraphBuilder.o; +text: .text%__1cLInstructionNas_StoreLocal6M_pnKStoreLocal__: c1_GraphBuilder.o; +text: .text%__1cKStoreLocalNas_StoreLocal6M_p0_: c1_GraphBuilder.o; +text: .text%__1cKScanBlocksRaccumulate_access6MinIValueTag_i_v_; +text: .text%__1cKScanBlocksPincrement_count6MnIValueTag_ii_v_; +text: .text%__1cKScanBlocksJget_array6MnIValueTag__pnIintStack__; +text: .text%__1cIintStackEgrow6Mki1_v_: c1_ScanBlocks.o; +text: .text%__1cKScanBlocksLupdate_type6MinIValueTag__v_; +text: .text%__1cLInstructionJas_Invoke6M_pnGInvoke__: c1_Canonicalizer.o; +text: .text%__1cLInstructionLas_NewArray6M_pnINewArray__: c1_Canonicalizer.o; +text: .text%__1cLInstructionOas_NewInstance6M_pnLNewInstance__: c1_Canonicalizer.o; +text: .text%__1cLInstructionQas_AccessMonitor6M_pnNAccessMonitor__: c1_Canonicalizer.o; +text: .text%__1cJ_LoopListIpush_all6Mpk0_v_: c1_Loops.o; +text: .text%__1cKLoopFinderbEcompute_loop_exits_and_entries6MpnILoopList__v_; +text: .text%__1cKLoopFinderRfind_loop_entries6MpnKBlockBegin_pnELoop__v_; +text: .text%__1cKLoopFinderPfind_loop_exits6MpnKBlockBegin_pnELoop__v_; +text: .text%__1cKLoopFinderbDcompute_single_precision_flag6MpnILoopList__v_; +text: .text%__1cKLoopFinderNinsert_blocks6MpnILoopList__v_; +text: .text%__1cIintArray2t6Mki1_v_: c1_Loops.o; +text: .text%__1cJBlockListPiterate_forward6MpnMBlockClosure__v_; +text: .text%__1cGTaggerIblock_do6MpnKBlockBegin__v_: c1_Loops.o; +text: .text%__1cNPairCollectorIblock_do6MpnKBlockBegin__v_: c1_Loops.o; +text: .text%__1cNResourceArrayEsort6MIpGpkv2_i_v_; +text: .text%__1cRsort_by_block_ids6FppnJBlockPair_2_i_: c1_Loops.o; +text: .text%__1cKLoopFinderUinsert_caching_block6MpnILoopList_pnKBlockBegin_4_4_; +text: .text%__1cLInstructionQas_CachingChange6M_pnNCachingChange__: c1_GraphBuilder.o; +text: .text%__1cKStateSplitFscope6kM_pnHIRScope__; +text: .text%__1cKLoopFinderJnew_block6MpnHIRScope_i_pnKBlockBegin__; +text: .text%__1cIBlockEndOsubstitute_sux6MpnKBlockBegin_2_v_; +text: .text%__1cILoopListMupdate_loops6MpnKBlockBegin_22_v_; +text: .text%__1cELoopSupdate_loop_blocks6MpnKBlockBegin_22_v_; +text: .text%__1cCIRMcompute_code6M_v_; +text: .text%__1cJboolArray2t6Mki1_v_: c1_IR.o; +text: .text%__1cCIRWiterate_and_set_weight6kMrnJboolArray_pnKBlockBegin_pnJBlockList_i_v_; +text: .text%__1cKBlockBeginKset_weight6Mi_v_; +text: .text%__1cLInstructionIas_Throw6M_pnFThrow__: c1_IR.o; +text: .text%__1cLInstructionJas_Return6M_pnGReturn__: c1_IR.o; +text: .text%__1cLInstructionIas_Throw6M_pnFThrow__: c1_GraphBuilder.o; +text: .text%__1cDcmp6FppnKBlockBegin_2_i_: c1_IR.o; +text: .text%__1cUSuxAndWeightAdjusterIblock_do6MpnKBlockBegin__v_: c1_IR.o; +text: .text%__1cJBlockListJblocks_do6MpFpnKBlockBegin__v_v_; +text: .text%__1cQUseCountComputerRcompute_use_count6FpnKBlockBegin__v_: c1_IR.o; +text: .text%__1cQUseCountComputerXbasic_compute_use_count6FpnKBlockBegin__v_: c1_IR.o; +text: .text%__1cQUseCountComputerQupdate_use_count6FppnLInstruction__v_: c1_IR.o; +text: .text%__1cFLocalIas_Local6M_p0_: c1_GraphBuilder.o; +text: .text%__1cKStateSplitPstate_values_do6MpFppnLInstruction__v_v_; +text: .text%__1cKValueStackJvalues_do6MpFppnLInstruction__v_v_; +text: .text%__1cQUseCountComputerPupdated_pinning6FpnKBlockBegin__i_: c1_IR.o; +text: .text%__1cNCachingChangePinput_values_do6MpFppnLInstruction__v_v_: c1_Loops.o; +text: .text%__1cLInstructionLas_BlockEnd6M_pnIBlockEnd__: c1_Loops.o; +text: .text%__1cIBlockEndLas_BlockEnd6M_p0_: c1_IR.o; +text: .text%__1cLCompilationIemit_lir6M_v_; +text: .text%__1cIFrameMap2t6Mi_v_; +text: .text%__1cIFrameMapLFpuStackSim2t6M_v_; +text: .text%__1cLCompilationNinit_framemap6MpnIFrameMap__v_; +text: .text%__1cIFrameMapbCset_local_name_to_offset_map6MpnMWordSizeList__v_; +text: .text%__1cLLIR_Emitter2t6MpnLCompilation__v_; +text: .text%__1cIValueGenOinit_value_gen6F_v_; +text: .text%__1cIRegAlloc2t6M_v_; +text: .text%__1cNc1_AllocTable2t6Mi_v_; +text: .text%__1cIRegAllocFclear6M_v_; +text: .text%__1cNCodeGenerator2t6MpnIValueGen_pnRValueGenInvariant__v_; +text: .text%__1cNCodeGeneratorIblock_do6MpnKBlockBegin__v_; +text: .text%__1cLLIR_EmitterMmust_bailout6kM_i_; +text: .text%__1cNCodeGeneratorPblock_do_prolog6MpnKBlockBegin__v_; +text: .text%__1cIValueGenLstart_block6MpnKBlockBegin__v_; +text: .text%__1cLLIR_EmitterLstart_block6MpnKBlockBegin__v_; +text: .text%__1cILIR_List2t6MpnLCompilation__v_; +text: .text%__1cIValueGenQbind_block_entry6MpnKBlockBegin__v_; +text: .text%__1cLLIR_EmitterQbind_block_entry6MpnKBlockBegin__v_; +text: .text%__1cIValueGenMblock_prolog6MpnKBlockBegin__v_; +text: .text%__1cIValueGenHdo_root6MpnLInstruction__v_; +text: .text%__1cLInstructionGas_Phi6M_pnDPhi__: c1_GraphBuilder.o; +text: .text%__1cIValueGenNdo_BlockBegin6MpnKBlockBegin__v_; +text: .text%__1cQDelayedSpillMark2T6M_v_: c1_CodeGenerator.o; +text: .text%__1cLInstructionGas_Phi6M_pnDPhi__: c1_IR.o; +text: .text%__1cIValueGenHdo_Base6MpnEBase__v_; +text: .text%__1cIValueGenNreceiverRInfo6F_nFRInfo__; +text: .text%__1cIValueGenMicKlassRInfo6F_nFRInfo__; +text: .text%__1cLCompilationNget_init_vars6M_pnIintStack__; +text: .text%__1cLLIR_EmitterJstd_entry6MpnHIRScope_pnIintStack_nFRInfo_5_v_; +text: .text%__1cILIR_ListWunverified_entry_point6MnFRInfo_1_v_: c1_LIREmitter.o; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_LIREmitter.o; +text: .text%__1cLLIR_EmitterGmethod6kM_pnIciMethod__; +text: .text%__1cMCodeEmitInfo2t6MpnLLIR_Emitter_ipnIintStack_pnKValueStack_pnOExceptionScope_pnPRInfoCollection__v_; +text: .text%__1cLCompilationVvalue_stack2lir_stack6MpnKValueStack__pnNGrowableArray4CpnLLIR_OprDesc____; +text: .text%__1cIValueGenMblock_epilog6MpnKBlockBegin__v_; +text: .text%__1cNCodeGeneratorPblock_do_epilog6MpnKBlockBegin__v_; +text: .text%__1cLInstructionGas_Phi6M_pnDPhi__: c1_Canonicalizer.o; +text: .text%__1cIValueGenHdo_Goto6MpnEGoto__v_; +text: .text%__1cIValueGenNset_no_result6MpnLInstruction__v_; +text: .text%__1cIValueGenLmove_to_phi6MpnKValueStack_i_i_; +text: .text%__1cIValueGenWgoto_default_successor6MpnIBlockEnd_pnMCodeEmitInfo__v_; +text: .text%__1cLInstructionGas_Phi6M_pnDPhi__: c1_Instruction.o; +text: .text%__1cIValueGenMdo_LoadField6MpnJLoadField__v_; +text: .text%__1cLAccessFieldKlock_stack6kM_pnKValueStack__: c1_Instruction.o; +text: .text%__1cIValueGenEwalk6MpnLInstruction__v_; +text: .text%__1cIValueGenMdo_LoadLocal6MpnJLoadLocal__v_; +text: .text%__1cIValueGenJload_item6MpnEItem__v_; +text: .text%__1cEItemGupdate6M_v_; +text: .text%__1cIValueGenQset_maynot_spill6MpnEItem__v_; +text: .text%__1cIValueGenSfpu_fanout_handled6MpnEItem__i_; +text: .text%__1cEItemEtype6kM_pnJValueType__: c1_Items.o; +text: .text%__1cIValueGenPlock_free_rinfo6MpnLInstruction_pnJValueType__nFRInfo__; +text: .text%__1cIRegAllocMhas_free_reg6kMpnJValueType__i_; +text: .text%__1cIRegAllocMhas_free_reg6kMnIValueTag__i_; +text: .text%__1cNc1_AllocTableMhas_one_free6kM_i_; +text: .text%__1cIRegAllocNget_lock_temp6MpnLInstruction_pnJValueType__nFRInfo__; +text: .text%__1cIRegAllocMget_free_reg6MpnJValueType__nFRInfo__; +text: .text%__1cIRegAllocMget_free_reg6MnIValueTag__nFRInfo__; +text: .text%__1cNc1_AllocTableIget_free6M_i_; +text: .text%__1cNc1_AllocTablePget_free_helper6Mi_i_; +text: .text%__1cIRegAllocIlock_reg6MpnLInstruction_nFRInfo_i_v_; +text: .text%__1cJRInfo2RegFdo_it6M_v_: c1_RegAlloc.o; +text: .text%__1cHLockRegGdo_cpu6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocOset_locked_cpu6MipnLInstruction_i_v_; +text: .text%__1cNc1_AllocTableKset_locked6Mi_v_; +text: .text%__1cLCompilationIitem2lir6MpknEItem__pnLLIR_OprDesc__; +text: .text%__1cLCompilationKitem2stack6MpknEItem__i_; +text: .text%__1cJValueTypeNas_DoubleType6M_pnKDoubleType__: c1_ValueType.o; +text: .text%__1cMas_BasicType6FpnJValueType__nJBasicType__; +text: .text%__1cJValueTypeMas_ArrayType6M_pnJArrayType__: c1_ValueType.o; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_Compilation.o; +text: .text%__1cLLIR_EmitterEmove6MpnLLIR_OprDesc_nFRInfo__v_; +text: .text%__1cILIR_ListEmove6MpnLLIR_OprDesc_2pnMCodeEmitInfo__v_: c1_LIREmitter.o; +text: .text%__1cIValueGenJitem_free6MpnEItem__v_; +text: .text%__1cIRegAllocPincr_spill_lock6MnFRInfo__v_; +text: .text%__1cQChangeSpillCountGdo_cpu6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIValueGenFrfree6MpnEItem__v_; +text: .text%__1cIRegAllocPdecr_spill_lock6MnFRInfo__v_; +text: .text%__1cIRegAllocIfree_reg6MnFRInfo__v_; +text: .text%__1cHFreeRegGdo_cpu6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocMset_free_cpu6Mi_v_; +text: .text%__1cNc1_AllocTableIset_free6Mi_v_; +text: .text%__1cIValueGenWrlock_result_with_hint6MpnLInstruction_pknEItem__nFRInfo__; +text: .text%__1cIValueGenFrlock6MpnLInstruction_pknEItem__nFRInfo__; +text: .text%__1cIRegAllocMget_lock_reg6MpnLInstruction_pnJValueType__nFRInfo__; +text: .text%__1cLLIR_EmitterKfield_load6MnFRInfo_pnHciField_pnLLIR_OprDesc_iiipnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListMload_mem_reg6MnFRInfo_i1nJBasicType_pnMCodeEmitInfo_nHLIR_Op1NLIR_PatchCode__v_; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_LIR.o; +text: .text%__1cIRegAllocHset_reg6MnFRInfo_ipnLInstruction__v_; +text: .text%__1cGSetRegGdo_cpu6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocLset_cpu_reg6MiipnLInstruction__v_; +text: .text%__1cIValueGenNdo_StoreLocal6MpnKStoreLocal__v_; +text: .text%__1cEItemRhandle_float_kind6M_v_; +text: .text%__1cEItemNset_from_item6Mpk0_v_: c1_Items.o; +text: .text%__1cIValueGenXcan_inline_any_constant6kM_i_; +text: .text%__1cIValueGenSmust_copy_register6MpnEItem__i_; +text: .text%__1cIValueGenUcheck_float_register6MpnEItem__v_; +text: .text%__1cIRegAllocLis_free_reg6kMnFRInfo__i_; +text: .text%__1cJIsFreeRegGdo_cpu6Mi_v_: c1_RegAlloc.o; +text: .text%__1cNc1_AllocTableHis_free6kMi_i_; +text: .text%__1cLLIR_EmitterJopr2local6MipnLLIR_OprDesc__v_; +text: .text%__1cILIR_ListQreg2single_stack6MnFRInfo_inJBasicType__v_: c1_LIREmitter.o; +text: .text%__1cIValueGenFdo_If6MpnCIf__v_; +text: .text%__1cIHintItemNset_from_item6MpknEItem__v_; +text: .text%__1cIHintItemEtype6kM_pnJValueType__: c1_Items.o; +text: .text%__1cJValueTypeMas_FloatType6M_pnJFloatType__: c1_ValueType.o; +text: .text%__1cIValueGenLdo_Constant6MpnIConstant__v_; +text: .text%__1cJValueTypeRas_ObjectConstant6M_pnOObjectConstant__: c1_Canonicalizer.o; +text: .text%__1cIValueGenOdont_load_item6MpnEItem__v_; +text: .text%__1cIValueGenWdont_load_item_nocheck6MpnEItem__v_; +text: .text%__1cLLIR_OprFactKvalue_type6FpnJValueType__pnLLIR_OprDesc__; +text: .text%__1cLLIR_EmitterFif_op6MinLInstructionJCondition_pnLLIR_OprDesc_4pnKBlockBegin_66pnMCodeEmitInfo__v_; +text: .text%__1cJLIR_ConstEtype6kM_nJBasicType__: c1_CacheLocals.o; +text: .text%__1cJLIR_ConstLas_constant6M_p0_: c1_CacheLocals.o; +text: .text%__1cLLIR_EmitterIlir_cond6MnLInstructionJCondition__nMLIR_OpBranchNLIR_Condition__; +text: .text%__1cILIR_ListDcmp6MnMLIR_OpBranchNLIR_Condition_pnLLIR_OprDesc_4pnMCodeEmitInfo__v_: c1_LIREmitter.o; +text: .text%__1cILIR_ListGbranch6MnMLIR_OpBranchNLIR_Condition_pnKBlockBegin__v_; +text: .text%__1cMLIR_OpBranch2t6Mn0ANLIR_Condition_pnKBlockBegin_pnMCodeEmitInfo__v_; +text: .text%__1cEItemEtype6kM_pnJValueType__: c1_CodeGenerator.o; +text: .text%__1cJArrayTypeMas_ArrayType6M_p0_: c1_ValueType.o; +text: .text%__1cLLIR_EmitterHopr2int6MpnLLIR_OprDesc__i_; +text: .text%__1cILIR_ListJint2stack6Mii_v_: c1_LIREmitter.o; +text: .text%__1cLInstructionGas_Phi6M_pnDPhi__: c1_Loops.o; +text: .text%__1cNCachingChangeFvisit6MpnSInstructionVisitor__v_: c1_Loops.o; +text: .text%__1cIValueGenQdo_CachingChange6MpnNCachingChange__v_; +text: .text%__1cIValueGenPdo_ArithmeticOp6MpnMArithmeticOp__v_; +text: .text%__1cIValueGenTdo_ArithmeticOp_Int6MpnMArithmeticOp__v_; +text: .text%__1cIValueGenOload_item_hint6MpnEItem_pk1_v_; +text: .text%__1cEItemRget_jint_constant6kM_i_; +text: .text%__1cLLIR_EmitterRarithmetic_op_int6MnJBytecodesECode_pnLLIR_OprDesc_44nFRInfo__v_; +text: .text%__1cLLIR_EmitterNarithmetic_op6MnJBytecodesECode_pnLLIR_OprDesc_44inFRInfo_pnMCodeEmitInfo__v_; +text: .text%__1cLLIR_EmitterYstrength_reduce_multiply6MpnLLIR_OprDesc_i22_i_; +text: .text%__1cILIR_ListHreg2reg6MnFRInfo_1nJBasicType__v_: c1_LIREmitter_x86.o; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_LIREmitter_x86.o; +text: .text%__1cLlog2_intptr6Fi_i_: c1_LIREmitter_x86.o; +text: .text%__1cILIR_ListKshift_left6MpnLLIR_OprDesc_222_v_; +text: .text%__1cILIR_ListDsub6MpnLLIR_OprDesc_22pnMCodeEmitInfo__v_: c1_LIREmitter_x86.o; +text: .text%__1cIValueGenWcan_inline_as_constant6MpnEItem__i_; +text: .text%__1cIRegAllocPget_register_rc6kMnFRInfo__i_; +text: .text%__1cLGetRefCountGdo_cpu6Mi_v_: c1_RegAlloc.o; +text: .text%__1cILIR_ListHreg2reg6MnFRInfo_1nJBasicType__v_: c1_LIREmitter.o; +text: .text%__1cILIR_ListDadd6MpnLLIR_OprDesc_22_v_: c1_LIREmitter.o; +text: .text%__1cIValueGenOdo_LoadIndexed6MpnLLoadIndexed__v_; +text: .text%__1cJValueTypeLas_LongType6M_pnILongType__: c1_ValueType.o; +text: .text%__1cLAccessArrayKlock_stack6kM_pnKValueStack__: c1_Instruction.o; +text: .text%__1cMCodeEmitInfoVfill_expression_stack6M_v_; +text: .text%__1cLLIR_EmitterRarray_range_check6MpnLLIR_OprDesc_2pnMCodeEmitInfo_4_v_; +text: .text%__1cORangeCheckStub2t6MpnMCodeEmitInfo_nFRInfo_ii_v_; +text: .text%__1cMCodeEmitInfo2t6Mp0i_v_; +text: .text%__1cLLIR_EmitterLcmp_reg_mem6MnMLIR_OpBranchNLIR_Condition_nFRInfo_3inJBasicType_pnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListLcmp_reg_mem6MnMLIR_OpBranchNLIR_Condition_nFRInfo_pnLLIR_Address_nJBasicType_pnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListGbranch6MnMLIR_OpBranchNLIR_Condition_pnICodeStub__v_; +text: .text%__1cMLIR_OpBranch2t6Mn0ANLIR_Condition_pnICodeStub_pnMCodeEmitInfo__v_; +text: .text%__1cLLIR_EmitterMindexed_load6MnFRInfo_nJBasicType_pnLLIR_OprDesc_4pnMCodeEmitInfo__v_; +text: .text%__1cLLIR_EmitterNarray_address6MpnLLIR_OprDesc_2inJBasicType__pnLLIR_Address__; +text: .text%__1cLLIR_AddressFscale6FnJBasicType__n0AFScale__; +text: .text%__1cILIR_ListEmove6MpnLLIR_Address_pnLLIR_OprDesc_pnMCodeEmitInfo__v_: c1_LIREmitter_x86.o; +text: .text%__1cIRegAllocNoops_in_spill6kM_pnIintStack__; +text: .text%__1cIRegAllocRoops_in_registers6kM_pnPRInfoCollection__; +text: .text%__1cIValueGenbDsafepoint_poll_needs_register6F_i_; +text: .text%__1cILIR_ListJsafepoint6MnFRInfo_pnMCodeEmitInfo__v_: c1_CodeGenerator.o; +text: .text%__1cLLIR_EmitterHgoto_op6MpnKBlockBegin_pnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListEjump6MpnKBlockBegin_pnMCodeEmitInfo__v_; +text: .text%__1cIValueGenNdo_StoreField6MpnKStoreField__v_; +text: .text%__1cIValueGenOscratch1_RInfo6kM_nFRInfo__; +text: .text%__1cIValueGenUprefer_alu_registers6kM_i_; +text: .text%__1cLLIR_EmitterLfield_store6MpnHciField_pnLLIR_OprDesc_i4iipnMCodeEmitInfo_nFRInfo__v_; +text: .text%__1cILIR_ListNstore_mem_reg6MnFRInfo_1inJBasicType_pnMCodeEmitInfo_nHLIR_Op1NLIR_PatchCode__v_; +text: .text%__1cIValueGenJdo_Return6MpnGReturn__v_; +text: .text%__1cJValueTypeLas_VoidType6M_pnIVoidType__: c1_ValueType.o; +text: .text%__1cIValueGenTresult_register_for6FpnJValueType_i_nFRInfo__; +text: .text%__1cIValueGenMreturn1RInfo6F_nFRInfo__; +text: .text%__1cIValueGenPload_item_force6MpnEItem_nFRInfo__v_; +text: .text%__1cIValueGenPlock_spill_temp6MpnLInstruction_nFRInfo__v_; +text: .text%__1cIRegAllocJlock_temp6MpnLInstruction_nFRInfo__v_; +text: .text%__1cLLIR_EmitterJreturn_op6MpnLLIR_OprDesc__v_; +text: .text%__1cNCodeGeneratorXclear_instruction_items6FpnKBlockBegin__v_; +text: .text%__1cQLIR_LocalCaching2t6MpnCIR__v_; +text: .text%__1cQLIR_LocalCachingQpreferred_locals6MpknIciMethod__pnMLocalMapping__; +text: .text%__1cMLocalMappingQinit_cached_regs6M_v_; +text: .text%__1cPRegisterManager2t6M_v_; +text: .text%__1cMLocalMappingNget_cache_reg6kMi_nFRInfo__; +text: .text%__1cQLIR_LocalCachingVcompute_cached_locals6M_v_; +text: .text%__1cQLIR_LocalCachingMcache_locals6M_v_; +text: .text%__1cLInstructionQas_CachingChange6M_pnNCachingChange__: c1_IR.o; +text: .text%__1cLInstructionQas_CachingChange6M_pnNCachingChange__: c1_Canonicalizer.o; +text: .text%__1cNCachingChangeQas_CachingChange6M_p0_: c1_Loops.o; +text: .text%__1cRBlockListScanInfo2t6MpnJBlockList__v_: c1_CacheLocals.o; +text: .text%__1cOLIR_OprRefList2t6M_v_: c1_CacheLocals.o; +text: .text%__1cRBlockListScanInfoItraverse6MpnKBlockBegin_pnKLIR_OpList__v_: c1_CacheLocals.o; +text: .text%__1cLLIR_OpLabelFvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cHLIR_Op1Fvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cPRegisterManagerElock6MnFRInfo__v_; +text: .text%__1cHLIR_Op2Fvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cMLIR_OpBranchFvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cORangeCheckStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cQLIR_OpVisitStateGappend6MnFRInfo__v_: c1_CodeStubs_x86.o; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_CodeStubs_x86.o; +text: .text%__1cNc1_AllocTableFmerge6Mp0_v_; +text: .text%__1cGLIR_OpFvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cQLIR_LocalCachingXcache_locals_for_blocks6MpnJBlockList_pnPRegisterManager_i_pnMLocalMapping__; +text: .text%__1cLInstructionNas_StateSplit6M_pnKStateSplit__: c1_Loops.o; +text: .text%__1cLInstructionOas_AccessField6M_pnLAccessField__: c1_Loops.o; +text: .text%__1cLInstructionOas_AccessLocal6M_pnLAccessLocal__: c1_Loops.o; +text: .text%__1cKStateSplitNas_StateSplit6M_p0_: c1_IR.o; +text: .text%__1cLInstructionJas_Invoke6M_pnGInvoke__: c1_IR.o; +text: .text%__1cLInstructionLas_NewArray6M_pnINewArray__: c1_IR.o; +text: .text%__1cLInstructionOas_NewInstance6M_pnLNewInstance__: c1_IR.o; +text: .text%__1cLInstructionQas_AccessMonitor6M_pnNAccessMonitor__: c1_IR.o; +text: .text%__1cLInstructionMas_Intrinsic6M_pnJIntrinsic__: c1_IR.o; +text: .text%__1cKScanBlocksQmost_used_locals6M_pnKALocalList__; +text: .text%__1cKScanBlocksMint_count_at6kMi_i_; +text: .text%__1cKScanBlocksIcount_at6kMnIValueTag_i_i_; +text: .text%__1cKScanBlocksJget_array6kMnIValueTag__pknIintStack__; +text: .text%__1cKScanBlocksNlong_count_at6kMi_i_; +text: .text%__1cKScanBlocksMobj_count_at6kMi_i_; +text: .text%__1cKScanBlocksLis_obj_only6kMi_i_; +text: .text%__1cKScanBlocksLis_int_only6kMi_i_; +text: .text%__1cGALocalUsort_by_access_count6Fpp02_i_: c1_ScanBlocks.o; +text: .text%__1cQLIR_LocalCachingPcompute_caching6MpnKALocalList_pnPRegisterManager__pnMLocalMapping__; +text: .text%__1cPRegisterManagerMnum_free_cpu6M_i_; +text: .text%__1cMLocalMappingNget_cache_reg6kMinIValueTag__nFRInfo__; +text: .text%__1cPRegisterManagerMhas_free_reg6MnIValueTag__i_; +text: .text%__1cPRegisterManagerNlock_free_reg6MnIValueTag__nFRInfo__; +text: .text%__1cQLIR_LocalCachingQadd_at_all_names6FpnPRInfoCollection_inFRInfo_pnMWordSizeList__v_; +text: .text%__1cIintStackEgrow6Mki1_v_: c1_CacheLocals.o; +text: .text%__1cMLocalMappingFmerge6Mp0_v_; +text: .text%__1cGALocalNsort_by_index6Fpp02_i_: c1_CacheLocals.o; +text: .text%__1cSLocalMappingSetterIblock_do6MpnKBlockBegin__v_; +text: .text%__1cMLocalMappingEjoin6Mp0_v_; +text: .text%__1cPRegisterManagerLis_free_reg6MnFRInfo__i_; +text: .text%__1cQLIR_LocalCachingYinsert_transition_blocks6M_v_; +text: .text%__1cPBlockTransitionIblock_do6MpnKBlockBegin__v_: c1_CacheLocals.o; +text: .text%__1cGLIR_OpLas_OpBranch6M_pnMLIR_OpBranch__: c1_LIR.o; +text: .text%__1cMLocalMappingPemit_transition6FpnILIR_List_p03pnCIR__v_; +text: .text%__1cCIRThighest_used_offset6kM_i_; +text: .text%__1cILIR_ListQreg2single_stack6MnFRInfo_inJBasicType__v_: c1_CacheLocals.o; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_CacheLocals.o; +text: .text%__1cILIR_ListQsingle_stack2reg6MinFRInfo_nJBasicType__v_; +text: .text%__1cLInstructionQas_CachingChange6M_pnNCachingChange__: c1_Instruction.o; +text: .text%__1cLCompilationbBemit_code_prolog_non_native6MpnIFrameMap__v_; +text: .text%__1cHIRScopeJmax_stack6kM_i_; +text: .text%__1cNLIR_Optimizer2t6MpnCIR__v_; +text: .text%__1cRLIR_PeepholeState2t6M_v_; +text: .text%__1cRLIR_PeepholeStateKinitialize6MpnMLocalMapping__v_; +text: .text%__1cRLIR_PeepholeStateMclear_values6M_v_; +text: .text%__1cOLIR_OprRefList2t6M_v_: c1_LIROptimizer.o; +text: .text%__1cNLIR_OptimizerIoptimize6M_v_; +text: .text%__1cNLIR_OptimizerIoptimize6MpnJBlockList__v_; +text: .text%__1cNLIR_OptimizerIoptimize6MpnKBlockBegin__v_; +text: .text%__1cNLIR_OptimizerMblock_prolog6M_v_; +text: .text%__1cNLIR_OptimizerKprocess_op6M_v_; +text: .text%__1cGLIR_OpGas_Op16M_pnHLIR_Op1__: c1_LIR.o; +text: .text%__1cLLIR_OpLabelKas_OpLabel6M_p0_: c1_LIR.o; +text: .text%__1cRLIR_PeepholeStateVfinish_forward_branch6MpnFLabel__v_; +text: .text%__1cJLabelListIindex_of6kMkpnFLabel__i_: c1_LIROptimizer.o; +text: .text%__1cRLIR_PeepholeStateYset_disable_optimization6Mi_v_; +text: .text%__1cLLIR_OpLabelJemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerMemit_opLabel6MpnLLIR_OpLabel__v_; +text: .text%__1cNLIR_OptimizerFvisit6M_v_: c1_LIROptimizer_x86.o; +text: .text%__1cHLIR_Op0Jemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerIemit_op06MpnHLIR_Op0__v_; +text: .text%__1cHLIR_Op2Jemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerIemit_op26MpnHLIR_Op2__v_; +text: .text%__1cNLIR_OptimizerKhandle_opr6MpnLLIR_OprDesc_nQLIR_OpVisitStateHOprMode__2_; +text: .text%__1cNLIR_OptimizerJis_cached6MpnLLIR_OprDesc__i_; +text: .text%__1cNLIR_OptimizerUrecord_opr_reference6MpnLLIR_OprDesc__v_; +text: .text%__1cRLIR_PeepholeStateUrecord_opr_reference6MpnLLIR_OprDesc__i_; +text: .text%__1cRLIR_PeepholeStateLdefining_op6MpnLLIR_OprDesc__i_; +text: .text%__1cRLIR_PeepholeStateJreg2index6MpnLLIR_OprDesc__i_; +text: .text%__1cIintStackEgrow6Mki1_v_: c1_LIROptimizer.o; +text: .text%__1cNLIR_OptimizerMblock_epilog6M_v_; +text: .text%__1cRLIR_PeepholeStateRis_safe_to_delete6kMi_i_; +text: .text%__1cHLIR_Op1Gas_Op16M_p0_: c1_LIR.o; +text: .text%__1cHLIR_Op1Jemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerIemit_op16MpnHLIR_Op1__v_; +text: .text%__1cNLIR_OptimizerMprocess_move6MpnHLIR_Op1__v_; +text: .text%__1cMLocalMappingNget_cache_reg6kMpnLLIR_OprDesc__2_; +text: .text%__1cRLIR_PeepholeStateTmark_safe_to_delete6Mi_v_; +text: .text%__1cNLIR_OptimizerRreplace_stack_opr6MpnLLIR_OprDesc__2_; +text: .text%__1cNLIR_OptimizerNoptimize_move6MpnHLIR_Op1_rpnLLIR_OprDesc_5_i_; +text: .text%__1cRLIR_PeepholeStatebFequivalent_register_or_constant6MpnLLIR_OprDesc__2_; +text: .text%__1cRLIR_PeepholeStateOequivalent_opr6MpnLLIR_OprDesc__2_; +text: .text%__1cNLIR_OptimizerKmaybe_opto6MpnLLIR_OprDesc_2_2_: c1_LIROptimizer_x86.o; +text: .text%__1cNLIR_OptimizerMis_cache_reg6MpnLLIR_OprDesc__i_; +text: .text%__1cMLocalMappingMis_cache_reg6kMpnLLIR_OprDesc__i_; +text: .text%__1cMLocalMappingMis_cache_reg6kMnFRInfo__i_; +text: .text%__1cRLIR_PeepholeStateSequivalent_address6MpnLLIR_OprDesc__2_; +text: .text%__1cNLIR_OptimizerRresult_substitute6M_v_; +text: .text%__1cNLIR_OptimizerRnext_op_with_code6MnILIR_Code__pnGLIR_Op__; +text: .text%__1cNLIR_OptimizerFop_at6Mi_pnGLIR_Op__; +text: .text%__1cRLIR_PeepholeStateMkill_operand6MpnLLIR_OprDesc_i_v_; +text: .text%__1cRLIR_PeepholeStateQkill_equivalents6MpnLLIR_OprDesc__v_; +text: .text%__1cRLIR_PeepholeStateNkill_register6Mi_v_; +text: .text%__1cRLIR_PeepholeStateSrecord_defining_op6MpnLLIR_OprDesc_i_v_; +text: .text%__1cRLIR_PeepholeStatePset_defining_op6Mii_v_; +text: .text%__1cRLIR_PeepholeStateHdo_move6MpnLLIR_OprDesc_2_v_; +text: .text%__1cLLIR_OprListEgrow6MkikpnLLIR_OprDesc__v_: c1_LIROptimizer.o; +text: .text%__1cLLIR_AddressKas_address6M_p0_: c1_LIR.o; +text: .text%__1cRLIR_PeepholeStateTequivalent_register6MpnLLIR_OprDesc__2_; +text: .text%__1cKLIR_OprPtrLas_constant6M_pnJLIR_Const__: c1_LIR.o; +text: .text%__1cNLIR_OptimizerKallow_opto6M_i_; +text: .text%__1cNLIR_OptimizerLrecord_opto6MpnLLIR_OprDesc_2_2_; +text: .text%__1cLLIR_AddressEtype6kM_nJBasicType__: c1_LIR.o; +text: .text%__1cRLIR_PeepholeStateNincrement_ref6Mi_v_; +text: .text%__1cKLIR_OprPtrKas_address6M_pnLLIR_Address__: c1_CacheLocals.o; +text: .text%__1cMLIR_OpBranchLas_OpBranch6M_p0_: c1_LIR.o; +text: .text%__1cMLIR_OpBranchJemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerNemit_opBranch6MpnMLIR_OpBranch__v_; +text: .text%__1cNLIR_OptimizerQopr_live_on_exit6MpnLLIR_OprDesc__i_; +text: .text%__1cNResourceArrayJremove_at6MIi_v_; +text: .text%__1cRLIR_PeepholeStateLstack2index6MpnLLIR_OprDesc__i_; +text: .text%__1cRLIR_PeepholeStatePkill_stack_slot6Mi_v_; +text: .text%__1cRLIR_PeepholeStatebCequivalent_register_or_stack6MpnLLIR_OprDesc__2_; +text: .text%__1cNLIR_OptimizerKmaybe_opto6MpnLLIR_OprDesc_2_2_: c1_LIROptimizer.o; +text: .text%__1cNLIR_OptimizerLhandle_info6MpnMCodeEmitInfo__v_; +text: .text%__1cMCodeEmitInfoRset_local_mapping6MpnMLocalMapping__v_; +text: .text%__1cNLIR_OptimizerUrecord_register_oops6MpnMCodeEmitInfo__v_; +text: .text%__1cNLIR_OptimizerOemit_code_stub6MpnICodeStub__v_; +text: .text%__1cLCompilationOemit_code_body6MpnLCodeOffsets__i_; +text: .text%__1cNLIR_Assembler2t6MpnLCompilation_pnLCodeOffsets__v_; +text: .text%__1cNConstantTable2t6M_v_; +text: .text%__1cNLIR_AssemblerJemit_code6MpnJBlockList__v_; +text: .text%__1cQCollectConstantsIblock_do6MpnKBlockBegin__v_: c1_LIRAssembler.o; +text: .text%__1cLInstructionLas_Constant6M_pnIConstant__: c1_IR.o; +text: .text%__1cLInstructionLas_Constant6M_pnIConstant__: c1_Canonicalizer.o; +text: .text%__1cLInstructionLas_Constant6M_pnIConstant__: c1_Instruction.o; +text: .text%__1cJValueTypeNas_DoubleType6M_pnKDoubleType__: c1_Canonicalizer.o; +text: .text%__1cJValueTypeMas_FloatType6M_pnJFloatType__: c1_Canonicalizer.o; +text: .text%__1cLInstructionLas_Constant6M_pnIConstant__: c1_Loops.o; +text: .text%__1cNLIR_AssemblerOemit_constants6M_v_; +text: .text%__1cNConstantTableMemit_entries6MpnOMacroAssembler_i_v_; +text: .text%__1cLLIR_CodeGenIblock_do6MpnKBlockBegin__v_; +text: .text%__1cNLIR_AssemblerPcheck_codespace6M_v_; +text: .text%__1cNLIR_AssemblerMemit_opLabel6MpnLLIR_OpLabel__v_; +text: .text%__1cNLIR_AssemblerIemit_op06MpnHLIR_Op0__v_; +text: .text%__1cNLIR_AssemblerIemit_op26MpnHLIR_Op2__v_; +text: .text%__1cNLIR_AssemblerMneeds_icache6kMpnIciMethod__i_; +text: .text%__1cFRInfoLas_register6kM_pnMRegisterImpl__; +text: .text%__1cNLIR_AssemblerMcheck_icache6MpnMRegisterImpl_2_i_; +text: .text%__1cRC1_MacroAssemblerSinline_cache_check6MpnMRegisterImpl_2_v_; +text: .text%__1cRC1_MacroAssemblerOverified_entry6M_v_; +text: .text%__1cNLIR_AssemblerLbuild_frame6M_v_; +text: .text%__1cNLIR_AssemblerbBinitial_frame_size_in_bytes6M_i_; +text: .text%__1cIFrameMapJframesize6kM_i_; +text: .text%__1cRC1_MacroAssemblerLbuild_frame6Mi_v_; +text: .text%__1cRAbstractAssemblerbDgenerate_stack_overflow_check6Mi_v_; +text: .text%__1cOMacroAssemblerWbang_stack_with_offset6Mi_v_: c1_Compiler.o; +text: .text%__1cNLIR_AssemblerVsetup_locals_at_entry6M_v_; +text: .text%__1cIFrameMapYsignature_type_array_for6FpknIciMethod__pnNBasicTypeList__; +text: .text%__1cIFrameMapScalling_convention6FpknIciMethod_pnIintArray__pnRCallingConvention__; +text: .text%__1cIFrameMapScalling_convention6FirknOBasicTypeArray_pnIintArray__pnRCallingConvention__; +text: .text%__1cIintArray2t6Mki1_v_: c1_FrameMap_x86.o; +text: .text%__1cIFrameMapRname_for_argument6Fi_i_; +text: .text%__1cIFrameMapSfp_offset_for_name6kMiii_i_; +text: .text%__1cIFrameMapPnum_local_names6kM_i_; +text: .text%__1cIFrameMapNlocal_to_slot6kMii_i_; +text: .text%__1cIFrameMapSfp_offset_for_slot6kMi_i_; +text: .text%__1cQArgumentLocation2t6Mci_v_: c1_FrameMap_x86.o; +text: .text%__1cQArgumentLocationSset_stack_location6Mi_v_; +text: .text%__1cIFrameMapQaddress_for_name6kMiii_nHAddress__; +text: .text%__1cIFrameMapQmake_new_address6kMi_nHAddress__; +text: .text%__1cNLIR_AssemblerIemit_op16MpnHLIR_Op1__v_; +text: .text%__1cNLIR_AssemblerHmove_op6MpnLLIR_OprDesc_2nJBasicType_nHLIR_Op1NLIR_PatchCode_pnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerHmem2reg6MpnLLIR_Address_nFRInfo_nJBasicType_nHLIR_Op1NLIR_PatchCode_pnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerKas_Address6MpnLLIR_Address__nHAddress__; +text: .text%__1cNLIR_AssemblerHcomp_op6MnMLIR_OpBranchNLIR_Condition_pnLLIR_OprDesc_4nJBasicType__v_; +text: .text%__1cNLIR_AssemblerNemit_opBranch6MpnMLIR_OpBranch__v_; +text: .text%__1cNLIR_AssemblerJreg2stack6MnFRInfo_inJBasicType__v_; +text: .text%__1cNLIR_AssemblerLconst2stack6MpnJLIR_Const_i_v_; +text: .text%__1cNLIR_AssemblerJstack2reg6MpnLLIR_OprDesc_2nJBasicType__v_; +text: .text%__1cNLIR_AssemblerHreg2reg6MnFRInfo_1_v_; +text: .text%__1cNLIR_AssemblerJmove_regs6MpnMRegisterImpl_2_v_; +text: .text%__1cNLIR_AssemblerIshift_op6MnILIR_Code_nFRInfo_i2_v_; +text: .text%__1cNLIR_AssemblerIarith_op6MnILIR_Code_pnLLIR_OprDesc_33pnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerbIadd_debug_info_for_null_check_here6MpnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerLcode_offset6kM_i_; +text: .text%__1cNLIR_AssemblerbDadd_debug_info_for_null_check6MipnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerOemit_code_stub6MpnICodeStub__v_; +text: .text%__1cVImplicitNullCheckStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cNLIR_AssemblerCpc6kM_pC_; +text: .text%__1cICodeStubLset_code_pc6MpC_v_: c1_CodeStubs_x86.o; +text: .text%__1cICodeStubMis_call_stub6kM_i_: c1_CodeStubs_x86.o; +text: .text%__1cNCodeStubArrayIindex_of6kMkpnICodeStub__i_: c1_LIRAssembler.o; +text: .text%__1cORangeCheckStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cNLIR_AssemblerOsafepoint_poll6MnFRInfo_pnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerZadd_debug_info_for_branch6MpnMCodeEmitInfo__v_; +text: .text%__1cPpoll_RelocationEtype6M_nJrelocInfoJrelocType__: codeBlob.o; +text: .text%__1cMCodeEmitInfoRrecord_debug_info6MpnYDebugInformationRecorder_ii_v_; +text: .text%__1cMCodeEmitInfoHoop_map6M_pnGOopMap__; +text: .text%__1cMCodeEmitInfoScompute_debug_info6M_v_; +text: .text%__1cMCodeEmitInfoOcreate_oop_map6M_pnGOopMap__; +text: .text%__1cIFrameMapRoop_map_arg_count6M_i_; +text: .text%__1cMCodeEmitInfoTrecord_spilled_oops6kMpnIFrameMap_pnGOopMap__v_; +text: .text%__1cKciLocalMapNindex_for_bci6kMi_i_; +text: .text%__1cSciLocalMapIteratorJfind_next6M_v_: c1_LIREmitter.o; +text: .text%__1cJLocalSlotIfor_type6MpnJValueType_ii_pnFLocal__: c1_LIREmitter.o; +text: .text%__1cMCodeEmitInfoNget_cache_reg6kMinIValueTag__nFRInfo__; +text: .text%__1cIFrameMapTsingle_word_regname6kMi_nHOptoRegEName__; +text: .text%__1cIFrameMapMfp2sp_offset6kMi_i_; +text: .text%__1cGOopMapHset_oop6MnHOptoRegEName_ii_v_; +text: .text%__1cMCodeEmitInfoVlir_stack2value_stack6MpnNGrowableArray4CpnLLIR_OprDesc____pnNGrowableArray4CpnKScopeValue____; +text: .text%__1cMCodeEmitInfobCcompute_debug_info_for_scope6MpnHIRScope_ipnNGrowableArray4CpnKScopeValue___inGValues_i_pnQIRScopeDebugInfo__; +text: .text%__1cMCodeEmitInfobCscope_value_for_local_offset6MinILocationEType_ppnKScopeValue__4_; +text: .text%__1cMCodeEmitInfobEget_cache_reg_for_local_offset6kMi_nFRInfo__; +text: .text%__1cMLocalMappingbEget_cache_reg_for_local_offset6kMi_nFRInfo__; +text: .text%__1cMCodeEmitInfoZlocation_for_local_offset6MinILocationEType__1_; +text: .text%__1cIFrameMapZlocation_for_local_offset6kMinILocationEType_p1_i_; +text: .text%__1cIFrameMapWlocation_for_fp_offset6kMinILocationEType_p1_i_; +text: .text%__1cILocationVlegal_offset_in_bytes6Fi_i_; +text: .text%__1cMCodeEmitInfoYscope_value_for_register6MnFRInfo_ppnKScopeValue_4nILocationEType__v_; +text: .text%__1cGOopMapJdeep_copy6M_p0_; +text: .text%__1cGOopMap2t6Mn0ANDeepCopyToken_p0_v_; +text: .text%__1cMOopMapStream2t6MpnGOopMap__v_; +text: .text%__1cMOopMapStreamJfind_next6M_v_; +text: .text%__1cUCompressedReadStreamIread_int6M_i_: oopMap.o; +text: .text%__1cYDebugInformationRecorderNadd_safepoint6MiipnGOopMap__v_; +text: .text%__1cYDebugInformationRecorderLcheck_phase6Mn0AFPhase__v_; +text: .text%__1cYDebugInformationRecorderKadd_oopmap6MiipnGOopMap__v_; +text: .text%__1cYDebugInformationRecorderTcreate_scope_values6MpnNGrowableArray4CpnKScopeValue____pnKDebugToken__; +text: .text%__1cYDebugInformationRecorderWserialize_scope_values6MpnNGrowableArray4CpnKScopeValue____i_; +text: .text%__1cVCompressedWriteStreamJwrite_int6Mi_v_: debugInfoRec.o; +text: .text%__1cNLocationValueIwrite_on6MpnUDebugInfoWriteStream__v_; +text: .text%__1cVCompressedWriteStreamJwrite_int6Mi_v_: debugInfo.o; +text: .text%__1cILocationIwrite_on6MpnUDebugInfoWriteStream__v_; +text: .text%__1cVCompressedWriteStreamJwrite_int6Mi_v_: location.o; +text: .text%__1cYDebugInformationRecorderVcreate_monitor_values6MpnNGrowableArray4CpnMMonitorValue____pnKDebugToken__; +text: .text%__1cYDebugInformationRecorderYserialize_monitor_values6MpnNGrowableArray4CpnMMonitorValue____i_; +text: .text%__1cYDebugInformationRecorderOdescribe_scope6MpnIciMethod_ipnKDebugToken_44_v_; +text: .text%__1cYDebugInformationRecorderNappend_handle6MpnI_jobject__i_; +text: .text%__1cLOopRecorderOallocate_index6MpnI_jobject__i_; +text: .text%__1cLCompilationbEadd_exception_handlers_for_pco6MiipnOExceptionScope__v_; +text: .text%__1cNExceptionInfo2t6MiipnOExceptionScope__v_; +text: .text%__1cJAssemblerFtestl6MpnMRegisterImpl_nHAddress__v_; +text: .text%__1cNLIR_AssemblerHreg2mem6MnFRInfo_pnLLIR_Address_nJBasicType_nHLIR_Op1NLIR_PatchCode_pnMCodeEmitInfo__v_; +text: .text%__1cLLIR_OprDescGis_oop6kM_i_; +text: .text%__1cNLIR_AssemblerJreturn_op6MnFRInfo_i_v_; +text: .text%__1cWpoll_return_RelocationEtype6M_nJrelocInfoJrelocType__: codeBlob.o; +text: .text%__1cRC1_MacroAssemblerLmethod_exit6Mi_v_; +text: .text%__1cLCompilationQemit_code_epilog6MpnNLIR_Assembler__v_; +text: .text%__1cNLIR_AssemblerUemit_slow_case_stubs6M_v_; +text: .text%__1cNLIR_AssemblerKemit_stubs6MpnMCodeStubList__v_; +text: .text%__1cVImplicitNullCheckStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cWImplicitExceptionTableGappend6MII_v_; +text: .text%__1cZresource_reallocate_bytes6FpcII_0_; +text: .text%__1cFArenaIArealloc6MpvII_1_; +text: .text%__1cNLIR_AssemblerNadd_call_info6MipnMCodeEmitInfo__v_; +text: .text%__1cOdummy_location6FnIValueTag__pnKScopeValue__: c1_LIREmitter.o; +text: .text%__1cQConstantIntValueIwrite_on6MpnUDebugInfoWriteStream__v_; +text: .text%__1cORangeCheckStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cNLIR_AssemblerWemit_exception_handler6M_i_; +text: .text%__1cRC1_MacroAssemblerRexception_handler6Mii_v_; +text: .text%__1cNLIR_AssemblerPemit_call_stubs6M_v_; +text: .text%__1cNLIR_AssemblerbCmaybe_adjust_stack_alignment6MpnIciMethod__v_; +text: .text%__1cKreal_index6FpnIFrameMap_i_i_: c1_LIRAssembler_x86.o; +text: .text%__1cLCompilationbEgenerate_exception_range_table6M_v_; +text: .text%__1cOExceptionScopeGequals6kMp0_i_; +text: .text%__1cLCompilationbBadd_exception_range_entries6MiipnOExceptionScope_ip2pi_v_; +text: .text%__1cTExceptionRangeTablebCcompute_modified_at_call_pco6Fii_i_; +text: .text%__1cOExceptionScopeMcaller_scope6kM_p0_; +text: .text%__1cLLIR_EmitterKframe_size6M_i_; +text: .text%__1cNLIR_Assembler2T6M_v_; +text: .text%__1cLCompilationMinstall_code6MpnLCodeOffsets_i_v_; +text: .text%__1cFciEnvPregister_method6MpnIciMethod_iiiiiipnKCodeBuffer_ipnJOopMapSet_pnVExceptionHandlerTable_pnWImplicitExceptionTable_pnTExceptionRangeTable_pnQAbstractCompiler_ii_v_; +text: .text%__1cFciEnvbOcheck_for_system_dictionary_modification6MpnIciMethod__v_; +text: .text%__1cFciEnvbUsystem_dictionary_modification_counter_changed6M_i_; +text: .text%__1cHnmethodLnew_nmethod6FnMmethodHandle_iiiiiipnYDebugInformationRecorder_pnKCodeBuffer_ipnJOopMapSet_pnVExceptionHandlerTable_pnWImplicitExceptionTable_pnTExceptionRangeTable_pnQAbstractCompiler__p0_; +text: .text%__1cLOopRecorderIoop_size6M_i_; +text: .text%__1cYDebugInformationRecorderIpcs_size6M_i_; +text: .text%__1cYDebugInformationRecorderJdata_size6M_i_; +text: .text%__1cHnmethod2n6FIi_pv_; +text: .text%__1cHnmethod2t6MpnNmethodOopDesc_iiiiiiipnYDebugInformationRecorder_pnKCodeBuffer_ipnJOopMapSet_pnVExceptionHandlerTable_pnWImplicitExceptionTable_pnTExceptionRangeTable_pnQAbstractCompiler__v_; +text: .text%__1cKRelocationWfix_relocation_at_move6Mi_v_: codeBlob.o; +text: .text%__1cLPcDescCache2t6M_v_; +text: .text%__1cHnmFlagsFclear6M_v_; +text: .text%__1cYDebugInformationRecorderHcopy_to6MpnHnmethod__v_; +text: .text%__1cLOopRecorderHcopy_to6MpnICodeBlob__v_; +text: .text%__1cICodeBlobJcopy_oops6MppnI_jobject_i_v_; +text: .text%__1cIUniverseMnon_oop_word6F_pv_; +text: .text%__1cHnmethodQcopy_scopes_data6MpCi_v_; +text: .text%__1cGPcDesc2t6Miii_v_; +text: .text%__1cHnmethodKcopy_pc_at6MipnGPcDesc__v_; +text: .text%__1cHnmethodSresolve_JNIHandles6M_v_; +text: .text%__1cNRelocIteratorEnext6M_i_: nmethod.o; +text: .text%__1cJCodeCacheGcommit6FpnICodeBlob__v_; +text: .text%__1cHnmethodKis_nmethod6kM_i_: nmethod.o; +text: .text%__1cHnmethodUnumber_of_dependents6kM_i_: nmethod.o; +text: .text%__1cFVTuneOcreate_nmethod6FpnHnmethod__v_; +text: .text%__1cWImplicitExceptionTableHcopy_to6MpnHnmethod__v_; +text: .text%__1cTExceptionRangeTableHcopy_to6MpnHnmethod__v_; +text: .text%__1cKNativeJumpbEcheck_verified_entry_alignment6FpC1_v_; +text: .text%__1cGEventsDlog6FpkcE_v_: nmethod.o; +text: .text%__1cFciEnvKcompile_id6M_I_; +text: .text%__1cNmethodOopDescIset_code6MpnHnmethod__v_; +text: .text%__1cFciEnvbFpost_compiled_method_load_event6MpnHnmethod__v_; +text: .text%__1cLCompilation2T6M_v_; +text: .text%__1cFArena2T6M_v_; +text: .text%__1cFArenaRdestruct_contents6M_v_; +text: .text%__1cICHeapObj2k6Fpv_v_; +text: .text%__1cTExceptionRangeTable2T6M_v_; +text: .text%__1cFciEnvVnum_inlined_bytecodes6kM_i_; +text: .text%__1cMelapsedTimerDadd6M0_v_; +text: .text%__1cFciEnv2T6M_v_; +text: .text%__1cNCompileBrokerUpop_jni_handle_block6F_v_; +text: .text%__1cNCompileBrokerScollect_statistics6FpnOCompilerThread_nMelapsedTimer_pnLCompileTask__v_; +text: .text%__1cHnmethodKtotal_size6kM_i_; +text: .text%__1cHnmethodJcode_size6kM_i_: nmethod.o; +text: .text%__1cHnmethodOexception_size6kM_i_: nmethod.o; +text: .text%__1cHnmethodJstub_size6kM_i_: nmethod.o; +text: .text%__1cHnmethodQscopes_data_size6kM_i_: nmethod.o; +text: .text%__1cHnmethodPscopes_pcs_size6kM_i_: nmethod.o; +text: .text%__1cLAccessFlagsRatomic_clear_bits6Mi_v_; +text: .text%__1cSCompileTaskWrapper2T6M_v_; +text: .text%__1cNCompileBrokerJfree_task6FpnLCompileTask__v_; +text: .text%__1cLCompileTaskEfree6M_v_; +text: .text%__1cKJNIHandlesOdestroy_global6FpnI_jobject_i_v_; +text: .text%__1cNSignatureInfoGdo_int6M_v_: reflection.o; +text: .text%__1cNArgumentCountDset6MinJBasicType__v_: reflection.o; +text: .text%__1cZget_mirror_from_signature6FnMmethodHandle_pnPSignatureStream_pnGThread__pnHoopDesc__; +text: .text%__1cPjava_lang_ClassQprimitive_mirror6FnJBasicType__pnHoopDesc__; +text: .text%__1cNSignatureInfoHdo_long6M_v_: reflection.o; +text: .text%__1cNSignatureInfoJdo_object6Mii_v_: reflection.o; +text: .text%__1cPSignatureStreamJas_symbol6MpnGThread__pnNsymbolOopDesc__; +text: .text%__1cKReflectionbFbasic_type_mirror_to_basic_type6FpnHoopDesc_pnGThread__nJBasicType__; +text: .text%__1cPjava_lang_ClassOprimitive_type6FpnHoopDesc__nJBasicType__; +text: .text%__1cQSystemDictionaryQjava_mirror_type6FpnHoopDesc__nJBasicType__; +text: .text%__1cKReflectionTunbox_for_primitive6FpnHoopDesc_pnGjvalue_pnGThread__nJBasicType__; +text: .text%__1cXjava_lang_boxing_objectJget_value6FpnHoopDesc_pnGjvalue__nJBasicType__; +text: .text%__1cUGenericGrowableArrayGgrow646Mi_v_; +text: .text%__1cRComputeEntryStackGdo_int6M_v_: generateOopMap.o; +text: .text%__1cOGenerateOopMapJppdupswap6Mipkc_v_; +text: .text%__1cOGenerateOopMapJdo_method6Miiii_v_; +text: .text%__1cQComputeCallStackHdo_void6M_v_: generateOopMap.o; +text: .text%__1cQComputeCallStackGdo_int6M_v_: generateOopMap.o; +text: .text%__1cLciSignatureHtype_at6kMi_pnGciType__; +text: .text%__1cLInstructionMas_CompareOp6M_pnJCompareOp__: c1_GraphBuilder.o; +text: .text%__1cLInstructionNas_InstanceOf6M_pnKInstanceOf__: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderMnew_instance6Mi_v_; +text: .text%__1cQciBytecodeStreamJget_klass6kM_pnHciKlass__; +text: .text%__1cQciBytecodeStreamPget_klass_index6kM_i_; +text: .text%__1cVLoaderConstraintTableWfind_constrained_klass6MnMsymbolHandle_nGHandle__pnMklassOopDesc__; +text: .text%__1cIciSymbolHbyte_at6Mi_i_; +text: .text%__1cPciInstanceKlassNloader_handle6M_pnI_jobject__; +text: .text%__1cPciInstanceKlassYprotection_domain_handle6M_pnI_jobject__; +text: .text%__1cGciTypeMis_classless6kM_i_: ciInstanceKlass.o; +text: .text%__1cMGraphBuilderMappend_split6MpnKStateSplit__pnLInstruction__; +text: .text%__1cLNewInstanceFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cNCanonicalizerOdo_NewInstance6MpnLNewInstance__v_; +text: .text%__1cLInstructionEhash6kM_i_: c1_Instruction.o; +text: .text%__1cKStateSplitNas_StateSplit6M_p0_: c1_Instruction.o; +text: .text%__1cLInstructionJas_Invoke6M_pnGInvoke__: c1_Instruction.o; +text: .text%__1cKValueStackMclear_locals6M_v_; +text: .text%__1cKValueStackMclear_stores6M_v_; +text: .text%__1cKValueStackZpin_stack_for_state_split6M_v_; +text: .text%__1cLNewInstanceIcan_trap6kM_i_: c1_Instruction.o; +text: .text%__1cMGraphBuilderIstack_op6MnJBytecodesECode__v_; +text: .text%__1cMGraphBuilderGinvoke6MnJBytecodesECode__v_; +text: .text%__1cQciBytecodeStreamKget_method6kM_pnIciMethod__; +text: .text%__1cQciBytecodeStreamQget_method_index6kM_i_; +text: .text%__1cFciEnvTget_method_by_index6MpnPciInstanceKlass_inJBytecodesECode__pnIciMethod__; +text: .text%__1cFciEnvYget_method_by_index_impl6MpnPciInstanceKlass_inJBytecodesECode__pnIciMethod__; +text: .text%__1cFciEnvbTget_instance_klass_for_declared_method_holder6FpnHciKlass__pnPciInstanceKlass__; +text: .text%__1cPciObjectFactoryTget_unloaded_method6MpnPciInstanceKlass_pnIciSymbol_4_pnIciMethod__; +text: .text%__1cIciMethod2t6MpnPciInstanceKlass_pnIciSymbol_4_v_; +text: .text%__1cNciMethodKlassEmake6F_p0_; +text: .text%__1cIciObjectMis_classless6kM_i_: ciMethod.o; +text: .text%__1cQciBytecodeStreambAget_declared_method_holder6M_pnHciKlass__; +text: .text%__1cQciBytecodeStreamXget_method_holder_index6M_i_; +text: .text%__1cLciSignatureLreturn_type6kM_pnGciType__; +text: .text%__1cKValueStackNpop_arguments6Mi_pnGValues__; +text: .text%__1cGInvoke2t6MnJBytecodesECode_pnJValueType_pnLInstruction_pnGValues_iiii_v_; +text: .text%__1cGInvokeFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cNCanonicalizerJdo_Invoke6MpnGInvoke__v_; +text: .text%__1cGInvokeJas_Invoke6M_p0_: c1_Instruction.o; +text: .text%__1cLInstructionMas_LoadLocal6M_pnJLoadLocal__: c1_Instruction.o; +text: .text%__1cGInvokeIcan_trap6kM_i_: c1_Instruction.o; +text: .text%__1cMGraphBuilderIthrow_op6M_v_; +text: .text%__1cFThrowFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cNCanonicalizerIdo_Throw6MpnFThrow__v_; +text: .text%__1cIBlockEndLas_BlockEnd6M_p0_: c1_Instruction.o; +text: .text%__1cFThrowIcan_trap6kM_i_: c1_Instruction.o; +text: .text%__1cLInstructionJas_Return6M_pnGReturn__: c1_Instruction.o; +text: .text%__1cFThrowIas_Throw6M_p0_: c1_Instruction.o; +text: .text%__1cLInstructionFas_If6M_pnCIf__: c1_Instruction.o; +text: .text%__1cLInstructionHas_Goto6M_pnEGoto__: c1_Instruction.o; +text: .text%__1cKStateSplitPinput_values_do6MpFppnLInstruction__v_v_: c1_Instruction.o; +text: .text%__1cQNullCheckVisitorOdo_NewInstance6MpnLNewInstance__v_; +text: .text%__1cTNullCheckEliminatorShandle_NewInstance6MpnLNewInstance__v_; +text: .text%__1cGInvokePinput_values_do6MpFppnLInstruction__v_v_: c1_Instruction.o; +text: .text%__1cQNullCheckVisitorJdo_Invoke6MpnGInvoke__v_; +text: .text%__1cTNullCheckEliminatorNhandle_Invoke6MpnGInvoke__v_; +text: .text%__1cFThrowPinput_values_do6MpFppnLInstruction__v_v_: c1_Instruction.o; +text: .text%__1cQNullCheckVisitorIdo_Throw6MpnFThrow__v_; +text: .text%__1cPBlockBeginArrayIindex_of6kMkpnKBlockBegin__i_: c1_IR.o; +text: .text%__1cLInstructionGnegate6Fn0AJCondition__1_; +text: .text%__1cFThrowPstate_values_do6MpFppnLInstruction__v_v_; +text: .text%__1cFRInfoIoverlaps6kMk0_i_; +text: .text%__1cIValueGenOdo_NewInstance6MpnLNewInstance__v_; +text: .text%__1cIValueGenVspill_values_on_stack6MpnKValueStack_nFRInfo_i_v_; +text: .text%__1cIRegAllocNlock_register6MpnLInstruction_nFRInfo__v_; +text: .text%__1cHHideReg2t6MpnIValueGen_pnJValueType__v_; +text: .text%__1cHHideReg2T6M_v_; +text: .text%__1cLLIR_EmitterMnew_instance6MnFRInfo_pnPciInstanceKlass_1111pnMCodeEmitInfo__v_; +text: .text%__1cLLIR_EmitterZjobject2reg_with_patching6MnFRInfo_pnIciObject_pnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListNoop2reg_patch6MpnI_jobject_nFRInfo_pnMCodeEmitInfo__v_; +text: .text%__1cPNewInstanceStub2t6MnFRInfo_pnLLIR_OprDesc_pnPciInstanceKlass_pnMCodeEmitInfo_nIRuntime1GStubID__v_; +text: .text%__1cIValueGenJdo_Invoke6MpnGInvoke__v_; +text: .text%__1cIValueGenWinvoke_visit_arguments6MpnGInvoke_pnRCallingConvention__pnJItemArray__; +text: .text%__1cIValueGenNis_free_rinfo6MnFRInfo__i_; +text: .text%__1cGInvokeRsize_of_arguments6kM_i_; +text: .text%__1cLLIR_EmitterVstore_stack_parameter6MpnLLIR_OprDesc_i_v_; +text: .text%__1cILIR_ListFstore6MpnLLIR_OprDesc_pnLLIR_Address_nJBasicType_pnMCodeEmitInfo_nHLIR_Op1NLIR_PatchCode__v_; +text: .text%__1cHHideReg2t6MpnIValueGen_nFRInfo_i_v_; +text: .text%__1cIValueGenVinvoke_load_arguments6MpnGInvoke_pnJItemArray_pnRCallingConvention__v_; +text: .text%__1cIValueGenPinvoke_do_spill6MpnGInvoke_nFRInfo__v_; +text: .text%__1cIValueGenXis_caller_save_register6FnFRInfo__i_; +text: .text%__1cIValueGenLspill_value6MpnLInstruction__v_; +text: .text%__1cIValueGenKspill_item6MpnEItem__v_; +text: .text%__1cIValueGenQround_spill_item6MpnEItem_i_v_; +text: .text%__1cIRegAllocOget_lock_spill6MpnLInstruction_i_i_; +text: .text%__1cIValueGenJraw_rfree6MpnEItem__v_; +text: .text%__1cLLIR_EmitterFspill6MipnLLIR_OprDesc__v_; +text: .text%__1cIFrameMapKspill_name6kMi_i_; +text: .text%__1cIValueGenQinvoke_do_result6MpnGInvoke_ipnEItem__v_; +text: .text%__1cIVoidTypeLas_VoidType6M_p0_: c1_ValueType.o; +text: .text%__1cLCompilationXlir_opr_for_instruction6MpnLInstruction__pnLLIR_OprDesc__; +text: .text%__1cLLIR_EmitterHcall_op6MnJBytecodesECode_pknOBasicTypeArray_pnMCodeEmitInfo_iiinFRInfo_pnLLIR_OprDesc__v_; +text: .text%__1cILIR_ListKnull_check6MnFRInfo_pnMCodeEmitInfo__v_: c1_LIREmitter.o; +text: .text%__1cILIR_ListQcall_opt_virtual6MnFRInfo_pnLLIR_OprDesc_pCpnMCodeEmitInfo_pnOStaticCallStub__v_: c1_LIREmitter.o; +text: .text%__1cIValueGenIdo_Throw6MpnFThrow__v_; +text: .text%__1cLNewInstanceKexact_type6kM_pnGciType__; +text: .text%__1cOExceptionScopeLcould_catch6kMpnPciInstanceKlass_i_i_; +text: .text%__1cIValueGenRexceptionOopRInfo6F_nFRInfo__; +text: .text%__1cIValueGenFsfree6MpnEItem__v_; +text: .text%__1cIRegAllocKfree_spill6MipnJValueType__v_; +text: .text%__1cIRegAllocNis_free_spill6kMipnJValueType__i_; +text: .text%__1cLNewInstanceOas_NewInstance6M_p0_: c1_Instruction.o; +text: .text%__1cIValueGenQexceptionPcRInfo6F_nFRInfo__; +text: .text%__1cILIR_ListPthrow_exception6MnFRInfo_1pnMCodeEmitInfo__v_: c1_CodeGenerator.o; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_CodeGenerator.o; +text: .text%__1cPNewInstanceStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cOLIR_OpJavaCallFvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cQLIR_OpVisitStateGappend6MnFRInfo__v_: c1_LIR.o; +text: .text%__1cOStaticCallStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cIFrameMapWcaller_save_cpu_reg_at6Fi_pnLLIR_OprDesc__; +text: .text%__1cLInstructionLas_NewArray6M_pnINewArray__: c1_Instruction.o; +text: .text%__1cIVoidTypeDtag6kM_nIValueTag__: c1_ValueType.o; +text: .text%__1cLInstructionOas_NewInstance6M_pnLNewInstance__: c1_Instruction.o; +text: .text%__1cLInstructionQas_AccessMonitor6M_pnNAccessMonitor__: c1_Instruction.o; +text: .text%__1cRLIR_PeepholeStateHdo_call6M_v_; +text: .text%__1cOLIR_OpJavaCallJemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerJemit_call6MpnOLIR_OpJavaCall__v_; +text: .text%__1cNLIR_AssemblerJconst2reg6MpnJLIR_Const_nFRInfo_nHLIR_Op1NLIR_PatchCode_pnMCodeEmitInfo__v_; +text: .text%__1cMPatchingStubQalign_patch_site6MpnOMacroAssembler__v_; +text: .text%__1cJAssemblerEmovl6MpnMRegisterImpl_pnI_jobject__v_; +text: .text%__1cOoop_RelocationLunpack_data6M_v_; +text: .text%__1cKRelocationNunpack_2_ints6Mri1_v_: relocInfo.o; +text: .text%__1cOoop_RelocationEtype6M_nJrelocInfoJrelocType__: relocInfo.o; +text: .text%__1cOoop_RelocationJpack_data6M_i_; +text: .text%__1cNLIR_AssemblerPpatching_epilog6MpnMPatchingStub_nHLIR_Op1NLIR_PatchCode_pnMRegisterImpl_pnMCodeEmitInfo__v_; +text: .text%__1cMPatchingStubHinstall6MpnOMacroAssembler_nHLIR_Op1NLIR_PatchCode_pnMRegisterImpl_pnMCodeEmitInfo__v_: c1_LIRAssembler.o; +text: .text%__1cNLIR_AssemblerUappend_patching_stub6MpnMPatchingStub__v_; +text: .text%__1cPNewInstanceStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cNLIR_AssemblerJemit_call6MpnOLIR_OpJavaCall__v_; +text: .text%__1cNLIR_AssemblerKalign_call6MnILIR_Code__v_; +text: .text%__1cICodeStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cOStaticCallStubLset_code_pc6MpC_v_: c1_CodeStubs_x86.o; +text: .text%__1cOStaticCallStubMis_call_stub6kM_i_: c1_CodeStubs_x86.o; +text: .text%__1cNLIR_AssemblerEcall6MpCnJrelocInfoJrelocType_pnMCodeEmitInfo__v_; +text: .text%__1cbBopt_virtual_call_RelocationEtype6M_nJrelocInfoJrelocType__: relocInfo.o; +text: .text%__1cKRelocationJpack_data6M_i_: relocInfo.o; +text: .text%__1cMCodeEmitInfoSappend_scope_value6MpnLLIR_OprDesc_pnNGrowableArray4CpnKScopeValue____v_; +text: .text%__1cMCodeEmitInfoRopr2location_type6MpnLLIR_OprDesc__nILocationEType__; +text: .text%__1cMCodeEmitInfoRlocation_for_name6MinILocationEType_ii_1_; +text: .text%__1cIFrameMapRlocation_for_name6kMinILocationEType_p1ii_i_; +text: .text%__1cNLIR_AssemblerIthrow_op6MnFRInfo_1pnMCodeEmitInfo_i_v_; +text: .text%__1cMCodeEmitInfoQadd_register_oop6MnFRInfo__v_; +text: .text%__1cIintArrayIindex_of6kMki_i_: c1_LIREmitter.o; +text: .text%__1cMCodeEmitInfoYadd_registers_to_oop_map6MpnGOopMap__v_; +text: .text%__1cYinternal_word_RelocationEtype6M_nJrelocInfoJrelocType__: relocInfo.o; +text: .text%__1cYinternal_word_RelocationJpack_data6M_i_; +text: .text%__1cJrelocInfoKset_format6Mi_v_; +text: .text%__1cMPatchingStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cRAbstractAssemblerGa_byte6Mi_v_; +text: .text%__1cRNativeGeneralJumpUinsert_unconditional6FpC1_v_; +text: .text%__1cNRelocIterator2t6MpnKCodeBuffer_pC3_v_; +text: .text%__1cJrelocInfobDchange_reloc_info_for_address6FpnNRelocIterator_pCn0AJrelocType_4_v_; +text: .text%__1cJrelocInfoIset_type6Mn0AJrelocType__v_; +text: .text%__1cPNewInstanceStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cJOopMapSetMgrow_om_data6M_v_; +text: .text%__1cOStaticCallStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cWstatic_stub_RelocationEtype6M_nJrelocInfoJrelocType__: relocInfo.o; +text: .text%__1cWstatic_stub_RelocationJpack_data6M_i_; +text: .text%__1cNRelocIteratorTadvance_over_prefix6M_v_; +text: .text%__1cOCallRelocationFvalue6M_pC_: relocInfo.o; +text: .text%__1cYinternal_word_RelocationLunpack_data6M_v_; +text: .text%__1cYinternal_word_RelocationWfix_relocation_at_move6Mi_v_; +text: .text%__1cYinternal_word_RelocationFvalue6M_pC_: relocInfo.o; +text: .text%__1cYinternal_word_RelocationGtarget6M_pC_; +text: .text%__1cODataRelocationJset_value6MpC_v_: relocInfo.o; +text: .text%__1cODataRelocationGoffset6M_i_: relocInfo.o; +text: .text%__1cKRelocationRpd_set_data_value6MpCi_v_; +text: .text%__1cKRelocationSpd_address_in_code6M_ppC_; +text: .text%__1cWstatic_stub_RelocationLunpack_data6M_v_; +text: .text%__1cPBoundRelocationLunpack_data6MnJrelocInfoJrelocType__v_: nmethod.o; +text: .text%__1cOoop_RelocationHoops_do6MpFppnHoopDesc__v_v_; +text: .text%__1cOoop_RelocationIoop_addr6M_ppnHoopDesc__; +text: .text%__1cRresolve_and_patch6FppnHoopDesc__v_; +text: .text%__1cMPeriodicTaskOreal_time_tick6FI_v_; +text: .text%__1cPStatSamplerTaskEtask6M_v_: statSampler.o; +text: .text%__1cLStatSamplerOcollect_sample6F_v_; +text: .text%__1cLStatSamplerLsample_data6FpnMPerfDataList__v_; +text: .text%jni_GetPrimitiveArrayCritical: jni.o; +text: .text%jni_ReleasePrimitiveArrayCritical: jni.o; +text: .text%jni_SetBooleanField: jni.o; +text: .text%__1cNFingerprinterIdo_float6M_v_: dump.o; +text: .text%__1cXNativeSignatureIteratorIdo_float6M_v_: interpreterRuntime.o; +text: .text%JVM_IsNaN; +text: .text%__1cNFingerprinterJdo_double6M_v_: dump.o; +text: .text%__1cXNativeSignatureIteratorJdo_double6M_v_: interpreterRuntime.o; +text: .text%__1cXNativeSignatureIteratorLpass_double6M_v_: interpreterRuntime.o; +text: .text%__1cKExceptionsL_throw_args6FpnGThread_pkcinMsymbolHandle_5pnRJavaCallArguments__v_; +text: .text%jni_GetArrayLength: jni.o; +text: .text%JVM_Read; +text: .text%__1cDhpiEread6FipvI_I_: jvm.o; +text: .text%__1cKJNIHandlesKmake_local6FpnGThread_pnHoopDesc__pnI_jobject__; +text: .text%__1cRComputeEntryStackJdo_object6Mii_v_: generateOopMap.o; +text: .text%__1cQComputeCallStackHdo_char6M_v_: generateOopMap.o; +text: .text%__1cQComputeCallStackJdo_object6Mii_v_: generateOopMap.o; +text: .text%__1cFciEnvNlookup_method6MpnNinstanceKlass_2pnNsymbolOopDesc_4nJBytecodesECode__pnNmethodOopDesc__; +text: .text%__1cMLinkResolverbNlinktime_resolve_virtual_method_or_null6FnLKlassHandle_nMsymbolHandle_21i_nMmethodHandle__; +text: .text%__1cIciMethodXfind_monomorphic_target6MpnHciKlass_22_p0_; +text: .text%__1cDCHAManalyze_call6FnLKlassHandle_11nMsymbolHandle_2_pnJCHAResult__; +text: .text%__1cMLinkResolverbCresolve_virtual_call_or_null6FnLKlassHandle_1nMsymbolHandle_21_nMmethodHandle__; +text: .text%__1cJCHAResult2t6MnLKlassHandle_nMsymbolHandle_2pnNGrowableArray4n0B___pnNGrowableArray4nMmethodHandle___n0E_i_v_; +text: .text%__1cJCHAResultOis_monomorphic6kM_i_; +text: .text%__1cJCHAResultSmonomorphic_target6kM_nMmethodHandle__; +text: .text%__1cIciMethodJwill_link6MpnHciKlass_2nJBytecodesECode__i_; +text: .text%__1cMGraphBuilderKtry_inline6MpnIciMethod_i_i_; +text: .text%__1cMGraphBuilderUclear_inline_bailout6M_v_; +text: .text%__1cIciMethodOshould_exclude6M_i_; +text: .text%__1cIciMethodPcan_be_compiled6M_i_; +text: .text%__1cMGraphBuilderVtry_inline_intrinsics6MpnIciMethod__i_; +text: .text%__1cMGraphBuilderPtry_inline_full6MpnIciMethod_i_i_; +text: .text%__1cIciMethodIhas_jsrs6kM_i_; +text: .text%__1cMGraphBuilderWrecursive_inline_level6kMpnIciMethod__i_; +text: .text%__1cPciObjectFactoryMvm_symbol_at6Fi_pnIciSymbol__; +text: .text%__1cJNullCheckFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerMdo_NullCheck6MpnJNullCheck__v_; +text: .text%__1cJNullCheckIcan_trap6kM_i_: c1_GraphBuilder.o; +text: .text%__1cKObjectTypeEbase6kM_pnJValueType__: c1_ValueType.o; +text: .text%__1cKValueStackEpush6MpnJValueType_pnLInstruction__v_: c1_ValueStack.o; +text: .text%__1cMGraphBuilderKpush_scope6MpnIciMethod_pnKBlockBegin_i_v_; +text: .text%__1cKValueStackKpush_scope6MpnHIRScope__p0_; +text: .text%__1cOExceptionScopeKpush_scope6M_p0_; +text: .text%__1cOExceptionScope2t6Mp0_v_; +text: .text%__1cHIRScopeXcompute_lock_stack_size6M_v_; +text: .text%__1cMGraphBuilderJScopeDataRcaller_stack_size6kM_i_; +text: .text%__1cMGraphBuilderJScopeDataLnum_returns6M_i_; +text: .text%__1cMGraphBuilderJScopeDataXset_inline_cleanup_info6MpnKBlockBegin_pnLInstruction_pnKValueStack__v_; +text: .text%__1cMGraphBuilderJScopeDataQincr_num_returns6M_v_; +text: .text%__1cKValueStackJpop_scope6Mii_p0_; +text: .text%__1cMGraphBuilderJpop_scope6M_v_; +text: .text%__1cMGraphBuilderTpop_exception_scope6M_v_; +text: .text%__1cOExceptionScopeJpop_scope6M_p0_; +text: .text%__1cLCompilationVnotice_inlined_method6MpnIciMethod__v_; +text: .text%__1cFciEnvVnotice_inlined_method6MpnIciMethod__v_; +text: .text%__1cMLinkResolverbCresolve_special_call_or_null6FnLKlassHandle_nMsymbolHandle_21_nMmethodHandle__; +text: .text%__1cMGraphBuilderOinline_bailout6Mpkc_v_; +text: .text%__1cLInstructionEprev6MpnKBlockBegin__p0_; +text: .text%__1cKBlockBeginUresolve_substitution6M_v_; +text: .text%__1cKBlockBeginPblock_values_do6MpFppnLInstruction__v_v_; +text: .text%__1cZresolve_substituted_value6FppnLInstruction__v_: c1_Instruction.o; +text: .text%__1cLInstructionFsubst6M_p0_: c1_Instruction.o; +text: .text%__1cLInstructionPother_values_do6MpFpp0_v_v_: c1_GraphBuilder.o; +text: .text%__1cLInstructionPstate_values_do6MpFpp0_v_v_: c1_GraphBuilder.o; +text: .text%__1cLInstructionPstate_values_do6MpFpp0_v_v_: c1_Instruction.o; +text: .text%__1cIConstantPother_values_do6MpFppnLInstruction__v_v_; +text: .text%__1cIBlockEndPother_values_do6MpFppnLInstruction__v_v_; +text: .text%__1cHIntTypeEsize6kM_i_: c1_Canonicalizer.o; +text: .text%__1cJNullCheckPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorMdo_NullCheck6MpnJNullCheck__v_; +text: .text%__1cTNullCheckEliminatorQhandle_NullCheck6MpnJNullCheck__v_; +text: .text%__1cLInstructionOas_AccessLocal6M_pnLAccessLocal__: c1_GraphBuilder.o; +text: .text%__1cHIRScopeNtop_scope_bci6kM_i_; +text: .text%__1cQUseCountComputerPclear_use_count6FpnKBlockBegin__v_: c1_IR.o; +text: .text%__1cIValueGenMdo_NullCheck6MpnJNullCheck__v_; +text: .text%__1cJNullCheckKlock_stack6kM_pnKValueStack__: c1_GraphBuilder.o; +text: .text%__1cLLIR_EmitterKnull_check6MpnLLIR_OprDesc_pnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListDsub6MpnLLIR_OprDesc_22pnMCodeEmitInfo__v_: c1_LIREmitter.o; +text: .text%__1cIValueGenQlock_spill_rinfo6MpnLInstruction_nFRInfo__v_; +text: .text%__1cQIRScopeDebugInfoRrecord_debug_info6MpnYDebugInformationRecorder__v_: c1_LIREmitter.o; +text: .text%__1cIRuntime1Yresolve_opt_virtual_call6FpnKJavaThread_pnHoopDesc__pC_; +text: .text%__1cNSharedRuntimeOresolve_helper6FpnKJavaThread_iipnGThread__nMmethodHandle__; +text: .text%__1cNSharedRuntimeSresolve_sub_helper6FpnKJavaThread_iipnGThread__nMmethodHandle__; +text: .text%__1cFframeZsender_for_compiled_frame6kMpnLRegisterMap_pnICodeBlob_i_0_; +text: .text%__1cLRuntimeStubYcaller_must_gc_arguments6kMpnKJavaThread__i_: codeBlob.o; +text: .text%__1cHnmethodJis_zombie6kM_i_: nmethod.o; +text: .text%__1cNnmethodLocker2t6MpnHnmethod__v_; +text: .text%__1cNSharedRuntimeQfind_callee_info6FpnKJavaThread_rnJBytecodesECode_rnICallInfo_pnGThread__nGHandle__; +text: .text%__1cHnmethodQis_native_method6kM_i_: nmethod.o; +text: .text%__1cHnmethodKpc_desc_at6MpCi_pnGPcDesc__; +text: .text%__1cGPcDescHreal_pc6kMpknHnmethod__pC_; +text: .text%__1cLPcDescCacheKpc_desc_at6kMpnHnmethod_pCi_pnGPcDesc__; +text: .text%__1cLPcDescCacheLadd_pc_desc6MpnGPcDesc__v_; +text: .text%__1cSvframeStreamCommonYfill_from_compiled_frame6MpnHnmethod_i_v_; +text: .text%__1cUCompressedReadStreamMraw_read_int6FrpC_i_: vframe.o; +text: .text%__1cICodeBlobLoop_addr_at6kMi_ppnHoopDesc__; +text: .text%__1cNSharedRuntimeXfind_callee_info_helper6FpnKJavaThread_rnMvframeStream_rnJBytecodesECode_rnICallInfo_pnGThread__nGHandle__; +text: .text%__1cPBytecode_invokeNstatic_target6MpnGThread__nMmethodHandle__; +text: .text%__1cMLinkResolverOresolve_method6FrnMmethodHandle_rnLKlassHandle_nSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cKCompiledICZcompute_monomorphic_entry6FnMmethodHandle_nLKlassHandle_iirnOCompiledICInfo_pnGThread__v_; +text: .text%__1cKCompiledIC2t6MpnKNativeCall__v_; +text: .text%__1cXvirtual_call_RelocationIparse_ic6FrpnICodeBlob_rpC5rppnHoopDesc_pi_nNRelocIterator__; +text: .text%__1cKCompiledICIis_clean6kM_i_; +text: .text%__1cKCompiledICOic_destination6kM_pC_; +text: .text%__1cKCompiledICWis_in_transition_state6kM_i_; +text: .text%__1cRInlineCacheBufferIcontains6FpC_i_; +text: .text%__1cKCompiledICSset_to_monomorphic6MrknOCompiledICInfo__v_; +text: .text%__1cSCompiledStaticCallSset_to_interpreted6MnMmethodHandle_pC_v_; +text: .text%__1cSCompiledStaticCallJfind_stub6M_pC_; +text: .text%__1cNRelocIteratorEnext6M_i_: compiledIC.o; +text: .text%__1cPBoundRelocationLunpack_data6MnJrelocInfoJrelocType__v_: compiledIC.o; +text: .text%__1cbBopt_virtual_call_RelocationLstatic_stub6M_pC_; +text: .text%__1cKNativeCallXset_destination_mt_safe6MpC_v_; +text: .text%__1cNnmethodLocker2T6M_v_; +text: .text%__1cNmethodOopDescTverified_code_entry6M_pC_; +text: .text%jni_GetByteArrayRegion: jni.o; +text: .text%JVM_DefineClassWithSource; +text: .text%__1cXjvm_define_class_common6FpnHJNIEnv__pkcpnI_jobject_pkWi53pnGThread__pnH_jclass__: jvm.o; +text: .text%__1cQSystemDictionaryTresolve_from_stream6FnMsymbolHandle_nGHandle_2pnPClassFileStream_pnGThread__pnMklassOopDesc__; +text: .text%__1cPClassFileParserbDverify_legal_method_signature6MnMsymbolHandle_1pnGThread__i_; +text: .text%__1cPClassFileParserZskip_over_field_signature6MpciIpnGThread__1_; +text: .text%__1cPClassFileParserXverify_legal_class_name6MnMsymbolHandle_pnGThread__v_; +text: .text%__1cQput_after_lookup6FnMsymbolHandle_0ppnLNameSigHash__i_; +text: .text%__1cEhash6Fpkc1_I_; +text: .text%__1cKDictionarybAis_valid_protection_domain6MiInMsymbolHandle_nGHandle_2_i_; +text: .text%__1cPDictionaryEntrybAcontains_protection_domain6kMpnHoopDesc__i_; +text: .text%__1cQSystemDictionarybAvalidate_protection_domain6FnTinstanceKlassHandle_nGHandle_2pnGThread__v_; +text: .text%__1cKDictionaryVadd_protection_domain6MiInTinstanceKlassHandle_nGHandle_2pnGThread__v_; +text: .text%__1cPDictionaryEntryVadd_protection_domain6MpnHoopDesc__v_; +text: .text%__1cUverify_byte_codes_fn6F_pv_: verifier.o; +text: .text%JVM_GetClassCPEntriesCount; +text: .text%JVM_GetClassCPTypes; +text: .text%JVM_GetClassNameUTF; +text: .text%JVM_ReleaseUTF; +text: .text%JVM_FindClassFromClass; +text: .text%jni_IsSameObject: jni.o; +text: .text%JVM_GetClassFieldsCount; +text: .text%JVM_GetClassMethodsCount; +text: .text%JVM_GetMethodIxModifiers; +text: .text%JVM_GetMethodIxByteCodeLength; +text: .text%JVM_GetMethodIxByteCode; +text: .text%JVM_GetMethodIxExceptionTableLength; +text: .text%JVM_GetMethodIxLocalsCount; +text: .text%JVM_GetMethodIxArgsSize; +text: .text%JVM_GetMethodIxSignatureUTF; +text: .text%JVM_GetMethodIxMaxStack; +text: .text%JVM_GetMethodIxExceptionsCount; +text: .text%JVM_GetMethodIxExceptionIndexes; +text: .text%JVM_GetCPMethodNameUTF; +text: .text%JVM_GetCPMethodClassNameUTF; +text: .text%jni_NewLocalRef: jni.o; +text: .text%JVM_GetCPMethodModifiers; +text: .text%JVM_IsConstructorIx; +text: .text%JVM_GetCPMethodSignatureUTF; +text: .text%jni_DeleteGlobalRef: jni.o; +text: .text%__1cQSystemDictionaryVadd_loader_constraint6FnMsymbolHandle_nGHandle_2pnGThread__v_; +text: .text%__1cVLoaderConstraintTableJadd_entry6MnMsymbolHandle_pnMklassOopDesc_nGHandle_34pnGThread__i_; +text: .text%__1cVLoaderConstraintTableJnew_entry6MIpnNsymbolOopDesc_pnMklassOopDesc_ii_pnVLoaderConstraintEntry__; +text: .text%jni_ToReflectedMethod: jni.o; +text: .text%__1cKReflectionKnew_method6FnMmethodHandle_iipnGThread__pnHoopDesc__; +text: .text%__1cNSignatureInfoIdo_array6Mii_v_: reflection.o; +text: .text%__1cYjava_lang_reflect_MethodGcreate6FpnGThread__nGHandle__; +text: .text%__1cYjava_lang_reflect_MethodJset_clazz6FpnHoopDesc_2_v_; +text: .text%__1cYjava_lang_reflect_MethodIset_slot6FpnHoopDesc_i_v_; +text: .text%__1cYjava_lang_reflect_MethodIset_name6FpnHoopDesc_2_v_; +text: .text%__1cYjava_lang_reflect_MethodPset_return_type6FpnHoopDesc_2_v_; +text: .text%__1cYjava_lang_reflect_MethodTset_parameter_types6FpnHoopDesc_2_v_; +text: .text%__1cYjava_lang_reflect_MethodTset_exception_types6FpnHoopDesc_2_v_; +text: .text%__1cYjava_lang_reflect_MethodNset_modifiers6FpnHoopDesc_i_v_; +text: .text%__1cYjava_lang_reflect_MethodThas_signature_field6F_i_; +text: .text%__1cYjava_lang_reflect_MethodVhas_annotations_field6F_i_; +text: .text%__1cYjava_lang_reflect_MethodPset_annotations6FpnHoopDesc_2_v_; +text: .text%__1cYjava_lang_reflect_MethodbFhas_parameter_annotations_field6F_i_; +text: .text%__1cYjava_lang_reflect_MethodZset_parameter_annotations6FpnHoopDesc_2_v_; +text: .text%__1cYjava_lang_reflect_MethodbChas_annotation_default_field6F_i_; +text: .text%__1cNmethodOopDescSannotation_default6kM_pnQtypeArrayOopDesc__; +text: .text%__1cYjava_lang_reflect_MethodWset_annotation_default6FpnHoopDesc_2_v_; +text: .text%jni_CallIntMethod: jni.o; +text: .text%jni_CallStaticVoidMethod: jni.o; +text: .text%jni_DetachCurrentThread; +text: .text%__1cKJavaThreadEexit6Mi_v_; +text: .text%__1cQjava_lang_ThreadLthreadGroup6FpnHoopDesc__2_; +text: .text%JVM_MonitorNotifyAll; +text: .text%__1cNThreadServiceWcurrent_thread_exiting6FpnKJavaThread__v_; +text: .text%__1cLensure_join6FpnKJavaThread__v_: thread.o; +text: .text%__1cQjava_lang_ThreadNset_stillborn6FpnHoopDesc__v_; +text: .text%__1cKJavaThreadYremove_stack_guard_pages6M_v_; +text: .text%__1cWThreadLocalAllocBufferFclear6M_v_; +text: .text%__1cHThreadsGremove6FpnKJavaThread__v_; +text: .text%__1cNThreadServiceNremove_thread6FpnKJavaThread_i_v_; +text: .text%__SLIP.DELETER__A: thread.o; +text: .text%__1cKJavaThread2T6M_v_; +text: .text%__1cGParker2T6M_v_; +text: .text%__1cHMonitor2T6M_v_; +text: .text%__1cFMutex2T6M_v_; +text: .text%lwp_cond_destroy: os_solaris.o; +text: .text%lwp_mutex_destroy: os_solaris.o; +text: .text%__1cUThreadSafepointStateHdestroy6FpnKJavaThread__v_; +text: .text%__1cUThreadSafepointState2T6M_v_; +text: .text%__1cGThread2T5B6M_v_; +text: .text%__1cCosLfree_thread6FpnIOSThread__v_; +text: .text%__1cIOSThread2T6M_v_; +text: .text%__1cIOSThreadKpd_destroy6M_v_; +text: .text%jni_DestroyJavaVM; +text: .text%jni_AttachCurrentThread; +text: .text%attach_current_thread: jni.o; +text: .text%__1cCosWcreate_attached_thread6FpnGThread__i_; +text: .text%__1cKJavaThreadSallocate_threadObj6MnGHandle_pcipnGThread__v_; +text: .text%__1cHThreadsKdestroy_vm6F_i_; +text: .text%__1cKJavaThreadVinvoke_shutdown_hooks6M_v_; +text: .text%__1cLbefore_exit6FpnKJavaThread__v_; +text: .text%__1cNWatcherThreadEstop6F_v_; +text: .text%__1cLStatSamplerJdisengage6F_v_; +text: .text%__1cMPeriodicTaskJdisenroll6M_v_; +text: .text%__1cMPeriodicTask2T5B6M_v_; +text: .text%__1cMPeriodicTaskLis_enrolled6kM_i_; +text: .text%__1cLStatSamplerHdestroy6F_v_; +text: .text%__1cMPerfDataList2T6M_v_; +text: .text%__1cLJvmtiExportNpost_vm_death6F_v_; +text: .text%__1cUJvmtiEventControllerIvm_death6F_v_; +text: .text%__1cCosXterminate_signal_thread6F_v_; +text: .text%__1cCosNsigexitnum_pd6F_i_; +text: .text%__1cCosNsignal_notify6Fi_v_; +text: .text%__1cQprint_statistics6F_v_; +text: .text%__1cFVTuneEexit6F_v_; +text: .text%__1cIVMThreadXwait_for_vm_thread_exit6F_v_; +text: .text%__1cUSafepointSynchronizeFbegin6F_v_; +text: .text%__1cORuntimeServiceWrecord_safepoint_begin6F_v_; +text: .text%__1cJTimeStampSticks_since_update6kM_x_; +text: .text%__1cTAbstractInterpreterRnotice_safepoints6F_v_; +text: .text%__1cKcopy_table6FppC1i_v_: interpreter.o; +text: .text%__1cUSafepointSynchronizeFblock6FpnKJavaThread__v_; +text: .text%__1cCosRcurrent_thread_id6F_i_; +text: .text%__1cJttyLockerbCbreak_tty_lock_for_safepoint6Fi_v_; +text: .text%__1cCosbCmake_polling_page_unreadable6F_v_; +text: .text%__1cUThreadSafepointStateXexamine_state_of_thread6Mi_v_; +text: .text%__1cUSafepointSynchronizeOsafepoint_safe6FpnKJavaThread_nPJavaThreadState__i_; +text: .text%__1cUThreadSafepointStateMroll_forward6Mn0AMsuspend_type_pnHnmethod_i_v_; +text: .text%__1cORuntimeServicebDrecord_safepoint_synchronized6F_v_; +text: .text%__1cUSafepointSynchronizeQdo_cleanup_tasks6F_v_; +text: .text%__1cSObjectSynchronizerVdeflate_idle_monitors6F_v_; +text: .text%__1cNObjectMonitorHis_busy6kM_i_; +text: .text%__1cRInlineCacheBufferUupdate_inline_caches6F_v_; +text: .text%__1cMCounterDecayFdecay6F_v_; +text: .text%__1cQSystemDictionaryRnumber_of_classes6F_i_; +text: .text%__1cQSystemDictionaryStry_get_next_class6F_pnMklassOopDesc__; +text: .text%__1cKDictionaryStry_get_next_class6M_pnMklassOopDesc__; +text: .text%__1cNinstanceKlassKmethods_do6MpFpnNmethodOopDesc__v_v_; +text: .text%__1cJdo_method6FpnNmethodOopDesc__v_: recompilationMonitor.o; +text: .text%__1cONMethodSweeperFsweep6F_v_; +text: .text%__1cNCompileBrokerQset_should_block6F_v_; +text: .text%__1cHVM_ExitbJwait_for_threads_in_native_to_block6F_i_; +text: .text%__1cURecompilationMonitorbFstop_recompilation_monitor_task6F_v_; +text: .text%__1cIVMThreadHdestroy6F_v_; +text: .text%__SLIP.DELETER__A: vmThread.o; +text: .text%__1cSThreadLocalStorageRpd_invalidate_all6F_v_; +text: .text%__1cHVM_ExitNset_vm_exited6F_i_; +text: .text%__1cMexit_globals6F_v_; +text: .text%__1cVverificationType_exit6F_v_; +text: .text%__1cQVerificationTypeIfinalize6F_v_; +text: .text%__1cPperfMemory_exit6F_v_; +text: .text%__1cPPerfDataManagerHdestroy6F_v_; +text: .text%__1cIPerfData2T6M_v_; +text: .text%__1cKPerfMemoryHdestroy6F_v_; +text: .text%__1cKPerfMemoryUdelete_memory_region6F_v_; +text: .text%__1cUdelete_shared_memory6FpcI_v_: perfMemory_solaris.o; +text: .text%__1cLremove_file6Fpkc_v_: perfMemory_solaris.o; +text: .text%__1cMostream_exit6F_v_; +text: .text%__SLIP.DELETER__C: ostream.o; +text: .text%__SLIP.FINAL__A: c1_Items.o; +# Test Exit +text: .text%__1cPSignatureStreamHis_done6kM_i_; +text: .text%JVM_Halt; +text: .text%__1cHvm_exit6Fi_v_; +text: .text%__1cIVMThreadHexecute6FpnMVM_Operation__v_; +text: .text%__1cMVM_OperationNdoit_prologue6M_i_: vm_operations.o; +text: .text%__1cGThreadMget_priority6Fkpk0_nOThreadPriority__; +text: .text%__1cCosMget_priority6FkpknGThread_rnOThreadPriority__nIOSReturn__; +text: .text%__1cCosTget_native_priority6FkpknGThread_pi_nIOSReturn__; +text: .text%__1cMVM_OperationSset_calling_thread6MpnGThread_nOThreadPriority__v_; +text: .text%__1cMVM_OperationPevaluation_mode6kM_n0AEMode__: vm_operations.o; +text: .text%__1cMVM_OperationSis_cheap_allocated6kM_i_: vm_operations.o; +text: .text%__1cQVMOperationQdDueueDadd6MpnMVM_Operation__i_; +text: .text%__1cQVMOperationQdDueueOqueue_add_back6MipnMVM_Operation__v_; +text: .text%__1cQVMOperationQdDueueGinsert6MpnMVM_Operation_2_v_; +text: .text%__1cQVMOperationQdDueueGunlink6MpnMVM_Operation__v_; +text: .text%__1cHVM_ExitEname6kM_pkc_: vm_operations.o; +text: .text%__1cJEventMark2t6MpkcE_v_: vmThread.o; +text: .text%__1cCosJyield_all6Fi_v_; +text: .text%__1cGThreadRis_Watcher_thread6kM_i_: vmThread.o; +text: .text%__1cSInterpreterRuntimeMat_safepoint6FpnKJavaThread__v_; +text: .text%__1cIVMThreadSevaluate_operation6MpnMVM_Operation__v_; +text: .text%__1cMVM_OperationIevaluate6M_v_; +text: .text%__1cHVM_ExitEdoit6M_v_; +# Test Hello +text: .text%JVM_GetCPFieldSignatureUTF; +text: .text%JVM_Write; +text: .text%__1cDhpiFwrite6FipkvI_I_: jvm.o; +# Test Sleep +text: .text%JVM_GetMethodIxExceptionTableEntry; +text: .text%JVM_GetCPClassNameUTF; +text: .text%JVM_Sleep; +text: .text%__1cCosHSolarisTsetup_interruptible6F_pnKJavaThread__; +text: .text%__1cCosHSolarisTsetup_interruptible6FpnKJavaThread__v_; +text: .text%__1cUSafepointSynchronizeRis_cleanup_needed6F_i_; +text: .text%__1cRInlineCacheBufferIis_empty6F_i_; +text: .text%__1cCosHSolarisVcleanup_interruptible6FpnKJavaThread__v_; +text: .text%__1cCosOunguard_memory6FpcI_i_; +# Test IntToString +text: .text%__1cQChunkPoolCleanerEtask6M_v_: allocation.o; +text: .text%__1cJChunkPoolMfree_all_but6MI_v_: allocation.o; +# Test LoadToolkit +text: .text%JVM_GetClassContext; +text: .text%__1cNCollectedHeapMobj_allocate6FnLKlassHandle_ipnGThread__pnHoopDesc__: jvm.o; +text: .text%jni_IsAssignableFrom: jni.o; +text: .text%__1cOGenerateOopMapGdo_ldc6Mii_v_; +text: .text%__1cQComputeCallStackIdo_array6Mii_v_: generateOopMap.o; +text: .text%__1cMGraphBuilderNload_constant6M_v_; +text: .text%__1cQciBytecodeStreamMget_constant6kM_nKciConstant__; +text: .text%__1cQciBytecodeStreamSget_constant_index6kM_i_; +text: .text%__1cFciEnvVget_constant_by_index6MpnPciInstanceKlass_i_nKciConstant__; +text: .text%__1cFciEnvbAget_constant_by_index_impl6MpnPciInstanceKlass_i_nKciConstant__; +text: .text%__1cMLinkResolverbBresolve_static_call_or_null6FnLKlassHandle_nMsymbolHandle_21_nMmethodHandle__; +text: .text%__1cLInstructionMas_LoadLocal6M_pnJLoadLocal__: c1_Canonicalizer.o; +text: .text%__1cTsort_by_start_block6FppnELoop_2_i_: c1_Loops.o; +text: .text%__1cILIR_ListLcall_static6MpnLLIR_OprDesc_pCpnMCodeEmitInfo_pnOStaticCallStub__v_: c1_LIREmitter.o; +text: .text%__1cLLIR_EmitterLcmp_mem_int6MnMLIR_OpBranchNLIR_Condition_nFRInfo_iipnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListLcmp_mem_int6MnMLIR_OpBranchNLIR_Condition_nFRInfo_iipnMCodeEmitInfo__v_; +text: .text%__1cJValueTypeLas_VoidType6M_pnIVoidType__: c1_Canonicalizer.o; +text: .text%__1cILIR_ListHint2reg6MinFRInfo__v_: c1_LIREmitter.o; +text: .text%__1cWstatic_call_RelocationEtype6M_nJrelocInfoJrelocType__: relocInfo.o; +text: .text%__1cRComputeEntryStackIdo_array6Mii_v_: generateOopMap.o; +text: .text%__1cKValueStackEpush6MpnJValueType_pnLInstruction__v_: c1_Optimizer.o; +text: .text%__1cEIfOpPinput_values_do6MpFppnLInstruction__v_v_: c1_Instruction.o; +text: .text%__1cEIfOpFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cQNullCheckVisitorHdo_IfOp6MpnEIfOp__v_; +text: .text%__1cIValueGenHdo_IfOp6MpnEIfOp__v_; +text: .text%__1cLLIR_EmitterLifop_phase16MnLInstructionJCondition_pnLLIR_OprDesc_4_v_; +text: .text%__1cLLIR_EmitterLifop_phase26MnFRInfo_pnLLIR_OprDesc_3nLInstructionJCondition__v_; +text: .text%__1cILIR_ListGbranch6MnMLIR_OpBranchNLIR_Condition_pnFLabel__v_; +text: .text%__1cRLIR_PeepholeStateUstart_forward_branch6MpnFLabel__v_; +text: .text%__1cOGenerateOopMapMdo_checkcast6M_v_; +text: .text%__1cMGraphBuilderLinstance_of6Mi_v_; +text: .text%__1cKInstanceOfFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerNdo_InstanceOf6MpnKInstanceOf__v_; +text: .text%__1cJTypeCheckIcan_trap6kM_i_: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderOdirect_compare6MpnHciKlass__i_; +text: .text%__1cKInstanceOfNas_InstanceOf6M_p0_: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderKcheck_cast6Mi_v_; +text: .text%__1cJCheckCastFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerMdo_CheckCast6MpnJCheckCast__v_; +text: .text%__1cJValueTypeKas_IntType6M_pnHIntType__: c1_ValueType.o; +text: .text%__1cJTypeCheckPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorNdo_InstanceOf6MpnKInstanceOf__v_; +text: .text%__1cQNullCheckVisitorMdo_CheckCast6MpnJCheckCast__v_; +text: .text%__1cIValueGenNdo_InstanceOf6MpnKInstanceOf__v_; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_CodeGenerator_x86.o; +text: .text%__1cLLIR_EmitterNinstanceof_op6MpnLLIR_OprDesc_2pnHciKlass_nFRInfo_5ipnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListKinstanceof6MpnLLIR_OprDesc_2pnHciKlass_22ipnMCodeEmitInfo__v_; +text: .text%__1cPLIR_OpTypeCheck2t6MnILIR_Code_pnLLIR_OprDesc_3pnHciKlass_33ipnMCodeEmitInfo_7pnICodeStub__v_; +text: .text%__1cIValueGenMdo_CheckCast6MpnJCheckCast__v_; +text: .text%__1cILIR_ListJcheckcast6MpnLLIR_OprDesc_2pnHciKlass_22ipnMCodeEmitInfo_6pnICodeStub__v_; +text: .text%__1cILIR_ListJsafepoint6MnFRInfo_pnMCodeEmitInfo__v_: c1_CodeGenerator_x86.o; +text: .text%__1cPLIR_OpTypeCheckFvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cTSimpleExceptionStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cPLIR_OpTypeCheckJemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerQemit_opTypeCheck6MpnPLIR_OpTypeCheck__v_; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_LIROptimizer.o; +text: .text%__1cIintArrayIindex_of6kMki_i_: c1_LIROptimizer.o; +text: .text%__1cNLIR_AssemblerQemit_opTypeCheck6MpnPLIR_OpTypeCheck__v_; +text: .text%__1cIciObjectIencoding6M_pnI_jobject__; +text: .text%__1cJAssemblerEcmpl6MnHAddress_pnI_jobject__v_; +text: .text%__1cTSimpleExceptionStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cTSimpleExceptionStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cJLoadFieldIis_equal6kMpnLInstruction__i_: c1_Instruction.o; +text: .text%__1cJLoadFieldMas_LoadField6M_p0_: c1_Instruction.o; +text: .text%__1cDPhiPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cDPhiFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorGdo_Phi6MpnDPhi__v_; +text: .text%__1cLInstructionIas_Local6M_pnFLocal__: c1_GraphBuilder.o; +text: .text%__1cDPhiGas_Phi6M_p0_: c1_GraphBuilder.o; +text: .text%__1cIValueGenScompute_phi_arrays6MpnKValueStack_pnGValues_pnIintStack_i_pnLInstruction__; +text: .text%__1cLLIR_EmitterTset_fpu_stack_empty6M_v_; +text: .text%__1cIRegAllocKlock_spill6MpnLInstruction_ii_v_; +text: .text%__1cIRegAllocRextend_spill_area6Mi_v_; +text: .text%__1cRclear_state_items6FppnLInstruction__v_: c1_CodeGenerator.o; +text: .text%__1cNLIR_AssemblerTset_fpu_stack_empty6M_v_; +text: .text%__1cIFrameMapLFpuStackSimFclear6M_v_; +text: .text%jni_GetEnv; +text: .text%jni_CallStaticBooleanMethod: jni.o; +text: .text%__1cOtypeArrayKlassQarray_klass_impl6MipnGThread__pnMklassOopDesc__; +text: .text%__1cOtypeArrayKlassKinitialize6MpnGThread__v_; +text: .text%__1cVcreate_gc_point_array6FpnFArena_i_pnNGrowableArray4Ci___; +text: .text%__1cOGenerateOopMapRdo_exception_edge6MpnOBytecodeStream__v_; +text: .text%__1cOGenerateOopMapIppop_any6Mi_v_; +text: .text%__1cYciExceptionHandlerStreamEnext6M_v_: c1_IR.o; +text: .text%__1cMGraphBuilderQhandle_exception6Mi_v_; +text: .text%__1cOExceptionScopeFclear6M_v_; +text: .text%__1cMGraphBuilderJScopeDataJxhandlers6kM_pnJXHandlers__; +text: .text%__1cTciConstantPoolCache2t6MpnFArena_i_v_; +text: .text%__1cTciConstantPoolCacheDget6Mi_pv_; +text: .text%__1cTciConstantPoolCacheEfind6Mi_i_; +text: .text%__1cTciConstantPoolCacheGinsert6Mipv_v_; +text: .text%__1cMGraphBuilderHif_null6MpnJValueType_nLInstructionJCondition__v_; +text: .text%__1cOObjectConstantRas_ObjectConstant6M_p0_: c1_ValueType.o; +text: .text%__1cMas_ValueType6FnKciConstant__pnJValueType__; +text: .text%__1cLInstructionGmirror6Fn0AJCondition__1_; +text: .text%__1cHis_true6FxnLInstructionJCondition_x_i_: c1_Canonicalizer.o; +text: .text%__1cNCanonicalizerNset_canonical6MpnLInstruction__v_; +text: .text%__1cKBlockBeginVadd_exception_handler6Mp0_v_; +text: .text%__1cPBlockBeginArrayIindex_of6kMkpnKBlockBegin__i_: c1_Instruction.o; +text: .text%__1cOExceptionScopeLadd_handler6MpnIXHandler__v_; +text: .text%__1cIciObjectEhash6M_i_; +text: .text%__1cPciObjectFactoryPinsert_non_perm6Mrpn0ANNonPermObject_pnHoopDesc_pnIciObject__v_; +text: .text%__1cIciObjectMhas_encoding6M_i_; +text: .text%__1cJValueTypeRas_ObjectConstant6M_pnOObjectConstant__: c1_ValueType.o; +text: .text%__1cNClassConstantQas_ClassConstant6M_p0_: c1_ValueType.o; +text: .text%__1cOExceptionScopeKhandler_at6kMi_pnIXHandler__; +text: .text%__1cLInstructionMas_LoadLocal6M_pnJLoadLocal__: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderIlogic_op6MpnJValueType_nJBytecodesECode__v_; +text: .text%__1cHLogicOpFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cNCanonicalizerKdo_LogicOp6MpnHLogicOp__v_; +text: .text%__1cHLogicOpEhash6kM_i_: c1_Instruction.o; +text: .text%__1cHLogicOpEname6kM_pkc_: c1_Instruction.o; +text: .text%__1cLInstructionIcan_trap6kM_i_: c1_Instruction.o; +text: .text%__1cMGraphBuilderHconvert6MnJBytecodesECode_nJBasicType_3_v_; +text: .text%__1cHConvertFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerKdo_Convert6MpnHConvert__v_; +text: .text%__1cHConvertEhash6kM_i_: c1_GraphBuilder.o; +text: .text%__1cHConvertEname6kM_pkc_: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderNstore_indexed6MnJBasicType__v_; +text: .text%__1cIValueMapKkill_array6MpnJValueType__v_; +text: .text%__1cGBucketKkill_array6MpnJValueType__v_; +text: .text%__1cLInstructionOas_LoadIndexed6M_pnLLoadIndexed__: c1_GraphBuilder.o; +text: .text%__1cLInstructionOas_LoadIndexed6M_pnLLoadIndexed__: c1_Instruction.o; +text: .text%__1cKValueStackRpin_stack_indexed6MpnJValueType__v_; +text: .text%__1cMStoreIndexedFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerPdo_StoreIndexed6MpnMStoreIndexed__v_; +text: .text%__1cLAccessArrayIcan_trap6kM_i_: c1_GraphBuilder.o; +text: .text%__1cLAccessFieldPother_values_do6MpFppnLInstruction__v_v_; +text: .text%__1cLInstructionPother_values_do6MpFpp0_v_v_: c1_Instruction.o; +text: .text%__1cIciObjectOis_null_object6kM_i_: ciInstance.o; +text: .text%__1cMStoreIndexedPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cHConvertPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorKdo_LogicOp6MpnHLogicOp__v_; +text: .text%__1cQNullCheckVisitorKdo_Convert6MpnHConvert__v_; +text: .text%__1cQNullCheckVisitorPdo_StoreIndexed6MpnMStoreIndexed__v_; +text: .text%__1cTNullCheckEliminatorThandle_StoreIndexed6MpnMStoreIndexed__v_; +text: .text%__1cMciNullObjectMis_classless6kM_i_: ciNullObject.o; +text: .text%__1cJValueTypeQas_ClassConstant6M_pnNClassConstant__: c1_ValueType.o; +text: .text%__1cOObjectConstantIencoding6kM_pnI_jobject__; +text: .text%__1cIValueGenbBrlock_byte_result_with_hint6MpnLInstruction_pknEItem__nFRInfo__; +text: .text%__1cNc1_AllocTableThas_one_free_masked6kMnKc1_RegMask__i_; +text: .text%__1cIRegAllocMget_lock_reg6MpnLInstruction_nKc1_RegMask__nFRInfo__; +text: .text%__1cIRegAllocMget_free_reg6MnKc1_RegMask__nFRInfo__; +text: .text%__1cNc1_AllocTablePget_free_masked6MnKc1_RegMask__i_; +text: .text%__1cNClassConstantIencoding6kM_pnI_jobject__; +text: .text%__1cLLIR_EmitterLopr2jobject6MpnLLIR_OprDesc__pnI_jobject__; +text: .text%__1cILIR_ListHoop2reg6MpnI_jobject_nFRInfo__v_: c1_LIREmitter.o; +text: .text%__1cIValueGenMrelease_item6MpnEItem__v_; +text: .text%__1cIValueGenPdo_StoreIndexed6MpnMStoreIndexed__v_; +text: .text%__1cIValueGenKdo_Convert6MpnHConvert__v_; +text: .text%__1cIValueGenKdo_LogicOp6MpnHLogicOp__v_; +text: .text%__1cLLIR_EmitterIlogic_op6MnJBytecodesECode_nFRInfo_pnLLIR_OprDesc_5_v_; +text: .text%__1cILIR_ListLlogical_and6MnFRInfo_pnLLIR_OprDesc_1_v_: c1_LIREmitter.o; +text: .text%__1cLLIR_EmitterKconvert_op6MnJBytecodesECode_pnLLIR_OprDesc_nFRInfo_i_v_; +text: .text%__1cILIR_ListHconvert6MnJBytecodesECode_pnLLIR_OprDesc_4i_v_: c1_LIREmitter.o; +text: .text%__1cIValueGenKmust_round6MpnLInstruction_pknEItem__i_; +text: .text%__1cLAccessArrayKlock_stack6kM_pnKValueStack__: c1_GraphBuilder.o; +text: .text%__1cLLIR_EmitterNindexed_store6MnJBasicType_pnLLIR_OprDesc_33nFRInfo_pnMCodeEmitInfo__v_; +text: .text%__1cLLIR_EmitterXlo_word_offset_in_bytes6kM_i_; +text: .text%__1cLLIR_EmitterXhi_word_offset_in_bytes6kM_i_; +text: .text%__1cILIR_ListLstore_array6MnFRInfo_pnLLIR_Address_nJBasicType_pnMCodeEmitInfo__v_; +text: .text%__1cIValueGenXexception_handler_start6MpnHIRScope_ipnKValueStack__v_; +text: .text%__1cLLIR_EmitterNhandler_entry6M_v_; +text: .text%__1cLLIR_OprFactQdummy_value_type6FpnJValueType__pnLLIR_OprDesc__; +text: .text%__1cLInstructionKexact_type6kM_pnGciType__: c1_GraphBuilder.o; +text: .text%__1cLInstructionNdeclared_type6kM_pnGciType__: c1_GraphBuilder.o; +text: .text%__1cILIR_ListKnull_check6MnFRInfo_pnMCodeEmitInfo__v_: c1_CodeGenerator.o; +text: .text%__1cNLIR_OpConvertJemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerOemit_opConvert6MpnNLIR_OpConvert__v_; +text: .text%__1cJAssemblerEcmpl6MpnMRegisterImpl_pnI_jobject__v_; +text: .text%__1cJAssemblerKemit_arith6MiipnMRegisterImpl_pnI_jobject__v_; +text: .text%__1cNLIR_AssemblerIlogic_op6MnILIR_Code_pnLLIR_OprDesc_33_v_; +text: .text%__1cNLIR_AssemblerOemit_opConvert6MpnNLIR_OpConvert__v_; +text: .text%__1cNLIR_AssemblerNarray_move_op6MpnLLIR_OprDesc_2nJBasicType_pnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerJreg2array6MnFRInfo_pnLLIR_Address_nJBasicType_pnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerPas_ArrayAddress6MpnLLIR_Address_nJBasicType__nHAddress__; +text: .text%__1cVConstantOopWriteValueIwrite_on6MpnUDebugInfoWriteStream__v_; +text: .text%__1cUDebugInfoWriteStreamMwrite_handle6MpnI_jobject__v_; +text: .text%__1cTExceptionRangeTableJadd_entry6Miiiiii_v_; +text: .text%__1cTExceptionRangeEntry2t6Miiiiii_v_; +text: .text%__1cTExceptionRangeTableJadd_entry6MnTExceptionRangeEntry__v_; +text: .text%__1cOExceptionScopeCid6kM_i_; +text: .text%__1cTExceptionRangeTableTentry_index_for_pco6kMi_i_; +text: .text%__1cTExceptionRangeTableIentry_at6kMi_pnTExceptionRangeEntry__; +text: .text%jni_CallStaticVoidMethodV: jni.o; +text: .text%JVM_GetLastErrorString; +text: .text%jni_Throw: jni.o; +text: .text%__1cKExceptionsK_throw_oop6FpnGThread_pkcipnHoopDesc__v_; +text: .text%JVM_DisableCompiler; +text: .text%__1cNinstanceKlassbFlookup_method_in_all_interfaces6kMpnNsymbolOopDesc_2_pnNmethodOopDesc__; +text: .text%JVM_Available; +text: .text%__1cOGenerateOopMapKpp_new_ref6MpnNCellTypeState_i_v_; +text: .text%__1cLInstructionMas_LoadField6M_pnJLoadField__: c1_Instruction.o; +text: .text%__1cHLogicOpOis_commutative6kM_i_; +text: .text%__1cDCHANprocess_class6FnLKlassHandle_pnNGrowableArray4n0B___pnNGrowableArray4nMmethodHandle___nMsymbolHandle_6_v_; +text: .text%__1cUGenericGrowableArrayMraw_contains6kMpknEGrET__i_; +text: .text%__1cLArrayLengthFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerOdo_ArrayLength6MpnLArrayLength__v_; +text: .text%__1cLArrayLengthEhash6kM_i_: c1_GraphBuilder.o; +text: .text%__1cLArrayLengthEname6kM_pkc_: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderOnew_type_array6M_v_; +text: .text%__1cMNewTypeArrayFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cNCanonicalizerPdo_NewTypeArray6MpnMNewTypeArray__v_; +text: .text%__1cINewArrayIcan_trap6kM_i_: c1_Instruction.o; +text: .text%__1cJIntrinsicFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerMdo_Intrinsic6MpnJIntrinsic__v_; +text: .text%__1cJIntrinsicMas_Intrinsic6M_p0_: c1_GraphBuilder.o; +text: .text%__1cJIntrinsicIcan_trap6kM_i_: c1_GraphBuilder.o; +text: .text%__1cLAccessArrayPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorOdo_ArrayLength6MpnLArrayLength__v_; +text: .text%__1cTNullCheckEliminatorShandle_ArrayLength6MpnLArrayLength__v_; +text: .text%__1cINewArrayPinput_values_do6MpFppnLInstruction__v_v_: c1_Instruction.o; +text: .text%__1cQNullCheckVisitorPdo_NewTypeArray6MpnMNewTypeArray__v_; +text: .text%__1cTNullCheckEliminatorPhandle_NewArray6MpnINewArray__v_; +text: .text%__1cJIntrinsicPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorMdo_Intrinsic6MpnJIntrinsic__v_; +text: .text%__1cJLoopArrayIindex_of6kMkpnELoop__i_: c1_Loops.o; +text: .text%__1cINewArrayLas_NewArray6M_p0_: c1_Instruction.o; +text: .text%__1cILIR_ListOcall_icvirtual6MnFRInfo_pnLLIR_OprDesc_pCpnMCodeEmitInfo__v_: c1_LIREmitter.o; +text: .text%__1cILIR_ListNstore_mem_int6MinFRInfo_inJBasicType_pnMCodeEmitInfo_nHLIR_Op1NLIR_PatchCode__v_; +text: .text%__1cIValueGenOdo_ArrayLength6MpnLArrayLength__v_; +text: .text%__1cLLIR_EmitterMarray_length6MnFRInfo_pnLLIR_OprDesc_pnMCodeEmitInfo__v_; +text: .text%__1cLlog2_intptr6Fi_i_: c1_LIREmitter.o; +text: .text%__1cIValueGenPdo_NewTypeArray6MpnMNewTypeArray__v_; +text: .text%__1cLLIR_EmitterOnew_type_array6MnFRInfo_nJBasicType_pnLLIR_OprDesc_11111pnMCodeEmitInfo__v_; +text: .text%__1cQNewTypeArrayStub2t6MnFRInfo_11pnMCodeEmitInfo__v_; +text: .text%__1cQciTypeArrayKlassEmake6FnJBasicType__p0_; +text: .text%__1cQciTypeArrayKlassJmake_impl6FnJBasicType__p0_; +text: .text%__1cILIR_ListHoop2reg6MpnI_jobject_nFRInfo__v_: c1_LIREmitter_x86.o; +text: .text%__1cILIR_ListOallocate_array6MnFRInfo_11111nJBasicType_1pnICodeStub__v_; +text: .text%__1cIValueGenMdo_Intrinsic6MpnJIntrinsic__v_; +text: .text%__1cIValueGenMdo_ArrayCopy6MpnJIntrinsic__v_; +text: .text%__1cIValueGenQarraycopy_helper6MpnJIntrinsic_pippnMciArrayKlass__v_; +text: .text%__1cJLoadFieldKexact_type6kM_pnGciType__; +text: .text%__1cJLoadFieldNdeclared_type6kM_pnGciType__; +text: .text%__1cQciTypeArrayKlassTis_type_array_klass6M_i_: ciTypeArrayKlass.o; +text: .text%__1cOas_array_klass6FpnGciType__pnMciArrayKlass__: c1_CodeGenerator.o; +text: .text%__1cMciArrayKlassOis_array_klass6M_i_: ciTypeArrayKlass.o; +text: .text%__1cMNewTypeArrayKexact_type6kM_pnGciType__; +text: .text%__1cLInstructionNdeclared_type6kM_pnGciType__: c1_Instruction.o; +text: .text%__1cRpositive_constant6FpnLInstruction__i_: c1_CodeGenerator.o; +text: .text%__1cLArrayLengthOas_ArrayLength6M_p0_: c1_GraphBuilder.o; +text: .text%__1cQis_constant_zero6FpnLInstruction__i_: c1_CodeGenerator.o; +text: .text%__1cILIR_ListJarraycopy6MpnLLIR_OprDesc_22222pnMciArrayKlass_ipnMCodeEmitInfo__v_: c1_CodeGenerator_x86.o; +text: .text%__1cLLIR_EmitterNwrite_barrier6MpnLLIR_OprDesc_2_v_; +text: .text%__1cILIR_ListUunsigned_shift_right6MnFRInfo_i1_v_: c1_LIREmitter_x86.o; +text: .text%__1cILIR_ListUunsigned_shift_right6MpnLLIR_OprDesc_222_v_; +text: .text%__1cQLIR_OpAllocArrayFvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cQNewTypeArrayStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cPLIR_OpArrayCopyFvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cQLIR_OpAllocArrayJemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerQemit_alloc_array6MpnQLIR_OpAllocArray__v_; +text: .text%__1cPLIR_OpArrayCopyJemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerOemit_arraycopy6MpnPLIR_OpArrayCopy__v_; +text: .text%__1cNLIR_AssemblerHic_call6MpCpnMCodeEmitInfo__v_; +text: .text%__1cJAssemblerEcall6MpCrknQRelocationHolder__v_; +text: .text%__1cXvirtual_call_RelocationEtype6M_nJrelocInfoJrelocType__: relocInfo.o; +text: .text%__1cXvirtual_call_RelocationJpack_data6M_i_; +text: .text%__1cNLIR_AssemblerJconst2mem6MpnJLIR_Const_pnLLIR_Address_nJBasicType_pnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerQemit_alloc_array6MpnQLIR_OpAllocArray__v_; +text: .text%__1cNLIR_AssemblerSarray_element_size6kMnJBasicType__nHAddressLScaleFactor__; +text: .text%__1cRC1_MacroAssemblerOallocate_array6MpnMRegisterImpl_222inHAddressLScaleFactor_2rnFLabel__v_; +text: .text%__1cRC1_MacroAssemblerMtry_allocate6MpnMRegisterImpl_2i22rnFLabel__v_; +text: .text%__1cQNewTypeArrayStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cNLIR_AssemblerOemit_arraycopy6MpnPLIR_OpArrayCopy__v_; +text: .text%__1cMciArrayKlassMelement_type6M_pnGciType__; +text: .text%__1cNArrayCopyStub2t6MpnMCodeEmitInfo_pnOStaticCallStub__v_; +text: .text%__1cFRInfoMset_word_reg6MkpnMRegisterImpl__v_; +text: .text%__1cNArrayCopyStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cNLIR_AssemblerOpush_parameter6MpnMRegisterImpl_i_v_; +text: .text%__1cQNewTypeArrayStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cNArrayCopyStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cXvirtual_call_RelocationLunpack_data6M_v_; +text: .text%__1cIRuntime1Uresolve_virtual_call6FpnKJavaThread_pnHoopDesc__pC_; +text: .text%__1cKoopFactoryUnew_compiledICHolder6FnMmethodHandle_nLKlassHandle_pnGThread__pnXcompiledICHolderOopDesc__; +text: .text%__1cVcompiledICHolderKlassIallocate6MpnGThread__pnXcompiledICHolderOopDesc__; +text: .text%__1cNCollectedHeapWpermanent_obj_allocate6FnLKlassHandle_ipnGThread__pnHoopDesc__: compiledICHolderKlass.o; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: compiledICHolderKlass.o; +text: .text%__1cRLowMemoryDetectorbLdetect_low_memory_for_collected_pools6F_v_: compiledICHolderKlass.o; +text: .text%__1cXvirtual_call_RelocationJfirst_oop6M_pC_; +text: .text%__1cXvirtual_call_RelocationJoop_limit6M_pC_; +text: .text%__1cNRelocIteratorJset_limit6MpC_v_; +text: .text%__1cRInlineCacheBufferWcreate_transition_stub6FpnKCompiledIC_pnHoopDesc_pC_v_; +text: .text%__1cGICStubIset_stub6MpnKCompiledIC_pnHoopDesc_pC_v_; +text: .text%__1cRInlineCacheBufferXassemble_ic_buffer_code6FpCpnHoopDesc_1_v_; +text: .text%__1cKCompiledICSset_ic_destination6MpC_v_; +text: .text%__1cRInlineCacheBufferLnew_ic_stub6F_pnGICStub__; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: objArrayKlass.o; +text: .text%JVM_NewArray; +text: .text%__1cKReflectionRreflect_new_array6FpnHoopDesc_ipnGThread__pnMarrayOopDesc__; +text: .text%__1cSInterpreterRuntimeOmultianewarray6FpnKJavaThread_pi_v_; +text: .text%__1cNobjArrayKlassOmulti_allocate6MipiipnGThread__pnHoopDesc__; +text: .text%__1cNinstanceKlassSlookup_osr_nmethod6kMkpnNmethodOopDesc_i_pnHnmethod__; +text: .text%__1cQSimpleCompPolicyYmethod_back_branch_event6MnMmethodHandle_iipnGThread__v_; +text: .text%__1cICompilerMsupports_osr6M_i_: c1_Compiler.o; +text: .text%__1cHciKlassOis_subclass_of6Mp0_i_; +text: .text%__1cMGraphBuilderQnew_object_array6M_v_; +text: .text%__1cONewObjectArrayFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cNCanonicalizerRdo_NewObjectArray6MpnONewObjectArray__v_; +text: .text%__1cPciObjArrayKlass2t6MnLKlassHandle__v_; +text: .text%__1cPciObjArrayKlassGloader6M_pnHoopDesc__: ciObjArrayKlass.o; +text: .text%__1cMGraphBuilderIshift_op6MpnJValueType_nJBytecodesECode__v_; +text: .text%__1cHShiftOpFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerKdo_ShiftOp6MpnHShiftOp__v_; +text: .text%__1cHShiftOpEhash6kM_i_: c1_GraphBuilder.o; +text: .text%__1cHShiftOpEname6kM_pkc_: c1_GraphBuilder.o; +text: .text%__1cLLoadIndexedOas_LoadIndexed6M_p0_: c1_Instruction.o; +text: .text%__1cMArithmeticOpIis_equal6kMpnLInstruction__i_: c1_Instruction.o; +text: .text%__1cDOp2Gas_Op26M_p0_: c1_Instruction.o; +text: .text%__1cLInstructionMas_LoadField6M_pnJLoadField__: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorRdo_NewObjectArray6MpnONewObjectArray__v_; +text: .text%__1cDOp2Pinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorKdo_ShiftOp6MpnHShiftOp__v_; +text: .text%__1cHciKlassMaccess_flags6M_i_; +text: .text%__1cILIR_ListPallocate_object6MnFRInfo_111ii1pnICodeStub__v_; +text: .text%__1cLLIR_EmitterOmembar_release6M_v_; +text: .text%__1cLLIR_EmitterGmembar6M_v_; +text: .text%__1cIValueGenRdo_NewObjectArray6MpnONewObjectArray__v_; +text: .text%__1cLLIR_EmitterQnew_object_array6MnFRInfo_pnHciKlass_pnLLIR_OprDesc_11111pnMCodeEmitInfo_7_v_; +text: .text%__1cSNewObjectArrayStub2t6MnFRInfo_11pnMCodeEmitInfo__v_; +text: .text%__1cPciObjArrayKlassEmake6FpnHciKlass__p0_; +text: .text%__1cPciObjArrayKlassJmake_impl6FpnHciKlass__p0_; +text: .text%__1cLLIR_EmitterOmembar_acquire6M_v_; +text: .text%__1cIValueGenKdo_ShiftOp6MpnHShiftOp__v_; +text: .text%__1cIValueGenPshiftCountRInfo6F_nFRInfo__; +text: .text%__1cLLIR_EmitterIshift_op6MnJBytecodesECode_nFRInfo_pnLLIR_OprDesc_53_v_; +text: .text%__1cILIR_ListKshift_left6MnFRInfo_i1_v_: c1_LIREmitter.o; +text: .text%__1cILIR_ListKlogical_or6MnFRInfo_pnLLIR_OprDesc_1_v_: c1_LIREmitter.o; +text: .text%__1cOLIR_OpAllocObjFvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cSNewObjectArrayStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cOLIR_OpAllocObjJemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerOemit_alloc_obj6MpnOLIR_OpAllocObj__v_; +text: .text%__1cNLIR_AssemblerOemit_alloc_obj6MpnOLIR_OpAllocObj__v_; +text: .text%__1cRC1_MacroAssemblerPallocate_object6MpnMRegisterImpl_22ii2rnFLabel__v_; +text: .text%__1cNLIR_AssemblerOmembar_release6M_v_; +text: .text%__1cNLIR_AssemblerGmembar6M_v_; +text: .text%__1cSNewObjectArrayStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cNLIR_AssemblerOmembar_acquire6M_v_; +text: .text%__1cEBaseHas_Base6M_p0_: c1_IR.o; +text: .text%__1cNLIR_AssemblerOemit_osr_entry6MpnHIRScope_ipnFLabel_i_v_; +text: .text%__1cSNewObjectArrayStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cNinstanceKlassPadd_osr_nmethod6MpnHnmethod__v_; +text: .text%__1cUGenericGrowableArrayLraw_at_grow6MipknEGrET__pv_; +text: .text%__1cNSignatureInfoIdo_short6M_v_: bytecode.o; +text: .text%jni_MonitorEnter: jni.o; +text: .text%__1cSObjectSynchronizerJjni_enter6FnGHandle_pnGThread__v_; +text: .text%jni_MonitorExit: jni.o; +text: .text%__1cSObjectSynchronizerIjni_exit6FpnHoopDesc_pnGThread__v_; +text: .text%jni_CallVoidMethod: jni.o; +text: .text%__1cXJNI_ArgumentPusherVaArgHget_int6M_v_: jni.o; +text: .text%jni_CallStaticBooleanMethodV: jni.o; +text: .text%JVM_GetStackTraceDepth; +text: .text%__1cTjava_lang_ThrowableVget_stack_trace_depth6FpnHoopDesc_pnGThread__i_; +text: .text%__1cTjava_lang_ThrowableJbacktrace6FpnHoopDesc__2_; +text: .text%JVM_GetStackTraceElement; +text: .text%__1cTjava_lang_ThrowableXget_stack_trace_element6FpnHoopDesc_ipnGThread__2_; +text: .text%__1cbBjava_lang_StackTraceElementGcreate6FnMmethodHandle_ipnGThread__pnHoopDesc__; +text: .text%__1cbBjava_lang_StackTraceElementNset_className6FpnHoopDesc_2_v_; +text: .text%__1cbBjava_lang_StackTraceElementOset_methodName6FpnHoopDesc_2_v_; +text: .text%__1cbBjava_lang_StackTraceElementMset_fileName6FpnHoopDesc_2_v_; +text: .text%__1cNmethodOopDescUline_number_from_bci6kMi_i_; +text: .text%__1cbECompressedLineNumberReadStream2t6MpC_v_; +text: .text%__1cbECompressedLineNumberReadStreamJread_pair6M_i_; +text: .text%__1cUCompressedReadStreamIread_int6M_i_: methodOop.o; +text: .text%__1cbBjava_lang_StackTraceElementOset_lineNumber6FpnHoopDesc_i_v_; +text: .text%__1cFKlassNoop_is_method6kM_i_: typeArrayKlass.o; +text: .text%__1cFKlassRoop_is_methodData6kM_i_: typeArrayKlass.o; +text: .text%__1cIciObjectOis_null_object6kM_i_: ciObjectFactory.o; +text: .text%__1cNObjectMonitorJnotifyAll6MpnGThread__v_; +text: .text%__1cNObjectMonitorREntryQdDueue_insert6MpnMObjectWaiter_i_v_; +text: .text%__1cNObjectMonitorbAEntryQdDueue_SelectSuccessor6M_pnMObjectWaiter__; +text: .text%__1cLServiceUtilLvisible_oop6FpnHoopDesc__i_: objectMonitor_solaris.o; +text: .text%__1cNObjectMonitorGEnterI6MpnGThread__v_; +text: .text%JVM_EnableCompiler; +text: .text%__1cCosHSolarisFEventEpark6Mx_i_: objectMonitor_solaris.o; +text: .text%__1cJStubQdDueueKremove_all6M_v_; +text: .text%__1cJStubQdDueueMremove_first6Mi_v_; +text: .text%__1cJStubQdDueueMremove_first6M_v_; +text: .text%__1cPICStubInterfaceIfinalize6MpnEStub__v_: icBuffer.o; +text: .text%__1cGICStubIfinalize6M_v_; +text: .text%__1cGICStubKcached_oop6kM_pnHoopDesc__; +text: .text%__1cRInlineCacheBufferUic_buffer_cached_oop6FpC_pnHoopDesc__; +text: .text%__1cKCompiledICOset_cached_oop6MpnHoopDesc__v_; +text: .text%__1cOoop_RelocationSfix_oop_relocation6M_v_; +text: .text%__1cGICStubLdestination6kM_pC_; +text: .text%__1cRInlineCacheBufferVic_buffer_entry_point6FpC_1_; +text: .text%__1cPICStubInterfaceEsize6kMpnEStub__i_: icBuffer.o; +text: .text%__1cUSafepointSynchronizeDend6F_v_; +text: .text%__1cCosbAmake_polling_page_readable6F_v_; +text: .text%__1cTAbstractInterpreterRignore_safepoints6F_v_; +text: .text%__1cGThreadQunboost_priority6Fp0_v_; +text: .text%__1cUThreadSafepointStateHrestart6M_v_; +text: .text%__1cORuntimeServiceUrecord_safepoint_end6F_v_; +text: .text%__1cKJavaThreadbScheck_safepoint_and_suspend_for_native_trans6Fp0_v_; +# Test LoadFrame +text: .text%__1cNObjectMonitorGenter26MpnGThread__v_; +text: .text%__1cICompilerPsupports_native6M_i_: c1_Compiler.o; +text: .text%__1cLCompilationVcompile_native_method6MpnLCodeOffsets__i_; +text: .text%__1cIciMethodMnative_entry6M_pC_; +text: .text%__1cLCompilationUemit_code_for_native6MpCpnLCodeOffsets__v_; +text: .text%__1cLCompilationXemit_code_prolog_native6MpnIFrameMap__v_; +text: .text%__1cNLIR_AssemblerRemit_method_entry6MpnLLIR_Emitter_pnHIRScope__v_; +text: .text%__1cOMacroAssemblerHfat_nop6M_v_; +text: .text%__1cNLIR_AssemblerQemit_native_call6MpCpnMCodeEmitInfo__v_; +text: .text%__1cMCodeEmitInfobGcreate_oop_map_for_own_signature6M_pnGOopMap__; +text: .text%__1cNLIR_AssemblerXemit_native_method_exit6MpnMCodeEmitInfo__v_; +text: .text%__1cNSignatureInfoHdo_char6M_v_: reflection.o; +text: .text%__1cNSignatureInfoHdo_bool6M_v_: reflection.o; +text: .text%jni_CallObjectMethodV: jni.o; +text: .text%jni_SetObjectField: jni.o; +text: .text%jni_IsInstanceOf: jni.o; +text: .text%jni_GetStaticObjectField: jni.o; +text: .text%__1cbCTwoGenerationCollectorPolicybMshould_try_older_generation_allocation6kMI_i_; +text: .text%__1cQGenCollectedHeapSattempt_allocation6MIiii_pnIHeapWord__; +text: .text%__1cQDefNewGenerationIallocate6MIii_pnIHeapWord__: defNewGeneration.o; +text: .text%__1cKGenerationInext_gen6kM_p0_; +text: .text%__1cKGenerationYallocation_limit_reached6MpnFSpace_pnIHeapWord_I_4_: tenuredGeneration.o; +text: .text%__1cQDefNewGenerationTallocate_from_space6MI_pnIHeapWord__; +text: .text%__1cPVM_GC_OperationNdoit_prologue6M_i_; +text: .text%__1cPVM_GC_OperationZacquire_pending_list_lock6M_v_; +text: .text%__1cQinstanceRefKlassZacquire_pending_list_lock6FpnJBasicLock__v_; +text: .text%__1cXjava_lang_ref_ReferenceWpending_list_lock_addr6F_ppnHoopDesc__; +text: .text%__1cPVM_GC_OperationQgc_count_changed6kM_i_; +text: .text%__1cbAVM_GenCollectForAllocationEname6kM_pkc_: vm_operations.o; +text: .text%__1cbAVM_GenCollectForAllocationEdoit6M_v_; +text: .text%__1cNJvmtiGCMarker2t6Mi_v_; +text: .text%__1cQGenCollectedHeapZsatisfy_failed_allocation6MIiipi_pnIHeapWord__; +text: .text%__1cbCTwoGenerationCollectorPolicyZsatisfy_failed_allocation6MIiipi_pnIHeapWord__; +text: .text%__1cQGenCollectedHeapNdo_collection6MiiIiiipi_v_; +text: .text%__1cXTraceMemoryManagerStats2t6Mi_v_; +text: .text%__1cNMemoryServiceIgc_begin6Fi_v_; +text: .text%__1cPGCMemoryManagerIgc_begin6M_v_; +text: .text%__1cKManagementJtimestamp6F_x_; +text: .text%__1cKGCStatInfoMset_gc_usage6MinLMemoryUsage_i_v_; +text: .text%__1cTContiguousSpacePoolQget_memory_usage6M_nLMemoryUsage__; +text: .text%__1cTContiguousSpacePoolNused_in_bytes6M_I_: memoryPool.o; +text: .text%__1cbBSurvivorContiguousSpacePoolQget_memory_usage6M_nLMemoryUsage__; +text: .text%__1cbBSurvivorContiguousSpacePoolNused_in_bytes6M_I_: memoryPool.o; +text: .text%__1cOGenerationPoolQget_memory_usage6M_nLMemoryUsage__; +text: .text%__1cOGenerationPoolNused_in_bytes6M_I_: memoryPool.o; +text: .text%__1cQGenCollectedHeapLgc_prologue6Mi_v_; +text: .text%__1cNCollectedHeapbFaccumulate_statistics_all_tlabs6M_v_; +text: .text%__1cWThreadLocalAllocBufferbFaccumulate_statistics_before_gc6F_v_; +text: .text%__1cWThreadLocalAllocBufferVaccumulate_statistics6MIi_v_; +text: .text%__1cPGlobalTLABStatsHpublish6M_v_; +text: .text%__1cQGenCollectedHeapTensure_parseability6M_v_; +text: .text%__1cNCollectedHeapTensure_parseability6M_v_; +text: .text%__1cNCollectedHeapOfill_all_tlabs6M_v_; +text: .text%__1cQGenCollectedHeapSgeneration_iterate6Mpn0AKGenClosure_i_v_; +text: .text%__1cbCGenEnsureParseabilityClosureNdo_generation6MpnKGeneration__v_: genCollectedHeap.o; +text: .text%__1cKGenerationTensure_parseability6M_v_: defNewGeneration.o; +text: .text%__1cKGenerationTensure_parseability6M_v_: tenuredGeneration.o; +text: .text%__1cKGenerationTensure_parseability6M_v_: compactingPermGenGen.o; +text: .text%__1cSAllocationProfilerViterate_since_last_gc6F_v_; +text: .text%__1cUGenGCPrologueClosureNdo_generation6MpnKGeneration__v_: genCollectedHeap.o; +text: .text%__1cQDefNewGenerationLgc_prologue6Mi_v_: defNewGeneration.o; +text: .text%__1cRTenuredGenerationLgc_prologue6Mi_v_; +text: .text%__1cKGenerationLgc_prologue6Mi_v_: compactingPermGenGen.o; +text: .text%__1cKGenerationOshould_collect6MiIii_i_: defNewGeneration.o; +text: .text%__1cQDefNewGenerationKshort_name6kM_pkc_: defNewGeneration.o; +text: .text%__1cKGenerationIcounters6M_pnRCollectorCounters__: defNewGeneration.o; +text: .text%__1cQGenCollectedHeapKsave_marks6M_v_; +text: .text%__1cQDefNewGenerationKsave_marks6M_v_; +text: .text%__1cbCOneContigSpaceCardGenerationKsave_marks6M_v_; +text: .text%__1cQDefNewGenerationHcollect6MiiIii_v_; +text: .text%__1cQDefNewGenerationbAcollection_attempt_is_safe6M_i_; +text: .text%__1cRTenuredGenerationZpromotion_attempt_is_safe6kMIi_i_; +text: .text%__1cKGenerationYmax_contiguous_available6kM_I_; +text: .text%__1cbCOneContigSpaceCardGenerationUcontiguous_available6kM_I_; +text: .text%__1cQDefNewGenerationbIinit_assuming_no_promotion_failure6M_v_; +text: .text%__1cQDefNewGenerationOIsAliveClosure2t6MpnKGeneration__v_; +text: .text%__1cSScanWeakRefClosure2t6MpnQDefNewGeneration__v_; +text: .text%__1cLCardTableRSbGprepare_for_younger_refs_iterate6Mi_v_; +text: .text%__1cULRUCurrentHeapPolicy2t6M_v_; +text: .text%__1cPCollectorPolicyPis_train_policy6M_i_: collectorPolicy.o; +text: .text%__1cPFastScanClosure2t6MpnQDefNewGeneration_i_v_; +text: .text%__1cQDefNewGenerationbCFastEvacuateFollowersClosure2t6MpnQGenCollectedHeap_ip0pnPFastScanClosure_6_v_; +text: .text%__1cQGenCollectedHeapUprocess_strong_roots6Miiin0ATClassScanningOption_pnQOopsInGenClosure_3_v_; +text: .text%__1cKSharedHeapbAchange_strong_roots_parity6M_v_; +text: .text%__1cMSubTasksDonePis_task_claimed6Mi_i_; +text: .text%__1cIUniverseHoops_do6FpnKOopClosure_i_v_; +text: .text%__1cPFastScanClosureGdo_oop6MppnHoopDesc__v_: defNewGeneration.o; +text: .text%__1cQDefNewGenerationWcopy_to_survivor_space6MpnHoopDesc_p2_2_; +text: .text%__1cKJNIHandlesHoops_do6FpnKOopClosure__v_; +text: .text%__1cOJNIHandleBlockHoops_do6MpnKOopClosure__v_; +text: .text%__1cHThreadsHoops_do6FpnKOopClosure__v_; +text: .text%__1cKJavaThreadHoops_do6MpnKOopClosure__v_; +text: .text%__1cGThreadHoops_do6MpnKOopClosure__v_; +text: .text%__1cKHandleAreaHoops_do6MpnKOopClosure__v_; +text: .text%__1cNchunk_oops_do6FpnKOopClosure_pnFChunk_pc_I_: handles.o; +text: .text%__1cQStackFrameStream2t6MpnKJavaThread_i_v_; +text: .text%__1cFframeQoops_do_internal6MpnKOopClosure_pnLRegisterMap_i_v_; +text: .text%__1cFframeToops_interpreted_do6MpnKOopClosure_pknLRegisterMap_i_v_; +text: .text%__1cFframeVinterpreter_frame_bci6kM_i_; +text: .text%__1cFframebDinterpreter_frame_monitor_end6kM_pnPBasicObjectLock__; +text: .text%__1cFframebFinterpreter_frame_monitor_begin6kM_pnPBasicObjectLock__; +text: .text%__1cRInterpreterOopMap2t6M_v_; +text: .text%__1cRInterpreterOopMapKinitialize6M_v_; +text: .text%__1cNmethodOopDescImask_for6MipnRInterpreterOopMap__v_; +text: .text%__1cNinstanceKlassImask_for6MnMmethodHandle_ipnRInterpreterOopMap__v_; +text: .text%__1cLOopMapCache2t6M_v_; +text: .text%__1cLOopMapCacheGlookup6MnMmethodHandle_ipnRInterpreterOopMap__v_; +text: .text%__1cLOopMapCacheIentry_at6kMi_pnQOopMapCacheEntry__; +text: .text%__1cRInterpreterOopMapIis_empty6M_i_; +text: .text%__1cQOopMapCacheEntryEfill6MnMmethodHandle_i_v_; +text: .text%__1cQOopMapCacheEntryFflush6M_v_; +text: .text%__1cQOopMapCacheEntryTdeallocate_bit_mask6M_v_; +text: .text%__1cQOopMapCacheEntryPfill_for_native6M_v_; +text: .text%__1cQOopMapCacheEntryRallocate_bit_mask6M_v_; +text: .text%__1cTMaskFillerForNative2t6MnMmethodHandle_pIi_v_: oopMapCache.o; +text: .text%__1cNFingerprinterLfingerprint6M_X_: oopMapCache.o; +text: .text%__1cTMaskFillerForNativeLpass_object6M_v_: oopMapCache.o; +text: .text%__1cRInterpreterOopMapNresource_copy6MpnQOopMapCacheEntry__v_; +text: .text%__1cRInterpreterOopMapLiterate_oop6MpnNOffsetClosure__v_; +text: .text%__1cXInterpreterFrameClosureJoffset_do6Mi_v_: frame.o; +text: .text%__1cRInterpreterOopMap2T6M_v_; +text: .text%__1cTOopMapForCacheEntry2t6MnMmethodHandle_ipnQOopMapCacheEntry__v_; +text: .text%__1cTOopMapForCacheEntryLcompute_map6MpnGThread__v_; +text: .text%__1cTOopMapForCacheEntryRpossible_gc_point6MpnOBytecodeStream__i_; +text: .text%__1cTOopMapForCacheEntryOreport_results6kM_i_: oopMapCache.o; +text: .text%__1cOGenerateOopMapVresult_for_basicblock6Mi_v_; +text: .text%__1cTOopMapForCacheEntryZfill_stackmap_for_opcodes6MpnOBytecodeStream_pnNCellTypeState_4i_v_; +text: .text%__1cQOopMapCacheEntryIset_mask6MpnNCellTypeState_2i_v_; +text: .text%__1cFframeNoops_entry_do6MpnKOopClosure_pknLRegisterMap__v_; +text: .text%__1cPJavaCallWrapperHoops_do6MpnKOopClosure__v_; +text: .text%__1cXNativeSignatureIteratorHdo_long6M_v_: oopMapCache.o; +text: .text%__1cTMaskFillerForNativeJpass_long6M_v_: oopMapCache.o; +text: .text%__1cFframebHnext_monitor_in_interpreter_frame6kMpnPBasicObjectLock__2_; +text: .text%__1cOGenerateOopMapPdo_monitorenter6Mi_v_; +text: .text%__1cOGenerateOopMapXreplace_all_CTS_matches6MnNCellTypeState_1_v_; +text: .text%__1cOGenerateOopMapMmonitor_push6MnNCellTypeState__v_; +text: .text%__1cQComputeCallStackHdo_bool6M_v_: generateOopMap.o; +text: .text%__1cQComputeCallStackHdo_long6M_v_: generateOopMap.o; +text: .text%__1cOGenerateOopMapOdo_monitorexit6Mi_v_; +text: .text%__1cOGenerateOopMapLmonitor_pop6M_nNCellTypeState__; +text: .text%__1cRComputeEntryStackHdo_long6M_v_: generateOopMap.o; +text: .text%__1cPBytecode_invokeIis_valid6kM_i_: frame.o; +text: .text%__1cXNativeSignatureIteratorJdo_object6Mii_v_: oopMapCache.o; +text: .text%__1cFframebDoops_interpreted_arguments_do6MnMsymbolHandle_ipnKOopClosure__v_; +text: .text%__1cRArgumentOopFinderDset6MinJBasicType__v_: frame.o; +text: .text%__1cIVMThreadHoops_do6MpnKOopClosure__v_; +text: .text%__1cQVMOperationQdDueueHoops_do6MpnKOopClosure__v_; +text: .text%__1cQVMOperationQdDueueNqueue_oops_do6MipnKOopClosure__v_; +text: .text%__1cSObjectSynchronizerHoops_do6FpnKOopClosure__v_; +text: .text%__1cMFlatProfilerHoops_do6FpnKOopClosure__v_; +text: .text%__1cKManagementHoops_do6FpnKOopClosure__v_; +text: .text%__1cNMemoryServiceHoops_do6FpnKOopClosure__v_; +text: .text%__1cKMemoryPoolHoops_do6MpnKOopClosure__v_; +text: .text%__1cNMemoryManagerHoops_do6MpnKOopClosure__v_; +text: .text%__1cNThreadServiceHoops_do6FpnKOopClosure__v_; +text: .text%__1cLJvmtiExportHoops_do6FpnKOopClosure__v_; +text: .text%__1cXJvmtiCurrentBreakpointsHoops_do6FpnKOopClosure__v_; +text: .text%__1cbGJvmtiVMObjectAllocEventCollectorXoops_do_for_all_threads6FpnKOopClosure__v_; +text: .text%__1cQSystemDictionaryHoops_do6FpnKOopClosure__v_; +text: .text%__1cQSystemDictionaryRpreloaded_oops_do6FpnKOopClosure__v_; +text: .text%__1cKDictionaryHoops_do6MpnKOopClosure__v_; +text: .text%__1cPDictionaryEntrybDprotection_domain_set_oops_do6MpnKOopClosure__v_: dictionary.o; +text: .text%__1cQPlaceholderTableHoops_do6MpnKOopClosure__v_; +text: .text%__1cVLoaderConstraintTableHoops_do6MpnKOopClosure__v_; +text: .text%__1cUCompactingPermGenGenUyounger_refs_iterate6MpnQOopsInGenClosure__v_; +text: .text%__1cbCOneContigSpaceCardGenerationUyounger_refs_iterate6MpnQOopsInGenClosure__v_; +text: .text%__1cKGenerationbDyounger_refs_in_space_iterate6MpnFSpace_pnQOopsInGenClosure__v_; +text: .text%__1cLCardTableRSbDyounger_refs_in_space_iterate6MpnFSpace_pnQOopsInGenClosure__v_; +text: .text%__1cPContiguousSpaceLnew_dcto_cl6MpnKOopClosure_nRCardTableModRefBSOPrecisionStyle_pnIHeapWord__pnVDirtyCardToOopClosure__; +text: .text%__1cPContiguousSpaceZused_region_at_save_marks6kM_nJMemRegion__: space.o; +text: .text%__1cRCardTableModRefBSWnon_clean_card_iterate6MpnFSpace_nJMemRegion_pnVDirtyCardToOopClosure_pnQMemRegionClosure_i_v_; +text: .text%__1cRCardTableModRefBSbBnon_clean_card_iterate_work6MnJMemRegion_pnQMemRegionClosure_i_v_; +text: .text%__1cJMemRegionMintersection6kMk0_0_; +text: .text%__1cYClearNoncleanCardWrapperMdo_MemRegion6MnJMemRegion__v_: cardTableRS.o; +text: .text%__1cYClearNoncleanCardWrapperKclear_card6MpW_i_: cardTableRS.o; +text: .text%__1cVDirtyCardToOopClosureMdo_MemRegion6MnJMemRegion__v_; +text: .text%__1cWOffsetTableContigSpaceLblock_start6kMpkv_pnIHeapWord__: space.o; +text: .text%__1cbBBlockOffsetArrayContigSpaceSblock_start_unsafe6kMpkv_pnIHeapWord__; +text: .text%__1cPContiguousSpaceKblock_size6kMpknIHeapWord__I_; +text: .text%__1cUContiguousSpaceDCTOCOget_actual_top6MpnIHeapWord_2_2_; +text: .text%__1cPContiguousSpaceRtoContiguousSpace6M_p0_: space.o; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: instanceKlass.o; +text: .text%__1cPFiltering_DCTOCPwalk_mem_region6MnJMemRegion_pnIHeapWord_3_v_; +text: .text%__1cUContiguousSpaceDCTOCXwalk_mem_region_with_cl6MnJMemRegion_pnIHeapWord_3pnQFilteringClosure__v_; +text: .text%__1cFKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_: methodKlass.o; +text: .text%__1cLmethodKlassRoop_oop_iterate_m6MpnHoopDesc_pnKOopClosure_nJMemRegion__i_; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: instanceKlassKlass.o; +text: .text%__1cSinstanceKlassKlassPoop_oop_iterate6MpnHoopDesc_pnKOopClosure__i_; +text: .text%__1cNinstanceKlassViterate_static_fields6MpnKOopClosure__v_; +text: .text%__1cLklassVtablePoop_oop_iterate6MpnKOopClosure__v_; +text: .text%__1cQFilteringClosureGdo_oop6MppnHoopDesc__v_; +text: .text%__1cLklassItablePoop_oop_iterate6MpnKOopClosure__v_; +text: .text%__1cKklassKlassPoop_oop_iterate6MpnHoopDesc_pnKOopClosure__i_; +text: .text%__1cKOopClosureXshould_remember_klasses6kM_ki_: space.o; +text: .text%__1cNinstanceKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_; +text: .text%__1cWconstantPoolCacheKlassIoop_size6kMpnHoopDesc__i_; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: cpCacheKlass.o; +text: .text%__1cWconstantPoolCacheKlassPoop_oop_iterate6MpnHoopDesc_pnKOopClosure__i_; +text: .text%__1cWConstantPoolCacheEntryLoop_iterate6MpnKOopClosure__v_; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: objArrayKlassKlass.o; +text: .text%__1cSobjArrayKlassKlassPoop_oop_iterate6MpnHoopDesc_pnKOopClosure__i_; +text: .text%__1cParrayKlassKlassPoop_oop_iterate6MpnHoopDesc_pnKOopClosure__i_; +text: .text%__1cNobjArrayKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_; +text: .text%__1cNinstanceKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_; +text: .text%__1cNobjArrayKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: typeArrayKlass.o; +text: .text%__1cOtypeArrayKlassPoop_oop_iterate6MpnHoopDesc_pnKOopClosure__i_; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: constMethodKlass.o; +text: .text%__1cQconstMethodKlassPoop_oop_iterate6MpnHoopDesc_pnKOopClosure__i_; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: methodKlass.o; +text: .text%__1cLmethodKlassPoop_oop_iterate6MpnHoopDesc_pnKOopClosure__i_; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: constantPoolKlass.o; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: constantPoolKlass.o; +text: .text%__1cFKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_: constMethodKlass.o; +text: .text%__1cQconstMethodKlassRoop_oop_iterate_m6MpnHoopDesc_pnKOopClosure_nJMemRegion__i_; +text: .text%__1cFKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_: constantPoolKlass.o; +text: .text%__1cRconstantPoolKlassRoop_oop_iterate_m6MpnHoopDesc_pnKOopClosure_nJMemRegion__i_; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: constMethodKlass.o; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: constMethodKlass.o; +text: .text%__1cFKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_: symbolKlass.o; +text: .text%__1cLsymbolKlassRoop_oop_iterate_m6MpnHoopDesc_pnKOopClosure_nJMemRegion__i_; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: symbolKlass.o; +text: .text%__1cLsymbolKlassPoop_oop_iterate6MpnHoopDesc_pnKOopClosure__i_; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: constantPoolKlass.o; +text: .text%__1cRconstantPoolKlassPoop_oop_iterate6MpnHoopDesc_pnKOopClosure__i_; +text: .text%__1cFKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_: cpCacheKlass.o; +text: .text%__1cWconstantPoolCacheKlassRoop_oop_iterate_m6MpnHoopDesc_pnKOopClosure_nJMemRegion__i_; +text: .text%__1cWConstantPoolCacheEntryNoop_iterate_m6MpnKOopClosure_nJMemRegion__v_; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: cpCacheKlass.o; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: cpCacheKlass.o; +text: .text%__1cFKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_: typeArrayKlass.o; +text: .text%__1cOtypeArrayKlassRoop_oop_iterate_m6MpnHoopDesc_pnKOopClosure_nJMemRegion__i_; +text: .text%__1cFKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_: instanceKlassKlass.o; +text: .text%__1cSinstanceKlassKlassRoop_oop_iterate_m6MpnHoopDesc_pnKOopClosure_nJMemRegion__i_; +text: .text%__1cNinstanceKlassViterate_static_fields6MpnKOopClosure_nJMemRegion__v_; +text: .text%__1cLklassVtableRoop_oop_iterate_m6MpnKOopClosure_nJMemRegion__v_; +text: .text%__1cLklassItableRoop_oop_iterate_m6MpnKOopClosure_nJMemRegion__v_; +text: .text%__1cKklassKlassRoop_oop_iterate_m6MpnHoopDesc_pnKOopClosure_nJMemRegion__i_; +text: .text%__1cLOopMapCacheLoop_iterate6MpnKOopClosure_nJMemRegion__v_; +text: .text%__1cRInterpreterOopMapLoop_iterate6MpnKOopClosure_nJMemRegion__v_; +text: .text%__1cKOopClosureIdo_oop_v6MppnHoopDesc__v_: space.o; +text: .text%__1cLOopMapCacheLoop_iterate6MpnKOopClosure__v_; +text: .text%__1cRInterpreterOopMapLoop_iterate6MpnKOopClosure__v_; +text: .text%__1cVcompiledICHolderKlassIoop_size6kMpnHoopDesc__i_; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: compiledICHolderKlass.o; +text: .text%__1cVcompiledICHolderKlassPoop_oop_iterate6MpnHoopDesc_pnKOopClosure__i_; +text: .text%__1cFKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_: klassKlass.o; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: klassKlass.o; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: typeArrayKlassKlass.o; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_: arrayKlassKlass.o; +text: .text%__1cLCardTableRSUyounger_refs_iterate6MpnKGeneration_pnQOopsInGenClosure__v_; +text: .text%__1cMSubTasksDoneTall_tasks_completed6M_v_; +text: .text%__1cQDefNewGenerationbCFastEvacuateFollowersClosureHdo_void6M_v_; +text: .text%__1cQGenCollectedHeapbCoop_since_save_marks_iterate6MipnPFastScanClosure_2_v_; +text: .text%__1cQDefNewGenerationbFoop_since_save_marks_iterate_nv6MpnPFastScanClosure__v_; +text: .text%__1cPContiguousSpacebFoop_since_save_marks_iterate_nv6MpnPFastScanClosure__v_; +text: .text%__1cNobjArrayKlassSoop_oop_iterate_nv6MpnHoopDesc_pnPFastScanClosure__i_; +text: .text%__1cNinstanceKlassSoop_oop_iterate_nv6MpnHoopDesc_pnPFastScanClosure__i_; +text: .text%__1cFKlassSoop_oop_iterate_nv6MpnHoopDesc_pnPFastScanClosure__i_: typeArrayKlass.o; +text: .text%__1cQinstanceRefKlassSoop_oop_iterate_nv6MpnHoopDesc_pnPFastScanClosure__i_; +text: .text%__1cXjava_lang_ref_ReferenceNreferent_addr6FpnHoopDesc__p2_; +text: .text%__1cSReferenceProcessorSdiscover_reference6MpnHoopDesc_nNReferenceType__i_; +text: .text%__1cXjava_lang_ref_ReferenceJnext_addr6FpnHoopDesc__p2_; +text: .text%__1cXjava_lang_ref_ReferencePdiscovered_addr6FpnHoopDesc__p2_; +text: .text%__1cSReferenceProcessorTget_discovered_list6MnNReferenceType__ppnHoopDesc__; +text: .text%__1cKGenerationHpromote6MpnHoopDesc_Ip2_2_; +text: .text%__1cbCOneContigSpaceCardGenerationIallocate6MIii_pnIHeapWord__: tenuredGeneration.o; +text: .text%__1cbCOneContigSpaceCardGenerationbFoop_since_save_marks_iterate_nv6MpnPFastScanClosure__v_; +text: .text%__1cQGenCollectedHeapbAno_allocs_since_save_marks6Mi_i_; +text: .text%__1cQDefNewGenerationbAno_allocs_since_save_marks6M_i_; +text: .text%__1cbCOneContigSpaceCardGenerationbAno_allocs_since_save_marks6M_i_; +text: .text%__1cQDefNewGenerationUFastKeepAliveClosure2t6Mp0pnSScanWeakRefClosure__v_; +text: .text%__1cQDefNewGenerationQKeepAliveClosure2t6MpnSScanWeakRefClosure__v_; +text: .text%__1cbDReferenceProcessorInitializerIis_clean6kM_v_: concurrentMarkSweepGeneration.o; +text: .text%__1cSReferenceProcessorbDprocess_discovered_references6M_v_; +text: .text%__1cSReferenceProcessorbAprocess_discovered_reflist6MppnHoopDesc_pnPReferencePolicy_i_v_; +text: .text%__1cSReferenceProcessorOprocess_phase16MppnHoopDesc_pnPReferencePolicy_pnRBoolObjectClosure_pnKOopClosure_pnLVoidClosure__v_; +text: .text%__1cQDefNewGenerationOIsAliveClosureLdo_object_b6MpnHoopDesc__i_; +text: .text%__1cULRUCurrentHeapPolicyWshould_clear_reference6MpnHoopDesc__i_; +text: .text%__1cbBjava_lang_ref_SoftReferenceFclock6F_x_; +text: .text%__1cbBjava_lang_ref_SoftReferenceJtimestamp6FpnHoopDesc__x_; +text: .text%__1cXjava_lang_ref_ReferenceIset_next6FpnHoopDesc_2_v_; +text: .text%__1cQDefNewGenerationUFastKeepAliveClosureGdo_oop6MppnHoopDesc__v_; +text: .text%__1cSReferenceProcessorOprocess_phase26MppnHoopDesc_pnRBoolObjectClosure_pnKOopClosure__v_; +text: .text%__1cSReferenceProcessorOprocess_phase36MppnHoopDesc_ipnRBoolObjectClosure_pnKOopClosure_pnLVoidClosure__v_; +text: .text%__1cSReferenceProcessorQprocess_phaseJNI6M_v_; +text: .text%__1cKJNIHandlesMweak_oops_do6FpnRBoolObjectClosure_pnKOopClosure__v_; +text: .text%__1cOJNIHandleBlockMweak_oops_do6MpnRBoolObjectClosure_pnKOopClosure__v_; +text: .text%__1cQDefNewGenerationLswap_spaces6M_v_; +text: .text%__1cIageTablebAcompute_tenuring_threshold6MI_i_; +text: .text%__1cKGenerationWupdate_time_of_last_gc6Mx_v_: defNewGeneration.o; +text: .text%__1cSReferenceProcessorbDenqueue_discovered_references6M_i_; +text: .text%__1cXjava_lang_ref_ReferenceRpending_list_addr6F_ppnHoopDesc__; +text: .text%__1cSReferenceProcessorbBenqueue_discovered_reflists6MppnHoopDesc__v_; +text: .text%__1cSReferenceProcessorbAenqueue_discovered_reflist6MpnHoopDesc_p2_v_; +text: .text%__1cQGenCollectedHeapPupdate_gc_stats6Mii_v_: genCollectedHeap.o; +text: .text%__1cKGenerationPupdate_gc_stats6Mii_v_: defNewGeneration.o; +text: .text%__1cRTenuredGenerationPupdate_gc_stats6Mii_v_; +text: .text%__1cVAdaptivePaddedAverageGsample6Mf_v_; +text: .text%__1cKGenerationPupdate_gc_stats6Mii_v_: compactingPermGenGen.o; +text: .text%__1cRTenuredGenerationOshould_collect6MiIii_i_; +text: .text%__1cKGenerationPshould_allocate6MIii_i_: tenuredGeneration.o; +text: .text%__1cbCOneContigSpaceCardGenerationEfree6kM_I_; +text: .text%__1cQDefNewGenerationQcompute_new_size6M_v_; +text: .text%__1cNMemoryServiceStrack_memory_usage6F_v_; +text: .text%__1cRLowMemoryDetectorRdetect_low_memory6F_v_; +text: .text%__1cQGenCollectedHeapLgc_epilogue6Mi_v_; +text: .text%__1cNCollectedHeapQresize_all_tlabs6M_v_; +text: .text%__1cWThreadLocalAllocBufferQresize_all_tlabs6F_v_; +text: .text%__1cWThreadLocalAllocBufferGresize6M_v_; +text: .text%__1cUGenGCEpilogueClosureNdo_generation6MpnKGeneration__v_: genCollectedHeap.o; +text: .text%__1cQDefNewGenerationLgc_epilogue6Mi_v_; +text: .text%__1cRTenuredGenerationLgc_epilogue6Mi_v_; +text: .text%__1cbCOneContigSpaceCardGenerationLgc_epilogue6Mi_v_; +text: .text%__1cRTenuredGenerationPupdate_counters6M_v_; +text: .text%__1cUCompactingPermGenGenPupdate_counters6M_v_; +text: .text%__1cXTraceMemoryManagerStats2T6M_v_; +text: .text%__1cNMemoryServiceGgc_end6Fi_v_; +text: .text%__1cPGCMemoryManagerGgc_end6M_v_; +text: .text%__1cRLowMemoryDetectorWdetect_after_gc_memory6FpnKMemoryPool__v_; +text: .text%__1cNJvmtiGCMarker2T6M_v_; +text: .text%__1cPVM_GC_OperationNdoit_epilogue6M_v_; +text: .text%__1cPVM_GC_OperationbKrelease_and_notify_pending_list_lock6M_v_; +text: .text%__1cQinstanceRefKlassbKrelease_and_notify_pending_list_lock6FipnJBasicLock__v_; +text: .text%__1cXJNI_ArgumentPusherVaArgIget_long6M_v_: jni.o; +text: .text%jni_GetIntArrayRegion: jni.o; +text: .text%jni_SetIntArrayRegion: jni.o; +text: .text%jni_PushLocalFrame: jni.o; +text: .text%jni_PopLocalFrame: jni.o; +text: .text%__1cMGraphBuilderJnegate_op6MpnJValueType__v_; +text: .text%__1cINegateOpFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerLdo_NegateOp6MpnINegateOp__v_; +text: .text%__1cMLinkResolverbPlinktime_resolve_interface_method_or_null6FnLKlassHandle_nMsymbolHandle_21i_nMmethodHandle__; +text: .text%__1cPciInstanceKlassLimplementor6M_p0_; +text: .text%__1cINegateOpPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorLdo_NegateOp6MpnINegateOp__v_; +text: .text%__1cIValueGenJspill_one6MpnJValueType__v_; +text: .text%__1cIRegAllocbBget_smallest_value_to_spill6kMpnJValueType__pnLInstruction__; +text: .text%__1cLLIR_EmitterRarray_store_check6MpnLLIR_OprDesc_2nFRInfo_33pnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListLstore_check6MpnLLIR_OprDesc_2222pnMCodeEmitInfo__v_; +text: .text%__1cPLIR_OpTypeCheck2t6MnILIR_Code_pnLLIR_OprDesc_3333pnMCodeEmitInfo__v_; +text: .text%__1cXArrayStoreExceptionStub2t6MpnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListLshift_right6MnFRInfo_i1_v_: c1_LIREmitter.o; +text: .text%__1cILIR_ListLshift_right6MpnLLIR_OprDesc_222_v_; +text: .text%__1cIValueGenLdo_NegateOp6MpnINegateOp__v_; +text: .text%__1cLLIR_EmitterGnegate6MnFRInfo_pnLLIR_OprDesc__v_; +text: .text%__1cILIR_ListGnegate6MnFRInfo_1_v_: c1_LIREmitter.o; +text: .text%__1cXArrayStoreExceptionStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cXArrayStoreExceptionStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cNLIR_AssemblerEleal6MpnLLIR_OprDesc_2_v_; +text: .text%__1cNLIR_AssemblerGnegate6MpnLLIR_OprDesc_2_v_; +text: .text%__1cNCodeStubArrayIindex_of6kMkpnICodeStub__i_: c1_LIRAssembler_x86.o; +text: .text%__1cXArrayStoreExceptionStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cIRuntime1Tresolve_static_call6FpnKJavaThread_pnHoopDesc__pC_; +text: .text%__1cSCompiledStaticCallNcompute_entry6FnMmethodHandle_rnOStaticCallInfo__v_; +text: .text%__1cSCompiledStaticCallIis_clean6kM_i_; +text: .text%__1cSCompiledStaticCallDset6MrknOStaticCallInfo__v_; +text: .text%__1cMLinkResolverYresolve_interface_method6FrnMmethodHandle_rnLKlassHandle_nSconstantPoolHandle_ipnGThread__v_; +text: .text%__1cHciKlassSsuper_check_offset6M_I_; +text: .text%__1cIRuntime1Thandle_wrong_method6FpnKJavaThread_pnHoopDesc__pC_; +text: .text%__1cNSharedRuntimeTreresolve_call_site6FpnKJavaThread_pnGThread__nMmethodHandle__; +text: .text%__1cFframeRis_compiled_frame6kMpi_i_; +text: .text%__1cHnmethodOis_java_method6kM_i_: nmethod.o; +text: .text%__1cGEventsDlog6FpkcE_v_: sharedRuntime.o; +text: .text%__1cJCodeCacheMfind_nmethod6Fpv_pnHnmethod__; +text: .text%__1cNRelocIteratorEnext6M_i_: sharedRuntime.o; +text: .text%__1cKCompiledICMset_to_clean6M_v_; +text: .text%__1cKCompiledICMstub_address6kM_pC_; +text: .text%__1cGICStubFclear6M_v_; +text: .text%__1cNSharedRuntimeSfind_callee_method6FpnKJavaThread_pnGThread__nMmethodHandle__; +text: .text%__1cRInlineCacheBufferSic_destination_for6FpnKCompiledIC__pC_; +text: .text%__1cIRuntime1Jarraycopy6FpnHoopDesc_i2ii_i_; +text: .text%__1cMGraphBuilderNadd_dependent6MpnPciInstanceKlass_pnIciMethod__v_; +text: .text%__1cYDebugInformationRecorderNadd_dependent6MpnPciInstanceKlass_pnIciMethod__v_; +text: .text%__1cNinstanceKlassVadd_dependent_nmethod6MpnHnmethod__v_; +text: .text%__1cJCodeCacheXmark_for_deoptimization6FpnMklassOopDesc__i_; +text: .text%__1cNinstanceKlassXmark_dependent_nmethods6MpnMklassOopDesc__i_; +text: .text%jni_NewWeakGlobalRef: jni.o; +text: .text%__1cKJNIHandlesQmake_weak_global6FnGHandle__pnI_jobject__; +text: .text%__1cMLinkResolverbBlookup_method_in_interfaces6FrnMmethodHandle_nLKlassHandle_nMsymbolHandle_4pnGThread__v_; +text: .text%jni_CallIntMethodV: jni.o; +text: .text%Unsafe_GetObject; +text: .text%jni_CallBooleanMethod: jni.o; +text: .text%jni_CallVoidMethodV: jni.o; +text: .text%JVM_GetClassDeclaredMethods; +text: .text%JVM_InvokeMethod; +text: .text%__1cKReflectionNinvoke_method6FpnHoopDesc_nGHandle_nOobjArrayHandle_pnGThread__2_; +text: .text%__1cYjava_lang_reflect_MethodFclazz6FpnHoopDesc__2_; +text: .text%__1cYjava_lang_reflect_MethodEslot6FpnHoopDesc__i_; +text: .text%__1cYjava_lang_reflect_MethodPparameter_types6FpnHoopDesc__2_; +text: .text%__1cYjava_lang_reflect_MethodLreturn_type6FpnHoopDesc__2_; +text: .text%JVM_IsInterrupted; +# Test LoadJFrame +text: .text%__1cTresource_free_bytes6FpcI_v_; +text: .text%__1cRComputeEntryStackHdo_bool6M_v_: generateOopMap.o; +text: .text%__1cJFloatTypeDtag6kM_nIValueTag__: c1_ValueType.o; +text: .text%__1cJFloatTypeEbase6kM_pnJValueType__: c1_ValueType.o; +text: .text%__1cJFloatTypeMas_FloatType6M_p0_: c1_ValueType.o; +text: .text%__1cIValueGenTdo_ArithmeticOp_FPU6MpnMArithmeticOp__v_; +text: .text%__1cHLockRegIdo_float6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocOset_locked_fpu6MipnLInstruction_i_v_; +text: .text%__1cIValueGenNis_32bit_mode6M_i_; +text: .text%__1cLGetRefCountIdo_float6Mi_v_: c1_RegAlloc.o; +text: .text%__1cJFloatTypeEsize6kM_i_: c1_ValueType.o; +text: .text%__1cHFreeRegIdo_float6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocMset_free_fpu6Mi_v_; +text: .text%__1cQChangeSpillCountIdo_float6Mi_v_: c1_RegAlloc.o; +text: .text%__1cLLIR_EmitterRarithmetic_op_fpu6MnJBytecodesECode_pnLLIR_OprDesc_44i_v_; +text: .text%__1cILIR_ListDmul6MpnLLIR_OprDesc_22_v_: c1_LIREmitter.o; +text: .text%__1cIValueGenKround_item6MpnEItem__v_; +text: .text%__1cLLIR_EmitterFround6MipnLLIR_OprDesc__v_; +text: .text%__1cILIR_ListKround32bit6MnFRInfo_i_v_: c1_LIREmitter.o; +text: .text%__1cIValueGenOspill_register6MnFRInfo__v_; +text: .text%__1cIRegAllocTget_value_for_rinfo6kMnFRInfo__pnLInstruction__; +text: .text%__1cLGetValueForGdo_cpu6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIValueGenKdivInRInfo6F_nFRInfo__; +text: .text%__1cIValueGenLremOutRInfo6F_nFRInfo__; +text: .text%__1cMArithmeticOpKlock_stack6kM_pnKValueStack__: c1_Instruction.o; +text: .text%__1cLLIR_EmitterParithmetic_idiv6MnJBytecodesECode_pnLLIR_OprDesc_44nFRInfo_pnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListEirem6MnFRInfo_111pnMCodeEmitInfo__v_; +text: .text%__1cHLIR_Op3Fvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cHLIR_Op3Jemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerIemit_op36MpnHLIR_Op3__v_; +text: .text%__1cNLIR_AssemblerIfpu_push6MnFRInfo__v_; +text: .text%__1cIFrameMapLFpuStackSimEpush6Mi_v_; +text: .text%__1cNLIR_AssemblerKfpu_on_tos6MnFRInfo__v_; +text: .text%__1cIFrameMapLFpuStackSimPoffset_from_tos6kMi_i_; +text: .text%__1cIintArrayIindex_of6kMki_i_: c1_FrameMap_x86.o; +text: .text%__1cNLIR_AssemblerHfpu_pop6MnFRInfo__v_; +text: .text%__1cIFrameMapLFpuStackSimDpop6Mi_i_; +text: .text%__1cNLIR_AssemblerKround32_op6MpnLLIR_OprDesc_2_v_; +text: .text%__1cJAssemblerGfist_s6MnHAddress__v_; +text: .text%__1cNLIR_AssemblerJreset_FPU6M_v_; +text: .text%__1cNLIR_AssemblerIemit_op36MpnHLIR_Op3__v_; +text: .text%__1cNLIR_AssemblerParithmetic_idiv6MnILIR_Code_pnLLIR_OprDesc_333pnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerXadd_debug_info_for_div06MipnMCodeEmitInfo__v_; +text: .text%__1cNDivByZeroStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cNDivByZeroStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cIciObjectSis_obj_array_klass6M_i_: ciTypeArrayKlass.o; +text: .text%__1cLInstructionOas_ArrayLength6M_pnLArrayLength__: c1_GraphBuilder.o; +text: .text%__1cLInstructionKas_ShiftOp6M_pnHShiftOp__: c1_Instruction.o; +text: .text%__1cILIR_ListLlogical_xor6MnFRInfo_pnLLIR_OprDesc_1_v_: c1_LIREmitter.o; +text: .text%__1cILIR_ListUunsigned_shift_right6MnFRInfo_i1_v_: c1_LIREmitter.o; +text: .text%__1cIRuntime1Ohandle_ic_miss6FpnKJavaThread_pnHoopDesc__pC_; +text: .text%__1cNSharedRuntimeVhandle_ic_miss_helper6FpnKJavaThread_pnGThread__nMmethodHandle__; +text: .text%__1cbEJvmtiDynamicCodeEventCollector2t6M_v_; +text: .text%__1cKCompiledICOis_megamorphic6kM_i_; +text: .text%__1cLVtableStubsOis_entry_point6FpC_i_; +text: .text%__1cKCompiledICSset_to_megamorphic6MpnICallInfo_nJBytecodesECode_pnGThread__v_; +text: .text%__1cLVtableStubsLcreate_stub6FiipnNmethodOopDesc__pC_; +text: .text%__1cLVtableStubsGlookup6Fiii_pnKVtableStub__; +text: .text%__1cLVtableStubsScreate_vtable_stub6Fii_pnKVtableStub__; +text: .text%__1cKVtableStubSpd_code_size_limit6Fi_i_; +text: .text%__1cKVtableStub2n6FIi_pv_; +text: .text%__1cKVtableStubRpd_code_alignment6F_i_; +text: .text%__1cLVtableStubsFenter6FiiipnKVtableStub__v_; +text: .text%__1cGEventsDlog6FpkcE_v_: compiledIC.o; +text: .text%__1cbEJvmtiDynamicCodeEventCollector2T6M_v_; +text: .text%Unsafe_EnsureClassInitialized; +text: .text%Unsafe_StaticFieldOffset; +text: .text%Unsafe_StaticFieldBaseFromField; +text: .text%Unsafe_GetIntVolatile; +text: .text%__1cUBytecode_tableswitchGlength6M_i_: generateOopMap.o; +text: .text%__1cUBytecode_tableswitchOdest_offset_at6kMi_i_; +text: .text%__1cUBytecode_tableswitchGlength6M_i_: c1_GraphBuilder.o; +text: .text%__1cLInstructionKas_ShiftOp6M_pnHShiftOp__: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderMtable_switch6M_v_; +text: .text%__1cLTableSwitchFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerOdo_TableSwitch6MpnLTableSwitch__v_; +text: .text%__1cLInstructionJas_Return6M_pnGReturn__: c1_GraphBuilder.o; +text: .text%__1cGSwitchPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorOdo_TableSwitch6MpnLTableSwitch__v_; +text: .text%__1cIValueGenOdo_TableSwitch6MpnLTableSwitch__v_; +text: .text%__1cIValueGenVsetup_phis_for_switch6MpnEItem_pnKValueStack__v_; +text: .text%__1cLLIR_EmitterOtableswitch_op6MpnLLIR_OprDesc_ipnKBlockBegin__v_; +text: .text%__1cWstatic_call_RelocationLstatic_stub6M_pC_; +text: .text%__1cSCompiledStaticCallMset_to_clean6M_v_; +# Test JHello +text: .text%__1cYjava_lang_reflect_MethodNset_signature6FpnHoopDesc_2_v_; +text: .text%JVM_InitializeSocketLibrary; +text: .text%__1cDhpiZinitialize_socket_library6F_i_; +text: .text%JVM_Socket; +text: .text%Unsafe_PageSize; +text: .text%__1cNFingerprinterHdo_byte6M_v_: dump.o; +text: .text%__1cXNativeSignatureIteratorHdo_byte6M_v_: interpreterRuntime.o; +text: .text%Unsafe_SetMemory; +text: .text%__1cECopyQpd_fill_to_words6FpnIHeapWord_II_v_: unsafe.o; +text: .text%__1cNSharedRuntimeElrem6Fxx_x_; +text: .text%Unsafe_DefineClass1; +text: .text%__1cSUnsafe_DefineClass6FpnHJNIEnv__pnI_jstring_pnL_jbyteArray_iipnI_jobject_7_pnH_jclass__: unsafe.o; +text: .text%JVM_DefineClass; +text: .text%__1cPClassFileParserXverify_unqualified_name6MpcIi_i_; +text: .text%__1cVLoaderConstraintTableYextend_loader_constraint6MpnVLoaderConstraintEntry_nGHandle_pnMklassOopDesc__v_; +text: .text%__1cVLoaderConstraintTablebHensure_loader_constraint_capacity6MpnVLoaderConstraintEntry_i_v_; +text: .text%__1cIciObjectIis_klass6M_i_: ciInstance.o; +text: .text%__1cQInstanceConstantIencoding6kM_pnI_jobject__; +text: .text%__1cLInstructionOas_ArrayLength6M_pnLArrayLength__: c1_Instruction.o; +text: .text%__1cILIR_ListQunwind_exception6MnFRInfo_1pnMCodeEmitInfo__v_: c1_CodeGenerator.o; +text: .text%__1cIRuntime1Tprimitive_arraycopy6FpnIHeapWord_2i_v_; +text: .text%__1cRComputeEntryStackHdo_char6M_v_: generateOopMap.o; +text: .text%jni_NewDirectByteBuffer; +text: .text%__1cbDinitializeDirectBufferSupport6FpnHJNIEnv___i_: jni.o; +text: .text%lookupDirectBufferClasses: jni.o; +text: .text%__1cJlookupOne6FpnHJNIEnv__pkcpnGThread__pnH_jclass__: jni.o; +text: .text%__1cHJNIEnv_JNewObject6MpnH_jclass_pnK_jmethodID_E_pnI_jobject__: jni.o; +text: .text%jni_GetDoubleArrayRegion: jni.o; +text: .text%__1cNSignatureInfoJdo_double6M_v_: bytecode.o; +text: .text%__1cXJNI_ArgumentPusherVaArgJget_float6M_v_: jni.o; +text: .text%__1cQComputeCallStackHdo_byte6M_v_: generateOopMap.o; +text: .text%__1cFKlassQup_cast_abstract6M_p0_; +text: .text%__1cRComputeEntryStackHdo_byte6M_v_: generateOopMap.o; +text: .text%__1cNSharedRuntimeDd2i6Fd_i_; +text: .text%__1cSInterpreterRuntimeWslow_signature_handler6FpnKJavaThread_pnNmethodOopDesc_pi5_pC_; +text: .text%__1cXNativeSignatureIteratorJdo_object6Mii_v_: interpreterRT_x86.o; +text: .text%__1cUSlowSignatureHandlerLpass_object6M_v_: interpreterRT_x86.o; +text: .text%__1cXNativeSignatureIteratorIdo_array6Mii_v_: interpreterRT_x86.o; +text: .text%__1cXNativeSignatureIteratorGdo_int6M_v_: interpreterRT_x86.o; +text: .text%__1cUSlowSignatureHandlerIpass_int6M_v_: interpreterRT_x86.o; +text: .text%__1cXNativeSignatureIteratorHdo_bool6M_v_: interpreterRT_x86.o; +text: .text%jni_GetFloatArrayRegion: jni.o; +text: .text%jni_GetCharArrayRegion: jni.o; +text: .text%jni_SetFloatField: jni.o; +text: .text%jni_NewFloatArray: jni.o; +text: .text%jni_SetFloatArrayRegion: jni.o; +# SwingSet +text: .text%JVM_GetFieldIxModifiers; +text: .text%JVM_GetCPFieldClassNameUTF; +text: .text%JVM_GetCPFieldModifiers; +text: .text%__1cPClassFileParserUverify_constantvalue6MiinSconstantPoolHandle_pnGThread__v_; +text: .text%__1cXjava_lang_ref_ReferenceOset_discovered6FpnHoopDesc_2_v_; +text: .text%__1cMStoreIndexedPother_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%JVM_MonitorNotify; +text: .text%__1cSObjectSynchronizerGnotify6FnGHandle_pnGThread__v_; +text: .text%__1cKValueStackElock6MpnHIRScope_pnLInstruction__i_; +text: .text%__1cKValueStackGunlock6M_i_; +text: .text%__1cLLIR_EmitterVmonitorenter_at_entry6MnFRInfo_pnMCodeEmitInfo__v_; +text: .text%__1cLLIR_EmitterNmonitor_enter6MnFRInfo_111ipnMCodeEmitInfo_3_v_; +text: .text%__1cQMonitorEnterStub2t6MnFRInfo_1pnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListbAload_stack_address_monitor6MinFRInfo__v_: c1_LIREmitter.o; +text: .text%__1cILIR_ListLlock_object6MnFRInfo_111pnICodeStub_pnMCodeEmitInfo__v_; +text: .text%__1cIValueGenNsyncTempRInfo6F_nFRInfo__; +text: .text%__1cLLIR_EmitterQreturn_op_prolog6Mi_v_; +text: .text%__1cLLIR_EmitterMmonitor_exit6MnFRInfo_11i_v_; +text: .text%__1cILIR_ListNunlock_object6MnFRInfo_11pnICodeStub__v_; +text: .text%__1cKLIR_OpLockFvisit6MpnQLIR_OpVisitState__v_; +text: .text%__1cQMonitorEnterStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cRMonitorAccessStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cKLIR_OpLockJemit_code6MpnVLIR_AbstractAssembler__v_; +text: .text%__1cNLIR_OptimizerJemit_lock6MpnKLIR_OpLock__v_; +text: .text%__1cNLIR_AssemblerPmonitor_address6MinFRInfo__v_; +text: .text%__1cIFrameMapbEaddress_for_monitor_lock_index6kMi_nHAddress__; +text: .text%__1cIFrameMapbAfp_offset_for_monitor_lock6kMi_i_; +text: .text%__1cNLIR_AssemblerJemit_lock6MpnKLIR_OpLock__v_; +text: .text%__1cRC1_MacroAssemblerLlock_object6MpnMRegisterImpl_22rnFLabel__v_; +text: .text%__1cQMonitorEnterStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cIFrameMapWmonitor_object_regname6kMi_nHOptoRegEName__; +text: .text%__1cIFrameMapbCfp_offset_for_monitor_object6kMi_i_; +text: .text%__1cMCodeEmitInfobHlocation_for_monitor_object_index6Mi_nILocation__; +text: .text%__1cIFrameMapbHlocation_for_monitor_object_index6kMipnILocation__i_; +text: .text%__1cMCodeEmitInfobFlocation_for_monitor_lock_index6Mi_nILocation__; +text: .text%__1cIFrameMapbFlocation_for_monitor_lock_index6kMipnILocation__i_; +text: .text%__1cMMonitorValue2t6MpnKScopeValue_nILocation__v_; +text: .text%__1cMMonitorValueIwrite_on6MpnUDebugInfoWriteStream__v_; +text: .text%__1cRC1_MacroAssemblerNunlock_object6MpnMRegisterImpl_22rnFLabel__v_; +text: .text%__1cPMonitorExitStubMis_call_stub6kM_i_: c1_CodeStubs_x86.o; +text: .text%__1cQMonitorEnterStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%__1cNLIR_AssemblerRload_receiver_reg6MpnMRegisterImpl__v_; +text: .text%__1cNLIR_AssemblerLmonitorexit6MnFRInfo_1pnMRegisterImpl_i3_v_; +text: .text%__1cPMonitorExitStubJemit_code6MpnNLIR_Assembler__v_; +text: .text%jni_NewIntArray: jni.o; +text: .text%__1cNCollectedHeapYlarge_typearray_allocate6FnLKlassHandle_iipnGThread__pnHoopDesc__: typeArrayKlass.o; +text: .text%__1cFKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_: objArrayKlassKlass.o; +text: .text%__1cSobjArrayKlassKlassRoop_oop_iterate_m6MpnHoopDesc_pnKOopClosure_nJMemRegion__i_; +text: .text%__1cQinstanceRefKlassSoop_oop_iterate_nv6MpnHoopDesc_pnQFilteringClosure__i_; +text: .text%__1cRTenuredGenerationKshort_name6kM_pkc_: tenuredGeneration.o; +text: .text%__1cKGenerationIcounters6M_pnRCollectorCounters__: tenuredGeneration.o; +text: .text%__1cRTenuredGenerationHcollect6MiiIii_v_; +text: .text%__1cRTenuredGenerationbJretire_alloc_buffers_before_full_gc6M_v_; +text: .text%__1cbCOneContigSpaceCardGenerationHcollect6MiiIii_v_; +text: .text%__1cMGenMarkSweepTinvoke_at_safepoint6FipnSReferenceProcessor_i_v_; +text: .text%__1cJCodeCacheLgc_prologue6F_v_; +text: .text%__1cHThreadsLgc_prologue6F_v_; +text: .text%__1cKJavaThreadLgc_prologue6M_v_; +text: .text%__1cKJavaThreadJframes_do6MpFpnFframe_pknLRegisterMap__v_v_; +text: .text%__1cRframe_gc_prologue6FpnFframe_pknLRegisterMap__v_: thread.o; +text: .text%__1cFframeLgc_prologue6M_v_; +text: .text%__1cQGenCollectedHeapRsave_used_regions6Mii_v_; +text: .text%__1cKGenerationQsave_used_region6M_v_: tenuredGeneration.o; +text: .text%__1cbCOneContigSpaceCardGenerationLused_region6kM_nJMemRegion__; +text: .text%__1cPContiguousSpaceLused_region6kM_nJMemRegion__: space.o; +text: .text%__1cKGenerationQsave_used_region6M_v_: defNewGeneration.o; +text: .text%__1cKGenerationLused_region6kM_nJMemRegion__: defNewGeneration.o; +text: .text%__1cKGenerationQsave_used_region6M_v_: compactingPermGenGen.o; +text: .text%__1cMGenMarkSweepPallocate_stacks6F_v_; +text: .text%__1cQGenCollectedHeapOgather_scratch6MpnKGeneration_I_pnMScratchBlock__; +text: .text%__1cQDefNewGenerationScontribute_scratch6MrpnMScratchBlock_pnKGeneration_I_v_; +text: .text%__1cKGenerationScontribute_scratch6MrpnMScratchBlock_p0I_v_: tenuredGeneration.o; +text: .text%__1cRsort_scratch_list6FrpnMScratchBlock__v_: genCollectedHeap.o; +text: .text%__1cVremoveSmallestScratch6FppnMScratchBlock__1_: genCollectedHeap.o; +text: .text%__1cMGenMarkSweepRmark_sweep_phase16Firii_v_; +text: .text%__1cJEventMark2t6MpkcE_v_: genMarkSweep.o; +text: .text%__1cJMarkSweepRFollowRootClosureGdo_oop6MppnHoopDesc__v_: markSweep.o; +text: .text%__1cJMarkSweepLfollow_root6FppnHoopDesc__v_; +text: .text%__1cParrayKlassKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cLklassVtableToop_follow_contents6M_v_; +text: .text%__1cJMarkSweepO_mark_and_push6FppnHoopDesc__v_; +text: .text%__1cKklassKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cJMarkSweepXrevisit_weak_klass_link6FpnFKlass__v_; +text: .text%__1cJMarkSweepMfollow_stack6F_v_; +text: .text%__1cNinstanceKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cSinstanceKlassKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cNinstanceKlassUfollow_static_fields6M_v_; +text: .text%__1cLklassItableToop_follow_contents6M_v_; +text: .text%__1cJMarkSweepNpreserve_mark6FpnHoopDesc_pnLmarkOopDesc__v_; +text: .text%__1cLsymbolKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cOtypeArrayKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cMjniIdMapBaseHoops_do6MpnKOopClosure__v_; +text: .text%__1cIjniIdMapHoops_do6MpnKOopClosure__v_; +text: .text%__1cJMarkSweepSMarkAndPushClosureGdo_oop6MppnHoopDesc__v_: markSweep.o; +text: .text%__1cNobjArrayKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cJMarkSweepPmark_and_follow6FppnHoopDesc__v_; +text: .text%__1cSobjArrayKlassKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cRconstantPoolKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cWconstantPoolCacheKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cWConstantPoolCacheEntryPfollow_contents6M_v_; +text: .text%__1cLmethodKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cQconstMethodKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cQinstanceRefKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cFJNIidHoops_do6MpnKOopClosure__v_; +text: .text%__1cQSystemDictionaryValways_strong_oops_do6FpnKOopClosure__v_; +text: .text%__1cQSystemDictionaryYalways_strong_classes_do6FpnKOopClosure__v_; +text: .text%__1cKDictionaryYalways_strong_classes_do6MpnKOopClosure__v_; +text: .text%__1cQSystemDictionaryPplaceholders_do6FpnKOopClosure__v_; +text: .text%__1cVLoaderConstraintTableYalways_strong_classes_do6MpnKOopClosure__v_; +text: .text%__1cJvmSymbolsHoops_do6FpnKOopClosure_i_v_; +text: .text%__1cJMarkSweepOIsAliveClosureLdo_object_b6MpnHoopDesc__i_: markSweep.o; +text: .text%__1cJMarkSweepQKeepAliveClosureGdo_oop6MppnHoopDesc__v_; +text: .text%__1cJMarkSweepSFollowStackClosureHdo_void6M_v_: markSweep.o; +text: .text%__1cQSystemDictionaryMdo_unloading6FpnRBoolObjectClosure_pnKOopClosure__i_; +text: .text%__1cKDictionaryMdo_unloading6MpnRBoolObjectClosure_pnKOopClosure__i_; +text: .text%__1cVLoaderConstraintTableYpurge_loader_constraints6MpnRBoolObjectClosure__v_; +text: .text%__1cJCodeCacheMdo_unloading6FpnRBoolObjectClosure_pnKOopClosure_iri_v_; +text: .text%__1cJCodeCacheFfirst6F_pnICodeBlob__; +text: .text%__1cICodeHeapLfirst_block6kM_pnJHeapBlock__; +text: .text%__1cICodeHeapJnext_free6kMpnJHeapBlock__pv_; +text: .text%__1cJCodeCacheFalive6FpnICodeBlob__2_; +text: .text%__1cKBufferBlobIis_alive6kM_i_: codeBlob.o; +text: .text%__1cKBufferBlobbIfollow_roots_or_mark_for_unloading6MpnRBoolObjectClosure_pnKOopClosure_iri_v_: codeBlob.o; +text: .text%__1cJCodeCacheEnext6FpnICodeBlob__2_; +text: .text%__1cICodeHeapLblock_start6kMpv_pnJHeapBlock__; +text: .text%__1cICodeHeapKnext_block6kMpnJHeapBlock__2_; +text: .text%__1cNSingletonBlobIis_alive6kM_i_: codeBlob.o; +text: .text%__1cNSingletonBlobbIfollow_roots_or_mark_for_unloading6MpnRBoolObjectClosure_pnKOopClosure_iri_v_: codeBlob.o; +text: .text%__1cLRuntimeStubIis_alive6kM_i_: codeBlob.o; +text: .text%__1cLRuntimeStubbIfollow_roots_or_mark_for_unloading6MpnRBoolObjectClosure_pnKOopClosure_iri_v_: codeBlob.o; +text: .text%__1cHnmethodIis_alive6kM_i_: nmethod.o; +text: .text%__1cHnmethodbIfollow_roots_or_mark_for_unloading6MpnRBoolObjectClosure_pnKOopClosure_iri_v_; +text: .text%__1cHnmethodOis_not_entrant6kM_i_: nmethod.o; +text: .text%__1cHnmethodbHfollow_root_or_mark_for_unloading6MpnRBoolObjectClosure_pnKOopClosure_ppnHoopDesc_iri_v_; +text: .text%__1cOoop_RelocationJoop_value6M_pnHoopDesc__; +text: .text%__1cVcompiledICHolderKlassSoop_being_unloaded6MpnRBoolObjectClosure_pnHoopDesc__i_; +text: .text%__1cVcompiledICHolderKlassToop_follow_contents6MpnHoopDesc__v_; +text: .text%__1cJMarkSweepXfollow_weak_klass_links6F_v_; +text: .text%__1cFKlassXfollow_weak_klass_links6MpnRBoolObjectClosure_pnKOopClosure__v_; +text: .text%__1cNinstanceKlassXfollow_weak_klass_links6MpnRBoolObjectClosure_pnKOopClosure__v_; +text: .text%__1cJHashtableGunlink6MpnRBoolObjectClosure__v_; +text: .text%__1cMGenMarkSweepRmark_sweep_phase26F_v_; +text: .text%__1cQGenCollectedHeapWprepare_for_compaction6M_v_; +text: .text%__1cKGenerationWprepare_for_compaction6MpnMCompactPoint__v_; +text: .text%__1cbCOneContigSpaceCardGenerationWfirst_compaction_space6kM_pnQCompactibleSpace__: tenuredGeneration.o; +text: .text%__1cPContiguousSpaceWprepare_for_compaction6MpnMCompactPoint__v_; +text: .text%__1cWOffsetTableContigSpaceUinitialize_threshold6M_pnIHeapWord__; +text: .text%__1cMTenuredSpaceSallowed_dead_ratio6kM_i_; +text: .text%__1cQCompactibleSpaceHforward6MpnHoopDesc_IpnMCompactPoint_pnIHeapWord__6_; +text: .text%__1cWOffsetTableContigSpacePcross_threshold6MpnIHeapWord_2_2_; +text: .text%__1cQCompactibleSpaceQinsert_deadspace6MrIpnIHeapWord_I_i_; +text: .text%__1cQCompactibleSpaceVnext_compaction_space6kM_p0_: space.o; +text: .text%__1cQDefNewGenerationWfirst_compaction_space6kM_pnQCompactibleSpace__: defNewGeneration.o; +text: .text%__1cQCompactibleSpaceSallowed_dead_ratio6kM_i_: space.o; +text: .text%__1cbCOneContigSpaceCardGenerationWfirst_compaction_space6kM_pnQCompactibleSpace__: compactingPermGenGen.o; +text: .text%__1cPContigPermSpaceSallowed_dead_ratio6kM_i_; +text: .text%__1cMGenMarkSweepRmark_sweep_phase36Fi_v_; +text: .text%__1cUCompactingPermGenGenTpre_adjust_pointers6M_v_; +text: .text%__1cJMarkSweepUAdjustPointerClosureGdo_oop6MppnHoopDesc__v_: markSweep.o; +text: .text%__1cQGenCollectedHeapSprocess_weak_roots6MpnKOopClosure_2_v_; +text: .text%__1cJCodeCacheHoops_do6FpnKOopClosure__v_; +text: .text%__1cKBufferBlobHoops_do6MpnKOopClosure__v_: codeBlob.o; +text: .text%__1cSDeoptimizationBlobHoops_do6MpnKOopClosure__v_: codeBlob.o; +text: .text%__1cLRuntimeStubHoops_do6MpnKOopClosure__v_: codeBlob.o; +text: .text%__1cNSafepointBlobHoops_do6MpnKOopClosure__v_: codeBlob.o; +text: .text%__1cHnmethodHoops_do6MpnKOopClosure__v_; +text: .text%__1cJHashtableHoops_do6MpnKOopClosure__v_; +text: .text%__1cSReferenceProcessorPoops_do_statics6FpnKOopClosure__v_; +text: .text%__1cSReferenceProcessorHoops_do6MpnKOopClosure__v_; +text: .text%__1cJMarkSweepMadjust_marks6F_v_; +text: .text%__1cYGenAdjustPointersClosureNdo_generation6MpnKGeneration__v_: genMarkSweep.o; +text: .text%__1cKGenerationPadjust_pointers6M_v_; +text: .text%__1cbCOneContigSpaceCardGenerationNspace_iterate6MpnMSpaceClosure_i_v_; +text: .text%__1cVAdjustPointersClosureIdo_space6MpnFSpace__v_: generation.o; +text: .text%__1cQCompactibleSpacePadjust_pointers6M_v_; +text: .text%__1cOtypeArrayKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cNobjArrayKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cQinstanceRefKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cNinstanceKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cQDefNewGenerationNspace_iterate6MpnMSpaceClosure_i_v_; +text: .text%__1cUCompactingPermGenGenPadjust_pointers6M_v_; +text: .text%__1cKklassKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cLsymbolKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cParrayKlassKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cLklassVtableToop_adjust_pointers6M_v_; +text: .text%__1cSobjArrayKlassKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cRconstantPoolKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cQconstMethodKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cLmethodKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cSinstanceKlassKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cNinstanceKlassUadjust_static_fields6M_v_; +text: .text%__1cLklassItableToop_adjust_pointers6M_v_; +text: .text%__1cWconstantPoolCacheKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cWConstantPoolCacheEntryPadjust_pointers6M_v_; +text: .text%__1cVcompiledICHolderKlassToop_adjust_pointers6MpnHoopDesc__i_; +text: .text%__1cMGenMarkSweepRmark_sweep_phase46F_v_; +text: .text%__1cUCompactingPermGenGenHcompact6M_v_; +text: .text%__1cQCompactibleSpaceHcompact6M_v_; +text: .text%__1cPContiguousSpaceWreset_after_compaction6M_v_: space.o; +text: .text%__1cRGenCompactClosureNdo_generation6MpnKGeneration__v_: genMarkSweep.o; +text: .text%__1cKGenerationHcompact6M_v_; +text: .text%__1cUCompactingPermGenGenMpost_compact6M_v_; +text: .text%__1cJMarkSweepNrestore_marks6F_v_; +text: .text%__1cMGenMarkSweepRdeallocate_stacks6F_v_; +text: .text%__1cLCardTableRSSclear_into_younger6MpnKGeneration_i_v_; +text: .text%__1cLCardTableRSFclear6MnJMemRegion__v_: cardTableRS.o; +text: .text%__1cRCardTableModRefBSFclear6MnJMemRegion__v_; +text: .text%__1cRCardTableModRefBSPclear_MemRegion6MnJMemRegion__v_; +text: .text%__1cHThreadsLgc_epilogue6F_v_; +text: .text%__1cKJavaThreadLgc_epilogue6M_v_; +text: .text%__1cRframe_gc_epilogue6FpnFframe_pknLRegisterMap__v_: thread.o; +text: .text%__1cFframeLgc_epilogue6M_v_; +text: .text%__1cFframeMpd_gc_epilog6M_v_; +text: .text%__1cJCodeCacheLgc_epilogue6F_v_; +text: .text%__1cICodeBlobTfix_oop_relocations6M_v_; +text: .text%__1cICodeBlobTfix_oop_relocations6MpC1_v_; +text: .text%__1cKRelocationSfix_oop_relocation6M_v_: codeBlob.o; +text: .text%__1cKRelocationSfix_oop_relocation6M_v_: relocInfo.o; +text: .text%__1cICodeBlobKis_nmethod6kM_i_: onStackReplacement.o; +text: .text%__1cQGenCollectedHeapWupdate_time_of_last_gc6Mx_v_: genMarkSweep.o; +text: .text%__1cKGenerationWupdate_time_of_last_gc6Mx_v_: tenuredGeneration.o; +text: .text%__1cKGenerationWupdate_time_of_last_gc6Mx_v_: compactingPermGenGen.o; +text: .text%__1cbCOneContigSpaceCardGenerationVunsafe_max_alloc_nogc6kM_I_; +text: .text%__1cRTenuredGenerationQcompute_new_size6M_v_; +text: .text%__1cKGenerationEspec6M_pnOGenerationSpec__; +text: .text%Unsafe_CompareAndSwapObject; +text: .text%__1cLVtableStubsScreate_itable_stub6Fii_pnKVtableStub__; +text: .text%__1cLLIR_EmitterDnop6M_v_; +text: .text%__1cJAssemblerEmovl6MnHAddress_pnI_jobject__v_; +text: .text%__1cMLinkResolverbEvtable_index_of_miranda_method6FnLKlassHandle_nMsymbolHandle_2pnGThread__i_; +text: .text%__1cLklassVtableQindex_of_miranda6MpnNsymbolOopDesc_2_i_; +text: .text%__1cLklassVtableTis_miranda_entry_at6Mi_i_; +text: .text%__1cRPrivilegedElementHoops_do6MpnKOopClosure__v_; +text: .text%__1cJCodeCacheIcontains6Fpv_i_; +text: .text%__1cFframeRoops_code_blob_do6MpnKOopClosure_pknLRegisterMap__v_; +text: .text%__1cJOopMapSetHoops_do6FpknFframe_pnICodeBlob_pknLRegisterMap_pnKOopClosure__v_; +text: .text%__1cJOopMapSetGall_do6FpknFframe_pnICodeBlob_pknLRegisterMap_pnKOopClosure_pFppnHoopDesc_9E_v9B9B_v_; +text: .text%__1cICodeBlobbAoop_map_for_return_address6MpCi_pnGOopMap__; +text: .text%__1cJOopMapSetSfind_map_at_offset6kMii_pnGOopMap__; +text: .text%__1cMOopMapStream2t6MpnGOopMap_i_v_; +text: .text%__1cFframeVoopmapreg_to_location6kMnFVMRegEName_pknLRegisterMap__ppnHoopDesc__; +text: .text%__1cKOopClosureLdo_nmethods6kM_ki_: defNewGeneration.o; +text: .text%__1cJOopMapSetTupdate_register_map6FpknFframe_pnICodeBlob_pnLRegisterMap__v_; +text: .text%__1cICodeBlobYcaller_must_gc_arguments6kMpnKJavaThread__i_: nmethod.o; +text: .text%__1cQComputeCallStackIdo_float6M_v_: generateOopMap.o; +text: .text%jni_DeleteWeakGlobalRef: jni.o; +text: .text%__1cKJNIHandlesTdestroy_weak_global6FpnI_jobject__v_; +text: .text%__1cILIR_ListJoop2stack6MpnI_jobject_i_v_: c1_LIREmitter.o; +text: .text%__1cNObjectMonitorREntryQdDueue_unlink6MpnMObjectWaiter__v_; +text: .text%JVM_IsSameClassPackage; +text: .text%__1cTGeneratePairingInfoRpossible_gc_point6MpnOBytecodeStream__i_: ciMethod.o; +text: .text%__1cTGeneratePairingInfoOreport_results6kM_i_: ciMethod.o; +text: .text%__1cMGraphBuilderMmonitorenter6MpnLInstruction__v_; +text: .text%__1cMMonitorEnterFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerPdo_MonitorEnter6MpnMMonitorEnter__v_; +text: .text%__1cNAccessMonitorIcan_trap6kM_i_: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderLmonitorexit6MpnLInstruction__v_; +text: .text%__1cLMonitorExitFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerOdo_MonitorExit6MpnLMonitorExit__v_; +text: .text%__1cILongTypeDtag6kM_nIValueTag__: c1_Canonicalizer.o; +text: .text%__1cILongTypeEsize6kM_i_: c1_Canonicalizer.o; +text: .text%__1cNAccessMonitorPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorPdo_MonitorEnter6MpnMMonitorEnter__v_; +text: .text%__1cTNullCheckEliminatorUhandle_AccessMonitor6MpnNAccessMonitor__v_; +text: .text%__1cQNullCheckVisitorOdo_MonitorExit6MpnLMonitorExit__v_; +text: .text%__1cIValueGenPdo_MonitorEnter6MpnMMonitorEnter__v_; +text: .text%__1cNc1_AllocTableMhas_two_free6kM_i_; +text: .text%__1cMLongConstantPas_LongConstant6M_p0_: c1_Canonicalizer.o; +text: .text%__1cFRInfoLas_rinfo_lo6kM_0_; +text: .text%__1cLLIR_EmitterJopr2intLo6MpnLLIR_OprDesc__i_; +text: .text%__1cFRInfoLas_rinfo_hi6kM_0_; +text: .text%__1cLLIR_EmitterJopr2intHi6MpnLLIR_OprDesc__i_; +text: .text%__1cIValueGenOdo_MonitorExit6MpnLMonitorExit__v_; +text: .text%__1cNAccessMonitorQas_AccessMonitor6M_p0_: c1_GraphBuilder.o; +text: .text%__1cJAssemblerFpushl6MpnI_jobject__v_; +text: .text%__1cNLIR_AssemblerNas_Address_hi6MpnLLIR_Address__nHAddress__; +text: .text%__1cFRInfoOas_register_hi6kM_pnMRegisterImpl__; +text: .text%__1cNLIR_AssemblerNas_Address_lo6MpnLLIR_Address__nHAddress__; +text: .text%__1cFRInfoOas_register_lo6kM_pnMRegisterImpl__; +text: .text%__1cCosHrealloc6FpvI_1_; +text: .text%Unsafe_GetNativeFloat; +text: .text%__1cIValueGenQdo_currentThread6MpnJIntrinsic__v_; +text: .text%__1cILIR_ListKget_thread6MnFRInfo__v_: c1_CodeGenerator_x86.o; +text: .text%__1cNLIR_AssemblerKget_thread6MpnLLIR_OprDesc__v_; +text: .text%__1cIValueGenSload_item_patching6MpnHIRScope_ipnEItem_pnKValueStack_pnOExceptionScope__v_; +text: .text%__1cEItemUget_jobject_constant6kM_pnIciObject__; +text: .text%__1cJValueTypeTas_InstanceConstant6M_pnQInstanceConstant__: c1_ValueType.o; +text: .text%__1cIintArrayIindex_of6kMki_i_: c1_CodeGenerator.o; +text: .text%__1cMLinkResolverbEresolve_interface_call_or_null6FnLKlassHandle_1nMsymbolHandle_21_nMmethodHandle__; +text: .text%__1cIciObjectTis_type_array_klass6M_i_: ciInstanceKlass.o; +text: .text%__1cGciTypeNis_subtype_of6Mp0_i_; +text: .text%__1cIValueGenOload_byte_item6MpnEItem__v_; +text: .text%__1cIValueGenPlock_free_rinfo6MpnLInstruction_nKc1_RegMask__nFRInfo__; +text: .text%__1cIRegAllocNget_lock_temp6MpnLInstruction_nKc1_RegMask__nFRInfo__; +text: .text%__1cQComputeCallStackIdo_short6M_v_: generateOopMap.o; +text: .text%__1cRComputeEntryStackIdo_short6M_v_: generateOopMap.o; +text: .text%__1cIFrameMapNis_byte_rinfo6FnFRInfo__i_; +text: .text%Unsafe_AllocateInstance; +text: .text%jni_AllocObject: jni.o; +text: .text%__1cQinstanceRefKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_; +text: .text%__1cNCanonicalizerMset_constant6Mi_v_: c1_Canonicalizer.o; +text: .text%__1cJTypeCheckPother_values_do6MpFppnLInstruction__v_v_; +text: .text%__1cNLIR_AssemblerMcheck_icache6M_i_; +text: .text%__1cRC1_MacroAssemblerTfast_ObjectHashCode6MpnMRegisterImpl_2_v_; +text: .text%__1cNLIR_AssemblerZjobject2reg_with_patching6MpnMRegisterImpl_pnMCodeEmitInfo__v_; +text: .text%__1cHLogicOpIis_equal6kMpnLInstruction__i_: c1_Instruction.o; +text: .text%__1cLAccessFieldKlock_stack6kM_pnKValueStack__: c1_GraphBuilder.o; +text: .text%__1cIRuntime1Mnew_instance6FpnKJavaThread_pnMklassOopDesc__v_; +text: .text%__1cQGenCollectedHeapXhandle_failed_promotion6MpnKGeneration_pnHoopDesc_Ip4_4_; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: instanceRefKlass.o; +text: .text%__1cbCOneContigSpaceCardGenerationTexpand_and_allocate6MIiii_pnIHeapWord__; +text: .text%__1cbCOneContigSpaceCardGenerationGexpand6MII_v_; +text: .text%__1cNGCMutexLocker2t6MpnFMutex__v_; +text: .text%__1cbCOneContigSpaceCardGenerationHgrow_by6MI_i_; +text: .text%__1cPContiguousSpaceNmangle_region6MnJMemRegion__v_; +text: .text%__1cJMarkSweepRFollowRootClosureLdo_nmethods6kM_ki_: markSweep.o; +text: .text%__1cQCompactibleSpaceUinitialize_threshold6M_pnIHeapWord__: space.o; +text: .text%__1cKOopClosureLdo_nmethods6kM_ki_: markSweep.o; +text: .text%__1cRAlwaysTrueClosureLdo_object_b6MpnHoopDesc__i_: genCollectedHeap.o; +text: .text%__1cLCardTableRSTinvalidate_or_clear6MpnKGeneration_ii_v_; +text: .text%__1cJMemRegionFminus6kMk0_0_; +text: .text%__1cLCardTableRSKinvalidate6MnJMemRegion__v_: cardTableRS.o; +text: .text%__1cRCardTableModRefBSKinvalidate6MnJMemRegion__v_; +text: .text%__1cIRuntime1Onew_type_array6FpnKJavaThread_pnMklassOopDesc_i_v_; +text: .text%__1cJFloatTypeDtag6kM_nIValueTag__: c1_Canonicalizer.o; +text: .text%__1cNFloatConstantQas_FloatConstant6M_p0_: c1_Canonicalizer.o; +text: .text%__1cILIR_ListNstore_mem_oop6MpnI_jobject_nFRInfo_inJBasicType_pnMCodeEmitInfo_nHLIR_Op1NLIR_PatchCode__v_; +text: .text%__1cJFloatTypeMas_FloatType6M_p0_: c1_Canonicalizer.o; +text: .text%__1cNConstantTableMappend_float6Mf_v_; +text: .text%__1cRAbstractAssemblerGa_long6Mi_v_; +text: .text%__1cNObjectMonitorGnotify6MpnGThread__v_; +text: .text%__1cDCHARprocess_interface6FnTinstanceKlassHandle_pnNGrowableArray4nLKlassHandle___pnNGrowableArray4nMmethodHandle___nMsymbolHandle_6_v_; +text: .text%__1cINewArrayPother_values_do6MpFppnLInstruction__v_v_; +text: .text%__1cLLIR_EmitterQfield_store_byte6MpnLLIR_OprDesc_i2nFRInfo_ipnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerIshift_op6MnILIR_Code_nFRInfo_222_v_; +text: .text%__1cIRuntime1Mmonitorenter6FpnKJavaThread_pnHoopDesc_pnPBasicObjectLock__v_; +text: .text%__1cIRuntime1Lmonitorexit6FpnKJavaThread_pnPBasicObjectLock__v_; +text: .text%__1cHnmethodPis_dependent_on6MpnMklassOopDesc__i_; +text: .text%__1cHnmethodVis_dependent_on_entry6MpnMklassOopDesc_2pnNmethodOopDesc__i_; +text: .text%__1cNVM_DeoptimizeEname6kM_pkc_: vm_operations.o; +text: .text%__1cNVM_DeoptimizeEdoit6M_v_; +text: .text%__1cODeoptimizationVdeoptimize_dependents6F_i_; +text: .text%__1cHThreadsbFdeoptimized_wrt_marked_nmethods6F_v_; +text: .text%__1cKJavaThreadbFdeoptimized_wrt_marked_nmethods6M_v_; +text: .text%__1cFframeVshould_be_deoptimized6kM_i_; +text: .text%__1cICodeBlobOis_java_method6kM_i_: codeBlob.o; +text: .text%__1cJCodeCachebGmake_marked_nmethods_not_entrant6F_v_; +text: .text%__1cJCodeCacheNalive_nmethod6FpnICodeBlob__pnHnmethod__; +text: .text%__1cHnmethodbAmake_not_entrant_or_zombie6Mi_v_; +text: .text%__1cHnmethodNis_osr_method6kM_i_: nmethod.o; +text: .text%__1cKNativeJumpUpatch_verified_entry6FpC11_v_; +text: .text%__1cHnmethodVmark_as_seen_on_stack6M_v_; +text: .text%__1cTinc_decompile_count6FpnHnmethod__v_: nmethod.o; +text: .text%__1cMVM_OperationNdoit_epilogue6M_v_: vm_operations.o; +text: .text%__1cHThreadsLnmethods_do6F_v_; +text: .text%__1cKJavaThreadLnmethods_do6M_v_; +text: .text%__1cGThreadLnmethods_do6M_v_; +text: .text%__1cFframeLnmethods_do6M_v_; +text: .text%__1cFframeVnmethods_code_blob_do6M_v_; +text: .text%__1cILIR_ListEidiv6MnFRInfo_i11pnMCodeEmitInfo__v_; +text: .text%__1cLlog2_intptr6Fi_i_: c1_LIRAssembler_x86.o; +text: .text%__1cONMethodSweeperPprocess_nmethod6FpnHnmethod__v_; +text: .text%__1cHnmethodPis_locked_by_vm6kM_i_: nmethod.o; +text: .text%__1cHnmethodLis_unloaded6kM_i_: nmethod.o; +text: .text%__1cHnmethodVcleanup_inline_caches6M_v_; +text: .text%__1cKCompiledIC2t6MpnKRelocation__v_; +text: .text%__1cILongTypeDtag6kM_nIValueTag__: c1_ValueType.o; +text: .text%__1cILongTypeEsize6kM_i_: c1_ValueType.o; +text: .text%JVM_HoldsLock; +text: .text%__1cSObjectSynchronizerZcurrent_thread_holds_lock6FpnKJavaThread_nGHandle__i_; +text: .text%__1cIciObjectRis_instance_klass6M_i_: ciObjArrayKlass.o; +text: .text%__1cLLoadIndexedIis_equal6kMpnLInstruction__i_: c1_Instruction.o; +text: .text%__1cFciEnvWis_dependence_violated6FpnMklassOopDesc_pnNmethodOopDesc__i_; +text: .text%__1cFciEnvZcall_has_multiple_targets6FpnNinstanceKlass_nMsymbolHandle_3ri_i_; +text: .text%__1cFMutexbLwait_for_lock_blocking_implementation6MpnKJavaThread__v_; +text: .text%__1cHnmethodbCcan_not_entrant_be_converted6M_i_; +text: .text%__1cXNativeSignatureIteratorHdo_bool6M_v_: oopMapCache.o; +text: .text%__1cTMaskFillerForNativeIpass_int6M_v_: oopMapCache.o; +text: .text%__1cGThreadOis_Java_thread6kM_i_: vmThread.o; +text: .text%__1cMLocalMappingDadd6MinFRInfo__v_; +text: .text%__1cILongTypeEbase6kM_pnJValueType__: c1_ValueType.o; +text: .text%__1cLLIR_EmitterQfield_store_long6MpnLLIR_OprDesc_i2ipnMCodeEmitInfo__v_; +text: .text%__1cKScanBlocksMis_long_only6kMi_i_; +text: .text%__1cRLIR_PeepholeStateLreg2indexLo6MpnLLIR_OprDesc__i_; +text: .text%__1cRLIR_PeepholeStateLreg2indexHi6MpnLLIR_OprDesc__i_; +text: .text%__1cNSharedRuntimeDf2l6Ff_x_; +text: .text%__1cIValueGenLdo_getClass6MpnJIntrinsic__v_; +text: .text%__1cLLIR_EmitterIgetClass6MnFRInfo_1pnMCodeEmitInfo__v_; +text: .text%__1cMGraphBuilderKcompare_op6MpnJValueType_nJBytecodesECode__v_; +text: .text%__1cJCompareOpFvisit6MpnSInstructionVisitor__v_: c1_Instruction.o; +text: .text%__1cNCanonicalizerMdo_CompareOp6MpnJCompareOp__v_; +text: .text%__1cJCompareOpEhash6kM_i_: c1_Instruction.o; +text: .text%__1cJCompareOpEname6kM_pkc_: c1_Instruction.o; +text: .text%__1cJCompareOpMas_CompareOp6M_p0_: c1_Instruction.o; +text: .text%__1cCIf2t6MpnLInstruction_n0BJCondition_i2pnKBlockBegin_5pnKValueStack_i_v_: c1_Canonicalizer.o; +text: .text%__1cGSetRegIdo_float6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocLset_fpu_reg6MiipnLInstruction__v_; +text: .text%__1cJIsFreeRegIdo_float6Mi_v_: c1_RegAlloc.o; +text: .text%__1cILIR_ListJfloat2reg6MfnFRInfo__v_: c1_LIREmitter.o; +text: .text%__1cILIR_ListMbranch_float6MnMLIR_OpBranchNLIR_Condition_pnFLabel_4_v_; +text: .text%__1cIValueGenNreturnF0RInfo6F_nFRInfo__; +text: .text%__1cLLIR_EmitterOset_fpu_result6MnFRInfo__v_; +text: .text%__1cILIR_ListIpush_fpu6MnFRInfo__v_: c1_LIREmitter.o; +text: .text%__1cNConstantTableZaddress_of_float_constant6Mf_pC_; +text: .text%__1cNLIR_AssemblerOfpu_two_on_tos6MnFRInfo_1i_v_; +text: .text%__1cIFrameMapLFpuStackSimEswap6M_v_; +text: .text%__1cIFrameMapLFpuStackSimRexchange_with_tos6Mi_v_; +text: .text%__1cHnmethodSflush_dependencies6MpnRBoolObjectClosure__v_; +text: .text%__1cNinstanceKlassYremove_dependent_nmethod6MpnHnmethod__v_; +text: .text%__1cFVTuneOdelete_nmethod6FpnHnmethod__v_; +text: .text%__1cQPlaceholderEntryHoops_do6MpnKOopClosure__v_; +text: .text%__1cHnmethodFflush6M_v_; +text: .text%__1cJEventMark2t6MpkcE_v_: nmethod.o; +text: .text%__1cICodeBlobFflush6M_v_; +text: .text%__1cJCodeCacheEfree6FpnICodeBlob__v_; +text: .text%__1cICodeHeapKdeallocate6Mpv_v_; +text: .text%__1cICodeHeapPadd_to_freelist6MpnJHeapBlock__v_; +text: .text%__1cICodeHeapPfollowing_block6MpnJFreeBlock__2_; +text: .text%__1cRComputeEntryStackIdo_float6M_v_: generateOopMap.o; +text: .text%__1cICodeHeapMinsert_after6MpnJFreeBlock_2_v_; +text: .text%__1cICodeHeapLmerge_right6MpnJFreeBlock__v_; +text: .text%__1cHnmethodbDpreserve_callee_argument_oops6MnFframe_pknLRegisterMap_pnKOopClosure__v_; +text: .text%__1cUCompressedReadStreamMraw_read_int6FrpC_i_: nmethod.o; +text: .text%__1cFframebAoops_compiled_arguments_do6MnMsymbolHandle_ipknLRegisterMap_pnKOopClosure__v_; +text: .text%__1cQComputeCallStackJdo_double6M_v_: generateOopMap.o; +text: .text%__1cbCOneContigSpaceCardGenerationGshrink6MI_v_; +text: .text%__1cbCOneContigSpaceCardGenerationJshrink_by6MI_v_; +text: .text%__1cMVirtualSpaceJshrink_by6MI_v_; +text: .text%__1cXNativeSignatureIteratorGdo_int6M_v_: oopMapCache.o; +text: .text%__1cRComputeEntryStackJdo_double6M_v_: generateOopMap.o; +text: .text%__1cKDoubleTypeDtag6kM_nIValueTag__: c1_ValueType.o; +text: .text%__1cKDoubleTypeDtag6kM_nIValueTag__: c1_Canonicalizer.o; +text: .text%__1cODoubleConstantRas_DoubleConstant6M_p0_: c1_Canonicalizer.o; +text: .text%__1cKDoubleTypeEbase6kM_pnJValueType__: c1_ValueType.o; +text: .text%__1cODoubleConstantLis_constant6kM_i_: c1_Canonicalizer.o; +text: .text%__1cKDoubleTypeEsize6kM_i_: c1_ValueType.o; +text: .text%__1cHLockRegJdo_double6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocRset_locked_double6MipnLInstruction_i_v_; +text: .text%__1cKDoubleTypeNas_DoubleType6M_p0_: c1_ValueType.o; +text: .text%__1cIFrameMapUare_adjacent_indeces6kMii_i_; +text: .text%__1cQChangeSpillCountJdo_double6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocZchange_double_spill_count6Mii_v_; +text: .text%__1cILIR_ListKdouble2reg6MdnFRInfo__v_: c1_LIREmitter.o; +text: .text%__1cHFreeRegJdo_double6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocPset_free_double6Mi_v_; +text: .text%__1cILIR_ListDrem6MpnLLIR_OprDesc_22pnMCodeEmitInfo__v_: c1_LIREmitter.o; +text: .text%__1cLGetRefCountJdo_double6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocNget_double_rc6kMi_i_; +text: .text%__1cLLIR_EmitterUcheck_double_address6Mi_v_; +text: .text%__1cILIR_ListQreg2double_stack6MnFRInfo_inJBasicType__v_: c1_LIREmitter.o; +text: .text%__1cRLIR_PeepholeStateNstack2indexHi6MpnLLIR_OprDesc__i_; +text: .text%__1cRLIR_PeepholeStateNstack2indexLo6MpnLLIR_OprDesc__i_; +text: .text%__1cKDoubleTypeNas_DoubleType6M_p0_: c1_Canonicalizer.o; +text: .text%__1cNConstantTableNappend_double6Md_v_; +text: .text%__1cNConstantTablebAaddress_of_double_constant6Md_pC_; +text: .text%__1cQGenCollectedHeapHcollect6MnHGCCauseFCause_i_v_; +text: .text%__1cQGenCollectedHeapOcollect_locked6MnHGCCauseFCause_i_v_; +text: .text%__1cRVM_GenCollectFullEname6kM_pkc_: vm_operations.o; +text: .text%__1cRVM_GenCollectFullEdoit6M_v_; +text: .text%__1cQGenCollectedHeapYmust_clear_all_soft_refs6M_i_; +text: .text%__1cQGenCollectedHeapSdo_full_collection6Miipi_v_; +text: .text%__1cKGenerationbHfull_collects_younger_generations6kM_i_: defNewGeneration.o; +text: .text%__1cKDoubleTypeEsize6kM_i_: c1_Canonicalizer.o; +text: .text%__1cKDoubleTypeEbase6kM_pnJValueType__: c1_Canonicalizer.o; +text: .text%__1cIValueMapNresize_bucket6MpnGBucket__v_; +text: .text%__1cNFloatConstantLis_constant6kM_i_: c1_Canonicalizer.o; +text: .text%__1cJNullCheckMas_NullCheck6M_p0_: c1_GraphBuilder.o; +text: .text%__1cLLIR_EmitterIopr2long6MpnLLIR_OprDesc__x_; +text: .text%__1cILIR_ListKlong2stack6Mxi_v_: c1_LIREmitter.o; +text: .text%__1cIValueGenNreturnD0RInfo6F_nFRInfo__; +text: .text%__1cJIsFreeRegJdo_double6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocOis_free_double6kMi_i_; +text: .text%__1cGSetRegJdo_double6Mi_v_: c1_RegAlloc.o; +text: .text%__1cIRegAllocOset_double_reg6MiipnLInstruction__v_; +text: .text%__1cLLIR_EmitterNcopy_fpu_item6MnFRInfo_pnLLIR_OprDesc__v_; +text: .text%__1cILIR_ListHdup_fpu6MnFRInfo_1_v_: c1_LIREmitter.o; +text: .text%__1cILIR_ListDdiv6MpnLLIR_OprDesc_22pnMCodeEmitInfo__v_: c1_LIREmitter.o; +text: .text%__1cJAssemblerFfsubp6Mi_v_; +text: .text%__1cNLIR_AssemblerHdup_fpu6MnFRInfo_1_v_; +text: .text%__1cIFrameMapLFpuStackSimLmove_on_tos6Mi_i_; +text: .text%__1cJAssemblerGfdiv_d6MnHAddress__v_; +text: .text%__1cJAssemblerFfdivp6Mi_v_; +text: .text%__1cIValueGenMreturn2RInfo6F_nFRInfo__; +text: .text%__1cJValueTypeQas_FloatConstant6M_pnNFloatConstant__: c1_Canonicalizer.o; +text: .text%__1cIRuntime1Qnew_object_array6FpnKJavaThread_pnMklassOopDesc_i_v_; +text: .text%__1cIValueGenLdivOutRInfo6F_nFRInfo__; +text: .text%__1cILIR_ListEidiv6MnFRInfo_111pnMCodeEmitInfo__v_; +text: .text%__1cILIR_ListVvolatile_load_mem_reg6MnFRInfo_i1nJBasicType_pnMCodeEmitInfo_nHLIR_Op1NLIR_PatchCode__v_; +text: .text%__1cEItemSget_jlong_constant6kM_x_; +text: .text%__1cNLIR_AssemblerQvolatile_move_op6MpnLLIR_OprDesc_2nJBasicType_nHLIR_Op1NLIR_PatchCode_pnMCodeEmitInfo__v_; +text: .text%__1cFKlassNoop_is_method6kM_i_: objArrayKlass.o; +text: .text%__1cFKlassRoop_is_methodData6kM_i_: objArrayKlass.o; +text: .text%__1cIciObjectTis_type_array_klass6M_i_: ciObjArrayKlass.o; +text: .text%__1cMciArrayKlassOis_array_klass6M_i_: ciObjArrayKlass.o; +text: .text%__1cONewObjectArrayKexact_type6kM_pnGciType__; +text: .text%__1cPciObjArrayKlassSis_obj_array_klass6M_i_: ciObjArrayKlass.o; +text: .text%__1cPciObjArrayKlassNelement_klass6M_pnHciKlass__; +text: .text%__1cIRuntime1Noop_arraycopy6FpnIHeapWord_2i_v_; +text: .text%__1cILongTypeEbase6kM_pnJValueType__: c1_Canonicalizer.o; +text: .text%__1cMLongConstantLis_constant6kM_i_: c1_Canonicalizer.o; +text: .text%__1cIValueGenUdo_ArithmeticOp_Long6MpnMArithmeticOp__v_; +text: .text%__1cLLIR_EmitterSarithmetic_op_long6MnJBytecodesECode_pnLLIR_OprDesc_44pnMCodeEmitInfo__v_; +text: .text%__1cFKlassUoop_oop_iterate_nv_m6MpnHoopDesc_pnQFilteringClosure_nJMemRegion__i_: compiledICHolderKlass.o; +text: .text%__1cVcompiledICHolderKlassRoop_oop_iterate_m6MpnHoopDesc_pnKOopClosure_nJMemRegion__i_; +text: .text%__1cIciObjectRis_instance_klass6M_i_: ciTypeArrayKlass.o; +text: .text%__1cLArrayLengthIis_equal6kMpnLInstruction__i_: c1_GraphBuilder.o; +text: .text%__1cFKlassPoop_is_objArray6kM_i_: compiledICHolderKlass.o; +text: .text%__1cFKlassQoop_is_typeArray6kM_i_: compiledICHolderKlass.o; +text: .text%__1cTunsafe_intrinsic_id6FpnNsymbolOopDesc_1_nNmethodOopDescLIntrinsicId__; +text: .text%__1cMGraphBuilderVappend_unsafe_put_raw6MpnIciMethod_nJBasicType__i_; +text: .text%__1cMUnsafePutRawFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerPdo_UnsafePutRaw6MpnMUnsafePutRaw__v_; +text: .text%__1cNCanonicalizerOdo_UnsafeRawOp6MpnLUnsafeRawOp__v_; +text: .text%__1cFmatch6FpnLUnsafeRawOp_ppnLInstruction_4pi_i_: c1_Canonicalizer.o; +text: .text%__1cLInstructionPas_ArithmeticOp6M_pnMArithmeticOp__: c1_Instruction.o; +text: .text%__1cIUnsafeOpLas_UnsafeOp6M_p0_: c1_GraphBuilder.o; +text: .text%__1cMGraphBuilderVappend_unsafe_get_raw6MpnIciMethod_nJBasicType__i_; +text: .text%__1cMUnsafeGetRawFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerPdo_UnsafeGetRaw6MpnMUnsafeGetRaw__v_; +text: .text%__1cMGraphBuilderNlookup_switch6M_v_; +text: .text%__1cIintArray2t6Mki1_v_: c1_GraphBuilder.o; +text: .text%__1cMLookupSwitchFvisit6MpnSInstructionVisitor__v_: c1_GraphBuilder.o; +text: .text%__1cNCanonicalizerPdo_LookupSwitch6MpnMLookupSwitch__v_; +text: .text%__1cMUnsafePutRawPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorPdo_UnsafePutRaw6MpnMUnsafePutRaw__v_; +text: .text%__1cTNullCheckEliminatorPhandle_UnsafeOp6MpnIUnsafeOp__v_; +text: .text%__1cLUnsafeRawOpPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBuilder.o; +text: .text%__1cQNullCheckVisitorPdo_UnsafeGetRaw6MpnMUnsafeGetRaw__v_; +text: .text%__1cQNullCheckVisitorPdo_LookupSwitch6MpnMLookupSwitch__v_; +text: .text%__1cIValueGenPdo_UnsafePutRaw6MpnMUnsafePutRaw__v_; +text: .text%__1cLLIR_EmitterOput_raw_unsafe6MpnLLIR_OprDesc_2i2nJBasicType__v_; +text: .text%__1cLLIR_EmitterMlong2address6MpnLLIR_OprDesc__nFRInfo__; +text: .text%__1cILIR_ListNstore_mem_reg6MnFRInfo_pnLLIR_Address_nJBasicType_pnMCodeEmitInfo_nHLIR_Op1NLIR_PatchCode__v_; +text: .text%__1cIValueGenPdo_UnsafeGetRaw6MpnMUnsafeGetRaw__v_; +text: .text%__1cLLIR_EmitterOget_raw_unsafe6MnFRInfo_pnLLIR_OprDesc_3inJBasicType__v_; +text: .text%__1cILIR_ListMload_mem_reg6MpnLLIR_Address_nFRInfo_nJBasicType_pnMCodeEmitInfo_nHLIR_Op1NLIR_PatchCode__v_; +text: .text%__1cIValueGenPdo_LookupSwitch6MpnMLookupSwitch__v_; +text: .text%__1cUcreate_lookup_ranges6FpnMLookupSwitch__pnQLookupRangeArray__: c1_CodeGenerator_x86.o; +text: .text%__1cLLIR_EmitterVlookupswitch_range_op6MpnLLIR_OprDesc_iipnKBlockBegin__v_; +text: .text%__1cNSharedRuntimeEldiv6Fxx_x_; +text: .text%Unsafe_GetObjectVolatile; +text: .text%signalHandler; +text: .text%JVM_handle_solaris_signal; +text: .text%__1cKJavaThreadUin_stack_yellow_zone6MpC_i_: os_solaris_x86.o; +text: .text%__1cICodeBlobRis_at_poll_return6MpC_i_; +text: .text%__1cUSafepointSynchronizebDhandle_polling_page_exception6FpnKJavaThread__pC_; +text: .text%__1cbCCompiledCodeSafepointHandlerbDhandle_polling_page_exception6M_pC_; +text: .text%__1cFframebDsender_for_raw_compiled_frame6kMpnLRegisterMap__0_; +text: .text%__1cNSafepointBlobYcaller_must_gc_arguments6kMpnKJavaThread__i_; +text: .text%__1cUThreadSafepointStateYcaller_must_gc_arguments6kM_i_; +text: .text%__1cbCCompiledCodeSafepointHandlerYcaller_must_gc_arguments6kM_i_: safepoint.o; +text: .text%__1cFframeIpatch_pc6MpnGThread_pC_v_; +text: .text%__1cNSafepointBlobbDpreserve_callee_argument_oops6MnFframe_pknLRegisterMap_pnKOopClosure__v_: codeBlob.o; +text: .text%__1cSvframeStreamCommonbFfill_in_compiled_inlined_sender6M_i_; +text: .text%__1cJFloatTypeEsize6kM_i_: c1_Canonicalizer.o; +text: .text%__1cIValueGenNrelease_roots6MpnKValueStack__v_; +text: .text%__1cSciExceptionHandlerLcatch_klass6M_pnPciInstanceKlass__; +text: .text%__1cHciKlassNis_subtype_of6Mp0_i_; +text: .text%__1cNSharedRuntimeDd2l6Fd_x_; +text: .text%__1cOObjectConstantLis_constant6kM_i_: c1_ValueType.o; +text: .text%__1cILIR_ListLstore_array6MipnLLIR_Address_nJBasicType_pnMCodeEmitInfo__v_; +text: .text%__1cNLIR_AssemblerLconst2array6MpnJLIR_Const_pnLLIR_Address_nJBasicType_pnMCodeEmitInfo__v_; +text: .text%__1cQInstanceConstantLis_constant6kM_i_: c1_ValueType.o; diff --git a/hotspot/make/solaris/makefiles/reorder_COMPILER1_i486 b/hotspot/make/solaris/makefiles/reorder_COMPILER1_i486 index bab5b288d70..caf8c0298ed 100644 --- a/hotspot/make/solaris/makefiles/reorder_COMPILER1_i486 +++ b/hotspot/make/solaris/makefiles/reorder_COMPILER1_i486 @@ -8,20 +8,20 @@ text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: arguments.o; text: .text%__1cQAgentLibraryList2t6M_v_: arguments.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_AllocTable.o; text: .text%__1cFRInfo2t6M_v_: c1_AllocTable.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_AllocTable_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_AllocTable_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_AllocTable_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_AllocTable_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CacheLocals.o; text: .text%__1cFRInfo2t6M_v_: c1_CacheLocals.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CacheLocals_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_CacheLocals_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CacheLocals_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_CacheLocals_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Canonicalizer.o; text: .text%__1cFRInfo2t6M_v_: c1_Canonicalizer.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CodeGenerator.o; text: .text%__1cFRInfo2t6M_v_: c1_CodeGenerator.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CodeGenerator_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_CodeGenerator_i486.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CodeStubs_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_CodeStubs_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CodeGenerator_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_CodeGenerator_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_CodeStubs_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_CodeStubs_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Compilation.o; text: .text%__1cFRInfo2t6M_v_: c1_Compilation.o; text: .text%__1cMelapsedTimer2t6M_v_: c1_Compilation.o; @@ -29,9 +29,9 @@ text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Compiler.o; text: .text%__1cFRInfo2t6M_v_: c1_Compiler.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_FrameMap.o; text: .text%__1cFRInfo2t6M_v_: c1_FrameMap.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_FrameMap_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_FrameMap_i486.o; -text: .text%__1cKc1_RegMask2t6M_v_: c1_FrameMap_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_FrameMap_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_FrameMap_x86.o; +text: .text%__1cKc1_RegMask2t6M_v_: c1_FrameMap_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_GraphBuilder.o; text: .text%__1cFRInfo2t6M_v_: c1_GraphBuilder.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_IR.o; @@ -43,41 +43,41 @@ text: .text%__1cFRInfo2t6M_v_: c1_InstructionPrinter.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Items.o; text: .text%__1cFRInfo2t6M_v_: c1_Items.o; text: .text%__1cIHintItem2t6MpnJValueType_i_v_: c1_Items.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Items_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_Items_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Items_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_Items_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIR.o; text: .text%__1cFRInfo2t6M_v_: c1_LIR.o; text: .text%__1cLLIR_OprFactHillegal6F_pnLLIR_OprDesc__: c1_LIR.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIRAssembler.o; text: .text%__1cFRInfo2t6M_v_: c1_LIRAssembler.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIRAssembler_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_LIRAssembler_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIRAssembler_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_LIRAssembler_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIREmitter.o; text: .text%__1cFRInfo2t6M_v_: c1_LIREmitter.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIREmitter_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_LIREmitter_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIREmitter_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_LIREmitter_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIROptimizer.o; text: .text%__1cFRInfo2t6M_v_: c1_LIROptimizer.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Loops.o; text: .text%__1cFRInfo2t6M_v_: c1_Loops.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_MacroAssembler_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_MacroAssembler_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_MacroAssembler_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_MacroAssembler_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Optimizer.o; text: .text%__1cFRInfo2t6M_v_: c1_Optimizer.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_RInfo.o; text: .text%__1cFRInfo2t6M_v_: c1_RInfo.o; text: .text%__1cKc1_RegMask2t6M_v_: c1_RInfo.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_RInfo_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_RInfo_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_RInfo_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_RInfo_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_RegAlloc.o; text: .text%__1cFRInfo2t6M_v_: c1_RegAlloc.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_RegAlloc_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_RegAlloc_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_RegAlloc_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_RegAlloc_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Runtime1.o; text: .text%__1cFRInfo2t6M_v_: c1_Runtime1.o; text: .text%__1cIiEntries2t6M_v_; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Runtime1_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_Runtime1_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_Runtime1_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_Runtime1_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_ScanBlocks.o; text: .text%__1cFRInfo2t6M_v_: c1_ScanBlocks.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_ValueMap.o; @@ -105,8 +105,8 @@ text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: fprofiler.o; text: .text%__1cMelapsedTimer2t6M_v_: fprofiler.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: frame.o; text: .text%__1cFRInfo2t6M_v_: frame.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: frame_i486.o; -text: .text%__1cFRInfo2t6M_v_: frame_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: frame_x86.o; +text: .text%__1cFRInfo2t6M_v_: frame_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: genCollectedHeap.o; text: .text%__1cTAssertIsPermClosure2t6M_v_: genCollectedHeap.o; text: .text%__1cRAlwaysTrueClosure2t6M_v_: genCollectedHeap.o; @@ -117,8 +117,8 @@ text: .text%__1cNCellTypeStateImake_top6F_0_: generateOopMap.o; text: .text%__1cMelapsedTimer2t6M_v_: generateOopMap.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: interpreter.o; text: .text%__1cKEntryPoint2t6M_v_; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: interpreter_i486.o; -text: .text%__1cFRInfo2t6M_v_: interpreter_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: interpreter_x86.o; +text: .text%__1cFRInfo2t6M_v_: interpreter_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: java.o; text: .text%__1cFRInfo2t6M_v_: java.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: jvmtiEnvBase.o; @@ -151,16 +151,16 @@ text: .text%__1cNGrowableArray4CpnKMemoryPool__2t6Mii_v_: memoryService.o; text: .text%__1cNGrowableArray4CpnNMemoryManager__2t6Mii_v_: memoryService.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: methodOop.o; text: .text%__1cFRInfo2t6M_v_: methodOop.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: nativeInst_i486.o; -text: .text%__1cFRInfo2t6M_v_: nativeInst_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: nativeInst_x86.o; +text: .text%__1cFRInfo2t6M_v_: nativeInst_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: nmethod.o; text: .text%__1cFRInfo2t6M_v_: nmethod.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: oopMap.o; text: .text%__1cQDoNothingClosure2t6M_v_: oopMap.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: os_solaris.o; text: .text%__1cFRInfo2t6M_v_: os_solaris.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: os_solaris_i486.o; -text: .text%__1cFRInfo2t6M_v_: os_solaris_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: os_solaris_x86.o; +text: .text%__1cFRInfo2t6M_v_: os_solaris_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: parGCAllocBuffer.o; text: .text%__1cMarrayOopDescLheader_size6FnJBasicType__i_: parGCAllocBuffer.o; text: .text%__1cRalign_object_size6Fi_i_: parGCAllocBuffer.o; @@ -181,8 +181,8 @@ text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: runtimeService.o; text: .text%__1cJTimeStamp2t6M_v_: runtimeService.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: safepoint.o; text: .text%__1cFRInfo2t6M_v_: safepoint.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: safepoint_solaris_i486.o; -text: .text%__1cFRInfo2t6M_v_: safepoint_solaris_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: safepoint_solaris_x86.o; +text: .text%__1cFRInfo2t6M_v_: safepoint_solaris_x86.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: sharedHeap.o; text: .text%__1cTAssertIsPermClosure2t6M_v_: sharedHeap.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: sharedRuntime.o; @@ -197,10 +197,10 @@ text: .text%__1cFRInfo2t6M_v_: vmStructs.o; text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: vm_version.o; text: .text%__1cTAbstract_VM_VersionKvm_release6F_pkc_; text: .text%__1cTAbstract_VM_VersionXinternal_vm_info_string6F_pkc_; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: vtableStubs_i486.o; -text: .text%__1cFRInfo2t6M_v_: vtableStubs_i486.o; -text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIROptimizer_i486.o; -text: .text%__1cFRInfo2t6M_v_: c1_LIROptimizer_i486.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: vtableStubs_x86.o; +text: .text%__1cFRInfo2t6M_v_: vtableStubs_x86.o; +text: .text%__1cU__STATIC_CONSTRUCTOR6F_v_: c1_LIROptimizer_x86.o; +text: .text%__1cFRInfo2t6M_v_: c1_LIROptimizer_x86.o; text: .text%JNI_CreateJavaVM; text: .text%__1cCosVatomic_xchg_bootstrap6Fipoi_i_; text: .text%__1cHThreadsJcreate_vm6FpnOJavaVMInitArgs_pi_i_; @@ -279,7 +279,7 @@ text: .text%__1cSThreadLocalStorageEinit6F_v_; text: .text%__1cSThreadLocalStorageHpd_init6F_v_; text: .text%__1cCosbDallocate_thread_local_storage6F_i_; text: .text%__1cSThreadLocalStoragebCgenerate_code_for_get_thread6F_v_; -text: .text%__1cRAllocateTLSOffset6F_v_: threadLS_solaris_i486.o; +text: .text%__1cRAllocateTLSOffset6F_v_: threadLS_solaris_x86.o; text: .text%__1cPvm_init_globals6F_v_; text: .text%__1cScheck_ThreadShadow6F_v_; text: .text%__1cRcheck_basic_types6F_v_; @@ -463,7 +463,7 @@ text: .text%__1cKMemoryPoolImax_size6kM_I_: memoryPool.o; text: .text%__1cXresource_allocate_bytes6FI_pc_; text: .text%__1cKCodeBuffer2t6MpCi_v_; text: .text%__1cRAbstractAssembler2t6MpnKCodeBuffer__v_; -text: .text%__1cYVM_Version_StubGeneratorTgenerate_getPsrInfo6M_pC_: vm_version_i486.o; +text: .text%__1cYVM_Version_StubGeneratorTgenerate_getPsrInfo6M_pC_: vm_version_x86.o; text: .text%__1cMStubCodeMark2t6MpnRStubCodeGenerator_pkc4_v_; text: .text%__1cRStubCodeGeneratorLstub_prolog6MpnMStubCodeDesc__v_; text: .text%__1cJAssemblerFpushl6MpnMRegisterImpl__v_; @@ -497,14 +497,14 @@ text: .text%__1cFVTuneNregister_stub6FpkcpC3_v_; text: .text%__1cFForteNregister_stub6FpkcpC3_v_; text: .text%__1cKVM_VersionWget_processor_features6F_v_; text: .text%__1cCosMsupports_sse6F_i_; -text: .text%__1cVcheck_for_sse_support6F_v_: os_solaris_i486.o; +text: .text%__1cVcheck_for_sse_support6F_v_: os_solaris_x86.o; text: .text%jio_snprintf; text: .text%jio_vsnprintf; text: .text%__1cPlocal_vsnprintf6FpcIpkcpv_i_; text: .text%__1cSstubRoutines_init16F_v_; text: .text%__1cMStubRoutinesLinitialize16F_v_; text: .text%__1cWStubGenerator_generate6FpnKCodeBuffer_i_v_; -text: .text%__1cNStubGeneratorbAgenerate_forward_exception6M_pC_: stubGenerator_i486.o; +text: .text%__1cNStubGeneratorbAgenerate_forward_exception6M_pC_: stubGenerator_x86.o; text: .text%__1cOMacroAssemblerMcall_VM_leaf6MpCpnMRegisterImpl__v_; text: .text%__1cOMacroAssemblerMcall_VM_leaf6MpCi_v_; text: .text%__1cOMacroAssemblerRcall_VM_leaf_base6MpCi_v_; @@ -525,7 +525,7 @@ text: .text%__1cJAssemblerEleal6MpnMRegisterImpl_nHAddress__v_; text: .text%__1cJAssemblerEmovl6MnHAddress_i_v_; text: .text%__1cOMacroAssemblerKverify_oop6MpnMRegisterImpl_pkc_v_; text: .text%__1cJAssemblerDjmp6MpnMRegisterImpl_nJrelocInfoJrelocType__v_; -text: .text%__1cNStubGeneratorSgenerate_call_stub6MrpC_1_: stubGenerator_i486.o; +text: .text%__1cNStubGeneratorSgenerate_call_stub6MrpC_1_: stubGenerator_x86.o; text: .text%__1cOMacroAssemblerFenter6M_v_; text: .text%__1cJAssemblerEsubl6MpnMRegisterImpl_i_v_; text: .text%__1cJAssemblerFtestl6MpnMRegisterImpl_2_v_; @@ -534,14 +534,14 @@ text: .text%__1cJAssemblerEcall6MpnMRegisterImpl_nJrelocInfoJrelocType__v_; text: .text%__1cJAssemblerEcmpl6MpnMRegisterImpl_i_v_; text: .text%__1cJAssemblerGfstp_s6MnHAddress__v_; text: .text%__1cJAssemblerGfstp_d6MnHAddress__v_; -text: .text%__1cNStubGeneratorYgenerate_catch_exception6M_pC_: stubGenerator_i486.o; +text: .text%__1cNStubGeneratorYgenerate_catch_exception6M_pC_: stubGenerator_x86.o; text: .text%__1cJAssemblerDjmp6MpCnJrelocInfoJrelocType__v_; -text: .text%__1cNStubGeneratorUgenerate_atomic_xchg6M_pC_: stubGenerator_i486.o; +text: .text%__1cNStubGeneratorUgenerate_atomic_xchg6M_pC_: stubGenerator_x86.o; text: .text%__1cJAssemblerExchg6MpnMRegisterImpl_nHAddress__v_; text: .text%__1cJAssemblerGpushad6M_v_; text: .text%__1cJAssemblerFpopad6M_v_; -text: .text%__1cNStubGeneratorYgenerate_get_previous_fp6M_pC_: stubGenerator_i486.o; -text: .text%__1cNStubGeneratorUgenerate_d2i_wrapper6MpC_1_: stubGenerator_i486.o; +text: .text%__1cNStubGeneratorYgenerate_get_previous_fp6M_pC_: stubGenerator_x86.o; +text: .text%__1cNStubGeneratorUgenerate_d2i_wrapper6MpC_1_: stubGenerator_x86.o; text: .text%__1cOMacroAssemblerOpush_FPU_state6M_v_; text: .text%__1cJAssemblerGfnsave6MnHAddress__v_; text: .text%__1cJAssemblerFfwait6M_v_; @@ -552,7 +552,7 @@ text: .text%__1cJAssemblerFffree6Mi_v_; text: .text%__1cJAssemblerLemit_farith6Miii_v_; text: .text%__1cOMacroAssemblerNpop_FPU_state6M_v_; text: .text%__1cJAssemblerGfrstor6MnHAddress__v_; -text: .text%__1cNStubGeneratorUcreate_control_words6M_v_: stubGenerator_i486.o; +text: .text%__1cNStubGeneratorUcreate_control_words6M_v_: stubGenerator_x86.o; text: .text%__1cJTraceTime2T6M_v_; text: .text%__1cNcarSpace_init6F_v_; text: .text%__1cICarSpaceEinit6F_v_; @@ -773,7 +773,7 @@ text: .text%__1cUInterpreterGeneratorVgenerate_counter_incr6MpnFLabel_22_v_; text: .text%__1cJAssemblerEaddl6MpnMRegisterImpl_2_v_; text: .text%__1cJAssemblerEcmpl6MpnMRegisterImpl_nHAddress__v_; text: .text%__1cbCAbstractInterpreterGeneratorXbang_stack_shadow_pages6Mi_v_; -text: .text%__1cOMacroAssemblerWbang_stack_with_offset6Mi_v_: interp_masm_i486.o; +text: .text%__1cOMacroAssemblerWbang_stack_with_offset6Mi_v_: interp_masm_x86.o; text: .text%__1cZInterpreterMacroAssemblerTnotify_method_entry6M_v_; text: .text%__1cUInterpreterGeneratorZgenerate_counter_overflow6MpC_v_; text: .text%__1cJAssemblerEnegl6MpnMRegisterImpl__v_; @@ -785,7 +785,7 @@ text: .text%__1cJAssemblerDorl6MpnMRegisterImpl_nHAddress__v_; text: .text%__1cUInterpreterGeneratorUgenerate_empty_entry6M_pC_; text: .text%__1cUInterpreterGeneratorXgenerate_accessor_entry6M_pC_; text: .text%__1cJAssemblerEshrl6MpnMRegisterImpl_i_v_; -text: .text%__1cLlog2_intptr6Fi_i_: interpreter_i486.o; +text: .text%__1cLlog2_intptr6Fi_i_: interpreter_x86.o; text: .text%__1cOMacroAssemblerQload_signed_byte6MpnMRegisterImpl_nHAddress__i_; text: .text%__1cJAssemblerGmovsxb6MpnMRegisterImpl_nHAddress__v_; text: .text%__1cOMacroAssemblerQload_signed_word6MpnMRegisterImpl_nHAddress__i_; @@ -982,7 +982,7 @@ text: .text%__1cNTemplateTableJfloat_cmp6Fii_v_; text: .text%__1cOMacroAssemblerIfcmp2int6MpnMRegisterImpl_i_v_; text: .text%__1cNTemplateTableKdouble_cmp6Fi_v_; text: .text%__1cNTemplateTableHif_0cmp6Fn0AJCondition__v_; -text: .text%__1cFj_not6FnNTemplateTableJCondition__nJAssemblerJCondition__: templateTable_i486.o; +text: .text%__1cFj_not6FnNTemplateTableJCondition__nJAssemblerJCondition__: templateTable_x86.o; text: .text%__1cNTemplateTableGbranch6Fii_v_; text: .text%__1cZInterpreterMacroAssemblerUprofile_taken_branch6MpnMRegisterImpl_2_v_; text: .text%__1cZInterpreterMacroAssemblerNdispatch_only6MnITosState__v_; @@ -1488,7 +1488,7 @@ text: .text%__1cKSharedInfoLset_regName6F_v_; text: .text%__1cIRegAllocYinit_register_allocation6F_v_; text: .text%__1cIFrameMapEinit6F_v_; text: .text%__1cKc1_RegMaskKinit_masks6Fi_v_; -text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_FrameMap_i486.o; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_FrameMap_x86.o; text: .text%__1cNc1_AllocTableLinit_tables6F_v_; text: .text%__1cIFrameMapOfirst_register6F_pnMRegisterImpl__; text: .text%__1cIFrameMapLcpu_reg2rnr6FpnMRegisterImpl__i_; @@ -1502,7 +1502,7 @@ text: .text%__1cKCodeBuffer2t6MiiiiiipnKBufferBlob_pnJrelocInfo_pnORelocateBuffe text: .text%__1cKCodeBufferQalloc_relocation6MI_v_; text: .text%__1cJOopMapSet2t6M_v_; text: .text%__1cJAssemblerEsubl6MnHAddress_i_v_; -text: .text%__1cTsave_live_registers6FpnOMacroAssembler_i_pnGOopMap__: c1_Runtime1_i486.o; +text: .text%__1cTsave_live_registers6FpnOMacroAssembler_i_pnGOopMap__: c1_Runtime1_x86.o; text: .text%__1cJAssemblerGfldenv6MnHAddress__v_; text: .text%__1cGOopMap2t6Mii_v_; text: .text%__1cGOopMapQset_callee_saved6MnHOptoRegEName_ii2_v_; @@ -1564,10 +1564,10 @@ text: .text%__1cNStubAssemblerHcall_RT6MpnMRegisterImpl_2pCi_i_; text: .text%__1cJStubFrame2T6M_v_; text: .text%__1cIRuntime1Ygenerate_exception_throw6FpnNStubAssembler_pCpnMRegisterImpl__pnJOopMapSet__; text: .text%__1cOMacroAssemblerLtlab_refill6MrnFLabel_22_v_; -text: .text%__1cLlog2_intptr6Fi_i_: assembler_i486.o; +text: .text%__1cLlog2_intptr6Fi_i_: assembler_x86.o; text: .text%__1cOMacroAssemblerNeden_allocate6MpnMRegisterImpl_2i2rnFLabel__v_; text: .text%__1cOMacroAssemblerLverify_tlab6M_v_; -text: .text%__1cLlog2_intptr6Fi_i_: c1_Runtime1_i486.o; +text: .text%__1cLlog2_intptr6Fi_i_: c1_Runtime1_x86.o; text: .text%__1cOMacroAssemblerNtlab_allocate6MpnMRegisterImpl_2i22rnFLabel__v_; text: .text%__1cRC1_MacroAssemblerRinitialize_object6MpnMRegisterImpl_22i22_v_; text: .text%__1cRC1_MacroAssemblerRinitialize_header6MpnMRegisterImpl_22_v_; @@ -1581,7 +1581,7 @@ text: .text%__1cIiEntries2t6Miiii_v_; text: .text%__1cRNativeGeneralJumpQjump_destination6kM_pC_; text: .text%__1cJAssemblerOlocate_operand6FpCn0AMWhichOperand__1_; text: .text%__1cIRuntime1Rgenerate_patching6FpnNStubAssembler_pC_pnJOopMapSet__; -text: .text%__1cWrestore_live_registers6FpnOMacroAssembler__v_: c1_Runtime1_i486.o; +text: .text%__1cWrestore_live_registers6FpnOMacroAssembler__v_: c1_Runtime1_x86.o; text: .text%__1cNSafepointBlobGcreate6FpnKCodeBuffer_pnJOopMapSet_i_p0_; text: .text%__1cNSafepointBlob2n6FII_pv_; text: .text%__1cNSafepointBlob2t6MpnKCodeBuffer_ipnJOopMapSet_i_v_; @@ -1778,8 +1778,8 @@ text: .text%__1cYsun_reflect_ConstantPoolPcompute_offsets6F_v_; text: .text%__1cZsun_misc_AtomicLongCSImplPcompute_offsets6F_v_; text: .text%__1cSstubRoutines_init26F_v_; text: .text%__1cMStubRoutinesLinitialize26F_v_; -text: .text%__1cNStubGeneratorYgenerate_throw_exception6MpkcpCi_3_: stubGenerator_i486.o; -text: .text%__1cNStubGeneratorTgenerate_verify_oop6M_pC_: stubGenerator_i486.o; +text: .text%__1cNStubGeneratorYgenerate_throw_exception6MpkcpCi_3_: stubGenerator_x86.o; +text: .text%__1cNStubGeneratorTgenerate_verify_oop6M_pC_: stubGenerator_x86.o; text: .text%__1cJAssemblerEincl6MnHAddress__v_; text: .text%__1cHThreadsDadd6FpnKJavaThread_i_v_; text: .text%__1cNThreadServiceKadd_thread6FpnKJavaThread_i_v_; @@ -3074,11 +3074,11 @@ text: .text%__1cEItemRget_jint_constant6kM_i_; text: .text%__1cLLIR_EmitterRarithmetic_op_int6MnJBytecodesECode_pnLLIR_OprDesc_44nFRInfo__v_; text: .text%__1cLLIR_EmitterNarithmetic_op6MnJBytecodesECode_pnLLIR_OprDesc_44inFRInfo_pnMCodeEmitInfo__v_; text: .text%__1cLLIR_EmitterYstrength_reduce_multiply6MpnLLIR_OprDesc_i22_i_; -text: .text%__1cILIR_ListHreg2reg6MnFRInfo_1nJBasicType__v_: c1_LIREmitter_i486.o; -text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_LIREmitter_i486.o; -text: .text%__1cLlog2_intptr6Fi_i_: c1_LIREmitter_i486.o; +text: .text%__1cILIR_ListHreg2reg6MnFRInfo_1nJBasicType__v_: c1_LIREmitter_x86.o; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_LIREmitter_x86.o; +text: .text%__1cLlog2_intptr6Fi_i_: c1_LIREmitter_x86.o; text: .text%__1cILIR_ListKshift_left6MpnLLIR_OprDesc_222_v_; -text: .text%__1cILIR_ListDsub6MpnLLIR_OprDesc_22pnMCodeEmitInfo__v_: c1_LIREmitter_i486.o; +text: .text%__1cILIR_ListDsub6MpnLLIR_OprDesc_22pnMCodeEmitInfo__v_: c1_LIREmitter_x86.o; text: .text%__1cIValueGenWcan_inline_as_constant6MpnEItem__i_; text: .text%__1cIRegAllocPget_register_rc6kMnFRInfo__i_; text: .text%__1cLGetRefCountGdo_cpu6Mi_v_: c1_RegAlloc.o; @@ -3098,7 +3098,7 @@ text: .text%__1cMLIR_OpBranch2t6Mn0ANLIR_Condition_pnICodeStub_pnMCodeEmitInfo__ text: .text%__1cLLIR_EmitterMindexed_load6MnFRInfo_nJBasicType_pnLLIR_OprDesc_4pnMCodeEmitInfo__v_; text: .text%__1cLLIR_EmitterNarray_address6MpnLLIR_OprDesc_2inJBasicType__pnLLIR_Address__; text: .text%__1cLLIR_AddressFscale6FnJBasicType__n0AFScale__; -text: .text%__1cILIR_ListEmove6MpnLLIR_Address_pnLLIR_OprDesc_pnMCodeEmitInfo__v_: c1_LIREmitter_i486.o; +text: .text%__1cILIR_ListEmove6MpnLLIR_Address_pnLLIR_OprDesc_pnMCodeEmitInfo__v_: c1_LIREmitter_x86.o; text: .text%__1cIRegAllocNoops_in_spill6kM_pnIintStack__; text: .text%__1cIRegAllocRoops_in_registers6kM_pnPRInfoCollection__; text: .text%__1cIValueGenbDsafepoint_poll_needs_register6F_i_; @@ -3137,9 +3137,9 @@ text: .text%__1cHLIR_Op1Fvisit6MpnQLIR_OpVisitState__v_; text: .text%__1cPRegisterManagerElock6MnFRInfo__v_; text: .text%__1cHLIR_Op2Fvisit6MpnQLIR_OpVisitState__v_; text: .text%__1cMLIR_OpBranchFvisit6MpnQLIR_OpVisitState__v_; -text: .text%__1cORangeCheckStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_i486.o; -text: .text%__1cQLIR_OpVisitStateGappend6MnFRInfo__v_: c1_CodeStubs_i486.o; -text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_CodeStubs_i486.o; +text: .text%__1cORangeCheckStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cQLIR_OpVisitStateGappend6MnFRInfo__v_: c1_CodeStubs_x86.o; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_CodeStubs_x86.o; text: .text%__1cNc1_AllocTableFmerge6Mp0_v_; text: .text%__1cGLIR_OpFvisit6MpnQLIR_OpVisitState__v_; text: .text%__1cQLIR_LocalCachingXcache_locals_for_blocks6MpnJBlockList_pnPRegisterManager_i_pnMLocalMapping__; @@ -3201,7 +3201,7 @@ text: .text%__1cJLabelListIindex_of6kMkpnFLabel__i_: c1_LIROptimizer.o; text: .text%__1cRLIR_PeepholeStateYset_disable_optimization6Mi_v_; text: .text%__1cLLIR_OpLabelJemit_code6MpnVLIR_AbstractAssembler__v_; text: .text%__1cNLIR_OptimizerMemit_opLabel6MpnLLIR_OpLabel__v_; -text: .text%__1cNLIR_OptimizerFvisit6M_v_: c1_LIROptimizer_i486.o; +text: .text%__1cNLIR_OptimizerFvisit6M_v_: c1_LIROptimizer_x86.o; text: .text%__1cHLIR_Op0Jemit_code6MpnVLIR_AbstractAssembler__v_; text: .text%__1cNLIR_OptimizerIemit_op06MpnHLIR_Op0__v_; text: .text%__1cHLIR_Op2Jemit_code6MpnVLIR_AbstractAssembler__v_; @@ -3225,7 +3225,7 @@ text: .text%__1cNLIR_OptimizerRreplace_stack_opr6MpnLLIR_OprDesc__2_; text: .text%__1cNLIR_OptimizerNoptimize_move6MpnHLIR_Op1_rpnLLIR_OprDesc_5_i_; text: .text%__1cRLIR_PeepholeStatebFequivalent_register_or_constant6MpnLLIR_OprDesc__2_; text: .text%__1cRLIR_PeepholeStateOequivalent_opr6MpnLLIR_OprDesc__2_; -text: .text%__1cNLIR_OptimizerKmaybe_opto6MpnLLIR_OprDesc_2_2_: c1_LIROptimizer_i486.o; +text: .text%__1cNLIR_OptimizerKmaybe_opto6MpnLLIR_OprDesc_2_2_: c1_LIROptimizer_x86.o; text: .text%__1cNLIR_OptimizerMis_cache_reg6MpnLLIR_OprDesc__i_; text: .text%__1cMLocalMappingMis_cache_reg6kMpnLLIR_OprDesc__i_; text: .text%__1cMLocalMappingMis_cache_reg6kMnFRInfo__i_; @@ -3294,13 +3294,13 @@ text: .text%__1cNLIR_AssemblerVsetup_locals_at_entry6M_v_; text: .text%__1cIFrameMapYsignature_type_array_for6FpknIciMethod__pnNBasicTypeList__; text: .text%__1cIFrameMapScalling_convention6FpknIciMethod_pnIintArray__pnRCallingConvention__; text: .text%__1cIFrameMapScalling_convention6FirknOBasicTypeArray_pnIintArray__pnRCallingConvention__; -text: .text%__1cIintArray2t6Mki1_v_: c1_FrameMap_i486.o; +text: .text%__1cIintArray2t6Mki1_v_: c1_FrameMap_x86.o; text: .text%__1cIFrameMapRname_for_argument6Fi_i_; text: .text%__1cIFrameMapSfp_offset_for_name6kMiii_i_; text: .text%__1cIFrameMapPnum_local_names6kM_i_; text: .text%__1cIFrameMapNlocal_to_slot6kMii_i_; text: .text%__1cIFrameMapSfp_offset_for_slot6kMi_i_; -text: .text%__1cQArgumentLocation2t6Mci_v_: c1_FrameMap_i486.o; +text: .text%__1cQArgumentLocation2t6Mci_v_: c1_FrameMap_x86.o; text: .text%__1cQArgumentLocationSset_stack_location6Mi_v_; text: .text%__1cIFrameMapQaddress_for_name6kMiii_nHAddress__; text: .text%__1cIFrameMapQmake_new_address6kMi_nHAddress__; @@ -3321,12 +3321,12 @@ text: .text%__1cNLIR_AssemblerbIadd_debug_info_for_null_check_here6MpnMCodeEmitI text: .text%__1cNLIR_AssemblerLcode_offset6kM_i_; text: .text%__1cNLIR_AssemblerbDadd_debug_info_for_null_check6MipnMCodeEmitInfo__v_; text: .text%__1cNLIR_AssemblerOemit_code_stub6MpnICodeStub__v_; -text: .text%__1cVImplicitNullCheckStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_i486.o; +text: .text%__1cVImplicitNullCheckStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; text: .text%__1cNLIR_AssemblerCpc6kM_pC_; -text: .text%__1cICodeStubLset_code_pc6MpC_v_: c1_CodeStubs_i486.o; -text: .text%__1cICodeStubMis_call_stub6kM_i_: c1_CodeStubs_i486.o; +text: .text%__1cICodeStubLset_code_pc6MpC_v_: c1_CodeStubs_x86.o; +text: .text%__1cICodeStubMis_call_stub6kM_i_: c1_CodeStubs_x86.o; text: .text%__1cNCodeStubArrayIindex_of6kMkpnICodeStub__i_: c1_LIRAssembler.o; -text: .text%__1cORangeCheckStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_i486.o; +text: .text%__1cORangeCheckStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; text: .text%__1cNLIR_AssemblerOsafepoint_poll6MnFRInfo_pnMCodeEmitInfo__v_; text: .text%__1cNLIR_AssemblerZadd_debug_info_for_branch6MpnMCodeEmitInfo__v_; text: .text%__1cPpoll_RelocationEtype6M_nJrelocInfoJrelocType__: codeBlob.o; @@ -3396,7 +3396,7 @@ text: .text%__1cNLIR_AssemblerWemit_exception_handler6M_i_; text: .text%__1cRC1_MacroAssemblerRexception_handler6Mii_v_; text: .text%__1cNLIR_AssemblerPemit_call_stubs6M_v_; text: .text%__1cNLIR_AssemblerbCmaybe_adjust_stack_alignment6MpnIciMethod__v_; -text: .text%__1cKreal_index6FpnIFrameMap_i_i_: c1_LIRAssembler_i486.o; +text: .text%__1cKreal_index6FpnIFrameMap_i_i_: c1_LIRAssembler_x86.o; text: .text%__1cLCompilationbEgenerate_exception_range_table6M_v_; text: .text%__1cOExceptionScopeGequals6kMp0_i_; text: .text%__1cLCompilationbBadd_exception_range_entries6MiipnOExceptionScope_ip2pi_v_; @@ -3582,10 +3582,10 @@ text: .text%__1cLNewInstanceOas_NewInstance6M_p0_: c1_Instruction.o; text: .text%__1cIValueGenQexceptionPcRInfo6F_nFRInfo__; text: .text%__1cILIR_ListPthrow_exception6MnFRInfo_1pnMCodeEmitInfo__v_: c1_CodeGenerator.o; text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_CodeGenerator.o; -text: .text%__1cPNewInstanceStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_i486.o; +text: .text%__1cPNewInstanceStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; text: .text%__1cOLIR_OpJavaCallFvisit6MpnQLIR_OpVisitState__v_; text: .text%__1cQLIR_OpVisitStateGappend6MnFRInfo__v_: c1_LIR.o; -text: .text%__1cOStaticCallStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_i486.o; +text: .text%__1cOStaticCallStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; text: .text%__1cIFrameMapWcaller_save_cpu_reg_at6Fi_pnLLIR_OprDesc__; text: .text%__1cLInstructionLas_NewArray6M_pnINewArray__: c1_Instruction.o; text: .text%__1cIVoidTypeDtag6kM_nIValueTag__: c1_ValueType.o; @@ -3604,12 +3604,12 @@ text: .text%__1cOoop_RelocationJpack_data6M_i_; text: .text%__1cNLIR_AssemblerPpatching_epilog6MpnMPatchingStub_nHLIR_Op1NLIR_PatchCode_pnMRegisterImpl_pnMCodeEmitInfo__v_; text: .text%__1cMPatchingStubHinstall6MpnOMacroAssembler_nHLIR_Op1NLIR_PatchCode_pnMRegisterImpl_pnMCodeEmitInfo__v_: c1_LIRAssembler.o; text: .text%__1cNLIR_AssemblerUappend_patching_stub6MpnMPatchingStub__v_; -text: .text%__1cPNewInstanceStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_i486.o; +text: .text%__1cPNewInstanceStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; text: .text%__1cNLIR_AssemblerJemit_call6MpnOLIR_OpJavaCall__v_; text: .text%__1cNLIR_AssemblerKalign_call6MnILIR_Code__v_; -text: .text%__1cICodeStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_i486.o; -text: .text%__1cOStaticCallStubLset_code_pc6MpC_v_: c1_CodeStubs_i486.o; -text: .text%__1cOStaticCallStubMis_call_stub6kM_i_: c1_CodeStubs_i486.o; +text: .text%__1cICodeStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; +text: .text%__1cOStaticCallStubLset_code_pc6MpC_v_: c1_CodeStubs_x86.o; +text: .text%__1cOStaticCallStubMis_call_stub6kM_i_: c1_CodeStubs_x86.o; text: .text%__1cNLIR_AssemblerEcall6MpCnJrelocInfoJrelocType_pnMCodeEmitInfo__v_; text: .text%__1cbBopt_virtual_call_RelocationEtype6M_nJrelocInfoJrelocType__: relocInfo.o; text: .text%__1cKRelocationJpack_data6M_i_: relocInfo.o; @@ -4010,15 +4010,15 @@ text: .text%__1cJTypeCheckPinput_values_do6MpFppnLInstruction__v_v_: c1_GraphBui text: .text%__1cQNullCheckVisitorNdo_InstanceOf6MpnKInstanceOf__v_; text: .text%__1cQNullCheckVisitorMdo_CheckCast6MpnJCheckCast__v_; text: .text%__1cIValueGenNdo_InstanceOf6MpnKInstanceOf__v_; -text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_CodeGenerator_i486.o; +text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_CodeGenerator_x86.o; text: .text%__1cLLIR_EmitterNinstanceof_op6MpnLLIR_OprDesc_2pnHciKlass_nFRInfo_5ipnMCodeEmitInfo__v_; text: .text%__1cILIR_ListKinstanceof6MpnLLIR_OprDesc_2pnHciKlass_22ipnMCodeEmitInfo__v_; text: .text%__1cPLIR_OpTypeCheck2t6MnILIR_Code_pnLLIR_OprDesc_3pnHciKlass_33ipnMCodeEmitInfo_7pnICodeStub__v_; text: .text%__1cIValueGenMdo_CheckCast6MpnJCheckCast__v_; text: .text%__1cILIR_ListJcheckcast6MpnLLIR_OprDesc_2pnHciKlass_22ipnMCodeEmitInfo_6pnICodeStub__v_; -text: .text%__1cILIR_ListJsafepoint6MnFRInfo_pnMCodeEmitInfo__v_: c1_CodeGenerator_i486.o; +text: .text%__1cILIR_ListJsafepoint6MnFRInfo_pnMCodeEmitInfo__v_: c1_CodeGenerator_x86.o; text: .text%__1cPLIR_OpTypeCheckFvisit6MpnQLIR_OpVisitState__v_; -text: .text%__1cTSimpleExceptionStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_i486.o; +text: .text%__1cTSimpleExceptionStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; text: .text%__1cPLIR_OpTypeCheckJemit_code6MpnVLIR_AbstractAssembler__v_; text: .text%__1cNLIR_OptimizerQemit_opTypeCheck6MpnPLIR_OpTypeCheck__v_; text: .text%__1cLLIR_OprDescIsize_for6FnJBasicType__n0AHOprSize__: c1_LIROptimizer.o; @@ -4026,7 +4026,7 @@ text: .text%__1cIintArrayIindex_of6kMki_i_: c1_LIROptimizer.o; text: .text%__1cNLIR_AssemblerQemit_opTypeCheck6MpnPLIR_OpTypeCheck__v_; text: .text%__1cIciObjectIencoding6M_pnI_jobject__; text: .text%__1cJAssemblerEcmpl6MnHAddress_pnI_jobject__v_; -text: .text%__1cTSimpleExceptionStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_i486.o; +text: .text%__1cTSimpleExceptionStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; text: .text%__1cTSimpleExceptionStubJemit_code6MpnNLIR_Assembler__v_; text: .text%__1cJLoadFieldIis_equal6kMpnLInstruction__i_: c1_Instruction.o; text: .text%__1cJLoadFieldMas_LoadField6M_p0_: c1_Instruction.o; @@ -4194,7 +4194,7 @@ text: .text%__1cLLIR_EmitterOnew_type_array6MnFRInfo_nJBasicType_pnLLIR_OprDesc_ text: .text%__1cQNewTypeArrayStub2t6MnFRInfo_11pnMCodeEmitInfo__v_; text: .text%__1cQciTypeArrayKlassEmake6FnJBasicType__p0_; text: .text%__1cQciTypeArrayKlassJmake_impl6FnJBasicType__p0_; -text: .text%__1cILIR_ListHoop2reg6MpnI_jobject_nFRInfo__v_: c1_LIREmitter_i486.o; +text: .text%__1cILIR_ListHoop2reg6MpnI_jobject_nFRInfo__v_: c1_LIREmitter_x86.o; text: .text%__1cILIR_ListOallocate_array6MnFRInfo_11111nJBasicType_1pnICodeStub__v_; text: .text%__1cIValueGenMdo_Intrinsic6MpnJIntrinsic__v_; text: .text%__1cIValueGenMdo_ArrayCopy6MpnJIntrinsic__v_; @@ -4209,12 +4209,12 @@ text: .text%__1cLInstructionNdeclared_type6kM_pnGciType__: c1_Instruction.o; text: .text%__1cRpositive_constant6FpnLInstruction__i_: c1_CodeGenerator.o; text: .text%__1cLArrayLengthOas_ArrayLength6M_p0_: c1_GraphBuilder.o; text: .text%__1cQis_constant_zero6FpnLInstruction__i_: c1_CodeGenerator.o; -text: .text%__1cILIR_ListJarraycopy6MpnLLIR_OprDesc_22222pnMciArrayKlass_ipnMCodeEmitInfo__v_: c1_CodeGenerator_i486.o; +text: .text%__1cILIR_ListJarraycopy6MpnLLIR_OprDesc_22222pnMciArrayKlass_ipnMCodeEmitInfo__v_: c1_CodeGenerator_x86.o; text: .text%__1cLLIR_EmitterNwrite_barrier6MpnLLIR_OprDesc_2_v_; -text: .text%__1cILIR_ListUunsigned_shift_right6MnFRInfo_i1_v_: c1_LIREmitter_i486.o; +text: .text%__1cILIR_ListUunsigned_shift_right6MnFRInfo_i1_v_: c1_LIREmitter_x86.o; text: .text%__1cILIR_ListUunsigned_shift_right6MpnLLIR_OprDesc_222_v_; text: .text%__1cQLIR_OpAllocArrayFvisit6MpnQLIR_OpVisitState__v_; -text: .text%__1cQNewTypeArrayStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_i486.o; +text: .text%__1cQNewTypeArrayStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; text: .text%__1cPLIR_OpArrayCopyFvisit6MpnQLIR_OpVisitState__v_; text: .text%__1cQLIR_OpAllocArrayJemit_code6MpnVLIR_AbstractAssembler__v_; text: .text%__1cNLIR_OptimizerQemit_alloc_array6MpnQLIR_OpAllocArray__v_; @@ -4229,12 +4229,12 @@ text: .text%__1cNLIR_AssemblerQemit_alloc_array6MpnQLIR_OpAllocArray__v_; text: .text%__1cNLIR_AssemblerSarray_element_size6kMnJBasicType__nHAddressLScaleFactor__; text: .text%__1cRC1_MacroAssemblerOallocate_array6MpnMRegisterImpl_222inHAddressLScaleFactor_2rnFLabel__v_; text: .text%__1cRC1_MacroAssemblerMtry_allocate6MpnMRegisterImpl_2i22rnFLabel__v_; -text: .text%__1cQNewTypeArrayStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_i486.o; +text: .text%__1cQNewTypeArrayStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; text: .text%__1cNLIR_AssemblerOemit_arraycopy6MpnPLIR_OpArrayCopy__v_; text: .text%__1cMciArrayKlassMelement_type6M_pnGciType__; text: .text%__1cNArrayCopyStub2t6MpnMCodeEmitInfo_pnOStaticCallStub__v_; text: .text%__1cFRInfoMset_word_reg6MkpnMRegisterImpl__v_; -text: .text%__1cNArrayCopyStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_i486.o; +text: .text%__1cNArrayCopyStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; text: .text%__1cNLIR_AssemblerOpush_parameter6MpnMRegisterImpl_i_v_; text: .text%__1cQNewTypeArrayStubJemit_code6MpnNLIR_Assembler__v_; text: .text%__1cNArrayCopyStubJemit_code6MpnNLIR_Assembler__v_; @@ -4295,14 +4295,14 @@ text: .text%__1cLLIR_EmitterIshift_op6MnJBytecodesECode_nFRInfo_pnLLIR_OprDesc_5 text: .text%__1cILIR_ListKshift_left6MnFRInfo_i1_v_: c1_LIREmitter.o; text: .text%__1cILIR_ListKlogical_or6MnFRInfo_pnLLIR_OprDesc_1_v_: c1_LIREmitter.o; text: .text%__1cOLIR_OpAllocObjFvisit6MpnQLIR_OpVisitState__v_; -text: .text%__1cSNewObjectArrayStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_i486.o; +text: .text%__1cSNewObjectArrayStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; text: .text%__1cOLIR_OpAllocObjJemit_code6MpnVLIR_AbstractAssembler__v_; text: .text%__1cNLIR_OptimizerOemit_alloc_obj6MpnOLIR_OpAllocObj__v_; text: .text%__1cNLIR_AssemblerOemit_alloc_obj6MpnOLIR_OpAllocObj__v_; text: .text%__1cRC1_MacroAssemblerPallocate_object6MpnMRegisterImpl_22ii2rnFLabel__v_; text: .text%__1cNLIR_AssemblerOmembar_release6M_v_; text: .text%__1cNLIR_AssemblerGmembar6M_v_; -text: .text%__1cSNewObjectArrayStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_i486.o; +text: .text%__1cSNewObjectArrayStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; text: .text%__1cNLIR_AssemblerOmembar_acquire6M_v_; text: .text%__1cEBaseHas_Base6M_p0_: c1_IR.o; text: .text%__1cNLIR_AssemblerOemit_osr_entry6MpnHIRScope_ipnFLabel_i_v_; @@ -4708,11 +4708,11 @@ text: .text%__1cILIR_ListLshift_right6MpnLLIR_OprDesc_222_v_; text: .text%__1cIValueGenLdo_NegateOp6MpnINegateOp__v_; text: .text%__1cLLIR_EmitterGnegate6MnFRInfo_pnLLIR_OprDesc__v_; text: .text%__1cILIR_ListGnegate6MnFRInfo_1_v_: c1_LIREmitter.o; -text: .text%__1cXArrayStoreExceptionStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_i486.o; -text: .text%__1cXArrayStoreExceptionStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_i486.o; +text: .text%__1cXArrayStoreExceptionStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cXArrayStoreExceptionStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; text: .text%__1cNLIR_AssemblerEleal6MpnLLIR_OprDesc_2_v_; text: .text%__1cNLIR_AssemblerGnegate6MpnLLIR_OprDesc_2_v_; -text: .text%__1cNCodeStubArrayIindex_of6kMkpnICodeStub__i_: c1_LIRAssembler_i486.o; +text: .text%__1cNCodeStubArrayIindex_of6kMkpnICodeStub__i_: c1_LIRAssembler_x86.o; text: .text%__1cXArrayStoreExceptionStubJemit_code6MpnNLIR_Assembler__v_; text: .text%__1cIRuntime1Tresolve_static_call6FpnKJavaThread_pnHoopDesc__pC_; text: .text%__1cSCompiledStaticCallNcompute_entry6FnMmethodHandle_rnOStaticCallInfo__v_; @@ -4788,7 +4788,7 @@ text: .text%__1cNLIR_AssemblerIfpu_push6MnFRInfo__v_; text: .text%__1cIFrameMapLFpuStackSimEpush6Mi_v_; text: .text%__1cNLIR_AssemblerKfpu_on_tos6MnFRInfo__v_; text: .text%__1cIFrameMapLFpuStackSimPoffset_from_tos6kMi_i_; -text: .text%__1cIintArrayIindex_of6kMki_i_: c1_FrameMap_i486.o; +text: .text%__1cIintArrayIindex_of6kMki_i_: c1_FrameMap_x86.o; text: .text%__1cNLIR_AssemblerHfpu_pop6MnFRInfo__v_; text: .text%__1cIFrameMapLFpuStackSimDpop6Mi_i_; text: .text%__1cNLIR_AssemblerKround32_op6MpnLLIR_OprDesc_2_v_; @@ -4797,7 +4797,7 @@ text: .text%__1cNLIR_AssemblerJreset_FPU6M_v_; text: .text%__1cNLIR_AssemblerIemit_op36MpnHLIR_Op3__v_; text: .text%__1cNLIR_AssemblerParithmetic_idiv6MnILIR_Code_pnLLIR_OprDesc_333pnMCodeEmitInfo__v_; text: .text%__1cNLIR_AssemblerXadd_debug_info_for_div06MipnMCodeEmitInfo__v_; -text: .text%__1cNDivByZeroStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_i486.o; +text: .text%__1cNDivByZeroStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; text: .text%__1cNDivByZeroStubJemit_code6MpnNLIR_Assembler__v_; text: .text%__1cIciObjectSis_obj_array_klass6M_i_: ciTypeArrayKlass.o; text: .text%__1cLInstructionOas_ArrayLength6M_pnLArrayLength__: c1_GraphBuilder.o; @@ -4874,12 +4874,12 @@ text: .text%__1cFKlassQup_cast_abstract6M_p0_; text: .text%__1cRComputeEntryStackHdo_byte6M_v_: generateOopMap.o; text: .text%__1cNSharedRuntimeDd2i6Fd_i_; text: .text%__1cSInterpreterRuntimeWslow_signature_handler6FpnKJavaThread_pnNmethodOopDesc_pi5_pC_; -text: .text%__1cXNativeSignatureIteratorJdo_object6Mii_v_: interpreterRT_i486.o; -text: .text%__1cUSlowSignatureHandlerLpass_object6M_v_: interpreterRT_i486.o; -text: .text%__1cXNativeSignatureIteratorIdo_array6Mii_v_: interpreterRT_i486.o; -text: .text%__1cXNativeSignatureIteratorGdo_int6M_v_: interpreterRT_i486.o; -text: .text%__1cUSlowSignatureHandlerIpass_int6M_v_: interpreterRT_i486.o; -text: .text%__1cXNativeSignatureIteratorHdo_bool6M_v_: interpreterRT_i486.o; +text: .text%__1cXNativeSignatureIteratorJdo_object6Mii_v_: interpreterRT_x86.o; +text: .text%__1cUSlowSignatureHandlerLpass_object6M_v_: interpreterRT_x86.o; +text: .text%__1cXNativeSignatureIteratorIdo_array6Mii_v_: interpreterRT_x86.o; +text: .text%__1cXNativeSignatureIteratorGdo_int6M_v_: interpreterRT_x86.o; +text: .text%__1cUSlowSignatureHandlerIpass_int6M_v_: interpreterRT_x86.o; +text: .text%__1cXNativeSignatureIteratorHdo_bool6M_v_: interpreterRT_x86.o; text: .text%jni_GetFloatArrayRegion: jni.o; text: .text%jni_GetCharArrayRegion: jni.o; text: .text%jni_SetFloatField: jni.o; @@ -4906,8 +4906,8 @@ text: .text%__1cLLIR_EmitterQreturn_op_prolog6Mi_v_; text: .text%__1cLLIR_EmitterMmonitor_exit6MnFRInfo_11i_v_; text: .text%__1cILIR_ListNunlock_object6MnFRInfo_11pnICodeStub__v_; text: .text%__1cKLIR_OpLockFvisit6MpnQLIR_OpVisitState__v_; -text: .text%__1cQMonitorEnterStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_i486.o; -text: .text%__1cRMonitorAccessStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_i486.o; +text: .text%__1cQMonitorEnterStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; +text: .text%__1cRMonitorAccessStubFvisit6MpnQLIR_OpVisitState__v_: c1_CodeStubs_x86.o; text: .text%__1cKLIR_OpLockJemit_code6MpnVLIR_AbstractAssembler__v_; text: .text%__1cNLIR_OptimizerJemit_lock6MpnKLIR_OpLock__v_; text: .text%__1cNLIR_AssemblerPmonitor_address6MinFRInfo__v_; @@ -4915,7 +4915,7 @@ text: .text%__1cIFrameMapbEaddress_for_monitor_lock_index6kMi_nHAddress__; text: .text%__1cIFrameMapbAfp_offset_for_monitor_lock6kMi_i_; text: .text%__1cNLIR_AssemblerJemit_lock6MpnKLIR_OpLock__v_; text: .text%__1cRC1_MacroAssemblerLlock_object6MpnMRegisterImpl_22rnFLabel__v_; -text: .text%__1cQMonitorEnterStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_i486.o; +text: .text%__1cQMonitorEnterStubEinfo6kM_pnMCodeEmitInfo__: c1_CodeStubs_x86.o; text: .text%__1cIFrameMapWmonitor_object_regname6kMi_nHOptoRegEName__; text: .text%__1cIFrameMapbCfp_offset_for_monitor_object6kMi_i_; text: .text%__1cMCodeEmitInfobHlocation_for_monitor_object_index6Mi_nILocation__; @@ -4925,7 +4925,7 @@ text: .text%__1cIFrameMapbFlocation_for_monitor_lock_index6kMipnILocation__i_; text: .text%__1cMMonitorValue2t6MpnKScopeValue_nILocation__v_; text: .text%__1cMMonitorValueIwrite_on6MpnUDebugInfoWriteStream__v_; text: .text%__1cRC1_MacroAssemblerNunlock_object6MpnMRegisterImpl_22rnFLabel__v_; -text: .text%__1cPMonitorExitStubMis_call_stub6kM_i_: c1_CodeStubs_i486.o; +text: .text%__1cPMonitorExitStubMis_call_stub6kM_i_: c1_CodeStubs_x86.o; text: .text%__1cQMonitorEnterStubJemit_code6MpnNLIR_Assembler__v_; text: .text%__1cNLIR_AssemblerRload_receiver_reg6MpnMRegisterImpl__v_; text: .text%__1cNLIR_AssemblerLmonitorexit6MnFRInfo_1pnMRegisterImpl_i3_v_; @@ -5168,7 +5168,7 @@ text: .text%__1cFRInfoOas_register_lo6kM_pnMRegisterImpl__; text: .text%__1cCosHrealloc6FpvI_1_; text: .text%Unsafe_GetNativeFloat; text: .text%__1cIValueGenQdo_currentThread6MpnJIntrinsic__v_; -text: .text%__1cILIR_ListKget_thread6MnFRInfo__v_: c1_CodeGenerator_i486.o; +text: .text%__1cILIR_ListKget_thread6MnFRInfo__v_: c1_CodeGenerator_x86.o; text: .text%__1cNLIR_AssemblerKget_thread6MpnLLIR_OprDesc__v_; text: .text%__1cIValueGenSload_item_patching6MpnHIRScope_ipnEItem_pnKValueStack_pnOExceptionScope__v_; text: .text%__1cEItemUget_jobject_constant6kM_pnIciObject__; @@ -5246,7 +5246,7 @@ text: .text%__1cGThreadLnmethods_do6M_v_; text: .text%__1cFframeLnmethods_do6M_v_; text: .text%__1cFframeVnmethods_code_blob_do6M_v_; text: .text%__1cILIR_ListEidiv6MnFRInfo_i11pnMCodeEmitInfo__v_; -text: .text%__1cLlog2_intptr6Fi_i_: c1_LIRAssembler_i486.o; +text: .text%__1cLlog2_intptr6Fi_i_: c1_LIRAssembler_x86.o; text: .text%__1cONMethodSweeperPprocess_nmethod6FpnHnmethod__v_; text: .text%__1cHnmethodPis_locked_by_vm6kM_i_: nmethod.o; text: .text%__1cHnmethodLis_unloaded6kM_i_: nmethod.o; @@ -5423,13 +5423,13 @@ text: .text%__1cIValueGenPdo_UnsafeGetRaw6MpnMUnsafeGetRaw__v_; text: .text%__1cLLIR_EmitterOget_raw_unsafe6MnFRInfo_pnLLIR_OprDesc_3inJBasicType__v_; text: .text%__1cILIR_ListMload_mem_reg6MpnLLIR_Address_nFRInfo_nJBasicType_pnMCodeEmitInfo_nHLIR_Op1NLIR_PatchCode__v_; text: .text%__1cIValueGenPdo_LookupSwitch6MpnMLookupSwitch__v_; -text: .text%__1cUcreate_lookup_ranges6FpnMLookupSwitch__pnQLookupRangeArray__: c1_CodeGenerator_i486.o; +text: .text%__1cUcreate_lookup_ranges6FpnMLookupSwitch__pnQLookupRangeArray__: c1_CodeGenerator_x86.o; text: .text%__1cLLIR_EmitterVlookupswitch_range_op6MpnLLIR_OprDesc_iipnKBlockBegin__v_; text: .text%__1cNSharedRuntimeEldiv6Fxx_x_; text: .text%Unsafe_GetObjectVolatile; text: .text%signalHandler; text: .text%JVM_handle_solaris_signal; -text: .text%__1cKJavaThreadUin_stack_yellow_zone6MpC_i_: os_solaris_i486.o; +text: .text%__1cKJavaThreadUin_stack_yellow_zone6MpC_i_: os_solaris_x86.o; text: .text%__1cICodeBlobRis_at_poll_return6MpC_i_; text: .text%__1cUSafepointSynchronizebDhandle_polling_page_exception6FpnKJavaThread__pC_; text: .text%__1cbCCompiledCodeSafepointHandlerbDhandle_polling_page_exception6M_pC_; diff --git a/hotspot/make/solaris/makefiles/sa.make b/hotspot/make/solaris/makefiles/sa.make index 6d700b23437..f8c1bf416c0 100644 --- a/hotspot/make/solaris/makefiles/sa.make +++ b/hotspot/make/solaris/makefiles/sa.make @@ -37,8 +37,9 @@ GENERATED = ../generated SA_CLASSPATH = $(BOOT_JAVA_HOME)/lib/tools.jar # gnumake 3.78.1 does not accept the *s that -# are in AGENT_ALLFILES, so use the shell to expand them -AGENT_ALLFILES := $(shell /usr/bin/test -d $(AGENT_DIR) && /bin/ls $(AGENT_ALLFILES)) +# are in AGENT_FILES1 and AGENT_FILES2, so use the shell to expand them +AGENT_FILES1 := $(shell /usr/bin/test -d $(AGENT_DIR) && /bin/ls $(AGENT_FILES1)) +AGENT_FILES2 := $(shell /usr/bin/test -d $(AGENT_DIR) && /bin/ls $(AGENT_FILES2)) SA_CLASSDIR = $(GENERATED)/saclasses @@ -52,7 +53,7 @@ all: $(MAKE) -f sa.make $(GENERATED)/sa-jdi.jar; \ fi -$(GENERATED)/sa-jdi.jar: $(AGENT_ALLFILES) +$(GENERATED)/sa-jdi.jar: $(AGENT_FILES1) $(AGENT_FILES2) $(QUIETLY) echo "Making $@"; $(QUIETLY) if [ "$(BOOT_JAVA_HOME)" = "" ]; then \ echo "ALT_BOOTDIR, BOOTDIR or JAVA_HOME needs to be defined to build SA"; \ @@ -66,9 +67,17 @@ $(GENERATED)/sa-jdi.jar: $(AGENT_ALLFILES) $(QUIETLY) if [ ! -d $(SA_CLASSDIR) ] ; then \ mkdir -p $(SA_CLASSDIR); \ fi - $(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -g -d $(SA_CLASSDIR) $(AGENT_ALLFILES) + $(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES1) + $(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES2) + $(QUIETLY) $(COMPILE.RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer $(QUIETLY) echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES) + $(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js + $(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql + $(QUIETLY) mkdir -p $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources + $(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources/* + $(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources/ + $(QUIETLY) cp -r $(AGENT_SRC_DIR)/images/* $(SA_CLASSDIR)/ $(QUIETLY) $(RUN.JAR) cf $@ -C $(SA_CLASSDIR)/ . $(QUIETLY) $(RUN.JAR) uf $@ -C $(AGENT_SRC_DIR) META-INF/services/com.sun.jdi.connect.Connector $(QUIETLY) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.proc.ProcDebuggerLocal diff --git a/hotspot/make/solaris/makefiles/sparcWorks.make b/hotspot/make/solaris/makefiles/sparcWorks.make index 83ef29612ee..5bbe70f9f10 100644 --- a/hotspot/make/solaris/makefiles/sparcWorks.make +++ b/hotspot/make/solaris/makefiles/sparcWorks.make @@ -51,12 +51,9 @@ ifeq ($(JDK_MINOR_VERSION),6) VALIDATED_COMPILER_REV := 5.8 VALIDATED_C_COMPILER_REV := 5.8 else - # FIXUP: Change to SS12 (5.9) once it has been validated. # Validated compiler for JDK7 is SS12 (5.9) - #VALIDATED_COMPILER_REV := 5.9 - #VALIDATED_C_COMPILER_REV := 5.9 - VALIDATED_COMPILER_REV := 5.8 - VALIDATED_C_COMPILER_REV := 5.8 + VALIDATED_COMPILER_REV := 5.9 + VALIDATED_C_COMPILER_REV := 5.9 endif # Warning messages about not using the above validated version diff --git a/hotspot/make/windows/makefiles/defs.make b/hotspot/make/windows/makefiles/defs.make index bfabddff58e..4b2fc14b3e2 100644 --- a/hotspot/make/windows/makefiles/defs.make +++ b/hotspot/make/windows/makefiles/defs.make @@ -107,7 +107,7 @@ ifeq ($(USING_CYGWIN), true) ABS_OUTPUTDIR := $(subst /,\\,$(shell /bin/cygpath -m -a "$(OUTPUTDIR)")) ABS_BOOTDIR := $(subst /,\\,$(shell /bin/cygpath -m -a "$(BOOTDIR)")) ABS_GAMMADIR := $(subst /,\\,$(shell /bin/cygpath -m -a "$(GAMMADIR)")) - ABS_OS_MAKEFILE := $(shell /bin/cygpath -m -a "$(HS_BUILD_DIR)/$(OSNAME)")/build.make + ABS_OS_MAKEFILE := $(shell /bin/cygpath -m -a "$(HS_MAKE_DIR)/$(OSNAME)")/build.make else ABS_OUTPUTDIR := $(subst /,\\,$(shell $(CD) $(OUTPUTDIR);$(PWD))) ABS_BOOTDIR := $(subst /,\\,$(shell $(CD) $(BOOTDIR);$(PWD))) diff --git a/hotspot/make/windows/makefiles/sa.make b/hotspot/make/windows/makefiles/sa.make index 481b5149d03..57fd493f823 100644 --- a/hotspot/make/windows/makefiles/sa.make +++ b/hotspot/make/windows/makefiles/sa.make @@ -49,15 +49,22 @@ SA_PROPERTIES = $(SA_CLASSDIR)\sa.properties default:: $(GENERATED)\sa-jdi.jar -$(GENERATED)\sa-jdi.jar: $(AGENT_ALLFILES:/=\) +$(GENERATED)\sa-jdi.jar: $(AGENT_FILES1:/=\) $(AGENT_FILES2:/=\) @if not exist $(SA_CLASSDIR) mkdir $(SA_CLASSDIR) @echo ...Building sa-jdi.jar @echo ...$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -g -d $(SA_CLASSDIR) .... - @$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -g -d $(SA_CLASSDIR) $(AGENT_ALLFILES:/=\) + @$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES1:/=\) + @$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES2:/=\) $(COMPILE_RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer $(QUIETLY) echo $(SA_BUILD_VERSION_PROP) > $(SA_PROPERTIES) $(RUN_JAR) cf $@ -C saclasses . $(RUN_JAR) uf $@ -C $(AGENT_SRC_DIR:/=\) META-INF\services\com.sun.jdi.connect.Connector + $(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js + $(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql + $(QUIETLY) mkdir -p $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources + $(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources/* + $(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources/ + $(QUIETLY) cp -r $(AGENT_SRC_DIR)/images/* $(SA_CLASSDIR)/ $(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal $(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.x86.X86ThreadContext $(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.ia64.IA64ThreadContext diff --git a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp index d5696d442f4..6d941c36866 100644 --- a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp @@ -956,7 +956,8 @@ void LIRGenerator::do_NewMultiArray(NewMultiArray* x) { size->load_item(); store_stack_parameter (size->result(), in_ByteSize(STACK_BIAS + - (i + frame::memory_parameter_word_sp_offset) * wordSize)); + frame::memory_parameter_word_sp_offset * wordSize + + i * sizeof(jint))); } // This instruction can be deoptimized in the slow path : use diff --git a/hotspot/src/cpu/sparc/vm/relocInfo_sparc.cpp b/hotspot/src/cpu/sparc/vm/relocInfo_sparc.cpp index 795e1831e52..ab365558201 100644 --- a/hotspot/src/cpu/sparc/vm/relocInfo_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/relocInfo_sparc.cpp @@ -204,3 +204,9 @@ void Relocation::pd_swap_out_breakpoint(address x, short* instrs, int instrlen) NativeInstruction* ni = nativeInstruction_at(x); ni->set_long_at(0, u.l); } + +void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { +} + +void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { +} diff --git a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp index 3812e2eaed9..6fed65b3ddc 100644 --- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp @@ -465,9 +465,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, case T_LONG: assert(sig_bt[i+1] == T_VOID, "expecting VOID in other half"); -#ifdef COMPILER2 #ifdef _LP64 - // Can't be tiered (yet) if (int_reg < int_reg_max) { Register r = is_outgoing ? as_oRegister(int_reg++) : as_iRegister(int_reg++); regs[i].set2(r->as_VMReg()); @@ -476,11 +474,12 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, stk_reg_pairs += 2; } #else +#ifdef COMPILER2 // For 32-bit build, can't pass longs in O-regs because they become // I-regs and get trashed. Use G-regs instead. G1 and G4 are almost // spare and available. This convention isn't used by the Sparc ABI or // anywhere else. If we're tiered then we don't use G-regs because c1 - // can't deal with them as a "pair". + // can't deal with them as a "pair". (Tiered makes this code think g's are filled) // G0: zero // G1: 1st Long arg // G2: global allocated to TLS @@ -500,7 +499,6 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, regs[i].set2(VMRegImpl::stack2reg(stk_reg_pairs)); stk_reg_pairs += 2; } -#endif // _LP64 #else // COMPILER2 if (int_reg_pairs + 1 < int_reg_max) { if (is_outgoing) { @@ -514,6 +512,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, stk_reg_pairs += 2; } #endif // COMPILER2 +#endif // _LP64 break; case T_FLOAT: @@ -699,17 +698,16 @@ Register AdapterGenerator::next_arg_slot(const int st_off){ // Stores long into offset pointed to by base void AdapterGenerator::store_c2i_long(Register r, Register base, const int st_off, bool is_stack) { -#ifdef COMPILER2 #ifdef _LP64 // In V9, longs are given 2 64-bit slots in the interpreter, but the // data is passed in only 1 slot. __ stx(r, base, next_arg_slot(st_off)); #else +#ifdef COMPILER2 // Misaligned store of 64-bit data __ stw(r, base, arg_slot(st_off)); // lo bits __ srlx(r, 32, r); __ stw(r, base, next_arg_slot(st_off)); // hi bits -#endif // _LP64 #else if (is_stack) { // Misaligned store of 64-bit data @@ -721,6 +719,7 @@ void AdapterGenerator::store_c2i_long(Register r, Register base, __ stw(r , base, next_arg_slot(st_off)); // hi bits } #endif // COMPILER2 +#endif // _LP64 tag_c2i_arg(frame::TagCategory2, base, st_off, r); } @@ -1637,7 +1636,7 @@ static void long_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { } } else if (dst.is_single_phys_reg()) { if (src.is_adjacent_aligned_on_stack(2)) { - __ ld_long(FP, reg2offset(src.first()) + STACK_BIAS, dst.first()->as_Register()); + __ ldx(FP, reg2offset(src.first()) + STACK_BIAS, dst.first()->as_Register()); } else { // dst is a single reg. // Remember lo is low address not msb for stack slots @@ -1811,7 +1810,6 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm, 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 diff --git a/hotspot/src/cpu/x86/vm/assembler_x86_64.cpp b/hotspot/src/cpu/x86/vm/assembler_x86.cpp similarity index 58% rename from hotspot/src/cpu/x86/vm/assembler_x86_64.cpp rename to hotspot/src/cpu/x86/vm/assembler_x86.cpp index 431c233df73..d8bc4948c92 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ */ #include "incls/_precompiled.incl" -#include "incls/_assembler_x86_64.cpp.incl" +#include "incls/_assembler_x86.cpp.incl" // Implementation of AddressLiteral @@ -52,6 +52,10 @@ AddressLiteral::AddressLiteral(address target, relocInfo::relocType rtype) { case relocInfo::runtime_call_type: _rspec = runtime_call_Relocation::spec(); break; + case relocInfo::poll_type: + case relocInfo::poll_return_type: + _rspec = Relocation::spec_simple(rtype); + break; case relocInfo::none: break; default: @@ -62,20 +66,13 @@ AddressLiteral::AddressLiteral(address target, relocInfo::relocType rtype) { // Implementation of Address -Address Address::make_array(ArrayAddress adr) { #ifdef _LP64 + +Address Address::make_array(ArrayAddress adr) { // Not implementable on 64bit machines // Should have been handled higher up the call chain. ShouldNotReachHere(); return Address(); -#else - AddressLiteral base = adr.base(); - Address index = adr.index(); - assert(index._disp == 0, "must not have disp"); // maybe it can? - Address array(index._base, index._index, index._scale, (intptr_t) base.target()); - array._rspec = base._rspec; - return array; -#endif // _LP64 } // exceedingly dangerous constructor @@ -95,12 +92,39 @@ Address::Address(int disp, address loc, relocInfo::relocType rtype) { // HMM _rspec = runtime_call_Relocation::spec(); break; + case relocInfo::poll_type: + case relocInfo::poll_return_type: + _rspec = Relocation::spec_simple(rtype); + break; case relocInfo::none: break; default: ShouldNotReachHere(); } } +#else // LP64 + +Address Address::make_array(ArrayAddress adr) { + AddressLiteral base = adr.base(); + Address index = adr.index(); + assert(index._disp == 0, "must not have disp"); // maybe it can? + Address array(index._base, index._index, index._scale, (intptr_t) base.target()); + array._rspec = base._rspec; + return array; +} + +// exceedingly dangerous constructor +Address::Address(address loc, RelocationHolder spec) { + _base = noreg; + _index = noreg; + _scale = no_scale; + _disp = (intptr_t) loc; + _rspec = spec; +} + +#endif // _LP64 + + // Convert the raw encoding form into the form expected by the constructor for // Address. An index of 4 (rsp) corresponds to having no index, so convert @@ -116,89 +140,21 @@ Address Address::make_raw(int base, int index, int scale, int disp) { } } - // Implementation of Assembler + int AbstractAssembler::code_fill_byte() { return (u_char)'\xF4'; // hlt } -// This should only be used by 64bit instructions that can use rip-relative -// it cannot be used by instructions that want an immediate value. - -bool Assembler::reachable(AddressLiteral adr) { - int64_t disp; - - // None will force a 64bit literal to the code stream. Likely a placeholder - // for something that will be patched later and we need to certain it will - // always be reachable. - if (adr.reloc() == relocInfo::none) { - return false; - } - if (adr.reloc() == relocInfo::internal_word_type) { - // This should be rip relative and easily reachable. - return true; - } - if (adr.reloc() != relocInfo::external_word_type && - adr.reloc() != relocInfo::runtime_call_type ) { - return false; - } - - // Stress the correction code - if (ForceUnreachable) { - // Must be runtimecall reloc, see if it is in the codecache - // Flipping stuff in the codecache to be unreachable causes issues - // with things like inline caches where the additional instructions - // are not handled. - if (CodeCache::find_blob(adr._target) == NULL) { - return false; - } - } - // For external_word_type/runtime_call_type if it is reachable from where we - // are now (possibly a temp buffer) and where we might end up - // anywhere in the codeCache then we are always reachable. - // This would have to change if we ever save/restore shared code - // to be more pessimistic. - - disp = (int64_t)adr._target - ((int64_t)CodeCache::low_bound() + sizeof(int)); - if (!is_simm32(disp)) return false; - disp = (int64_t)adr._target - ((int64_t)CodeCache::high_bound() + sizeof(int)); - if (!is_simm32(disp)) return false; - - disp = (int64_t)adr._target - ((int64_t)_code_pos + sizeof(int)); - - // Because rip relative is a disp + address_of_next_instruction and we - // don't know the value of address_of_next_instruction we apply a fudge factor - // to make sure we will be ok no matter the size of the instruction we get placed into. - // We don't have to fudge the checks above here because they are already worst case. - - // 12 == override/rex byte, opcode byte, rm byte, sib byte, a 4-byte disp , 4-byte literal - // + 4 because better safe than sorry. - const int fudge = 12 + 4; - if (disp < 0) { - disp -= fudge; - } else { - disp += fudge; - } - return is_simm32(disp); +// make this go away someday +void Assembler::emit_data(jint data, relocInfo::relocType rtype, int format) { + if (rtype == relocInfo::none) + emit_long(data); + else emit_data(data, Relocation::spec_simple(rtype), format); } - -// make this go away eventually -void Assembler::emit_data(jint data, - relocInfo::relocType rtype, - int format) { - if (rtype == relocInfo::none) { - emit_long(data); - } else { - emit_data(data, Relocation::spec_simple(rtype), format); - } -} - -void Assembler::emit_data(jint data, - RelocationHolder const& rspec, - int format) { - assert(imm64_operand == 0, "default format must be imm64 in this file"); - assert(imm64_operand != format, "must not be imm64"); +void Assembler::emit_data(jint data, RelocationHolder const& rspec, int format) { + assert(imm_operand == 0, "default format must be immediate in this file"); assert(inst_mark() != NULL, "must be inside InstructionMark"); if (rspec.type() != relocInfo::none) { #ifdef ASSERT @@ -216,67 +172,50 @@ void Assembler::emit_data(jint data, emit_long(data); } -void Assembler::emit_data64(jlong data, - relocInfo::relocType rtype, - int format) { - if (rtype == relocInfo::none) { - emit_long64(data); - } else { - emit_data64(data, Relocation::spec_simple(rtype), format); +static int encode(Register r) { + int enc = r->encoding(); + if (enc >= 8) { + enc -= 8; } + return enc; } -void Assembler::emit_data64(jlong data, - RelocationHolder const& rspec, - int format) { - assert(imm64_operand == 0, "default format must be imm64 in this file"); - assert(imm64_operand == format, "must be imm64"); - assert(inst_mark() != NULL, "must be inside InstructionMark"); - // Do not use AbstractAssembler::relocate, which is not intended for - // embedded words. Instead, relocate to the enclosing instruction. - code_section()->relocate(inst_mark(), rspec, format); -#ifdef ASSERT - check_relocation(rspec, format); -#endif - emit_long64(data); +static int encode(XMMRegister r) { + int enc = r->encoding(); + if (enc >= 8) { + enc -= 8; + } + return enc; } void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) { + assert(dst->has_byte_register(), "must have byte register"); assert(isByte(op1) && isByte(op2), "wrong opcode"); assert(isByte(imm8), "not a byte"); assert((op1 & 0x01) == 0, "should be 8bit operation"); - int dstenc = dst->encoding(); - if (dstenc >= 8) { - dstenc -= 8; - } emit_byte(op1); - emit_byte(op2 | dstenc); + emit_byte(op2 | encode(dst)); emit_byte(imm8); } -void Assembler::emit_arith(int op1, int op2, Register dst, int imm32) { + +void Assembler::emit_arith(int op1, int op2, Register dst, int32_t imm32) { assert(isByte(op1) && isByte(op2), "wrong opcode"); assert((op1 & 0x01) == 1, "should be 32bit operation"); assert((op1 & 0x02) == 0, "sign-extension bit should not be set"); - int dstenc = dst->encoding(); - if (dstenc >= 8) { - dstenc -= 8; - } if (is8bit(imm32)) { emit_byte(op1 | 0x02); // set sign bit - emit_byte(op2 | dstenc); + emit_byte(op2 | encode(dst)); emit_byte(imm32 & 0xFF); } else { emit_byte(op1); - emit_byte(op2 | dstenc); + emit_byte(op2 | encode(dst)); emit_long(imm32); } } // immediate-to-memory forms -void Assembler::emit_arith_operand(int op1, - Register rm, Address adr, - int imm32) { +void Assembler::emit_arith_operand(int op1, Register rm, Address adr, int32_t imm32) { assert((op1 & 0x01) == 1, "should be 32bit operation"); assert((op1 & 0x02) == 0, "sign-extension bit should not be set"); if (is8bit(imm32)) { @@ -290,127 +229,117 @@ void Assembler::emit_arith_operand(int op1, } } +void Assembler::emit_arith(int op1, int op2, Register dst, jobject obj) { + LP64_ONLY(ShouldNotReachHere()); + assert(isByte(op1) && isByte(op2), "wrong opcode"); + assert((op1 & 0x01) == 1, "should be 32bit operation"); + assert((op1 & 0x02) == 0, "sign-extension bit should not be set"); + InstructionMark im(this); + emit_byte(op1); + emit_byte(op2 | encode(dst)); + emit_data((intptr_t)obj, relocInfo::oop_type, 0); +} + void Assembler::emit_arith(int op1, int op2, Register dst, Register src) { assert(isByte(op1) && isByte(op2), "wrong opcode"); - int dstenc = dst->encoding(); - int srcenc = src->encoding(); - if (dstenc >= 8) { - dstenc -= 8; - } - if (srcenc >= 8) { - srcenc -= 8; - } emit_byte(op1); - emit_byte(op2 | dstenc << 3 | srcenc); + emit_byte(op2 | encode(dst) << 3 | encode(src)); } + void Assembler::emit_operand(Register reg, Register base, Register index, Address::ScaleFactor scale, int disp, RelocationHolder const& rspec, int rip_relative_correction) { relocInfo::relocType rtype = (relocInfo::relocType) rspec.type(); - int regenc = reg->encoding(); - if (regenc >= 8) { - regenc -= 8; - } + + // Encode the registers as needed in the fields they are used in + + int regenc = encode(reg) << 3; + int indexenc = index->is_valid() ? encode(index) << 3 : 0; + int baseenc = base->is_valid() ? encode(base) : 0; + if (base->is_valid()) { if (index->is_valid()) { assert(scale != Address::no_scale, "inconsistent address"); - int indexenc = index->encoding(); - if (indexenc >= 8) { - indexenc -= 8; - } - int baseenc = base->encoding(); - if (baseenc >= 8) { - baseenc -= 8; - } // [base + index*scale + disp] if (disp == 0 && rtype == relocInfo::none && - base != rbp && base != r13) { + base != rbp LP64_ONLY(&& base != r13)) { // [base + index*scale] // [00 reg 100][ss index base] assert(index != rsp, "illegal addressing mode"); - emit_byte(0x04 | regenc << 3); - emit_byte(scale << 6 | indexenc << 3 | baseenc); + emit_byte(0x04 | regenc); + emit_byte(scale << 6 | indexenc | baseenc); } else if (is8bit(disp) && rtype == relocInfo::none) { // [base + index*scale + imm8] // [01 reg 100][ss index base] imm8 assert(index != rsp, "illegal addressing mode"); - emit_byte(0x44 | regenc << 3); - emit_byte(scale << 6 | indexenc << 3 | baseenc); + emit_byte(0x44 | regenc); + emit_byte(scale << 6 | indexenc | baseenc); emit_byte(disp & 0xFF); } else { // [base + index*scale + disp32] // [10 reg 100][ss index base] disp32 assert(index != rsp, "illegal addressing mode"); - emit_byte(0x84 | regenc << 3); - emit_byte(scale << 6 | indexenc << 3 | baseenc); + emit_byte(0x84 | regenc); + emit_byte(scale << 6 | indexenc | baseenc); emit_data(disp, rspec, disp32_operand); } - } else if (base == rsp || base == r12) { + } else if (base == rsp LP64_ONLY(|| base == r12)) { // [rsp + disp] if (disp == 0 && rtype == relocInfo::none) { // [rsp] // [00 reg 100][00 100 100] - emit_byte(0x04 | regenc << 3); + emit_byte(0x04 | regenc); emit_byte(0x24); } else if (is8bit(disp) && rtype == relocInfo::none) { // [rsp + imm8] // [01 reg 100][00 100 100] disp8 - emit_byte(0x44 | regenc << 3); + emit_byte(0x44 | regenc); emit_byte(0x24); emit_byte(disp & 0xFF); } else { // [rsp + imm32] // [10 reg 100][00 100 100] disp32 - emit_byte(0x84 | regenc << 3); + emit_byte(0x84 | regenc); emit_byte(0x24); emit_data(disp, rspec, disp32_operand); } } else { // [base + disp] - assert(base != rsp && base != r12, "illegal addressing mode"); - int baseenc = base->encoding(); - if (baseenc >= 8) { - baseenc -= 8; - } + assert(base != rsp LP64_ONLY(&& base != r12), "illegal addressing mode"); if (disp == 0 && rtype == relocInfo::none && - base != rbp && base != r13) { + base != rbp LP64_ONLY(&& base != r13)) { // [base] // [00 reg base] - emit_byte(0x00 | regenc << 3 | baseenc); + emit_byte(0x00 | regenc | baseenc); } else if (is8bit(disp) && rtype == relocInfo::none) { // [base + disp8] // [01 reg base] disp8 - emit_byte(0x40 | regenc << 3 | baseenc); + emit_byte(0x40 | regenc | baseenc); emit_byte(disp & 0xFF); } else { // [base + disp32] // [10 reg base] disp32 - emit_byte(0x80 | regenc << 3 | baseenc); + emit_byte(0x80 | regenc | baseenc); emit_data(disp, rspec, disp32_operand); } } } else { if (index->is_valid()) { assert(scale != Address::no_scale, "inconsistent address"); - int indexenc = index->encoding(); - if (indexenc >= 8) { - indexenc -= 8; - } // [index*scale + disp] // [00 reg 100][ss index 101] disp32 assert(index != rsp, "illegal addressing mode"); - emit_byte(0x04 | regenc << 3); - emit_byte(scale << 6 | indexenc << 3 | 0x05); + emit_byte(0x04 | regenc); + emit_byte(scale << 6 | indexenc | 0x05); emit_data(disp, rspec, disp32_operand); -#ifdef _LP64 } else if (rtype != relocInfo::none ) { - // [disp] RIP-RELATIVE + // [disp] (64bit) RIP-RELATIVE (32bit) abs // [00 000 101] disp32 - emit_byte(0x05 | regenc << 3); + emit_byte(0x05 | regenc); // Note that the RIP-rel. correction applies to the generated // disp field, but _not_ to the target address in the rspec. @@ -419,16 +348,18 @@ void Assembler::emit_operand(Register reg, Register base, Register index, // intptr_t disp = target - next_ip; assert(inst_mark() != NULL, "must be inside InstructionMark"); address next_ip = pc() + sizeof(int32_t) + rip_relative_correction; - int64_t adjusted = (int64_t) disp - (next_ip - inst_mark()); + int64_t adjusted = disp; + // Do rip-rel adjustment for 64bit + LP64_ONLY(adjusted -= (next_ip - inst_mark())); assert(is_simm32(adjusted), "must be 32bit offset (RIP relative address)"); - emit_data((int) adjusted, rspec, disp32_operand); + emit_data((int32_t) adjusted, rspec, disp32_operand); -#endif // _LP64 } else { + // 32bit never did this, did everything as the rip-rel/disp code above // [disp] ABSOLUTE // [00 reg 100][00 100 101] disp32 - emit_byte(0x04 | regenc << 3); + emit_byte(0x04 | regenc); emit_byte(0x25); emit_data(disp, rspec, disp32_operand); } @@ -437,132 +368,8 @@ void Assembler::emit_operand(Register reg, Register base, Register index, void Assembler::emit_operand(XMMRegister reg, Register base, Register index, Address::ScaleFactor scale, int disp, - RelocationHolder const& rspec, - int rip_relative_correction) { - relocInfo::relocType rtype = (relocInfo::relocType) rspec.type(); - int regenc = reg->encoding(); - if (regenc >= 8) { - regenc -= 8; - } - if (base->is_valid()) { - if (index->is_valid()) { - assert(scale != Address::no_scale, "inconsistent address"); - int indexenc = index->encoding(); - if (indexenc >= 8) { - indexenc -= 8; - } - int baseenc = base->encoding(); - if (baseenc >= 8) { - baseenc -= 8; - } - // [base + index*scale + disp] - if (disp == 0 && rtype == relocInfo::none && - base != rbp && base != r13) { - // [base + index*scale] - // [00 reg 100][ss index base] - assert(index != rsp, "illegal addressing mode"); - emit_byte(0x04 | regenc << 3); - emit_byte(scale << 6 | indexenc << 3 | baseenc); - } else if (is8bit(disp) && rtype == relocInfo::none) { - // [base + index*scale + disp8] - // [01 reg 100][ss index base] disp8 - assert(index != rsp, "illegal addressing mode"); - emit_byte(0x44 | regenc << 3); - emit_byte(scale << 6 | indexenc << 3 | baseenc); - emit_byte(disp & 0xFF); - } else { - // [base + index*scale + disp32] - // [10 reg 100][ss index base] disp32 - assert(index != rsp, "illegal addressing mode"); - emit_byte(0x84 | regenc << 3); - emit_byte(scale << 6 | indexenc << 3 | baseenc); - emit_data(disp, rspec, disp32_operand); - } - } else if (base == rsp || base == r12) { - // [rsp + disp] - if (disp == 0 && rtype == relocInfo::none) { - // [rsp] - // [00 reg 100][00 100 100] - emit_byte(0x04 | regenc << 3); - emit_byte(0x24); - } else if (is8bit(disp) && rtype == relocInfo::none) { - // [rsp + imm8] - // [01 reg 100][00 100 100] disp8 - emit_byte(0x44 | regenc << 3); - emit_byte(0x24); - emit_byte(disp & 0xFF); - } else { - // [rsp + imm32] - // [10 reg 100][00 100 100] disp32 - emit_byte(0x84 | regenc << 3); - emit_byte(0x24); - emit_data(disp, rspec, disp32_operand); - } - } else { - // [base + disp] - assert(base != rsp && base != r12, "illegal addressing mode"); - int baseenc = base->encoding(); - if (baseenc >= 8) { - baseenc -= 8; - } - if (disp == 0 && rtype == relocInfo::none && - base != rbp && base != r13) { - // [base] - // [00 reg base] - emit_byte(0x00 | regenc << 3 | baseenc); - } else if (is8bit(disp) && rtype == relocInfo::none) { - // [base + imm8] - // [01 reg base] disp8 - emit_byte(0x40 | regenc << 3 | baseenc); - emit_byte(disp & 0xFF); - } else { - // [base + imm32] - // [10 reg base] disp32 - emit_byte(0x80 | regenc << 3 | baseenc); - emit_data(disp, rspec, disp32_operand); - } - } - } else { - if (index->is_valid()) { - assert(scale != Address::no_scale, "inconsistent address"); - int indexenc = index->encoding(); - if (indexenc >= 8) { - indexenc -= 8; - } - // [index*scale + disp] - // [00 reg 100][ss index 101] disp32 - assert(index != rsp, "illegal addressing mode"); - emit_byte(0x04 | regenc << 3); - emit_byte(scale << 6 | indexenc << 3 | 0x05); - emit_data(disp, rspec, disp32_operand); -#ifdef _LP64 - } else if ( rtype != relocInfo::none ) { - // [disp] RIP-RELATIVE - // [00 reg 101] disp32 - emit_byte(0x05 | regenc << 3); - // Note that the RIP-rel. correction applies to the generated - // disp field, but _not_ to the target address in the rspec. - - // disp was created by converting the target address minus the pc - // at the start of the instruction. That needs more correction here. - // intptr_t disp = target - next_ip; - - assert(inst_mark() != NULL, "must be inside InstructionMark"); - address next_ip = pc() + sizeof(int32_t) + rip_relative_correction; - - int64_t adjusted = (int64_t) disp - (next_ip - inst_mark()); - assert(is_simm32(adjusted), - "must be 32bit offset (RIP relative address)"); - emit_data((int) adjusted, rspec, disp32_operand); -#endif // _LP64 - } else { - // [disp] ABSOLUTE - // [00 reg 100][00 100 101] disp32 - emit_byte(0x04 | regenc << 3); - emit_byte(0x25); - emit_data(disp, rspec, disp32_operand); - } - } + RelocationHolder const& rspec) { + emit_operand((Register)reg, base, index, scale, disp, rspec); } // Secret local extension to Assembler::WhichOperand: @@ -603,8 +410,9 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case ES_segment: case FS_segment: case GS_segment: - assert(0, "shouldn't have that prefix"); - assert(ip == inst + 1 || ip == inst + 2, "only two prefixes allowed"); + // Seems dubious + LP64_ONLY(assert(false, "shouldn't have that prefix")); + assert(ip == inst+1, "only one prefix allowed"); goto again_after_prefix; case 0x67: @@ -616,7 +424,7 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case REX_RB: case REX_RX: case REX_RXB: -// assert(ip == inst + 1, "only one prefix allowed"); + NOT_LP64(assert(false, "64bit prefixes")); goto again_after_prefix; case REX_W: @@ -627,8 +435,8 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case REX_WRB: case REX_WRX: case REX_WRXB: + NOT_LP64(assert(false, "64bit prefixes")); is_64bit = true; -// assert(ip == inst + 1, "only one prefix allowed"); goto again_after_prefix; case 0xFF: // pushq a; decl a; incl a; call a; jmp a @@ -637,15 +445,15 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case 0x8A: // movb r, a case 0x8B: // movl r, a case 0x8F: // popl a - debug_only(has_disp32 = true;) + debug_only(has_disp32 = true); break; case 0x68: // pushq #32 if (which == end_pc_operand) { return ip + 4; } - assert(0, "pushq has no disp32 or imm64"); - ShouldNotReachHere(); + assert(which == imm_operand && !is_64bit, "pushl has no disp32 or 64bit immediate"); + return ip; // not produced by emit_operand case 0x66: // movw ... (size prefix) again_after_size_prefix2: @@ -666,11 +474,14 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case REX_WRB: case REX_WRX: case REX_WRXB: + NOT_LP64(assert(false, "64bit prefix found")); goto again_after_size_prefix2; case 0x8B: // movw r, a case 0x89: // movw a, r + debug_only(has_disp32 = true); break; case 0xC7: // movw a, #16 + debug_only(has_disp32 = true); tail_size = 2; // the imm16 break; case 0x0F: // several SSE/SSE2 variants @@ -683,8 +494,13 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case REP8(0xB8): // movl/q r, #32/#64(oop?) if (which == end_pc_operand) return ip + (is_64bit ? 8 : 4); - assert((which == call32_operand || which == imm64_operand) && is_64bit || + // these asserts are somewhat nonsensical +#ifndef _LP64 + assert(which == imm_operand || which == disp32_operand, ""); +#else + assert((which == call32_operand || which == imm_operand) && is_64bit || which == narrow_oop_operand && !is_64bit, ""); +#endif // _LP64 return ip; case 0x69: // imul r, a, #32 @@ -700,18 +516,23 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case 0x2E: // ucomiss case 0x2F: // comiss case 0x54: // andps + case 0x55: // andnps + case 0x56: // orps case 0x57: // xorps case 0x6E: // movd case 0x7E: // movd case 0xAE: // ldmxcsr a - debug_only(has_disp32 = true); // has both kinds of operands! + // 64bit side says it these have both operands but that doesn't + // appear to be true + debug_only(has_disp32 = true); break; + case 0xAD: // shrd r, a, %cl case 0xAF: // imul r, a - case 0xBE: // movsbl r, a - case 0xBF: // movswl r, a - case 0xB6: // movzbl r, a - case 0xB7: // movzwl r, a + case 0xBE: // movsbl r, a (movsxb) + case 0xBF: // movswl r, a (movsxw) + case 0xB6: // movzbl r, a (movzxb) + case 0xB7: // movzwl r, a (movzxw) case REP16(0x40): // cmovl cc, r, a case 0xB0: // cmpxchgb case 0xB1: // cmpxchg @@ -721,13 +542,15 @@ address Assembler::locate_operand(address inst, WhichOperand which) { debug_only(has_disp32 = true); // fall out of the switch to decode the address break; + case 0xAC: // shrd r, a, #8 debug_only(has_disp32 = true); tail_size = 1; // the imm8 break; + case REP16(0x80): // jcc rdisp32 if (which == end_pc_operand) return ip + 4; - assert(which == call32_operand, "jcc has no disp32 or imm64"); + assert(which == call32_operand, "jcc has no disp32 or imm"); return ip; default: ShouldNotReachHere(); @@ -736,6 +559,7 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case 0x81: // addl a, #32; addl r, #32 // also: orl, adcl, sbbl, andl, subl, xorl, cmpl + // on 32bit in the case of cmpl, the imm might be an oop tail_size = 4; debug_only(has_disp32 = true); // has both kinds of operands! break; @@ -764,11 +588,9 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case REP4(0x18): // sbb... case REP4(0x28): // sub... case 0xF7: // mull a - case 0x87: // xchg r, a - debug_only(has_disp32 = true); - break; - case REP4(0x38): // cmp... case 0x8D: // lea r, a + case 0x87: // xchg r, a + case REP4(0x38): // cmp... case 0x85: // test r, a debug_only(has_disp32 = true); // has both kinds of operands! break; @@ -784,7 +606,7 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case 0xE8: // call rdisp32 case 0xE9: // jmp rdisp32 if (which == end_pc_operand) return ip + 4; - assert(which == call32_operand, "call has no disp32 or imm32"); + assert(which == call32_operand, "call has no disp32 or imm"); return ip; case 0xD1: // sal a, 1; sar a, 1; shl a, 1; shr a, 1 @@ -818,6 +640,7 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case REX_WRB: case REX_WRX: case REX_WRXB: + NOT_LP64(assert(false, "found 64bit prefix")); ip++; default: ip++; @@ -833,7 +656,12 @@ address Assembler::locate_operand(address inst, WhichOperand which) { } assert(which != call32_operand, "instruction is not a call, jmp, or jcc"); - assert(which != imm64_operand, "instruction is not a movq reg, imm64"); +#ifdef _LP64 + assert(which != imm_operand, "instruction is not a movq reg, imm64"); +#else + // assert(which != imm_operand || has_imm32, "instruction has no imm32 field"); + assert(which != imm_operand || has_disp32, "instruction has no imm32 field"); +#endif // LP64 assert(which != disp32_operand || has_disp32, "instruction has no disp32 field"); // parse the output of emit_operand @@ -888,7 +716,11 @@ address Assembler::locate_operand(address inst, WhichOperand which) { return ip + tail_size; } - assert(0, "fix locate_operand"); +#ifdef _LP64 + assert(false, "fix locate_operand"); +#else + assert(which == imm_operand, "instruction has only an imm field"); +#endif // LP64 return ip; } @@ -897,219 +729,36 @@ address Assembler::locate_next_instruction(address inst) { return locate_operand(inst, end_pc_operand); } + #ifdef ASSERT void Assembler::check_relocation(RelocationHolder const& rspec, int format) { address inst = inst_mark(); - assert(inst != NULL && inst < pc(), - "must point to beginning of instruction"); + assert(inst != NULL && inst < pc(), "must point to beginning of instruction"); address opnd; Relocation* r = rspec.reloc(); if (r->type() == relocInfo::none) { return; } else if (r->is_call() || format == call32_operand) { + // assert(format == imm32_operand, "cannot specify a nonzero format"); opnd = locate_operand(inst, call32_operand); } else if (r->is_data()) { - assert(format == imm64_operand || format == disp32_operand || - format == narrow_oop_operand, "format ok"); - opnd = locate_operand(inst, (WhichOperand) format); + assert(format == imm_operand || format == disp32_operand + LP64_ONLY(|| format == narrow_oop_operand), "format ok"); + opnd = locate_operand(inst, (WhichOperand)format); } else { - assert(format == 0, "cannot specify a format"); + assert(format == imm_operand, "cannot specify a format"); return; } assert(opnd == pc(), "must put operand where relocs can find it"); } -#endif +#endif // ASSERT -int Assembler::prefix_and_encode(int reg_enc, bool byteinst) { - if (reg_enc >= 8) { - prefix(REX_B); - reg_enc -= 8; - } else if (byteinst && reg_enc >= 4) { - prefix(REX); - } - return reg_enc; -} - -int Assembler::prefixq_and_encode(int reg_enc) { - if (reg_enc < 8) { - prefix(REX_W); - } else { - prefix(REX_WB); - reg_enc -= 8; - } - return reg_enc; -} - -int Assembler::prefix_and_encode(int dst_enc, int src_enc, bool byteinst) { - if (dst_enc < 8) { - if (src_enc >= 8) { - prefix(REX_B); - src_enc -= 8; - } else if (byteinst && src_enc >= 4) { - prefix(REX); - } - } else { - if (src_enc < 8) { - prefix(REX_R); - } else { - prefix(REX_RB); - src_enc -= 8; - } - dst_enc -= 8; - } - return dst_enc << 3 | src_enc; -} - -int Assembler::prefixq_and_encode(int dst_enc, int src_enc) { - if (dst_enc < 8) { - if (src_enc < 8) { - prefix(REX_W); - } else { - prefix(REX_WB); - src_enc -= 8; - } - } else { - if (src_enc < 8) { - prefix(REX_WR); - } else { - prefix(REX_WRB); - src_enc -= 8; - } - dst_enc -= 8; - } - return dst_enc << 3 | src_enc; -} - -void Assembler::prefix(Register reg) { - if (reg->encoding() >= 8) { - prefix(REX_B); - } -} - -void Assembler::prefix(Address adr) { - if (adr.base_needs_rex()) { - if (adr.index_needs_rex()) { - prefix(REX_XB); - } else { - prefix(REX_B); - } - } else { - if (adr.index_needs_rex()) { - prefix(REX_X); - } - } -} - -void Assembler::prefixq(Address adr) { - if (adr.base_needs_rex()) { - if (adr.index_needs_rex()) { - prefix(REX_WXB); - } else { - prefix(REX_WB); - } - } else { - if (adr.index_needs_rex()) { - prefix(REX_WX); - } else { - prefix(REX_W); - } - } -} - - -void Assembler::prefix(Address adr, Register reg, bool byteinst) { - if (reg->encoding() < 8) { - if (adr.base_needs_rex()) { - if (adr.index_needs_rex()) { - prefix(REX_XB); - } else { - prefix(REX_B); - } - } else { - if (adr.index_needs_rex()) { - prefix(REX_X); - } else if (reg->encoding() >= 4 ) { - prefix(REX); - } - } - } else { - if (adr.base_needs_rex()) { - if (adr.index_needs_rex()) { - prefix(REX_RXB); - } else { - prefix(REX_RB); - } - } else { - if (adr.index_needs_rex()) { - prefix(REX_RX); - } else { - prefix(REX_R); - } - } - } -} - -void Assembler::prefixq(Address adr, Register src) { - if (src->encoding() < 8) { - if (adr.base_needs_rex()) { - if (adr.index_needs_rex()) { - prefix(REX_WXB); - } else { - prefix(REX_WB); - } - } else { - if (adr.index_needs_rex()) { - prefix(REX_WX); - } else { - prefix(REX_W); - } - } - } else { - if (adr.base_needs_rex()) { - if (adr.index_needs_rex()) { - prefix(REX_WRXB); - } else { - prefix(REX_WRB); - } - } else { - if (adr.index_needs_rex()) { - prefix(REX_WRX); - } else { - prefix(REX_WR); - } - } - } -} - -void Assembler::prefix(Address adr, XMMRegister reg) { - if (reg->encoding() < 8) { - if (adr.base_needs_rex()) { - if (adr.index_needs_rex()) { - prefix(REX_XB); - } else { - prefix(REX_B); - } - } else { - if (adr.index_needs_rex()) { - prefix(REX_X); - } - } - } else { - if (adr.base_needs_rex()) { - if (adr.index_needs_rex()) { - prefix(REX_RXB); - } else { - prefix(REX_RB); - } - } else { - if (adr.index_needs_rex()) { - prefix(REX_RX); - } else { - prefix(REX_R); - } - } - } +void Assembler::emit_operand32(Register reg, Address adr) { + assert(reg->encoding() < 8, "no extended registers"); + assert(!adr.base_needs_rex() && !adr.index_needs_rex(), "no extended registers"); + emit_operand(reg, adr._base, adr._index, adr._scale, adr._disp, + adr._rspec); } void Assembler::emit_operand(Register reg, Address adr, @@ -1119,13 +768,24 @@ void Assembler::emit_operand(Register reg, Address adr, rip_relative_correction); } -void Assembler::emit_operand(XMMRegister reg, Address adr, - int rip_relative_correction) { +void Assembler::emit_operand(XMMRegister reg, Address adr) { emit_operand(reg, adr._base, adr._index, adr._scale, adr._disp, - adr._rspec, - rip_relative_correction); + adr._rspec); } +// MMX operations +void Assembler::emit_operand(MMXRegister reg, Address adr) { + assert(!adr.base_needs_rex() && !adr.index_needs_rex(), "no extended registers"); + emit_operand((Register)reg, adr._base, adr._index, adr._scale, adr._disp, adr._rspec); +} + +// work around gcc (3.2.1-7a) bug +void Assembler::emit_operand(Address adr, MMXRegister reg) { + assert(!adr.base_needs_rex() && !adr.index_needs_rex(), "no extended registers"); + emit_operand((Register)reg, adr._base, adr._index, adr._scale, adr._disp, adr._rspec); +} + + void Assembler::emit_farith(int b1, int b2, int i) { assert(isByte(b1) && isByte(b2), "wrong opcode"); assert(0 <= i && i < 8, "illegal stack offset"); @@ -1133,612 +793,10 @@ void Assembler::emit_farith(int b1, int b2, int i) { emit_byte(b2 + i); } -// pushad is invalid, use this instead. -// NOTE: Kills flags!! -void Assembler::pushaq() { - // we have to store original rsp. ABI says that 128 bytes - // below rsp are local scratch. - movq(Address(rsp, -5 * wordSize), rsp); - subq(rsp, 16 * wordSize); +// Now the Assembler instruction (identical for 32/64 bits) - movq(Address(rsp, 15 * wordSize), rax); - movq(Address(rsp, 14 * wordSize), rcx); - movq(Address(rsp, 13 * wordSize), rdx); - movq(Address(rsp, 12 * wordSize), rbx); - // skip rsp - movq(Address(rsp, 10 * wordSize), rbp); - movq(Address(rsp, 9 * wordSize), rsi); - movq(Address(rsp, 8 * wordSize), rdi); - movq(Address(rsp, 7 * wordSize), r8); - movq(Address(rsp, 6 * wordSize), r9); - movq(Address(rsp, 5 * wordSize), r10); - movq(Address(rsp, 4 * wordSize), r11); - movq(Address(rsp, 3 * wordSize), r12); - movq(Address(rsp, 2 * wordSize), r13); - movq(Address(rsp, wordSize), r14); - movq(Address(rsp, 0), r15); -} - -// popad is invalid, use this instead -// NOTE: Kills flags!! -void Assembler::popaq() { - movq(r15, Address(rsp, 0)); - movq(r14, Address(rsp, wordSize)); - movq(r13, Address(rsp, 2 * wordSize)); - movq(r12, Address(rsp, 3 * wordSize)); - movq(r11, Address(rsp, 4 * wordSize)); - movq(r10, Address(rsp, 5 * wordSize)); - movq(r9, Address(rsp, 6 * wordSize)); - movq(r8, Address(rsp, 7 * wordSize)); - movq(rdi, Address(rsp, 8 * wordSize)); - movq(rsi, Address(rsp, 9 * wordSize)); - movq(rbp, Address(rsp, 10 * wordSize)); - // skip rsp - movq(rbx, Address(rsp, 12 * wordSize)); - movq(rdx, Address(rsp, 13 * wordSize)); - movq(rcx, Address(rsp, 14 * wordSize)); - movq(rax, Address(rsp, 15 * wordSize)); - - addq(rsp, 16 * wordSize); -} - -void Assembler::pushfq() { - emit_byte(0x9C); -} - -void Assembler::popfq() { - emit_byte(0x9D); -} - -void Assembler::pushq(int imm32) { - emit_byte(0x68); - emit_long(imm32); -} - -void Assembler::pushq(Register src) { - int encode = prefix_and_encode(src->encoding()); - - emit_byte(0x50 | encode); -} - -void Assembler::pushq(Address src) { - InstructionMark im(this); - prefix(src); - emit_byte(0xFF); - emit_operand(rsi, src); -} - -void Assembler::popq(Register dst) { - int encode = prefix_and_encode(dst->encoding()); - emit_byte(0x58 | encode); -} - -void Assembler::popq(Address dst) { - InstructionMark im(this); - prefix(dst); - emit_byte(0x8F); - emit_operand(rax, dst); -} - -void Assembler::prefix(Prefix p) { - a_byte(p); -} - -void Assembler::movb(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst, true); - emit_byte(0x8A); - emit_operand(dst, src); -} - -void Assembler::movb(Address dst, int imm8) { - InstructionMark im(this); - prefix(dst); - emit_byte(0xC6); - emit_operand(rax, dst, 1); - emit_byte(imm8); -} - -void Assembler::movb(Address dst, Register src) { - InstructionMark im(this); - prefix(dst, src, true); - emit_byte(0x88); - emit_operand(src, dst); -} - -void Assembler::movw(Address dst, int imm16) { - InstructionMark im(this); - emit_byte(0x66); // switch to 16-bit mode - prefix(dst); - emit_byte(0xC7); - emit_operand(rax, dst, 2); - emit_word(imm16); -} - -void Assembler::movw(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x66); - prefix(src, dst); - emit_byte(0x8B); - emit_operand(dst, src); -} - -void Assembler::movw(Address dst, Register src) { - InstructionMark im(this); - emit_byte(0x66); - prefix(dst, src); - emit_byte(0x89); - emit_operand(src, dst); -} - -// Uses zero extension. -void Assembler::movl(Register dst, int imm32) { - int encode = prefix_and_encode(dst->encoding()); - emit_byte(0xB8 | encode); - emit_long(imm32); -} - -void Assembler::movl(Register dst, Register src) { - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x8B); - emit_byte(0xC0 | encode); -} - -void Assembler::movl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x8B); - emit_operand(dst, src); -} - -void Assembler::movl(Address dst, int imm32) { - InstructionMark im(this); - prefix(dst); - emit_byte(0xC7); - emit_operand(rax, dst, 4); - emit_long(imm32); -} - -void Assembler::movl(Address dst, Register src) { - InstructionMark im(this); - prefix(dst, src); - emit_byte(0x89); - emit_operand(src, dst); -} - -void Assembler::mov64(Register dst, intptr_t imm64) { - InstructionMark im(this); - int encode = prefixq_and_encode(dst->encoding()); - emit_byte(0xB8 | encode); - emit_long64(imm64); -} - -void Assembler::mov_literal64(Register dst, intptr_t imm64, RelocationHolder const& rspec) { - InstructionMark im(this); - int encode = prefixq_and_encode(dst->encoding()); - emit_byte(0xB8 | encode); - emit_data64(imm64, rspec); -} - -void Assembler::movq(Register dst, Register src) { - int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x8B); - emit_byte(0xC0 | encode); -} - -void Assembler::movq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x8B); - emit_operand(dst, src); -} - -void Assembler::mov64(Address dst, intptr_t imm32) { - assert(is_simm32(imm32), "lost bits"); - InstructionMark im(this); - prefixq(dst); - emit_byte(0xC7); - emit_operand(rax, dst, 4); - emit_long(imm32); -} - -void Assembler::movq(Address dst, Register src) { - InstructionMark im(this); - prefixq(dst, src); - emit_byte(0x89); - emit_operand(src, dst); -} - -void Assembler::movsbl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0xBE); - emit_operand(dst, src); -} - -void Assembler::movsbl(Register dst, Register src) { - int encode = prefix_and_encode(dst->encoding(), src->encoding(), true); - emit_byte(0x0F); - emit_byte(0xBE); - emit_byte(0xC0 | encode); -} - -void Assembler::movswl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0xBF); - emit_operand(dst, src); -} - -void Assembler::movswl(Register dst, Register src) { - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0xBF); - emit_byte(0xC0 | encode); -} - -void Assembler::movslq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x63); - emit_operand(dst, src); -} - -void Assembler::movslq(Register dst, Register src) { - int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x63); - emit_byte(0xC0 | encode); -} - -void Assembler::movzbl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0xB6); - emit_operand(dst, src); -} - -void Assembler::movzbl(Register dst, Register src) { - int encode = prefix_and_encode(dst->encoding(), src->encoding(), true); - emit_byte(0x0F); - emit_byte(0xB6); - emit_byte(0xC0 | encode); -} - -void Assembler::movzwl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0xB7); - emit_operand(dst, src); -} - -void Assembler::movzwl(Register dst, Register src) { - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0xB7); - emit_byte(0xC0 | encode); -} - -void Assembler::movss(XMMRegister dst, XMMRegister src) { - emit_byte(0xF3); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x10); - emit_byte(0xC0 | encode); -} - -void Assembler::movss(XMMRegister dst, Address src) { - InstructionMark im(this); - emit_byte(0xF3); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x10); - emit_operand(dst, src); -} - -void Assembler::movss(Address dst, XMMRegister src) { - InstructionMark im(this); - emit_byte(0xF3); - prefix(dst, src); - emit_byte(0x0F); - emit_byte(0x11); - emit_operand(src, dst); -} - -void Assembler::movsd(XMMRegister dst, XMMRegister src) { - emit_byte(0xF2); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x10); - emit_byte(0xC0 | encode); -} - -void Assembler::movsd(XMMRegister dst, Address src) { - InstructionMark im(this); - emit_byte(0xF2); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x10); - emit_operand(dst, src); -} - -void Assembler::movsd(Address dst, XMMRegister src) { - InstructionMark im(this); - emit_byte(0xF2); - prefix(dst, src); - emit_byte(0x0F); - emit_byte(0x11); - emit_operand(src, dst); -} - -// New cpus require to use movsd and movss to avoid partial register stall -// when loading from memory. But for old Opteron use movlpd instead of movsd. -// The selection is done in MacroAssembler::movdbl() and movflt(). -void Assembler::movlpd(XMMRegister dst, Address src) { - InstructionMark im(this); - emit_byte(0x66); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x12); - emit_operand(dst, src); -} - -void Assembler::movapd(XMMRegister dst, XMMRegister src) { - int dstenc = dst->encoding(); - int srcenc = src->encoding(); - emit_byte(0x66); - if (dstenc < 8) { - if (srcenc >= 8) { - prefix(REX_B); - srcenc -= 8; - } - } else { - if (srcenc < 8) { - prefix(REX_R); - } else { - prefix(REX_RB); - srcenc -= 8; - } - dstenc -= 8; - } - emit_byte(0x0F); - emit_byte(0x28); - emit_byte(0xC0 | dstenc << 3 | srcenc); -} - -void Assembler::movaps(XMMRegister dst, XMMRegister src) { - int dstenc = dst->encoding(); - int srcenc = src->encoding(); - if (dstenc < 8) { - if (srcenc >= 8) { - prefix(REX_B); - srcenc -= 8; - } - } else { - if (srcenc < 8) { - prefix(REX_R); - } else { - prefix(REX_RB); - srcenc -= 8; - } - dstenc -= 8; - } - emit_byte(0x0F); - emit_byte(0x28); - emit_byte(0xC0 | dstenc << 3 | srcenc); -} - -void Assembler::movdl(XMMRegister dst, Register src) { - emit_byte(0x66); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x6E); - emit_byte(0xC0 | encode); -} - -void Assembler::movdl(Register dst, XMMRegister src) { - emit_byte(0x66); - // swap src/dst to get correct prefix - int encode = prefix_and_encode(src->encoding(), dst->encoding()); - emit_byte(0x0F); - emit_byte(0x7E); - emit_byte(0xC0 | encode); -} - -void Assembler::movdq(XMMRegister dst, Register src) { - emit_byte(0x66); - int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x6E); - emit_byte(0xC0 | encode); -} - -void Assembler::movdq(Register dst, XMMRegister src) { - emit_byte(0x66); - // swap src/dst to get correct prefix - int encode = prefixq_and_encode(src->encoding(), dst->encoding()); - emit_byte(0x0F); - emit_byte(0x7E); - emit_byte(0xC0 | encode); -} - -void Assembler::pxor(XMMRegister dst, Address src) { - InstructionMark im(this); - emit_byte(0x66); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0xEF); - emit_operand(dst, src); -} - -void Assembler::pxor(XMMRegister dst, XMMRegister src) { - InstructionMark im(this); - emit_byte(0x66); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0xEF); - emit_byte(0xC0 | encode); -} - -void Assembler::movdqa(XMMRegister dst, Address src) { - InstructionMark im(this); - emit_byte(0x66); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x6F); - emit_operand(dst, src); -} - -void Assembler::movdqa(XMMRegister dst, XMMRegister src) { - emit_byte(0x66); - int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x6F); - emit_byte(0xC0 | encode); -} - -void Assembler::movdqa(Address dst, XMMRegister src) { - InstructionMark im(this); - emit_byte(0x66); - prefix(dst, src); - emit_byte(0x0F); - emit_byte(0x7F); - emit_operand(src, dst); -} - -void Assembler::movq(XMMRegister dst, Address src) { - InstructionMark im(this); - emit_byte(0xF3); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x7E); - emit_operand(dst, src); -} - -void Assembler::movq(Address dst, XMMRegister src) { - InstructionMark im(this); - emit_byte(0x66); - prefix(dst, src); - emit_byte(0x0F); - emit_byte(0xD6); - emit_operand(src, dst); -} - -void Assembler::pshufd(XMMRegister dst, XMMRegister src, int mode) { - assert(isByte(mode), "invalid value"); - emit_byte(0x66); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x70); - emit_byte(0xC0 | encode); - emit_byte(mode & 0xFF); -} - -void Assembler::pshufd(XMMRegister dst, Address src, int mode) { - assert(isByte(mode), "invalid value"); - InstructionMark im(this); - emit_byte(0x66); - emit_byte(0x0F); - emit_byte(0x70); - emit_operand(dst, src); - emit_byte(mode & 0xFF); -} - -void Assembler::pshuflw(XMMRegister dst, XMMRegister src, int mode) { - assert(isByte(mode), "invalid value"); - emit_byte(0xF2); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x70); - emit_byte(0xC0 | encode); - emit_byte(mode & 0xFF); -} - -void Assembler::pshuflw(XMMRegister dst, Address src, int mode) { - assert(isByte(mode), "invalid value"); - InstructionMark im(this); - emit_byte(0xF2); - emit_byte(0x0F); - emit_byte(0x70); - emit_operand(dst, src); - emit_byte(mode & 0xFF); -} - -void Assembler::cmovl(Condition cc, Register dst, Register src) { - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x40 | cc); - emit_byte(0xC0 | encode); -} - -void Assembler::cmovl(Condition cc, Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x40 | cc); - emit_operand(dst, src); -} - -void Assembler::cmovq(Condition cc, Register dst, Register src) { - int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x40 | cc); - emit_byte(0xC0 | encode); -} - -void Assembler::cmovq(Condition cc, Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x0F); - emit_byte(0x40 | cc); - emit_operand(dst, src); -} - -void Assembler::prefetch_prefix(Address src) { - prefix(src); - emit_byte(0x0F); -} - -void Assembler::prefetcht0(Address src) { - InstructionMark im(this); - prefetch_prefix(src); - emit_byte(0x18); - emit_operand(rcx, src); // 1, src -} - -void Assembler::prefetcht1(Address src) { - InstructionMark im(this); - prefetch_prefix(src); - emit_byte(0x18); - emit_operand(rdx, src); // 2, src -} - -void Assembler::prefetcht2(Address src) { - InstructionMark im(this); - prefetch_prefix(src); - emit_byte(0x18); - emit_operand(rbx, src); // 3, src -} - -void Assembler::prefetchnta(Address src) { - InstructionMark im(this); - prefetch_prefix(src); - emit_byte(0x18); - emit_operand(rax, src); // 0, src -} - -void Assembler::prefetchw(Address src) { - InstructionMark im(this); - prefetch_prefix(src); - emit_byte(0x0D); - emit_operand(rcx, src); // 1, src -} - -void Assembler::adcl(Register dst, int imm32) { +void Assembler::adcl(Register dst, int32_t imm32) { prefix(dst); emit_arith(0x81, 0xD0, dst, imm32); } @@ -1755,27 +813,10 @@ void Assembler::adcl(Register dst, Register src) { emit_arith(0x13, 0xC0, dst, src); } -void Assembler::adcq(Register dst, int imm32) { - (void) prefixq_and_encode(dst->encoding()); - emit_arith(0x81, 0xD0, dst, imm32); -} - -void Assembler::adcq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x13); - emit_operand(dst, src); -} - -void Assembler::adcq(Register dst, Register src) { - (int) prefixq_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x13, 0xC0, dst, src); -} - -void Assembler::addl(Address dst, int imm32) { +void Assembler::addl(Address dst, int32_t imm32) { InstructionMark im(this); prefix(dst); - emit_arith_operand(0x81, rax, dst,imm32); + emit_arith_operand(0x81, rax, dst, imm32); } void Assembler::addl(Address dst, Register src) { @@ -1785,7 +826,7 @@ void Assembler::addl(Address dst, Register src) { emit_operand(src, dst); } -void Assembler::addl(Register dst, int imm32) { +void Assembler::addl(Register dst, int32_t imm32) { prefix(dst); emit_arith(0x81, 0xC0, dst, imm32); } @@ -1802,786 +843,6 @@ void Assembler::addl(Register dst, Register src) { emit_arith(0x03, 0xC0, dst, src); } -void Assembler::addq(Address dst, int imm32) { - InstructionMark im(this); - prefixq(dst); - emit_arith_operand(0x81, rax, dst,imm32); -} - -void Assembler::addq(Address dst, Register src) { - InstructionMark im(this); - prefixq(dst, src); - emit_byte(0x01); - emit_operand(src, dst); -} - -void Assembler::addq(Register dst, int imm32) { - (void) prefixq_and_encode(dst->encoding()); - emit_arith(0x81, 0xC0, dst, imm32); -} - -void Assembler::addq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x03); - emit_operand(dst, src); -} - -void Assembler::addq(Register dst, Register src) { - (void) prefixq_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x03, 0xC0, dst, src); -} - -void Assembler::andl(Register dst, int imm32) { - prefix(dst); - emit_arith(0x81, 0xE0, dst, imm32); -} - -void Assembler::andl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x23); - emit_operand(dst, src); -} - -void Assembler::andl(Register dst, Register src) { - (void) prefix_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x23, 0xC0, dst, src); -} - -void Assembler::andq(Register dst, int imm32) { - (void) prefixq_and_encode(dst->encoding()); - emit_arith(0x81, 0xE0, dst, imm32); -} - -void Assembler::andq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x23); - emit_operand(dst, src); -} - -void Assembler::andq(Register dst, Register src) { - (int) prefixq_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x23, 0xC0, dst, src); -} - -void Assembler::cmpb(Address dst, int imm8) { - InstructionMark im(this); - prefix(dst); - emit_byte(0x80); - emit_operand(rdi, dst, 1); - emit_byte(imm8); -} - -void Assembler::cmpl(Address dst, int imm32) { - InstructionMark im(this); - prefix(dst); - emit_byte(0x81); - emit_operand(rdi, dst, 4); - emit_long(imm32); -} - -void Assembler::cmpl(Register dst, int imm32) { - prefix(dst); - emit_arith(0x81, 0xF8, dst, imm32); -} - -void Assembler::cmpl(Register dst, Register src) { - (void) prefix_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x3B, 0xC0, dst, src); -} - -void Assembler::cmpl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x3B); - emit_operand(dst, src); -} - -void Assembler::cmpq(Address dst, int imm32) { - InstructionMark im(this); - prefixq(dst); - emit_byte(0x81); - emit_operand(rdi, dst, 4); - emit_long(imm32); -} - -void Assembler::cmpq(Register dst, int imm32) { - (void) prefixq_and_encode(dst->encoding()); - emit_arith(0x81, 0xF8, dst, imm32); -} - -void Assembler::cmpq(Address dst, Register src) { - prefixq(dst, src); - emit_byte(0x3B); - emit_operand(src, dst); -} - -void Assembler::cmpq(Register dst, Register src) { - (void) prefixq_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x3B, 0xC0, dst, src); -} - -void Assembler::cmpq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x3B); - emit_operand(dst, src); -} - -void Assembler::ucomiss(XMMRegister dst, XMMRegister src) { - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x2E); - emit_byte(0xC0 | encode); -} - -void Assembler::ucomisd(XMMRegister dst, XMMRegister src) { - emit_byte(0x66); - ucomiss(dst, src); -} - -void Assembler::decl(Register dst) { - // Don't use it directly. Use MacroAssembler::decrementl() instead. - // Use two-byte form (one-byte from is a REX prefix in 64-bit mode) - int encode = prefix_and_encode(dst->encoding()); - emit_byte(0xFF); - emit_byte(0xC8 | encode); -} - -void Assembler::decl(Address dst) { - // Don't use it directly. Use MacroAssembler::decrementl() instead. - InstructionMark im(this); - prefix(dst); - emit_byte(0xFF); - emit_operand(rcx, dst); -} - -void Assembler::decq(Register dst) { - // Don't use it directly. Use MacroAssembler::decrementq() instead. - // Use two-byte form (one-byte from is a REX prefix in 64-bit mode) - int encode = prefixq_and_encode(dst->encoding()); - emit_byte(0xFF); - emit_byte(0xC8 | encode); -} - -void Assembler::decq(Address dst) { - // Don't use it directly. Use MacroAssembler::decrementq() instead. - InstructionMark im(this); - prefixq(dst); - emit_byte(0xFF); - emit_operand(rcx, dst); -} - -void Assembler::idivl(Register src) { - int encode = prefix_and_encode(src->encoding()); - emit_byte(0xF7); - emit_byte(0xF8 | encode); -} - -void Assembler::idivq(Register src) { - int encode = prefixq_and_encode(src->encoding()); - emit_byte(0xF7); - emit_byte(0xF8 | encode); -} - -void Assembler::cdql() { - emit_byte(0x99); -} - -void Assembler::cdqq() { - prefix(REX_W); - emit_byte(0x99); -} - -void Assembler::imull(Register dst, Register src) { - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0xAF); - emit_byte(0xC0 | encode); -} - -void Assembler::imull(Register dst, Register src, int value) { - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - if (is8bit(value)) { - emit_byte(0x6B); - emit_byte(0xC0 | encode); - emit_byte(value); - } else { - emit_byte(0x69); - emit_byte(0xC0 | encode); - emit_long(value); - } -} - -void Assembler::imulq(Register dst, Register src) { - int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0xAF); - emit_byte(0xC0 | encode); -} - -void Assembler::imulq(Register dst, Register src, int value) { - int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - if (is8bit(value)) { - emit_byte(0x6B); - emit_byte(0xC0 | encode); - emit_byte(value); - } else { - emit_byte(0x69); - emit_byte(0xC0 | encode); - emit_long(value); - } -} - -void Assembler::incl(Register dst) { - // Don't use it directly. Use MacroAssembler::incrementl() instead. - // Use two-byte form (one-byte from is a REX prefix in 64-bit mode) - int encode = prefix_and_encode(dst->encoding()); - emit_byte(0xFF); - emit_byte(0xC0 | encode); -} - -void Assembler::incl(Address dst) { - // Don't use it directly. Use MacroAssembler::incrementl() instead. - InstructionMark im(this); - prefix(dst); - emit_byte(0xFF); - emit_operand(rax, dst); -} - -void Assembler::incq(Register dst) { - // Don't use it directly. Use MacroAssembler::incrementq() instead. - // Use two-byte form (one-byte from is a REX prefix in 64-bit mode) - int encode = prefixq_and_encode(dst->encoding()); - emit_byte(0xFF); - emit_byte(0xC0 | encode); -} - -void Assembler::incq(Address dst) { - // Don't use it directly. Use MacroAssembler::incrementq() instead. - InstructionMark im(this); - prefixq(dst); - emit_byte(0xFF); - emit_operand(rax, dst); -} - -void Assembler::leal(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x67); // addr32 - prefix(src, dst); - emit_byte(0x8D); - emit_operand(dst, src); -} - -void Assembler::leaq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x8D); - emit_operand(dst, src); -} - -void Assembler::mull(Address src) { - InstructionMark im(this); - // was missing - prefix(src); - emit_byte(0xF7); - emit_operand(rsp, src); -} - -void Assembler::mull(Register src) { - // was missing - int encode = prefix_and_encode(src->encoding()); - emit_byte(0xF7); - emit_byte(0xE0 | encode); -} - -void Assembler::negl(Register dst) { - int encode = prefix_and_encode(dst->encoding()); - emit_byte(0xF7); - emit_byte(0xD8 | encode); -} - -void Assembler::negq(Register dst) { - int encode = prefixq_and_encode(dst->encoding()); - emit_byte(0xF7); - emit_byte(0xD8 | encode); -} - -void Assembler::notl(Register dst) { - int encode = prefix_and_encode(dst->encoding()); - emit_byte(0xF7); - emit_byte(0xD0 | encode); -} - -void Assembler::notq(Register dst) { - int encode = prefixq_and_encode(dst->encoding()); - emit_byte(0xF7); - emit_byte(0xD0 | encode); -} - -void Assembler::orl(Address dst, int imm32) { - InstructionMark im(this); - prefix(dst); - emit_byte(0x81); - emit_operand(rcx, dst, 4); - emit_long(imm32); -} - -void Assembler::orl(Register dst, int imm32) { - prefix(dst); - emit_arith(0x81, 0xC8, dst, imm32); -} - -void Assembler::orl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x0B); - emit_operand(dst, src); -} - -void Assembler::orl(Register dst, Register src) { - (void) prefix_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x0B, 0xC0, dst, src); -} - -void Assembler::orq(Address dst, int imm32) { - InstructionMark im(this); - prefixq(dst); - emit_byte(0x81); - emit_operand(rcx, dst, 4); - emit_long(imm32); -} - -void Assembler::orq(Register dst, int imm32) { - (void) prefixq_and_encode(dst->encoding()); - emit_arith(0x81, 0xC8, dst, imm32); -} - -void Assembler::orq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x0B); - emit_operand(dst, src); -} - -void Assembler::orq(Register dst, Register src) { - (void) prefixq_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x0B, 0xC0, dst, src); -} - -void Assembler::rcll(Register dst, int imm8) { - assert(isShiftCount(imm8), "illegal shift count"); - int encode = prefix_and_encode(dst->encoding()); - if (imm8 == 1) { - emit_byte(0xD1); - emit_byte(0xD0 | encode); - } else { - emit_byte(0xC1); - emit_byte(0xD0 | encode); - emit_byte(imm8); - } -} - -void Assembler::rclq(Register dst, int imm8) { - assert(isShiftCount(imm8 >> 1), "illegal shift count"); - int encode = prefixq_and_encode(dst->encoding()); - if (imm8 == 1) { - emit_byte(0xD1); - emit_byte(0xD0 | encode); - } else { - emit_byte(0xC1); - emit_byte(0xD0 | encode); - emit_byte(imm8); - } -} - -void Assembler::sarl(Register dst, int imm8) { - int encode = prefix_and_encode(dst->encoding()); - assert(isShiftCount(imm8), "illegal shift count"); - if (imm8 == 1) { - emit_byte(0xD1); - emit_byte(0xF8 | encode); - } else { - emit_byte(0xC1); - emit_byte(0xF8 | encode); - emit_byte(imm8); - } -} - -void Assembler::sarl(Register dst) { - int encode = prefix_and_encode(dst->encoding()); - emit_byte(0xD3); - emit_byte(0xF8 | encode); -} - -void Assembler::sarq(Register dst, int imm8) { - assert(isShiftCount(imm8 >> 1), "illegal shift count"); - int encode = prefixq_and_encode(dst->encoding()); - if (imm8 == 1) { - emit_byte(0xD1); - emit_byte(0xF8 | encode); - } else { - emit_byte(0xC1); - emit_byte(0xF8 | encode); - emit_byte(imm8); - } -} - -void Assembler::sarq(Register dst) { - int encode = prefixq_and_encode(dst->encoding()); - emit_byte(0xD3); - emit_byte(0xF8 | encode); -} - -void Assembler::sbbl(Address dst, int imm32) { - InstructionMark im(this); - prefix(dst); - emit_arith_operand(0x81, rbx, dst, imm32); -} - -void Assembler::sbbl(Register dst, int imm32) { - prefix(dst); - emit_arith(0x81, 0xD8, dst, imm32); -} - -void Assembler::sbbl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x1B); - emit_operand(dst, src); -} - -void Assembler::sbbl(Register dst, Register src) { - (void) prefix_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x1B, 0xC0, dst, src); -} - -void Assembler::sbbq(Address dst, int imm32) { - InstructionMark im(this); - prefixq(dst); - emit_arith_operand(0x81, rbx, dst, imm32); -} - -void Assembler::sbbq(Register dst, int imm32) { - (void) prefixq_and_encode(dst->encoding()); - emit_arith(0x81, 0xD8, dst, imm32); -} - -void Assembler::sbbq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x1B); - emit_operand(dst, src); -} - -void Assembler::sbbq(Register dst, Register src) { - (void) prefixq_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x1B, 0xC0, dst, src); -} - -void Assembler::shll(Register dst, int imm8) { - assert(isShiftCount(imm8), "illegal shift count"); - int encode = prefix_and_encode(dst->encoding()); - if (imm8 == 1 ) { - emit_byte(0xD1); - emit_byte(0xE0 | encode); - } else { - emit_byte(0xC1); - emit_byte(0xE0 | encode); - emit_byte(imm8); - } -} - -void Assembler::shll(Register dst) { - int encode = prefix_and_encode(dst->encoding()); - emit_byte(0xD3); - emit_byte(0xE0 | encode); -} - -void Assembler::shlq(Register dst, int imm8) { - assert(isShiftCount(imm8 >> 1), "illegal shift count"); - int encode = prefixq_and_encode(dst->encoding()); - if (imm8 == 1) { - emit_byte(0xD1); - emit_byte(0xE0 | encode); - } else { - emit_byte(0xC1); - emit_byte(0xE0 | encode); - emit_byte(imm8); - } -} - -void Assembler::shlq(Register dst) { - int encode = prefixq_and_encode(dst->encoding()); - emit_byte(0xD3); - emit_byte(0xE0 | encode); -} - -void Assembler::shrl(Register dst, int imm8) { - assert(isShiftCount(imm8), "illegal shift count"); - int encode = prefix_and_encode(dst->encoding()); - emit_byte(0xC1); - emit_byte(0xE8 | encode); - emit_byte(imm8); -} - -void Assembler::shrl(Register dst) { - int encode = prefix_and_encode(dst->encoding()); - emit_byte(0xD3); - emit_byte(0xE8 | encode); -} - -void Assembler::shrq(Register dst, int imm8) { - assert(isShiftCount(imm8 >> 1), "illegal shift count"); - int encode = prefixq_and_encode(dst->encoding()); - emit_byte(0xC1); - emit_byte(0xE8 | encode); - emit_byte(imm8); -} - -void Assembler::shrq(Register dst) { - int encode = prefixq_and_encode(dst->encoding()); - emit_byte(0xD3); - emit_byte(0xE8 | encode); -} - -void Assembler::subl(Address dst, int imm32) { - InstructionMark im(this); - prefix(dst); - if (is8bit(imm32)) { - emit_byte(0x83); - emit_operand(rbp, dst, 1); - emit_byte(imm32 & 0xFF); - } else { - emit_byte(0x81); - emit_operand(rbp, dst, 4); - emit_long(imm32); - } -} - -void Assembler::subl(Register dst, int imm32) { - prefix(dst); - emit_arith(0x81, 0xE8, dst, imm32); -} - -void Assembler::subl(Address dst, Register src) { - InstructionMark im(this); - prefix(dst, src); - emit_byte(0x29); - emit_operand(src, dst); -} - -void Assembler::subl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x2B); - emit_operand(dst, src); -} - -void Assembler::subl(Register dst, Register src) { - (void) prefix_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x2B, 0xC0, dst, src); -} - -void Assembler::subq(Address dst, int imm32) { - InstructionMark im(this); - prefixq(dst); - if (is8bit(imm32)) { - emit_byte(0x83); - emit_operand(rbp, dst, 1); - emit_byte(imm32 & 0xFF); - } else { - emit_byte(0x81); - emit_operand(rbp, dst, 4); - emit_long(imm32); - } -} - -void Assembler::subq(Register dst, int imm32) { - (void) prefixq_and_encode(dst->encoding()); - emit_arith(0x81, 0xE8, dst, imm32); -} - -void Assembler::subq(Address dst, Register src) { - InstructionMark im(this); - prefixq(dst, src); - emit_byte(0x29); - emit_operand(src, dst); -} - -void Assembler::subq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x2B); - emit_operand(dst, src); -} - -void Assembler::subq(Register dst, Register src) { - (void) prefixq_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x2B, 0xC0, dst, src); -} - -void Assembler::testb(Register dst, int imm8) { - (void) prefix_and_encode(dst->encoding(), true); - emit_arith_b(0xF6, 0xC0, dst, imm8); -} - -void Assembler::testl(Register dst, int imm32) { - // not using emit_arith because test - // doesn't support sign-extension of - // 8bit operands - int encode = dst->encoding(); - if (encode == 0) { - emit_byte(0xA9); - } else { - encode = prefix_and_encode(encode); - emit_byte(0xF7); - emit_byte(0xC0 | encode); - } - emit_long(imm32); -} - -void Assembler::testl(Register dst, Register src) { - (void) prefix_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x85, 0xC0, dst, src); -} - -void Assembler::testq(Register dst, int imm32) { - // not using emit_arith because test - // doesn't support sign-extension of - // 8bit operands - int encode = dst->encoding(); - if (encode == 0) { - prefix(REX_W); - emit_byte(0xA9); - } else { - encode = prefixq_and_encode(encode); - emit_byte(0xF7); - emit_byte(0xC0 | encode); - } - emit_long(imm32); -} - -void Assembler::testq(Register dst, Register src) { - (void) prefixq_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x85, 0xC0, dst, src); -} - -void Assembler::xaddl(Address dst, Register src) { - InstructionMark im(this); - prefix(dst, src); - emit_byte(0x0F); - emit_byte(0xC1); - emit_operand(src, dst); -} - -void Assembler::xaddq(Address dst, Register src) { - InstructionMark im(this); - prefixq(dst, src); - emit_byte(0x0F); - emit_byte(0xC1); - emit_operand(src, dst); -} - -void Assembler::xorl(Register dst, int imm32) { - prefix(dst); - emit_arith(0x81, 0xF0, dst, imm32); -} - -void Assembler::xorl(Register dst, Register src) { - (void) prefix_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x33, 0xC0, dst, src); -} - -void Assembler::xorl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x33); - emit_operand(dst, src); -} - -void Assembler::xorq(Register dst, int imm32) { - (void) prefixq_and_encode(dst->encoding()); - emit_arith(0x81, 0xF0, dst, imm32); -} - -void Assembler::xorq(Register dst, Register src) { - (void) prefixq_and_encode(dst->encoding(), src->encoding()); - emit_arith(0x33, 0xC0, dst, src); -} - -void Assembler::xorq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x33); - emit_operand(dst, src); -} - -void Assembler::bswapl(Register reg) { - int encode = prefix_and_encode(reg->encoding()); - emit_byte(0x0F); - emit_byte(0xC8 | encode); -} - -void Assembler::bswapq(Register reg) { - int encode = prefixq_and_encode(reg->encoding()); - emit_byte(0x0F); - emit_byte(0xC8 | encode); -} - -void Assembler::lock() { - emit_byte(0xF0); -} - -void Assembler::xchgl(Register dst, Address src) { - InstructionMark im(this); - prefix(src, dst); - emit_byte(0x87); - emit_operand(dst, src); -} - -void Assembler::xchgl(Register dst, Register src) { - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x87); - emit_byte(0xc0 | encode); -} - -void Assembler::xchgq(Register dst, Address src) { - InstructionMark im(this); - prefixq(src, dst); - emit_byte(0x87); - emit_operand(dst, src); -} - -void Assembler::xchgq(Register dst, Register src) { - int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x87); - emit_byte(0xc0 | encode); -} - -void Assembler::cmpxchgl(Register reg, Address adr) { - InstructionMark im(this); - prefix(adr, reg); - emit_byte(0x0F); - emit_byte(0xB1); - emit_operand(reg, adr); -} - -void Assembler::cmpxchgq(Register reg, Address adr) { - InstructionMark im(this); - prefixq(adr, reg); - emit_byte(0x0F); - emit_byte(0xB1); - emit_operand(reg, adr); -} - -void Assembler::hlt() { - emit_byte(0xF4); -} - - void Assembler::addr_nop_4() { // 4 bytes: NOP DWORD PTR [EAX+0] emit_byte(0x0F); @@ -2616,8 +877,1009 @@ void Assembler::addr_nop_8() { emit_long(0); // 32-bits offset (4 bytes) } +void Assembler::addsd(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF2); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x58); + emit_byte(0xC0 | encode); +} + +void Assembler::addsd(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0xF2); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x58); + emit_operand(dst, src); +} + +void Assembler::addss(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + emit_byte(0xF3); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x58); + emit_byte(0xC0 | encode); +} + +void Assembler::addss(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + InstructionMark im(this); + emit_byte(0xF3); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x58); + emit_operand(dst, src); +} + +void Assembler::andl(Register dst, int32_t imm32) { + prefix(dst); + emit_arith(0x81, 0xE0, dst, imm32); +} + +void Assembler::andl(Register dst, Address src) { + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x23); + emit_operand(dst, src); +} + +void Assembler::andl(Register dst, Register src) { + (void) prefix_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x23, 0xC0, dst, src); +} + +void Assembler::andpd(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0x66); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x54); + emit_operand(dst, src); +} + +void Assembler::bswapl(Register reg) { // bswap + int encode = prefix_and_encode(reg->encoding()); + emit_byte(0x0F); + emit_byte(0xC8 | encode); +} + +void Assembler::call(Label& L, relocInfo::relocType rtype) { + // suspect disp32 is always good + int operand = LP64_ONLY(disp32_operand) NOT_LP64(imm_operand); + + if (L.is_bound()) { + const int long_size = 5; + int offs = (int)( target(L) - pc() ); + assert(offs <= 0, "assembler error"); + InstructionMark im(this); + // 1110 1000 #32-bit disp + emit_byte(0xE8); + emit_data(offs - long_size, rtype, operand); + } else { + InstructionMark im(this); + // 1110 1000 #32-bit disp + L.add_patch_at(code(), locator()); + + emit_byte(0xE8); + emit_data(int(0), rtype, operand); + } +} + +void Assembler::call(Register dst) { + // This was originally using a 32bit register encoding + // and surely we want 64bit! + // this is a 32bit encoding but in 64bit mode the default + // operand size is 64bit so there is no need for the + // wide prefix. So prefix only happens if we use the + // new registers. Much like push/pop. + int x = offset(); + // this may be true but dbx disassembles it as if it + // were 32bits... + // int encode = prefix_and_encode(dst->encoding()); + // if (offset() != x) assert(dst->encoding() >= 8, "what?"); + int encode = prefixq_and_encode(dst->encoding()); + + emit_byte(0xFF); + emit_byte(0xD0 | encode); +} + + +void Assembler::call(Address adr) { + InstructionMark im(this); + prefix(adr); + emit_byte(0xFF); + emit_operand(rdx, adr); +} + +void Assembler::call_literal(address entry, RelocationHolder const& rspec) { + assert(entry != NULL, "call most probably wrong"); + InstructionMark im(this); + emit_byte(0xE8); + intptr_t disp = entry - (_code_pos + sizeof(int32_t)); + assert(is_simm32(disp), "must be 32bit offset (call2)"); + // Technically, should use call32_operand, but this format is + // implied by the fact that we're emitting a call instruction. + + int operand = LP64_ONLY(disp32_operand) NOT_LP64(call32_operand); + emit_data((int) disp, rspec, operand); +} + +void Assembler::cdql() { + emit_byte(0x99); +} + +void Assembler::cmovl(Condition cc, Register dst, Register src) { + NOT_LP64(guarantee(VM_Version::supports_cmov(), "illegal instruction")); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x40 | cc); + emit_byte(0xC0 | encode); +} + + +void Assembler::cmovl(Condition cc, Register dst, Address src) { + NOT_LP64(guarantee(VM_Version::supports_cmov(), "illegal instruction")); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x40 | cc); + emit_operand(dst, src); +} + +void Assembler::cmpb(Address dst, int imm8) { + InstructionMark im(this); + prefix(dst); + emit_byte(0x80); + emit_operand(rdi, dst, 1); + emit_byte(imm8); +} + +void Assembler::cmpl(Address dst, int32_t imm32) { + InstructionMark im(this); + prefix(dst); + emit_byte(0x81); + emit_operand(rdi, dst, 4); + emit_long(imm32); +} + +void Assembler::cmpl(Register dst, int32_t imm32) { + prefix(dst); + emit_arith(0x81, 0xF8, dst, imm32); +} + +void Assembler::cmpl(Register dst, Register src) { + (void) prefix_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x3B, 0xC0, dst, src); +} + + +void Assembler::cmpl(Register dst, Address src) { + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x3B); + emit_operand(dst, src); +} + +void Assembler::cmpw(Address dst, int imm16) { + InstructionMark im(this); + assert(!dst.base_needs_rex() && !dst.index_needs_rex(), "no extended registers"); + emit_byte(0x66); + emit_byte(0x81); + emit_operand(rdi, dst, 2); + emit_word(imm16); +} + +// The 32-bit cmpxchg compares the value at adr with the contents of rax, +// and stores reg into adr if so; otherwise, the value at adr is loaded into rax,. +// The ZF is set if the compared values were equal, and cleared otherwise. +void Assembler::cmpxchgl(Register reg, Address adr) { // cmpxchg + if (Atomics & 2) { + // caveat: no instructionmark, so this isn't relocatable. + // Emit a synthetic, non-atomic, CAS equivalent. + // Beware. The synthetic form sets all ICCs, not just ZF. + // cmpxchg r,[m] is equivalent to rax, = CAS (m, rax, r) + cmpl(rax, adr); + movl(rax, adr); + if (reg != rax) { + Label L ; + jcc(Assembler::notEqual, L); + movl(adr, reg); + bind(L); + } + } else { + InstructionMark im(this); + prefix(adr, reg); + emit_byte(0x0F); + emit_byte(0xB1); + emit_operand(reg, adr); + } +} + +void Assembler::comisd(XMMRegister dst, Address src) { + // NOTE: dbx seems to decode this as comiss even though the + // 0x66 is there. Strangly ucomisd comes out correct + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0x66); + comiss(dst, src); +} + +void Assembler::comiss(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x2F); + emit_operand(dst, src); +} + +void Assembler::cvtdq2pd(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF3); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0xE6); + emit_byte(0xC0 | encode); +} + +void Assembler::cvtdq2ps(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x5B); + emit_byte(0xC0 | encode); +} + +void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF2); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x5A); + emit_byte(0xC0 | encode); +} + +void Assembler::cvtsi2sdl(XMMRegister dst, Register src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF2); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x2A); + emit_byte(0xC0 | encode); +} + +void Assembler::cvtsi2ssl(XMMRegister dst, Register src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + emit_byte(0xF3); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x2A); + emit_byte(0xC0 | encode); +} + +void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF3); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x5A); + emit_byte(0xC0 | encode); +} + +void Assembler::cvttsd2sil(Register dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF2); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x2C); + emit_byte(0xC0 | encode); +} + +void Assembler::cvttss2sil(Register dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + emit_byte(0xF3); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x2C); + emit_byte(0xC0 | encode); +} + +void Assembler::decl(Address dst) { + // Don't use it directly. Use MacroAssembler::decrement() instead. + InstructionMark im(this); + prefix(dst); + emit_byte(0xFF); + emit_operand(rcx, dst); +} + +void Assembler::divsd(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0xF2); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x5E); + emit_operand(dst, src); +} + +void Assembler::divsd(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF2); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x5E); + emit_byte(0xC0 | encode); +} + +void Assembler::divss(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + InstructionMark im(this); + emit_byte(0xF3); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x5E); + emit_operand(dst, src); +} + +void Assembler::divss(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + emit_byte(0xF3); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x5E); + emit_byte(0xC0 | encode); +} + +void Assembler::emms() { + NOT_LP64(assert(VM_Version::supports_mmx(), "")); + emit_byte(0x0F); + emit_byte(0x77); +} + +void Assembler::hlt() { + emit_byte(0xF4); +} + +void Assembler::idivl(Register src) { + int encode = prefix_and_encode(src->encoding()); + emit_byte(0xF7); + emit_byte(0xF8 | encode); +} + +void Assembler::imull(Register dst, Register src) { + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0xAF); + emit_byte(0xC0 | encode); +} + + +void Assembler::imull(Register dst, Register src, int value) { + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + if (is8bit(value)) { + emit_byte(0x6B); + emit_byte(0xC0 | encode); + emit_byte(value); + } else { + emit_byte(0x69); + emit_byte(0xC0 | encode); + emit_long(value); + } +} + +void Assembler::incl(Address dst) { + // Don't use it directly. Use MacroAssembler::increment() instead. + InstructionMark im(this); + prefix(dst); + emit_byte(0xFF); + emit_operand(rax, dst); +} + +void Assembler::jcc(Condition cc, Label& L, relocInfo::relocType rtype) { + InstructionMark im(this); + relocate(rtype); + assert((0 <= cc) && (cc < 16), "illegal cc"); + if (L.is_bound()) { + address dst = target(L); + assert(dst != NULL, "jcc most probably wrong"); + + const int short_size = 2; + const int long_size = 6; + intptr_t offs = (intptr_t)dst - (intptr_t)_code_pos; + if (rtype == relocInfo::none && is8bit(offs - short_size)) { + // 0111 tttn #8-bit disp + emit_byte(0x70 | cc); + emit_byte((offs - short_size) & 0xFF); + } else { + // 0000 1111 1000 tttn #32-bit disp + assert(is_simm32(offs - long_size), + "must be 32bit offset (call4)"); + emit_byte(0x0F); + emit_byte(0x80 | cc); + emit_long(offs - long_size); + } + } else { + // Note: could eliminate cond. jumps to this jump if condition + // is the same however, seems to be rather unlikely case. + // Note: use jccb() if label to be bound is very close to get + // an 8-bit displacement + L.add_patch_at(code(), locator()); + emit_byte(0x0F); + emit_byte(0x80 | cc); + emit_long(0); + } +} + +void Assembler::jccb(Condition cc, Label& L) { + if (L.is_bound()) { + const int short_size = 2; + address entry = target(L); + assert(is8bit((intptr_t)entry - ((intptr_t)_code_pos + short_size)), + "Dispacement too large for a short jmp"); + intptr_t offs = (intptr_t)entry - (intptr_t)_code_pos; + // 0111 tttn #8-bit disp + emit_byte(0x70 | cc); + emit_byte((offs - short_size) & 0xFF); + } else { + InstructionMark im(this); + L.add_patch_at(code(), locator()); + emit_byte(0x70 | cc); + emit_byte(0); + } +} + +void Assembler::jmp(Address adr) { + InstructionMark im(this); + prefix(adr); + emit_byte(0xFF); + emit_operand(rsp, adr); +} + +void Assembler::jmp(Label& L, relocInfo::relocType rtype) { + if (L.is_bound()) { + address entry = target(L); + assert(entry != NULL, "jmp most probably wrong"); + InstructionMark im(this); + const int short_size = 2; + const int long_size = 5; + intptr_t offs = entry - _code_pos; + if (rtype == relocInfo::none && is8bit(offs - short_size)) { + emit_byte(0xEB); + emit_byte((offs - short_size) & 0xFF); + } else { + emit_byte(0xE9); + emit_long(offs - long_size); + } + } else { + // By default, forward jumps are always 32-bit displacements, since + // we can't yet know where the label will be bound. If you're sure that + // the forward jump will not run beyond 256 bytes, use jmpb to + // force an 8-bit displacement. + InstructionMark im(this); + relocate(rtype); + L.add_patch_at(code(), locator()); + emit_byte(0xE9); + emit_long(0); + } +} + +void Assembler::jmp(Register entry) { + int encode = prefix_and_encode(entry->encoding()); + emit_byte(0xFF); + emit_byte(0xE0 | encode); +} + +void Assembler::jmp_literal(address dest, RelocationHolder const& rspec) { + InstructionMark im(this); + emit_byte(0xE9); + assert(dest != NULL, "must have a target"); + intptr_t disp = dest - (_code_pos + sizeof(int32_t)); + assert(is_simm32(disp), "must be 32bit offset (jmp)"); + emit_data(disp, rspec.reloc(), call32_operand); +} + +void Assembler::jmpb(Label& L) { + if (L.is_bound()) { + const int short_size = 2; + address entry = target(L); + assert(is8bit((entry - _code_pos) + short_size), + "Dispacement too large for a short jmp"); + assert(entry != NULL, "jmp most probably wrong"); + intptr_t offs = entry - _code_pos; + emit_byte(0xEB); + emit_byte((offs - short_size) & 0xFF); + } else { + InstructionMark im(this); + L.add_patch_at(code(), locator()); + emit_byte(0xEB); + emit_byte(0); + } +} + +void Assembler::ldmxcsr( Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + InstructionMark im(this); + prefix(src); + emit_byte(0x0F); + emit_byte(0xAE); + emit_operand(as_Register(2), src); +} + +void Assembler::leal(Register dst, Address src) { + InstructionMark im(this); +#ifdef _LP64 + emit_byte(0x67); // addr32 + prefix(src, dst); +#endif // LP64 + emit_byte(0x8D); + emit_operand(dst, src); +} + +void Assembler::lock() { + if (Atomics & 1) { + // Emit either nothing, a NOP, or a NOP: prefix + emit_byte(0x90) ; + } else { + emit_byte(0xF0); + } +} + +// Serializes memory. +void Assembler::mfence() { + // Memory barriers are only needed on multiprocessors + if (os::is_MP()) { + if( LP64_ONLY(true ||) VM_Version::supports_sse2() ) { + emit_byte( 0x0F ); // MFENCE; faster blows no regs + emit_byte( 0xAE ); + emit_byte( 0xF0 ); + } else { + // All usable chips support "locked" instructions which suffice + // as barriers, and are much faster than the alternative of + // using cpuid instruction. We use here a locked add [esp],0. + // This is conveniently otherwise a no-op except for blowing + // flags (which we save and restore.) + pushf(); // Save eflags register + lock(); + addl(Address(rsp, 0), 0);// Assert the lock# signal here + popf(); // Restore eflags register + } + } +} + +void Assembler::mov(Register dst, Register src) { + LP64_ONLY(movq(dst, src)) NOT_LP64(movl(dst, src)); +} + +void Assembler::movapd(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + int dstenc = dst->encoding(); + int srcenc = src->encoding(); + emit_byte(0x66); + if (dstenc < 8) { + if (srcenc >= 8) { + prefix(REX_B); + srcenc -= 8; + } + } else { + if (srcenc < 8) { + prefix(REX_R); + } else { + prefix(REX_RB); + srcenc -= 8; + } + dstenc -= 8; + } + emit_byte(0x0F); + emit_byte(0x28); + emit_byte(0xC0 | dstenc << 3 | srcenc); +} + +void Assembler::movaps(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + int dstenc = dst->encoding(); + int srcenc = src->encoding(); + if (dstenc < 8) { + if (srcenc >= 8) { + prefix(REX_B); + srcenc -= 8; + } + } else { + if (srcenc < 8) { + prefix(REX_R); + } else { + prefix(REX_RB); + srcenc -= 8; + } + dstenc -= 8; + } + emit_byte(0x0F); + emit_byte(0x28); + emit_byte(0xC0 | dstenc << 3 | srcenc); +} + +void Assembler::movb(Register dst, Address src) { + NOT_LP64(assert(dst->has_byte_register(), "must have byte register")); + InstructionMark im(this); + prefix(src, dst, true); + emit_byte(0x8A); + emit_operand(dst, src); +} + + +void Assembler::movb(Address dst, int imm8) { + InstructionMark im(this); + prefix(dst); + emit_byte(0xC6); + emit_operand(rax, dst, 1); + emit_byte(imm8); +} + + +void Assembler::movb(Address dst, Register src) { + assert(src->has_byte_register(), "must have byte register"); + InstructionMark im(this); + prefix(dst, src, true); + emit_byte(0x88); + emit_operand(src, dst); +} + +void Assembler::movdl(XMMRegister dst, Register src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0x66); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x6E); + emit_byte(0xC0 | encode); +} + +void Assembler::movdl(Register dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0x66); + // swap src/dst to get correct prefix + int encode = prefix_and_encode(src->encoding(), dst->encoding()); + emit_byte(0x0F); + emit_byte(0x7E); + emit_byte(0xC0 | encode); +} + +void Assembler::movdqa(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0x66); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x6F); + emit_operand(dst, src); +} + +void Assembler::movdqa(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0x66); + int encode = prefixq_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x6F); + emit_byte(0xC0 | encode); +} + +void Assembler::movdqa(Address dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0x66); + prefix(dst, src); + emit_byte(0x0F); + emit_byte(0x7F); + emit_operand(src, dst); +} + +// Uses zero extension on 64bit + +void Assembler::movl(Register dst, int32_t imm32) { + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0xB8 | encode); + emit_long(imm32); +} + +void Assembler::movl(Register dst, Register src) { + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x8B); + emit_byte(0xC0 | encode); +} + +void Assembler::movl(Register dst, Address src) { + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x8B); + emit_operand(dst, src); +} + +void Assembler::movl(Address dst, int32_t imm32) { + InstructionMark im(this); + prefix(dst); + emit_byte(0xC7); + emit_operand(rax, dst, 4); + emit_long(imm32); +} + +void Assembler::movl(Address dst, Register src) { + InstructionMark im(this); + prefix(dst, src); + emit_byte(0x89); + emit_operand(src, dst); +} + +// New cpus require to use movsd and movss to avoid partial register stall +// when loading from memory. But for old Opteron use movlpd instead of movsd. +// The selection is done in MacroAssembler::movdbl() and movflt(). +void Assembler::movlpd(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0x66); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x12); + emit_operand(dst, src); +} + +void Assembler::movq( MMXRegister dst, Address src ) { + assert( VM_Version::supports_mmx(), "" ); + emit_byte(0x0F); + emit_byte(0x6F); + emit_operand(dst, src); +} + +void Assembler::movq( Address dst, MMXRegister src ) { + assert( VM_Version::supports_mmx(), "" ); + emit_byte(0x0F); + emit_byte(0x7F); + // workaround gcc (3.2.1-7a) bug + // In that version of gcc with only an emit_operand(MMX, Address) + // gcc will tail jump and try and reverse the parameters completely + // obliterating dst in the process. By having a version available + // that doesn't need to swap the args at the tail jump the bug is + // avoided. + emit_operand(dst, src); +} + +void Assembler::movq(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0xF3); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x7E); + emit_operand(dst, src); +} + +void Assembler::movq(Address dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0x66); + prefix(dst, src); + emit_byte(0x0F); + emit_byte(0xD6); + emit_operand(src, dst); +} + +void Assembler::movsbl(Register dst, Address src) { // movsxb + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0xBE); + emit_operand(dst, src); +} + +void Assembler::movsbl(Register dst, Register src) { // movsxb + NOT_LP64(assert(src->has_byte_register(), "must have byte register")); + int encode = prefix_and_encode(dst->encoding(), src->encoding(), true); + emit_byte(0x0F); + emit_byte(0xBE); + emit_byte(0xC0 | encode); +} + +void Assembler::movsd(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF2); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x10); + emit_byte(0xC0 | encode); +} + +void Assembler::movsd(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0xF2); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x10); + emit_operand(dst, src); +} + +void Assembler::movsd(Address dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0xF2); + prefix(dst, src); + emit_byte(0x0F); + emit_byte(0x11); + emit_operand(src, dst); +} + +void Assembler::movss(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + emit_byte(0xF3); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x10); + emit_byte(0xC0 | encode); +} + +void Assembler::movss(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + InstructionMark im(this); + emit_byte(0xF3); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x10); + emit_operand(dst, src); +} + +void Assembler::movss(Address dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + InstructionMark im(this); + emit_byte(0xF3); + prefix(dst, src); + emit_byte(0x0F); + emit_byte(0x11); + emit_operand(src, dst); +} + +void Assembler::movswl(Register dst, Address src) { // movsxw + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0xBF); + emit_operand(dst, src); +} + +void Assembler::movswl(Register dst, Register src) { // movsxw + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0xBF); + emit_byte(0xC0 | encode); +} + +void Assembler::movw(Address dst, int imm16) { + InstructionMark im(this); + + emit_byte(0x66); // switch to 16-bit mode + prefix(dst); + emit_byte(0xC7); + emit_operand(rax, dst, 2); + emit_word(imm16); +} + +void Assembler::movw(Register dst, Address src) { + InstructionMark im(this); + emit_byte(0x66); + prefix(src, dst); + emit_byte(0x8B); + emit_operand(dst, src); +} + +void Assembler::movw(Address dst, Register src) { + InstructionMark im(this); + emit_byte(0x66); + prefix(dst, src); + emit_byte(0x89); + emit_operand(src, dst); +} + +void Assembler::movzbl(Register dst, Address src) { // movzxb + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0xB6); + emit_operand(dst, src); +} + +void Assembler::movzbl(Register dst, Register src) { // movzxb + NOT_LP64(assert(src->has_byte_register(), "must have byte register")); + int encode = prefix_and_encode(dst->encoding(), src->encoding(), true); + emit_byte(0x0F); + emit_byte(0xB6); + emit_byte(0xC0 | encode); +} + +void Assembler::movzwl(Register dst, Address src) { // movzxw + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0xB7); + emit_operand(dst, src); +} + +void Assembler::movzwl(Register dst, Register src) { // movzxw + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0xB7); + emit_byte(0xC0 | encode); +} + +void Assembler::mull(Address src) { + InstructionMark im(this); + prefix(src); + emit_byte(0xF7); + emit_operand(rsp, src); +} + +void Assembler::mull(Register src) { + int encode = prefix_and_encode(src->encoding()); + emit_byte(0xF7); + emit_byte(0xE0 | encode); +} + +void Assembler::mulsd(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0xF2); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x59); + emit_operand(dst, src); +} + +void Assembler::mulsd(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF2); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x59); + emit_byte(0xC0 | encode); +} + +void Assembler::mulss(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + InstructionMark im(this); + emit_byte(0xF3); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x59); + emit_operand(dst, src); +} + +void Assembler::mulss(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + emit_byte(0xF3); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x59); + emit_byte(0xC0 | encode); +} + +void Assembler::negl(Register dst) { + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0xF7); + emit_byte(0xD8 | encode); +} + void Assembler::nop(int i) { +#ifdef ASSERT assert(i > 0, " "); + // The fancy nops aren't currently recognized by debuggers making it a + // pain to disassemble code while debugging. If asserts are on clearly + // speed is not an issue so simply use the single byte traditional nop + // to do alignment. + + for (; i > 0 ; i--) emit_byte(0x90); + return; + +#endif // ASSERT + if (UseAddressNop && VM_Version::is_intel()) { // // Using multi-bytes nops "0x0F 0x1F [address]" for Intel @@ -2853,6 +2115,281 @@ void Assembler::nop(int i) { } } +void Assembler::notl(Register dst) { + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0xF7); + emit_byte(0xD0 | encode ); +} + +void Assembler::orl(Address dst, int32_t imm32) { + InstructionMark im(this); + prefix(dst); + emit_byte(0x81); + emit_operand(rcx, dst, 4); + emit_long(imm32); +} + +void Assembler::orl(Register dst, int32_t imm32) { + prefix(dst); + emit_arith(0x81, 0xC8, dst, imm32); +} + + +void Assembler::orl(Register dst, Address src) { + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x0B); + emit_operand(dst, src); +} + + +void Assembler::orl(Register dst, Register src) { + (void) prefix_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x0B, 0xC0, dst, src); +} + +// generic +void Assembler::pop(Register dst) { + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0x58 | encode); +} + +void Assembler::popf() { + emit_byte(0x9D); +} + +void Assembler::popl(Address dst) { + // NOTE: this will adjust stack by 8byte on 64bits + InstructionMark im(this); + prefix(dst); + emit_byte(0x8F); + emit_operand(rax, dst); +} + +void Assembler::prefetch_prefix(Address src) { + prefix(src); + emit_byte(0x0F); +} + +void Assembler::prefetchnta(Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "must support")); + InstructionMark im(this); + prefetch_prefix(src); + emit_byte(0x18); + emit_operand(rax, src); // 0, src +} + +void Assembler::prefetchr(Address src) { + NOT_LP64(assert(VM_Version::supports_3dnow(), "must support")); + InstructionMark im(this); + prefetch_prefix(src); + emit_byte(0x0D); + emit_operand(rax, src); // 0, src +} + +void Assembler::prefetcht0(Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "must support")); + InstructionMark im(this); + prefetch_prefix(src); + emit_byte(0x18); + emit_operand(rcx, src); // 1, src +} + +void Assembler::prefetcht1(Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "must support")); + InstructionMark im(this); + prefetch_prefix(src); + emit_byte(0x18); + emit_operand(rdx, src); // 2, src +} + +void Assembler::prefetcht2(Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "must support")); + InstructionMark im(this); + prefetch_prefix(src); + emit_byte(0x18); + emit_operand(rbx, src); // 3, src +} + +void Assembler::prefetchw(Address src) { + NOT_LP64(assert(VM_Version::supports_3dnow(), "must support")); + InstructionMark im(this); + prefetch_prefix(src); + emit_byte(0x0D); + emit_operand(rcx, src); // 1, src +} + +void Assembler::prefix(Prefix p) { + a_byte(p); +} + +void Assembler::pshufd(XMMRegister dst, XMMRegister src, int mode) { + assert(isByte(mode), "invalid value"); + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + + emit_byte(0x66); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x70); + emit_byte(0xC0 | encode); + emit_byte(mode & 0xFF); + +} + +void Assembler::pshufd(XMMRegister dst, Address src, int mode) { + assert(isByte(mode), "invalid value"); + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + + InstructionMark im(this); + emit_byte(0x66); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x70); + emit_operand(dst, src); + emit_byte(mode & 0xFF); +} + +void Assembler::pshuflw(XMMRegister dst, XMMRegister src, int mode) { + assert(isByte(mode), "invalid value"); + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + + emit_byte(0xF2); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x70); + emit_byte(0xC0 | encode); + emit_byte(mode & 0xFF); +} + +void Assembler::pshuflw(XMMRegister dst, Address src, int mode) { + assert(isByte(mode), "invalid value"); + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + + InstructionMark im(this); + emit_byte(0xF2); + prefix(src, dst); // QQ new + emit_byte(0x0F); + emit_byte(0x70); + emit_operand(dst, src); + emit_byte(mode & 0xFF); +} + +void Assembler::psrlq(XMMRegister dst, int shift) { + // HMM Table D-1 says sse2 or mmx + NOT_LP64(assert(VM_Version::supports_sse(), "")); + + int encode = prefixq_and_encode(xmm2->encoding(), dst->encoding()); + emit_byte(0x66); + emit_byte(0x0F); + emit_byte(0x73); + emit_byte(0xC0 | encode); + emit_byte(shift); +} + +void Assembler::punpcklbw(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0x66); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x60); + emit_byte(0xC0 | encode); +} + +void Assembler::push(int32_t imm32) { + // in 64bits we push 64bits onto the stack but only + // take a 32bit immediate + emit_byte(0x68); + emit_long(imm32); +} + +void Assembler::push(Register src) { + int encode = prefix_and_encode(src->encoding()); + + emit_byte(0x50 | encode); +} + +void Assembler::pushf() { + emit_byte(0x9C); +} + +void Assembler::pushl(Address src) { + // Note this will push 64bit on 64bit + InstructionMark im(this); + prefix(src); + emit_byte(0xFF); + emit_operand(rsi, src); +} + +void Assembler::pxor(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0x66); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0xEF); + emit_operand(dst, src); +} + +void Assembler::pxor(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0x66); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0xEF); + emit_byte(0xC0 | encode); +} + +void Assembler::rcll(Register dst, int imm8) { + assert(isShiftCount(imm8), "illegal shift count"); + int encode = prefix_and_encode(dst->encoding()); + if (imm8 == 1) { + emit_byte(0xD1); + emit_byte(0xD0 | encode); + } else { + emit_byte(0xC1); + emit_byte(0xD0 | encode); + emit_byte(imm8); + } +} + +// copies data from [esi] to [edi] using rcx pointer sized words +// generic +void Assembler::rep_mov() { + emit_byte(0xF3); + // MOVSQ + LP64_ONLY(prefix(REX_W)); + emit_byte(0xA5); +} + +// sets rcx pointer sized words with rax, value at [edi] +// generic +void Assembler::rep_set() { // rep_set + emit_byte(0xF3); + // STOSQ + LP64_ONLY(prefix(REX_W)); + emit_byte(0xAB); +} + +// scans rcx pointer sized words at [edi] for occurance of rax, +// generic +void Assembler::repne_scan() { // repne_scan + emit_byte(0xF2); + // SCASQ + LP64_ONLY(prefix(REX_W)); + emit_byte(0xAF); +} + +#ifdef _LP64 +// scans rcx 4 byte words at [edi] for occurance of rax, +// generic +void Assembler::repne_scanl() { // repne_scan + emit_byte(0xF2); + // SCASL + emit_byte(0xAF); +} +#endif + void Assembler::ret(int imm16) { if (imm16 == 0) { emit_byte(0xC3); @@ -2862,53 +2399,56 @@ void Assembler::ret(int imm16) { } } -// copies a single word from [esi] to [edi] -void Assembler::smovl() { - emit_byte(0xA5); +void Assembler::sahf() { +#ifdef _LP64 + // Not supported in 64bit mode + ShouldNotReachHere(); +#endif + emit_byte(0x9E); } -// copies data from [rsi] to [rdi] using rcx words (m32) -void Assembler::rep_movl() { - // REP - emit_byte(0xF3); - // MOVSL - emit_byte(0xA5); +void Assembler::sarl(Register dst, int imm8) { + int encode = prefix_and_encode(dst->encoding()); + assert(isShiftCount(imm8), "illegal shift count"); + if (imm8 == 1) { + emit_byte(0xD1); + emit_byte(0xF8 | encode); + } else { + emit_byte(0xC1); + emit_byte(0xF8 | encode); + emit_byte(imm8); + } } -// copies data from [rsi] to [rdi] using rcx double words (m64) -void Assembler::rep_movq() { - // REP - emit_byte(0xF3); - // MOVSQ - prefix(REX_W); - emit_byte(0xA5); +void Assembler::sarl(Register dst) { + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0xD3); + emit_byte(0xF8 | encode); } -// sets rcx double words (m64) with rax value at [rdi] -void Assembler::rep_set() { - // REP - emit_byte(0xF3); - // STOSQ - prefix(REX_W); - emit_byte(0xAB); +void Assembler::sbbl(Address dst, int32_t imm32) { + InstructionMark im(this); + prefix(dst); + emit_arith_operand(0x81, rbx, dst, imm32); } -// scans rcx double words (m64) at [rdi] for occurance of rax -void Assembler::repne_scanq() { - // REPNE/REPNZ - emit_byte(0xF2); - // SCASQ - prefix(REX_W); - emit_byte(0xAF); +void Assembler::sbbl(Register dst, int32_t imm32) { + prefix(dst); + emit_arith(0x81, 0xD8, dst, imm32); } -void Assembler::repne_scanl() { - // REPNE/REPNZ - emit_byte(0xF2); - // SCASL - emit_byte(0xAF); + +void Assembler::sbbl(Register dst, Address src) { + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x1B); + emit_operand(dst, src); } +void Assembler::sbbl(Register dst, Register src) { + (void) prefix_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x1B, 0xC0, dst, src); +} void Assembler::setb(Condition cc, Register dst) { assert(0 <= cc && cc < 16, "illegal cc"); @@ -2918,6 +2458,1155 @@ void Assembler::setb(Condition cc, Register dst) { emit_byte(0xC0 | encode); } +void Assembler::shll(Register dst, int imm8) { + assert(isShiftCount(imm8), "illegal shift count"); + int encode = prefix_and_encode(dst->encoding()); + if (imm8 == 1 ) { + emit_byte(0xD1); + emit_byte(0xE0 | encode); + } else { + emit_byte(0xC1); + emit_byte(0xE0 | encode); + emit_byte(imm8); + } +} + +void Assembler::shll(Register dst) { + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0xD3); + emit_byte(0xE0 | encode); +} + +void Assembler::shrl(Register dst, int imm8) { + assert(isShiftCount(imm8), "illegal shift count"); + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0xC1); + emit_byte(0xE8 | encode); + emit_byte(imm8); +} + +void Assembler::shrl(Register dst) { + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0xD3); + emit_byte(0xE8 | encode); +} + +// copies a single word from [esi] to [edi] +void Assembler::smovl() { + emit_byte(0xA5); +} + +void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) { + // HMM Table D-1 says sse2 + // NOT_LP64(assert(VM_Version::supports_sse(), "")); + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF2); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x51); + emit_byte(0xC0 | encode); +} + +void Assembler::stmxcsr( Address dst) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + InstructionMark im(this); + prefix(dst); + emit_byte(0x0F); + emit_byte(0xAE); + emit_operand(as_Register(3), dst); +} + +void Assembler::subl(Address dst, int32_t imm32) { + InstructionMark im(this); + prefix(dst); + if (is8bit(imm32)) { + emit_byte(0x83); + emit_operand(rbp, dst, 1); + emit_byte(imm32 & 0xFF); + } else { + emit_byte(0x81); + emit_operand(rbp, dst, 4); + emit_long(imm32); + } +} + +void Assembler::subl(Register dst, int32_t imm32) { + prefix(dst); + emit_arith(0x81, 0xE8, dst, imm32); +} + +void Assembler::subl(Address dst, Register src) { + InstructionMark im(this); + prefix(dst, src); + emit_byte(0x29); + emit_operand(src, dst); +} + +void Assembler::subl(Register dst, Address src) { + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x2B); + emit_operand(dst, src); +} + +void Assembler::subl(Register dst, Register src) { + (void) prefix_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x2B, 0xC0, dst, src); +} + +void Assembler::subsd(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF2); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x5C); + emit_byte(0xC0 | encode); +} + +void Assembler::subsd(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0xF2); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x5C); + emit_operand(dst, src); +} + +void Assembler::subss(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + emit_byte(0xF3); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x5C); + emit_byte(0xC0 | encode); +} + +void Assembler::subss(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + InstructionMark im(this); + emit_byte(0xF3); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x5C); + emit_operand(dst, src); +} + +void Assembler::testb(Register dst, int imm8) { + NOT_LP64(assert(dst->has_byte_register(), "must have byte register")); + (void) prefix_and_encode(dst->encoding(), true); + emit_arith_b(0xF6, 0xC0, dst, imm8); +} + +void Assembler::testl(Register dst, int32_t imm32) { + // not using emit_arith because test + // doesn't support sign-extension of + // 8bit operands + int encode = dst->encoding(); + if (encode == 0) { + emit_byte(0xA9); + } else { + encode = prefix_and_encode(encode); + emit_byte(0xF7); + emit_byte(0xC0 | encode); + } + emit_long(imm32); +} + +void Assembler::testl(Register dst, Register src) { + (void) prefix_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x85, 0xC0, dst, src); +} + +void Assembler::testl(Register dst, Address src) { + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x85); + emit_operand(dst, src); +} + +void Assembler::ucomisd(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0x66); + ucomiss(dst, src); +} + +void Assembler::ucomisd(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0x66); + ucomiss(dst, src); +} + +void Assembler::ucomiss(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x2E); + emit_operand(dst, src); +} + +void Assembler::ucomiss(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x2E); + emit_byte(0xC0 | encode); +} + + +void Assembler::xaddl(Address dst, Register src) { + InstructionMark im(this); + prefix(dst, src); + emit_byte(0x0F); + emit_byte(0xC1); + emit_operand(src, dst); +} + +void Assembler::xchgl(Register dst, Address src) { // xchg + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x87); + emit_operand(dst, src); +} + +void Assembler::xchgl(Register dst, Register src) { + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x87); + emit_byte(0xc0 | encode); +} + +void Assembler::xorl(Register dst, int32_t imm32) { + prefix(dst); + emit_arith(0x81, 0xF0, dst, imm32); +} + +void Assembler::xorl(Register dst, Address src) { + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x33); + emit_operand(dst, src); +} + +void Assembler::xorl(Register dst, Register src) { + (void) prefix_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x33, 0xC0, dst, src); +} + +void Assembler::xorpd(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0x66); + xorps(dst, src); +} + +void Assembler::xorpd(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + emit_byte(0x66); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x57); + emit_operand(dst, src); +} + + +void Assembler::xorps(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + int encode = prefix_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x57); + emit_byte(0xC0 | encode); +} + +void Assembler::xorps(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + InstructionMark im(this); + prefix(src, dst); + emit_byte(0x0F); + emit_byte(0x57); + emit_operand(dst, src); +} + +#ifndef _LP64 +// 32bit only pieces of the assembler + +void Assembler::cmp_literal32(Register src1, int32_t imm32, RelocationHolder const& rspec) { + // NO PREFIX AS NEVER 64BIT + InstructionMark im(this); + emit_byte(0x81); + emit_byte(0xF8 | src1->encoding()); + emit_data(imm32, rspec, 0); +} + +void Assembler::cmp_literal32(Address src1, int32_t imm32, RelocationHolder const& rspec) { + // NO PREFIX AS NEVER 64BIT (not even 32bit versions of 64bit regs + InstructionMark im(this); + emit_byte(0x81); + emit_operand(rdi, src1); + emit_data(imm32, rspec, 0); +} + +// The 64-bit (32bit platform) cmpxchg compares the value at adr with the contents of rdx:rax, +// and stores rcx:rbx into adr if so; otherwise, the value at adr is loaded +// into rdx:rax. The ZF is set if the compared values were equal, and cleared otherwise. +void Assembler::cmpxchg8(Address adr) { + InstructionMark im(this); + emit_byte(0x0F); + emit_byte(0xc7); + emit_operand(rcx, adr); +} + +void Assembler::decl(Register dst) { + // Don't use it directly. Use MacroAssembler::decrementl() instead. + emit_byte(0x48 | dst->encoding()); +} + +#endif // _LP64 + +// 64bit typically doesn't use the x87 but needs to for the trig funcs + +void Assembler::fabs() { + emit_byte(0xD9); + emit_byte(0xE1); +} + +void Assembler::fadd(int i) { + emit_farith(0xD8, 0xC0, i); +} + +void Assembler::fadd_d(Address src) { + InstructionMark im(this); + emit_byte(0xDC); + emit_operand32(rax, src); +} + +void Assembler::fadd_s(Address src) { + InstructionMark im(this); + emit_byte(0xD8); + emit_operand32(rax, src); +} + +void Assembler::fadda(int i) { + emit_farith(0xDC, 0xC0, i); +} + +void Assembler::faddp(int i) { + emit_farith(0xDE, 0xC0, i); +} + +void Assembler::fchs() { + emit_byte(0xD9); + emit_byte(0xE0); +} + +void Assembler::fcom(int i) { + emit_farith(0xD8, 0xD0, i); +} + +void Assembler::fcomp(int i) { + emit_farith(0xD8, 0xD8, i); +} + +void Assembler::fcomp_d(Address src) { + InstructionMark im(this); + emit_byte(0xDC); + emit_operand32(rbx, src); +} + +void Assembler::fcomp_s(Address src) { + InstructionMark im(this); + emit_byte(0xD8); + emit_operand32(rbx, src); +} + +void Assembler::fcompp() { + emit_byte(0xDE); + emit_byte(0xD9); +} + +void Assembler::fcos() { + emit_byte(0xD9); + emit_byte(0xFF); +} + +void Assembler::fdecstp() { + emit_byte(0xD9); + emit_byte(0xF6); +} + +void Assembler::fdiv(int i) { + emit_farith(0xD8, 0xF0, i); +} + +void Assembler::fdiv_d(Address src) { + InstructionMark im(this); + emit_byte(0xDC); + emit_operand32(rsi, src); +} + +void Assembler::fdiv_s(Address src) { + InstructionMark im(this); + emit_byte(0xD8); + emit_operand32(rsi, src); +} + +void Assembler::fdiva(int i) { + emit_farith(0xDC, 0xF8, i); +} + +// Note: The Intel manual (Pentium Processor User's Manual, Vol.3, 1994) +// is erroneous for some of the floating-point instructions below. + +void Assembler::fdivp(int i) { + emit_farith(0xDE, 0xF8, i); // ST(0) <- ST(0) / ST(1) and pop (Intel manual wrong) +} + +void Assembler::fdivr(int i) { + emit_farith(0xD8, 0xF8, i); +} + +void Assembler::fdivr_d(Address src) { + InstructionMark im(this); + emit_byte(0xDC); + emit_operand32(rdi, src); +} + +void Assembler::fdivr_s(Address src) { + InstructionMark im(this); + emit_byte(0xD8); + emit_operand32(rdi, src); +} + +void Assembler::fdivra(int i) { + emit_farith(0xDC, 0xF0, i); +} + +void Assembler::fdivrp(int i) { + emit_farith(0xDE, 0xF0, i); // ST(0) <- ST(1) / ST(0) and pop (Intel manual wrong) +} + +void Assembler::ffree(int i) { + emit_farith(0xDD, 0xC0, i); +} + +void Assembler::fild_d(Address adr) { + InstructionMark im(this); + emit_byte(0xDF); + emit_operand32(rbp, adr); +} + +void Assembler::fild_s(Address adr) { + InstructionMark im(this); + emit_byte(0xDB); + emit_operand32(rax, adr); +} + +void Assembler::fincstp() { + emit_byte(0xD9); + emit_byte(0xF7); +} + +void Assembler::finit() { + emit_byte(0x9B); + emit_byte(0xDB); + emit_byte(0xE3); +} + +void Assembler::fist_s(Address adr) { + InstructionMark im(this); + emit_byte(0xDB); + emit_operand32(rdx, adr); +} + +void Assembler::fistp_d(Address adr) { + InstructionMark im(this); + emit_byte(0xDF); + emit_operand32(rdi, adr); +} + +void Assembler::fistp_s(Address adr) { + InstructionMark im(this); + emit_byte(0xDB); + emit_operand32(rbx, adr); +} + +void Assembler::fld1() { + emit_byte(0xD9); + emit_byte(0xE8); +} + +void Assembler::fld_d(Address adr) { + InstructionMark im(this); + emit_byte(0xDD); + emit_operand32(rax, adr); +} + +void Assembler::fld_s(Address adr) { + InstructionMark im(this); + emit_byte(0xD9); + emit_operand32(rax, adr); +} + + +void Assembler::fld_s(int index) { + emit_farith(0xD9, 0xC0, index); +} + +void Assembler::fld_x(Address adr) { + InstructionMark im(this); + emit_byte(0xDB); + emit_operand32(rbp, adr); +} + +void Assembler::fldcw(Address src) { + InstructionMark im(this); + emit_byte(0xd9); + emit_operand32(rbp, src); +} + +void Assembler::fldenv(Address src) { + InstructionMark im(this); + emit_byte(0xD9); + emit_operand32(rsp, src); +} + +void Assembler::fldlg2() { + emit_byte(0xD9); + emit_byte(0xEC); +} + +void Assembler::fldln2() { + emit_byte(0xD9); + emit_byte(0xED); +} + +void Assembler::fldz() { + emit_byte(0xD9); + emit_byte(0xEE); +} + +void Assembler::flog() { + fldln2(); + fxch(); + fyl2x(); +} + +void Assembler::flog10() { + fldlg2(); + fxch(); + fyl2x(); +} + +void Assembler::fmul(int i) { + emit_farith(0xD8, 0xC8, i); +} + +void Assembler::fmul_d(Address src) { + InstructionMark im(this); + emit_byte(0xDC); + emit_operand32(rcx, src); +} + +void Assembler::fmul_s(Address src) { + InstructionMark im(this); + emit_byte(0xD8); + emit_operand32(rcx, src); +} + +void Assembler::fmula(int i) { + emit_farith(0xDC, 0xC8, i); +} + +void Assembler::fmulp(int i) { + emit_farith(0xDE, 0xC8, i); +} + +void Assembler::fnsave(Address dst) { + InstructionMark im(this); + emit_byte(0xDD); + emit_operand32(rsi, dst); +} + +void Assembler::fnstcw(Address src) { + InstructionMark im(this); + emit_byte(0x9B); + emit_byte(0xD9); + emit_operand32(rdi, src); +} + +void Assembler::fnstsw_ax() { + emit_byte(0xdF); + emit_byte(0xE0); +} + +void Assembler::fprem() { + emit_byte(0xD9); + emit_byte(0xF8); +} + +void Assembler::fprem1() { + emit_byte(0xD9); + emit_byte(0xF5); +} + +void Assembler::frstor(Address src) { + InstructionMark im(this); + emit_byte(0xDD); + emit_operand32(rsp, src); +} + +void Assembler::fsin() { + emit_byte(0xD9); + emit_byte(0xFE); +} + +void Assembler::fsqrt() { + emit_byte(0xD9); + emit_byte(0xFA); +} + +void Assembler::fst_d(Address adr) { + InstructionMark im(this); + emit_byte(0xDD); + emit_operand32(rdx, adr); +} + +void Assembler::fst_s(Address adr) { + InstructionMark im(this); + emit_byte(0xD9); + emit_operand32(rdx, adr); +} + +void Assembler::fstp_d(Address adr) { + InstructionMark im(this); + emit_byte(0xDD); + emit_operand32(rbx, adr); +} + +void Assembler::fstp_d(int index) { + emit_farith(0xDD, 0xD8, index); +} + +void Assembler::fstp_s(Address adr) { + InstructionMark im(this); + emit_byte(0xD9); + emit_operand32(rbx, adr); +} + +void Assembler::fstp_x(Address adr) { + InstructionMark im(this); + emit_byte(0xDB); + emit_operand32(rdi, adr); +} + +void Assembler::fsub(int i) { + emit_farith(0xD8, 0xE0, i); +} + +void Assembler::fsub_d(Address src) { + InstructionMark im(this); + emit_byte(0xDC); + emit_operand32(rsp, src); +} + +void Assembler::fsub_s(Address src) { + InstructionMark im(this); + emit_byte(0xD8); + emit_operand32(rsp, src); +} + +void Assembler::fsuba(int i) { + emit_farith(0xDC, 0xE8, i); +} + +void Assembler::fsubp(int i) { + emit_farith(0xDE, 0xE8, i); // ST(0) <- ST(0) - ST(1) and pop (Intel manual wrong) +} + +void Assembler::fsubr(int i) { + emit_farith(0xD8, 0xE8, i); +} + +void Assembler::fsubr_d(Address src) { + InstructionMark im(this); + emit_byte(0xDC); + emit_operand32(rbp, src); +} + +void Assembler::fsubr_s(Address src) { + InstructionMark im(this); + emit_byte(0xD8); + emit_operand32(rbp, src); +} + +void Assembler::fsubra(int i) { + emit_farith(0xDC, 0xE0, i); +} + +void Assembler::fsubrp(int i) { + emit_farith(0xDE, 0xE0, i); // ST(0) <- ST(1) - ST(0) and pop (Intel manual wrong) +} + +void Assembler::ftan() { + emit_byte(0xD9); + emit_byte(0xF2); + emit_byte(0xDD); + emit_byte(0xD8); +} + +void Assembler::ftst() { + emit_byte(0xD9); + emit_byte(0xE4); +} + +void Assembler::fucomi(int i) { + // make sure the instruction is supported (introduced for P6, together with cmov) + guarantee(VM_Version::supports_cmov(), "illegal instruction"); + emit_farith(0xDB, 0xE8, i); +} + +void Assembler::fucomip(int i) { + // make sure the instruction is supported (introduced for P6, together with cmov) + guarantee(VM_Version::supports_cmov(), "illegal instruction"); + emit_farith(0xDF, 0xE8, i); +} + +void Assembler::fwait() { + emit_byte(0x9B); +} + +void Assembler::fxch(int i) { + emit_farith(0xD9, 0xC8, i); +} + +void Assembler::fyl2x() { + emit_byte(0xD9); + emit_byte(0xF1); +} + +void Assembler::mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec, int format) { + InstructionMark im(this); + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0xB8 | encode); + emit_data((int)imm32, rspec, format); +} + +#ifndef _LP64 + +void Assembler::incl(Register dst) { + // Don't use it directly. Use MacroAssembler::incrementl() instead. + emit_byte(0x40 | dst->encoding()); +} + +void Assembler::lea(Register dst, Address src) { + leal(dst, src); +} + +void Assembler::mov_literal32(Address dst, int32_t imm32, RelocationHolder const& rspec) { + InstructionMark im(this); + emit_byte(0xC7); + emit_operand(rax, dst); + emit_data((int)imm32, rspec, 0); +} + + +void Assembler::popa() { // 32bit + emit_byte(0x61); +} + +void Assembler::push_literal32(int32_t imm32, RelocationHolder const& rspec) { + InstructionMark im(this); + emit_byte(0x68); + emit_data(imm32, rspec, 0); +} + +void Assembler::pusha() { // 32bit + emit_byte(0x60); +} + +void Assembler::set_byte_if_not_zero(Register dst) { + emit_byte(0x0F); + emit_byte(0x95); + emit_byte(0xE0 | dst->encoding()); +} + +void Assembler::shldl(Register dst, Register src) { + emit_byte(0x0F); + emit_byte(0xA5); + emit_byte(0xC0 | src->encoding() << 3 | dst->encoding()); +} + +void Assembler::shrdl(Register dst, Register src) { + emit_byte(0x0F); + emit_byte(0xAD); + emit_byte(0xC0 | src->encoding() << 3 | dst->encoding()); +} + +#else // LP64 + +// 64bit only pieces of the assembler +// This should only be used by 64bit instructions that can use rip-relative +// it cannot be used by instructions that want an immediate value. + +bool Assembler::reachable(AddressLiteral adr) { + int64_t disp; + // None will force a 64bit literal to the code stream. Likely a placeholder + // for something that will be patched later and we need to certain it will + // always be reachable. + if (adr.reloc() == relocInfo::none) { + return false; + } + if (adr.reloc() == relocInfo::internal_word_type) { + // This should be rip relative and easily reachable. + return true; + } + if (adr.reloc() == relocInfo::virtual_call_type || + adr.reloc() == relocInfo::opt_virtual_call_type || + adr.reloc() == relocInfo::static_call_type || + adr.reloc() == relocInfo::static_stub_type ) { + // This should be rip relative within the code cache and easily + // reachable until we get huge code caches. (At which point + // ic code is going to have issues). + return true; + } + if (adr.reloc() != relocInfo::external_word_type && + adr.reloc() != relocInfo::poll_return_type && // these are really external_word but need special + adr.reloc() != relocInfo::poll_type && // relocs to identify them + adr.reloc() != relocInfo::runtime_call_type ) { + return false; + } + + // Stress the correction code + if (ForceUnreachable) { + // Must be runtimecall reloc, see if it is in the codecache + // Flipping stuff in the codecache to be unreachable causes issues + // with things like inline caches where the additional instructions + // are not handled. + if (CodeCache::find_blob(adr._target) == NULL) { + return false; + } + } + // For external_word_type/runtime_call_type if it is reachable from where we + // are now (possibly a temp buffer) and where we might end up + // anywhere in the codeCache then we are always reachable. + // This would have to change if we ever save/restore shared code + // to be more pessimistic. + + disp = (int64_t)adr._target - ((int64_t)CodeCache::low_bound() + sizeof(int)); + if (!is_simm32(disp)) return false; + disp = (int64_t)adr._target - ((int64_t)CodeCache::high_bound() + sizeof(int)); + if (!is_simm32(disp)) return false; + + disp = (int64_t)adr._target - ((int64_t)_code_pos + sizeof(int)); + + // Because rip relative is a disp + address_of_next_instruction and we + // don't know the value of address_of_next_instruction we apply a fudge factor + // to make sure we will be ok no matter the size of the instruction we get placed into. + // We don't have to fudge the checks above here because they are already worst case. + + // 12 == override/rex byte, opcode byte, rm byte, sib byte, a 4-byte disp , 4-byte literal + // + 4 because better safe than sorry. + const int fudge = 12 + 4; + if (disp < 0) { + disp -= fudge; + } else { + disp += fudge; + } + return is_simm32(disp); +} + +void Assembler::emit_data64(jlong data, + relocInfo::relocType rtype, + int format) { + if (rtype == relocInfo::none) { + emit_long64(data); + } else { + emit_data64(data, Relocation::spec_simple(rtype), format); + } +} + +void Assembler::emit_data64(jlong data, + RelocationHolder const& rspec, + int format) { + assert(imm_operand == 0, "default format must be immediate in this file"); + assert(imm_operand == format, "must be immediate"); + assert(inst_mark() != NULL, "must be inside InstructionMark"); + // Do not use AbstractAssembler::relocate, which is not intended for + // embedded words. Instead, relocate to the enclosing instruction. + code_section()->relocate(inst_mark(), rspec, format); +#ifdef ASSERT + check_relocation(rspec, format); +#endif + emit_long64(data); +} + +int Assembler::prefix_and_encode(int reg_enc, bool byteinst) { + if (reg_enc >= 8) { + prefix(REX_B); + reg_enc -= 8; + } else if (byteinst && reg_enc >= 4) { + prefix(REX); + } + return reg_enc; +} + +int Assembler::prefixq_and_encode(int reg_enc) { + if (reg_enc < 8) { + prefix(REX_W); + } else { + prefix(REX_WB); + reg_enc -= 8; + } + return reg_enc; +} + +int Assembler::prefix_and_encode(int dst_enc, int src_enc, bool byteinst) { + if (dst_enc < 8) { + if (src_enc >= 8) { + prefix(REX_B); + src_enc -= 8; + } else if (byteinst && src_enc >= 4) { + prefix(REX); + } + } else { + if (src_enc < 8) { + prefix(REX_R); + } else { + prefix(REX_RB); + src_enc -= 8; + } + dst_enc -= 8; + } + return dst_enc << 3 | src_enc; +} + +int Assembler::prefixq_and_encode(int dst_enc, int src_enc) { + if (dst_enc < 8) { + if (src_enc < 8) { + prefix(REX_W); + } else { + prefix(REX_WB); + src_enc -= 8; + } + } else { + if (src_enc < 8) { + prefix(REX_WR); + } else { + prefix(REX_WRB); + src_enc -= 8; + } + dst_enc -= 8; + } + return dst_enc << 3 | src_enc; +} + +void Assembler::prefix(Register reg) { + if (reg->encoding() >= 8) { + prefix(REX_B); + } +} + +void Assembler::prefix(Address adr) { + if (adr.base_needs_rex()) { + if (adr.index_needs_rex()) { + prefix(REX_XB); + } else { + prefix(REX_B); + } + } else { + if (adr.index_needs_rex()) { + prefix(REX_X); + } + } +} + +void Assembler::prefixq(Address adr) { + if (adr.base_needs_rex()) { + if (adr.index_needs_rex()) { + prefix(REX_WXB); + } else { + prefix(REX_WB); + } + } else { + if (adr.index_needs_rex()) { + prefix(REX_WX); + } else { + prefix(REX_W); + } + } +} + + +void Assembler::prefix(Address adr, Register reg, bool byteinst) { + if (reg->encoding() < 8) { + if (adr.base_needs_rex()) { + if (adr.index_needs_rex()) { + prefix(REX_XB); + } else { + prefix(REX_B); + } + } else { + if (adr.index_needs_rex()) { + prefix(REX_X); + } else if (reg->encoding() >= 4 ) { + prefix(REX); + } + } + } else { + if (adr.base_needs_rex()) { + if (adr.index_needs_rex()) { + prefix(REX_RXB); + } else { + prefix(REX_RB); + } + } else { + if (adr.index_needs_rex()) { + prefix(REX_RX); + } else { + prefix(REX_R); + } + } + } +} + +void Assembler::prefixq(Address adr, Register src) { + if (src->encoding() < 8) { + if (adr.base_needs_rex()) { + if (adr.index_needs_rex()) { + prefix(REX_WXB); + } else { + prefix(REX_WB); + } + } else { + if (adr.index_needs_rex()) { + prefix(REX_WX); + } else { + prefix(REX_W); + } + } + } else { + if (adr.base_needs_rex()) { + if (adr.index_needs_rex()) { + prefix(REX_WRXB); + } else { + prefix(REX_WRB); + } + } else { + if (adr.index_needs_rex()) { + prefix(REX_WRX); + } else { + prefix(REX_WR); + } + } + } +} + +void Assembler::prefix(Address adr, XMMRegister reg) { + if (reg->encoding() < 8) { + if (adr.base_needs_rex()) { + if (adr.index_needs_rex()) { + prefix(REX_XB); + } else { + prefix(REX_B); + } + } else { + if (adr.index_needs_rex()) { + prefix(REX_X); + } + } + } else { + if (adr.base_needs_rex()) { + if (adr.index_needs_rex()) { + prefix(REX_RXB); + } else { + prefix(REX_RB); + } + } else { + if (adr.index_needs_rex()) { + prefix(REX_RX); + } else { + prefix(REX_R); + } + } + } +} + +void Assembler::adcq(Register dst, int32_t imm32) { + (void) prefixq_and_encode(dst->encoding()); + emit_arith(0x81, 0xD0, dst, imm32); +} + +void Assembler::adcq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x13); + emit_operand(dst, src); +} + +void Assembler::adcq(Register dst, Register src) { + (int) prefixq_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x13, 0xC0, dst, src); +} + +void Assembler::addq(Address dst, int32_t imm32) { + InstructionMark im(this); + prefixq(dst); + emit_arith_operand(0x81, rax, dst,imm32); +} + +void Assembler::addq(Address dst, Register src) { + InstructionMark im(this); + prefixq(dst, src); + emit_byte(0x01); + emit_operand(src, dst); +} + +void Assembler::addq(Register dst, int32_t imm32) { + (void) prefixq_and_encode(dst->encoding()); + emit_arith(0x81, 0xC0, dst, imm32); +} + +void Assembler::addq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x03); + emit_operand(dst, src); +} + +void Assembler::addq(Register dst, Register src) { + (void) prefixq_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x03, 0xC0, dst, src); +} + +void Assembler::andq(Register dst, int32_t imm32) { + (void) prefixq_and_encode(dst->encoding()); + emit_arith(0x81, 0xE0, dst, imm32); +} + +void Assembler::andq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x23); + emit_operand(dst, src); +} + +void Assembler::andq(Register dst, Register src) { + (int) prefixq_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x23, 0xC0, dst, src); +} + +void Assembler::bswapq(Register reg) { + int encode = prefixq_and_encode(reg->encoding()); + emit_byte(0x0F); + emit_byte(0xC8 | encode); +} + +void Assembler::cdqq() { + prefix(REX_W); + emit_byte(0x99); +} + void Assembler::clflush(Address adr) { prefix(adr); emit_byte(0x0F); @@ -2925,185 +3614,119 @@ void Assembler::clflush(Address adr) { emit_operand(rdi, adr); } -void Assembler::call(Label& L, relocInfo::relocType rtype) { - if (L.is_bound()) { - const int long_size = 5; - int offs = (int)( target(L) - pc() ); - assert(offs <= 0, "assembler error"); - InstructionMark im(this); - // 1110 1000 #32-bit disp - emit_byte(0xE8); - emit_data(offs - long_size, rtype, disp32_operand); - } else { - InstructionMark im(this); - // 1110 1000 #32-bit disp - L.add_patch_at(code(), locator()); - - emit_byte(0xE8); - emit_data(int(0), rtype, disp32_operand); - } +void Assembler::cmovq(Condition cc, Register dst, Register src) { + int encode = prefixq_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x40 | cc); + emit_byte(0xC0 | encode); } -void Assembler::call_literal(address entry, RelocationHolder const& rspec) { - assert(entry != NULL, "call most probably wrong"); +void Assembler::cmovq(Condition cc, Register dst, Address src) { InstructionMark im(this); - emit_byte(0xE8); - intptr_t disp = entry - (_code_pos + sizeof(int32_t)); - assert(is_simm32(disp), "must be 32bit offset (call2)"); - // Technically, should use call32_operand, but this format is - // implied by the fact that we're emitting a call instruction. - emit_data((int) disp, rspec, disp32_operand); + prefixq(src, dst); + emit_byte(0x0F); + emit_byte(0x40 | cc); + emit_operand(dst, src); } +void Assembler::cmpq(Address dst, int32_t imm32) { + InstructionMark im(this); + prefixq(dst); + emit_byte(0x81); + emit_operand(rdi, dst, 4); + emit_long(imm32); +} -void Assembler::call(Register dst) { - // This was originally using a 32bit register encoding - // and surely we want 64bit! - // this is a 32bit encoding but in 64bit mode the default - // operand size is 64bit so there is no need for the - // wide prefix. So prefix only happens if we use the - // new registers. Much like push/pop. +void Assembler::cmpq(Register dst, int32_t imm32) { + (void) prefixq_and_encode(dst->encoding()); + emit_arith(0x81, 0xF8, dst, imm32); +} + +void Assembler::cmpq(Address dst, Register src) { + InstructionMark im(this); + prefixq(dst, src); + emit_byte(0x3B); + emit_operand(src, dst); +} + +void Assembler::cmpq(Register dst, Register src) { + (void) prefixq_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x3B, 0xC0, dst, src); +} + +void Assembler::cmpq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x3B); + emit_operand(dst, src); +} + +void Assembler::cmpxchgq(Register reg, Address adr) { + InstructionMark im(this); + prefixq(adr, reg); + emit_byte(0x0F); + emit_byte(0xB1); + emit_operand(reg, adr); +} + +void Assembler::cvtsi2sdq(XMMRegister dst, Register src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF2); + int encode = prefixq_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x2A); + emit_byte(0xC0 | encode); +} + +void Assembler::cvtsi2ssq(XMMRegister dst, Register src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + emit_byte(0xF3); + int encode = prefixq_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x2A); + emit_byte(0xC0 | encode); +} + +void Assembler::cvttsd2siq(Register dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_byte(0xF2); + int encode = prefixq_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x2C); + emit_byte(0xC0 | encode); +} + +void Assembler::cvttss2siq(Register dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + emit_byte(0xF3); + int encode = prefixq_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x0F); + emit_byte(0x2C); + emit_byte(0xC0 | encode); +} + +void Assembler::decl(Register dst) { + // Don't use it directly. Use MacroAssembler::decrementl() instead. + // Use two-byte form (one-byte form is a REX prefix in 64-bit mode) + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0xFF); + emit_byte(0xC8 | encode); +} + +void Assembler::decq(Register dst) { + // Don't use it directly. Use MacroAssembler::decrementq() instead. + // Use two-byte form (one-byte from is a REX prefix in 64-bit mode) int encode = prefixq_and_encode(dst->encoding()); emit_byte(0xFF); - emit_byte(0xD0 | encode); + emit_byte(0xC8 | encode); } -void Assembler::call(Address adr) { +void Assembler::decq(Address dst) { + // Don't use it directly. Use MacroAssembler::decrementq() instead. InstructionMark im(this); - prefix(adr); - emit_byte(0xFF); - emit_operand(rdx, adr); -} - -void Assembler::jmp(Register reg) { - int encode = prefix_and_encode(reg->encoding()); - emit_byte(0xFF); - emit_byte(0xE0 | encode); -} - -void Assembler::jmp(Address adr) { - InstructionMark im(this); - prefix(adr); - emit_byte(0xFF); - emit_operand(rsp, adr); -} - -void Assembler::jmp_literal(address dest, RelocationHolder const& rspec) { - InstructionMark im(this); - emit_byte(0xE9); - assert(dest != NULL, "must have a target"); - intptr_t disp = dest - (_code_pos + sizeof(int32_t)); - assert(is_simm32(disp), "must be 32bit offset (jmp)"); - emit_data(disp, rspec.reloc(), call32_operand); -} - -void Assembler::jmp(Label& L, relocInfo::relocType rtype) { - if (L.is_bound()) { - address entry = target(L); - assert(entry != NULL, "jmp most probably wrong"); - InstructionMark im(this); - const int short_size = 2; - const int long_size = 5; - intptr_t offs = entry - _code_pos; - if (rtype == relocInfo::none && is8bit(offs - short_size)) { - emit_byte(0xEB); - emit_byte((offs - short_size) & 0xFF); - } else { - emit_byte(0xE9); - emit_long(offs - long_size); - } - } else { - // By default, forward jumps are always 32-bit displacements, since - // we can't yet know where the label will be bound. If you're sure that - // the forward jump will not run beyond 256 bytes, use jmpb to - // force an 8-bit displacement. - InstructionMark im(this); - relocate(rtype); - L.add_patch_at(code(), locator()); - emit_byte(0xE9); - emit_long(0); - } -} - -void Assembler::jmpb(Label& L) { - if (L.is_bound()) { - const int short_size = 2; - address entry = target(L); - assert(is8bit((entry - _code_pos) + short_size), - "Dispacement too large for a short jmp"); - assert(entry != NULL, "jmp most probably wrong"); - intptr_t offs = entry - _code_pos; - emit_byte(0xEB); - emit_byte((offs - short_size) & 0xFF); - } else { - InstructionMark im(this); - L.add_patch_at(code(), locator()); - emit_byte(0xEB); - emit_byte(0); - } -} - -void Assembler::jcc(Condition cc, Label& L, relocInfo::relocType rtype) { - InstructionMark im(this); - relocate(rtype); - assert((0 <= cc) && (cc < 16), "illegal cc"); - if (L.is_bound()) { - address dst = target(L); - assert(dst != NULL, "jcc most probably wrong"); - - const int short_size = 2; - const int long_size = 6; - intptr_t offs = (intptr_t)dst - (intptr_t)_code_pos; - if (rtype == relocInfo::none && is8bit(offs - short_size)) { - // 0111 tttn #8-bit disp - emit_byte(0x70 | cc); - emit_byte((offs - short_size) & 0xFF); - } else { - // 0000 1111 1000 tttn #32-bit disp - assert(is_simm32(offs - long_size), - "must be 32bit offset (call4)"); - emit_byte(0x0F); - emit_byte(0x80 | cc); - emit_long(offs - long_size); - } - } else { - // Note: could eliminate cond. jumps to this jump if condition - // is the same however, seems to be rather unlikely case. - // Note: use jccb() if label to be bound is very close to get - // an 8-bit displacement - L.add_patch_at(code(), locator()); - emit_byte(0x0F); - emit_byte(0x80 | cc); - emit_long(0); - } -} - -void Assembler::jccb(Condition cc, Label& L) { - if (L.is_bound()) { - const int short_size = 2; - const int long_size = 6; - address entry = target(L); - assert(is8bit((intptr_t)entry - ((intptr_t)_code_pos + short_size)), - "Dispacement too large for a short jmp"); - intptr_t offs = (intptr_t)entry - (intptr_t)_code_pos; - // 0111 tttn #8-bit disp - emit_byte(0x70 | cc); - emit_byte((offs - short_size) & 0xFF); - } else { - InstructionMark im(this); - L.add_patch_at(code(), locator()); - emit_byte(0x70 | cc); - emit_byte(0); - } -} - -// FP instructions - -void Assembler::fxsave(Address dst) { prefixq(dst); - emit_byte(0x0F); - emit_byte(0xAE); - emit_operand(as_Register(0), dst); + emit_byte(0xFF); + emit_operand(rcx, dst); } void Assembler::fxrstor(Address src) { @@ -3113,167 +3736,347 @@ void Assembler::fxrstor(Address src) { emit_operand(as_Register(1), src); } -void Assembler::ldmxcsr(Address src) { - InstructionMark im(this); - prefix(src); +void Assembler::fxsave(Address dst) { + prefixq(dst); emit_byte(0x0F); emit_byte(0xAE); - emit_operand(as_Register(2), src); + emit_operand(as_Register(0), dst); } -void Assembler::stmxcsr(Address dst) { - InstructionMark im(this); - prefix(dst); - emit_byte(0x0F); - emit_byte(0xAE); - emit_operand(as_Register(3), dst); +void Assembler::idivq(Register src) { + int encode = prefixq_and_encode(src->encoding()); + emit_byte(0xF7); + emit_byte(0xF8 | encode); } -void Assembler::addss(XMMRegister dst, XMMRegister src) { - emit_byte(0xF3); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); +void Assembler::imulq(Register dst, Register src) { + int encode = prefixq_and_encode(dst->encoding(), src->encoding()); emit_byte(0x0F); - emit_byte(0x58); + emit_byte(0xAF); emit_byte(0xC0 | encode); } -void Assembler::addss(XMMRegister dst, Address src) { +void Assembler::imulq(Register dst, Register src, int value) { + int encode = prefixq_and_encode(dst->encoding(), src->encoding()); + if (is8bit(value)) { + emit_byte(0x6B); + emit_byte(0xC0 | encode); + emit_byte(value); + } else { + emit_byte(0x69); + emit_byte(0xC0 | encode); + emit_long(value); + } +} + +void Assembler::incl(Register dst) { + // Don't use it directly. Use MacroAssembler::incrementl() instead. + // Use two-byte form (one-byte from is a REX prefix in 64-bit mode) + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0xFF); + emit_byte(0xC0 | encode); +} + +void Assembler::incq(Register dst) { + // Don't use it directly. Use MacroAssembler::incrementq() instead. + // Use two-byte form (one-byte from is a REX prefix in 64-bit mode) + int encode = prefixq_and_encode(dst->encoding()); + emit_byte(0xFF); + emit_byte(0xC0 | encode); +} + +void Assembler::incq(Address dst) { + // Don't use it directly. Use MacroAssembler::incrementq() instead. InstructionMark im(this); - emit_byte(0xF3); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x58); + prefixq(dst); + emit_byte(0xFF); + emit_operand(rax, dst); +} + +void Assembler::lea(Register dst, Address src) { + leaq(dst, src); +} + +void Assembler::leaq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x8D); emit_operand(dst, src); } -void Assembler::subss(XMMRegister dst, XMMRegister src) { - emit_byte(0xF3); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); +void Assembler::mov64(Register dst, int64_t imm64) { + InstructionMark im(this); + int encode = prefixq_and_encode(dst->encoding()); + emit_byte(0xB8 | encode); + emit_long64(imm64); +} + +void Assembler::mov_literal64(Register dst, intptr_t imm64, RelocationHolder const& rspec) { + InstructionMark im(this); + int encode = prefixq_and_encode(dst->encoding()); + emit_byte(0xB8 | encode); + emit_data64(imm64, rspec); +} + +void Assembler::movdq(XMMRegister dst, Register src) { + // table D-1 says MMX/SSE2 + NOT_LP64(assert(VM_Version::supports_sse2() || VM_Version::supports_mmx(), "")); + emit_byte(0x66); + int encode = prefixq_and_encode(dst->encoding(), src->encoding()); emit_byte(0x0F); - emit_byte(0x5C); + emit_byte(0x6E); emit_byte(0xC0 | encode); } -void Assembler::subss(XMMRegister dst, Address src) { - InstructionMark im(this); - emit_byte(0xF3); - prefix(src, dst); +void Assembler::movdq(Register dst, XMMRegister src) { + // table D-1 says MMX/SSE2 + NOT_LP64(assert(VM_Version::supports_sse2() || VM_Version::supports_mmx(), "")); + emit_byte(0x66); + // swap src/dst to get correct prefix + int encode = prefixq_and_encode(src->encoding(), dst->encoding()); emit_byte(0x0F); - emit_byte(0x5C); + emit_byte(0x7E); + emit_byte(0xC0 | encode); +} + +void Assembler::movq(Register dst, Register src) { + int encode = prefixq_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x8B); + emit_byte(0xC0 | encode); +} + +void Assembler::movq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x8B); emit_operand(dst, src); } -void Assembler::mulss(XMMRegister dst, XMMRegister src) { - emit_byte(0xF3); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x59); - emit_byte(0xC0 | encode); +void Assembler::movq(Address dst, Register src) { + InstructionMark im(this); + prefixq(dst, src); + emit_byte(0x89); + emit_operand(src, dst); } -void Assembler::mulss(XMMRegister dst, Address src) { +void Assembler::movslq(Register dst, int32_t imm32) { + // dbx shows movslq(rcx, 3) as movq $0x0000000049000000,(%rbx) + // and movslq(r8, 3); as movl $0x0000000048000000,(%rbx) + // as a result we shouldn't use until tested at runtime... + ShouldNotReachHere(); InstructionMark im(this); - emit_byte(0xF3); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x59); + int encode = prefixq_and_encode(dst->encoding()); + emit_byte(0xC7 | encode); + emit_long(imm32); +} + +void Assembler::movslq(Address dst, int32_t imm32) { + assert(is_simm32(imm32), "lost bits"); + InstructionMark im(this); + prefixq(dst); + emit_byte(0xC7); + emit_operand(rax, dst, 4); + emit_long(imm32); +} + +void Assembler::movslq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x63); emit_operand(dst, src); } -void Assembler::divss(XMMRegister dst, XMMRegister src) { - emit_byte(0xF3); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x5E); +void Assembler::movslq(Register dst, Register src) { + int encode = prefixq_and_encode(dst->encoding(), src->encoding()); + emit_byte(0x63); emit_byte(0xC0 | encode); } -void Assembler::divss(XMMRegister dst, Address src) { +void Assembler::negq(Register dst) { + int encode = prefixq_and_encode(dst->encoding()); + emit_byte(0xF7); + emit_byte(0xD8 | encode); +} + +void Assembler::notq(Register dst) { + int encode = prefixq_and_encode(dst->encoding()); + emit_byte(0xF7); + emit_byte(0xD0 | encode); +} + +void Assembler::orq(Address dst, int32_t imm32) { InstructionMark im(this); - emit_byte(0xF3); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x5E); + prefixq(dst); + emit_byte(0x81); + emit_operand(rcx, dst, 4); + emit_long(imm32); +} + +void Assembler::orq(Register dst, int32_t imm32) { + (void) prefixq_and_encode(dst->encoding()); + emit_arith(0x81, 0xC8, dst, imm32); +} + +void Assembler::orq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x0B); emit_operand(dst, src); } -void Assembler::addsd(XMMRegister dst, XMMRegister src) { - emit_byte(0xF2); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x58); - emit_byte(0xC0 | encode); +void Assembler::orq(Register dst, Register src) { + (void) prefixq_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x0B, 0xC0, dst, src); } -void Assembler::addsd(XMMRegister dst, Address src) { +void Assembler::popa() { // 64bit + movq(r15, Address(rsp, 0)); + movq(r14, Address(rsp, wordSize)); + movq(r13, Address(rsp, 2 * wordSize)); + movq(r12, Address(rsp, 3 * wordSize)); + movq(r11, Address(rsp, 4 * wordSize)); + movq(r10, Address(rsp, 5 * wordSize)); + movq(r9, Address(rsp, 6 * wordSize)); + movq(r8, Address(rsp, 7 * wordSize)); + movq(rdi, Address(rsp, 8 * wordSize)); + movq(rsi, Address(rsp, 9 * wordSize)); + movq(rbp, Address(rsp, 10 * wordSize)); + // skip rsp + movq(rbx, Address(rsp, 12 * wordSize)); + movq(rdx, Address(rsp, 13 * wordSize)); + movq(rcx, Address(rsp, 14 * wordSize)); + movq(rax, Address(rsp, 15 * wordSize)); + + addq(rsp, 16 * wordSize); +} + +void Assembler::popq(Address dst) { InstructionMark im(this); - emit_byte(0xF2); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x58); + prefixq(dst); + emit_byte(0x8F); + emit_operand(rax, dst); +} + +void Assembler::pusha() { // 64bit + // we have to store original rsp. ABI says that 128 bytes + // below rsp are local scratch. + movq(Address(rsp, -5 * wordSize), rsp); + + subq(rsp, 16 * wordSize); + + movq(Address(rsp, 15 * wordSize), rax); + movq(Address(rsp, 14 * wordSize), rcx); + movq(Address(rsp, 13 * wordSize), rdx); + movq(Address(rsp, 12 * wordSize), rbx); + // skip rsp + movq(Address(rsp, 10 * wordSize), rbp); + movq(Address(rsp, 9 * wordSize), rsi); + movq(Address(rsp, 8 * wordSize), rdi); + movq(Address(rsp, 7 * wordSize), r8); + movq(Address(rsp, 6 * wordSize), r9); + movq(Address(rsp, 5 * wordSize), r10); + movq(Address(rsp, 4 * wordSize), r11); + movq(Address(rsp, 3 * wordSize), r12); + movq(Address(rsp, 2 * wordSize), r13); + movq(Address(rsp, wordSize), r14); + movq(Address(rsp, 0), r15); +} + +void Assembler::pushq(Address src) { + InstructionMark im(this); + prefixq(src); + emit_byte(0xFF); + emit_operand(rsi, src); +} + +void Assembler::rclq(Register dst, int imm8) { + assert(isShiftCount(imm8 >> 1), "illegal shift count"); + int encode = prefixq_and_encode(dst->encoding()); + if (imm8 == 1) { + emit_byte(0xD1); + emit_byte(0xD0 | encode); + } else { + emit_byte(0xC1); + emit_byte(0xD0 | encode); + emit_byte(imm8); + } +} +void Assembler::sarq(Register dst, int imm8) { + assert(isShiftCount(imm8 >> 1), "illegal shift count"); + int encode = prefixq_and_encode(dst->encoding()); + if (imm8 == 1) { + emit_byte(0xD1); + emit_byte(0xF8 | encode); + } else { + emit_byte(0xC1); + emit_byte(0xF8 | encode); + emit_byte(imm8); + } +} + +void Assembler::sarq(Register dst) { + int encode = prefixq_and_encode(dst->encoding()); + emit_byte(0xD3); + emit_byte(0xF8 | encode); +} +void Assembler::sbbq(Address dst, int32_t imm32) { + InstructionMark im(this); + prefixq(dst); + emit_arith_operand(0x81, rbx, dst, imm32); +} + +void Assembler::sbbq(Register dst, int32_t imm32) { + (void) prefixq_and_encode(dst->encoding()); + emit_arith(0x81, 0xD8, dst, imm32); +} + +void Assembler::sbbq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x1B); emit_operand(dst, src); } -void Assembler::subsd(XMMRegister dst, XMMRegister src) { - emit_byte(0xF2); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x5C); - emit_byte(0xC0 | encode); +void Assembler::sbbq(Register dst, Register src) { + (void) prefixq_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x1B, 0xC0, dst, src); } -void Assembler::subsd(XMMRegister dst, Address src) { - InstructionMark im(this); - emit_byte(0xF2); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x5C); - emit_operand(dst, src); +void Assembler::shlq(Register dst, int imm8) { + assert(isShiftCount(imm8 >> 1), "illegal shift count"); + int encode = prefixq_and_encode(dst->encoding()); + if (imm8 == 1) { + emit_byte(0xD1); + emit_byte(0xE0 | encode); + } else { + emit_byte(0xC1); + emit_byte(0xE0 | encode); + emit_byte(imm8); + } } -void Assembler::mulsd(XMMRegister dst, XMMRegister src) { - emit_byte(0xF2); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x59); - emit_byte(0xC0 | encode); +void Assembler::shlq(Register dst) { + int encode = prefixq_and_encode(dst->encoding()); + emit_byte(0xD3); + emit_byte(0xE0 | encode); } -void Assembler::mulsd(XMMRegister dst, Address src) { - InstructionMark im(this); - emit_byte(0xF2); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x59); - emit_operand(dst, src); +void Assembler::shrq(Register dst, int imm8) { + assert(isShiftCount(imm8 >> 1), "illegal shift count"); + int encode = prefixq_and_encode(dst->encoding()); + emit_byte(0xC1); + emit_byte(0xE8 | encode); + emit_byte(imm8); } -void Assembler::divsd(XMMRegister dst, XMMRegister src) { - emit_byte(0xF2); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x5E); - emit_byte(0xC0 | encode); -} - -void Assembler::divsd(XMMRegister dst, Address src) { - InstructionMark im(this); - emit_byte(0xF2); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x5E); - emit_operand(dst, src); -} - -void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) { - emit_byte(0xF2); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x51); - emit_byte(0xC0 | encode); +void Assembler::shrq(Register dst) { + int encode = prefixq_and_encode(dst->encoding()); + emit_byte(0xD3); + emit_byte(0xE8 | encode); } void Assembler::sqrtsd(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); InstructionMark im(this); emit_byte(0xF2); prefix(src, dst); @@ -3282,171 +4085,99 @@ void Assembler::sqrtsd(XMMRegister dst, Address src) { emit_operand(dst, src); } -void Assembler::xorps(XMMRegister dst, XMMRegister src) { - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x57); - emit_byte(0xC0 | encode); +void Assembler::subq(Address dst, int32_t imm32) { + InstructionMark im(this); + prefixq(dst); + if (is8bit(imm32)) { + emit_byte(0x83); + emit_operand(rbp, dst, 1); + emit_byte(imm32 & 0xFF); + } else { + emit_byte(0x81); + emit_operand(rbp, dst, 4); + emit_long(imm32); + } } -void Assembler::xorps(XMMRegister dst, Address src) { +void Assembler::subq(Register dst, int32_t imm32) { + (void) prefixq_and_encode(dst->encoding()); + emit_arith(0x81, 0xE8, dst, imm32); +} + +void Assembler::subq(Address dst, Register src) { InstructionMark im(this); - prefix(src, dst); - emit_byte(0x0F); - emit_byte(0x57); + prefixq(dst, src); + emit_byte(0x29); + emit_operand(src, dst); +} + +void Assembler::subq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x2B); emit_operand(dst, src); } -void Assembler::xorpd(XMMRegister dst, XMMRegister src) { - emit_byte(0x66); - xorps(dst, src); +void Assembler::subq(Register dst, Register src) { + (void) prefixq_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x2B, 0xC0, dst, src); } -void Assembler::xorpd(XMMRegister dst, Address src) { +void Assembler::testq(Register dst, int32_t imm32) { + // not using emit_arith because test + // doesn't support sign-extension of + // 8bit operands + int encode = dst->encoding(); + if (encode == 0) { + prefix(REX_W); + emit_byte(0xA9); + } else { + encode = prefixq_and_encode(encode); + emit_byte(0xF7); + emit_byte(0xC0 | encode); + } + emit_long(imm32); +} + +void Assembler::testq(Register dst, Register src) { + (void) prefixq_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x85, 0xC0, dst, src); +} + +void Assembler::xaddq(Address dst, Register src) { InstructionMark im(this); - emit_byte(0x66); - prefix(src, dst); + prefixq(dst, src); emit_byte(0x0F); - emit_byte(0x57); + emit_byte(0xC1); + emit_operand(src, dst); +} + +void Assembler::xchgq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x87); emit_operand(dst, src); } -void Assembler::cvtsi2ssl(XMMRegister dst, Register src) { - emit_byte(0xF3); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x2A); - emit_byte(0xC0 | encode); -} - -void Assembler::cvtsi2ssq(XMMRegister dst, Register src) { - emit_byte(0xF3); +void Assembler::xchgq(Register dst, Register src) { int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x2A); - emit_byte(0xC0 | encode); + emit_byte(0x87); + emit_byte(0xc0 | encode); } -void Assembler::cvtsi2sdl(XMMRegister dst, Register src) { - emit_byte(0xF2); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x2A); - emit_byte(0xC0 | encode); +void Assembler::xorq(Register dst, Register src) { + (void) prefixq_and_encode(dst->encoding(), src->encoding()); + emit_arith(0x33, 0xC0, dst, src); } -void Assembler::cvtsi2sdq(XMMRegister dst, Register src) { - emit_byte(0xF2); - int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x2A); - emit_byte(0xC0 | encode); +void Assembler::xorq(Register dst, Address src) { + InstructionMark im(this); + prefixq(src, dst); + emit_byte(0x33); + emit_operand(dst, src); } -void Assembler::cvttss2sil(Register dst, XMMRegister src) { - emit_byte(0xF3); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x2C); - emit_byte(0xC0 | encode); -} - -void Assembler::cvttss2siq(Register dst, XMMRegister src) { - emit_byte(0xF3); - int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x2C); - emit_byte(0xC0 | encode); -} - -void Assembler::cvttsd2sil(Register dst, XMMRegister src) { - emit_byte(0xF2); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x2C); - emit_byte(0xC0 | encode); -} - -void Assembler::cvttsd2siq(Register dst, XMMRegister src) { - emit_byte(0xF2); - int encode = prefixq_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x2C); - emit_byte(0xC0 | encode); -} - -void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) { - emit_byte(0xF3); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x5A); - emit_byte(0xC0 | encode); -} - -void Assembler::cvtdq2pd(XMMRegister dst, XMMRegister src) { - emit_byte(0xF3); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0xE6); - emit_byte(0xC0 | encode); -} - -void Assembler::cvtdq2ps(XMMRegister dst, XMMRegister src) { - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x5B); - emit_byte(0xC0 | encode); -} - -void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) { - emit_byte(0xF2); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x5A); - emit_byte(0xC0 | encode); -} - -void Assembler::punpcklbw(XMMRegister dst, XMMRegister src) { - emit_byte(0x66); - int encode = prefix_and_encode(dst->encoding(), src->encoding()); - emit_byte(0x0F); - emit_byte(0x60); - emit_byte(0xC0 | encode); -} - -// Implementation of MacroAssembler - -// On 32 bit it returns a vanilla displacement on 64 bit is a rip relative displacement -Address MacroAssembler::as_Address(AddressLiteral adr) { - assert(!adr.is_lval(), "must be rval"); - assert(reachable(adr), "must be"); - return Address((int)(intptr_t)(adr.target() - pc()), adr.target(), adr.reloc()); -} - -Address MacroAssembler::as_Address(ArrayAddress adr) { -#ifdef _LP64 - AddressLiteral base = adr.base(); - lea(rscratch1, base); - Address index = adr.index(); - assert(index._disp == 0, "must not have disp"); // maybe it can? - Address array(rscratch1, index._index, index._scale, index._disp); - return array; -#else - return Address::make_array(adr); -#endif // _LP64 - -} - -void MacroAssembler::fat_nop() { - // A 5 byte nop that is safe for patching (see patch_verified_entry) - // Recommened sequence from 'Software Optimization Guide for the AMD - // Hammer Processor' - emit_byte(0x66); - emit_byte(0x66); - emit_byte(0x90); - emit_byte(0x66); - emit_byte(0x90); -} +#endif // !LP64 static Assembler::Condition reverse[] = { Assembler::noOverflow /* overflow = 0x0 */ , @@ -3468,1515 +4199,613 @@ static Assembler::Condition reverse[] = { }; + +// Implementation of MacroAssembler + +// First all the versions that have distinct versions depending on 32/64 bit +// Unless the difference is trivial (1 line or so). + +#ifndef _LP64 + +// 32bit versions + +Address MacroAssembler::as_Address(AddressLiteral adr) { + return Address(adr.target(), adr.rspec()); +} + +Address MacroAssembler::as_Address(ArrayAddress adr) { + return Address::make_array(adr); +} + +int MacroAssembler::biased_locking_enter(Register lock_reg, + Register obj_reg, + Register swap_reg, + Register tmp_reg, + bool swap_reg_contains_mark, + Label& done, + Label* slow_case, + BiasedLockingCounters* counters) { + assert(UseBiasedLocking, "why call this otherwise?"); + assert(swap_reg == rax, "swap_reg must be rax, for cmpxchg"); + assert_different_registers(lock_reg, obj_reg, swap_reg); + + if (PrintBiasedLockingStatistics && counters == NULL) + counters = BiasedLocking::counters(); + + bool need_tmp_reg = false; + if (tmp_reg == noreg) { + need_tmp_reg = true; + tmp_reg = lock_reg; + } else { + assert_different_registers(lock_reg, obj_reg, swap_reg, tmp_reg); + } + assert(markOopDesc::age_shift == markOopDesc::lock_bits + markOopDesc::biased_lock_bits, "biased locking makes assumptions about bit layout"); + Address mark_addr (obj_reg, oopDesc::mark_offset_in_bytes()); + Address klass_addr (obj_reg, oopDesc::klass_offset_in_bytes()); + Address saved_mark_addr(lock_reg, 0); + + // Biased locking + // See whether the lock is currently biased toward our thread and + // whether the epoch is still valid + // Note that the runtime guarantees sufficient alignment of JavaThread + // pointers to allow age to be placed into low bits + // First check to see whether biasing is even enabled for this object + Label cas_label; + int null_check_offset = -1; + if (!swap_reg_contains_mark) { + null_check_offset = offset(); + movl(swap_reg, mark_addr); + } + if (need_tmp_reg) { + push(tmp_reg); + } + movl(tmp_reg, swap_reg); + andl(tmp_reg, markOopDesc::biased_lock_mask_in_place); + cmpl(tmp_reg, markOopDesc::biased_lock_pattern); + if (need_tmp_reg) { + pop(tmp_reg); + } + jcc(Assembler::notEqual, cas_label); + // The bias pattern is present in the object's header. Need to check + // whether the bias owner and the epoch are both still current. + // Note that because there is no current thread register on x86 we + // need to store off the mark word we read out of the object to + // avoid reloading it and needing to recheck invariants below. This + // store is unfortunate but it makes the overall code shorter and + // simpler. + movl(saved_mark_addr, swap_reg); + if (need_tmp_reg) { + push(tmp_reg); + } + get_thread(tmp_reg); + xorl(swap_reg, tmp_reg); + if (swap_reg_contains_mark) { + null_check_offset = offset(); + } + movl(tmp_reg, klass_addr); + xorl(swap_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + andl(swap_reg, ~((int) markOopDesc::age_mask_in_place)); + if (need_tmp_reg) { + pop(tmp_reg); + } + if (counters != NULL) { + cond_inc32(Assembler::zero, + ExternalAddress((address)counters->biased_lock_entry_count_addr())); + } + jcc(Assembler::equal, done); + + Label try_revoke_bias; + Label try_rebias; + + // At this point we know that the header has the bias pattern and + // that we are not the bias owner in the current epoch. We need to + // figure out more details about the state of the header in order to + // know what operations can be legally performed on the object's + // header. + + // If the low three bits in the xor result aren't clear, that means + // the prototype header is no longer biased and we have to revoke + // the bias on this object. + testl(swap_reg, markOopDesc::biased_lock_mask_in_place); + jcc(Assembler::notZero, try_revoke_bias); + + // Biasing is still enabled for this data type. See whether the + // epoch of the current bias is still valid, meaning that the epoch + // bits of the mark word are equal to the epoch bits of the + // prototype header. (Note that the prototype header's epoch bits + // only change at a safepoint.) If not, attempt to rebias the object + // toward the current thread. Note that we must be absolutely sure + // that the current epoch is invalid in order to do this because + // otherwise the manipulations it performs on the mark word are + // illegal. + testl(swap_reg, markOopDesc::epoch_mask_in_place); + jcc(Assembler::notZero, try_rebias); + + // The epoch of the current bias is still valid but we know nothing + // about the owner; it might be set or it might be clear. Try to + // acquire the bias of the object using an atomic operation. If this + // fails we will go in to the runtime to revoke the object's bias. + // Note that we first construct the presumed unbiased header so we + // don't accidentally blow away another thread's valid bias. + movl(swap_reg, saved_mark_addr); + andl(swap_reg, + markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place); + if (need_tmp_reg) { + push(tmp_reg); + } + get_thread(tmp_reg); + orl(tmp_reg, swap_reg); + if (os::is_MP()) { + lock(); + } + cmpxchgptr(tmp_reg, Address(obj_reg, 0)); + if (need_tmp_reg) { + pop(tmp_reg); + } + // If the biasing toward our thread failed, this means that + // another thread succeeded in biasing it toward itself and we + // need to revoke that bias. The revocation will occur in the + // interpreter runtime in the slow case. + if (counters != NULL) { + cond_inc32(Assembler::zero, + ExternalAddress((address)counters->anonymously_biased_lock_entry_count_addr())); + } + if (slow_case != NULL) { + jcc(Assembler::notZero, *slow_case); + } + jmp(done); + + bind(try_rebias); + // At this point we know the epoch has expired, meaning that the + // current "bias owner", if any, is actually invalid. Under these + // circumstances _only_, we are allowed to use the current header's + // value as the comparison value when doing the cas to acquire the + // bias in the current epoch. In other words, we allow transfer of + // the bias from one thread to another directly in this situation. + // + // FIXME: due to a lack of registers we currently blow away the age + // bits in this situation. Should attempt to preserve them. + if (need_tmp_reg) { + push(tmp_reg); + } + get_thread(tmp_reg); + movl(swap_reg, klass_addr); + orl(tmp_reg, Address(swap_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + movl(swap_reg, saved_mark_addr); + if (os::is_MP()) { + lock(); + } + cmpxchgptr(tmp_reg, Address(obj_reg, 0)); + if (need_tmp_reg) { + pop(tmp_reg); + } + // If the biasing toward our thread failed, then another thread + // succeeded in biasing it toward itself and we need to revoke that + // bias. The revocation will occur in the runtime in the slow case. + if (counters != NULL) { + cond_inc32(Assembler::zero, + ExternalAddress((address)counters->rebiased_lock_entry_count_addr())); + } + if (slow_case != NULL) { + jcc(Assembler::notZero, *slow_case); + } + jmp(done); + + bind(try_revoke_bias); + // The prototype mark in the klass doesn't have the bias bit set any + // more, indicating that objects of this data type are not supposed + // to be biased any more. We are going to try to reset the mark of + // this object to the prototype value and fall through to the + // CAS-based locking scheme. Note that if our CAS fails, it means + // that another thread raced us for the privilege of revoking the + // bias of this particular object, so it's okay to continue in the + // normal locking code. + // + // FIXME: due to a lack of registers we currently blow away the age + // bits in this situation. Should attempt to preserve them. + movl(swap_reg, saved_mark_addr); + if (need_tmp_reg) { + push(tmp_reg); + } + movl(tmp_reg, klass_addr); + movl(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + if (os::is_MP()) { + lock(); + } + cmpxchgptr(tmp_reg, Address(obj_reg, 0)); + if (need_tmp_reg) { + pop(tmp_reg); + } + // Fall through to the normal CAS-based lock, because no matter what + // the result of the above CAS, some thread must have succeeded in + // removing the bias bit from the object's header. + if (counters != NULL) { + cond_inc32(Assembler::zero, + ExternalAddress((address)counters->revoked_lock_entry_count_addr())); + } + + bind(cas_label); + + return null_check_offset; +} +void MacroAssembler::call_VM_leaf_base(address entry_point, + int number_of_arguments) { + call(RuntimeAddress(entry_point)); + increment(rsp, number_of_arguments * wordSize); +} + +void MacroAssembler::cmpoop(Address src1, jobject obj) { + cmp_literal32(src1, (int32_t)obj, oop_Relocation::spec_for_immediate()); +} + +void MacroAssembler::cmpoop(Register src1, jobject obj) { + cmp_literal32(src1, (int32_t)obj, oop_Relocation::spec_for_immediate()); +} + +void MacroAssembler::extend_sign(Register hi, Register lo) { + // According to Intel Doc. AP-526, "Integer Divide", p.18. + if (VM_Version::is_P6() && hi == rdx && lo == rax) { + cdql(); + } else { + movl(hi, lo); + sarl(hi, 31); + } +} + +void MacroAssembler::fat_nop() { + // A 5 byte nop that is safe for patching (see patch_verified_entry) + emit_byte(0x26); // es: + emit_byte(0x2e); // cs: + emit_byte(0x64); // fs: + emit_byte(0x65); // gs: + emit_byte(0x90); +} + +void MacroAssembler::jC2(Register tmp, Label& L) { + // set parity bit if FPU flag C2 is set (via rax) + save_rax(tmp); + fwait(); fnstsw_ax(); + sahf(); + restore_rax(tmp); + // branch + jcc(Assembler::parity, L); +} + +void MacroAssembler::jnC2(Register tmp, Label& L) { + // set parity bit if FPU flag C2 is set (via rax) + save_rax(tmp); + fwait(); fnstsw_ax(); + sahf(); + restore_rax(tmp); + // branch + jcc(Assembler::noParity, L); +} + // 32bit can do a case table jump in one instruction but we no longer allow the base // to be installed in the Address class void MacroAssembler::jump(ArrayAddress entry) { -#ifdef _LP64 - lea(rscratch1, entry.base()); - Address dispatch = entry.index(); - assert(dispatch._base == noreg, "must be"); - dispatch._base = rscratch1; - jmp(dispatch); -#else jmp(as_Address(entry)); -#endif // _LP64 } -void MacroAssembler::jump(AddressLiteral dst) { - if (reachable(dst)) { - jmp_literal(dst.target(), dst.rspec()); - } else { - lea(rscratch1, dst); - jmp(rscratch1); - } -} +// Note: y_lo will be destroyed +void MacroAssembler::lcmp2int(Register x_hi, Register x_lo, Register y_hi, Register y_lo) { + // Long compare for Java (semantics as described in JVM spec.) + Label high, low, done; -void MacroAssembler::jump_cc(Condition cc, AddressLiteral dst) { - if (reachable(dst)) { - InstructionMark im(this); - relocate(dst.reloc()); - const int short_size = 2; - const int long_size = 6; - int offs = (intptr_t)dst.target() - ((intptr_t)_code_pos); - if (dst.reloc() == relocInfo::none && is8bit(offs - short_size)) { - // 0111 tttn #8-bit disp - emit_byte(0x70 | cc); - emit_byte((offs - short_size) & 0xFF); - } else { - // 0000 1111 1000 tttn #32-bit disp - emit_byte(0x0F); - emit_byte(0x80 | cc); - emit_long(offs - long_size); - } - } else { -#ifdef ASSERT - warning("reversing conditional branch"); -#endif /* ASSERT */ - Label skip; - jccb(reverse[cc], skip); - lea(rscratch1, dst); - Assembler::jmp(rscratch1); - bind(skip); - } -} + cmpl(x_hi, y_hi); + jcc(Assembler::less, low); + jcc(Assembler::greater, high); + // x_hi is the return register + xorl(x_hi, x_hi); + cmpl(x_lo, y_lo); + jcc(Assembler::below, low); + jcc(Assembler::equal, done); -// Wouldn't need if AddressLiteral version had new name -void MacroAssembler::call(Label& L, relocInfo::relocType rtype) { - Assembler::call(L, rtype); -} + bind(high); + xorl(x_hi, x_hi); + increment(x_hi); + jmp(done); -// Wouldn't need if AddressLiteral version had new name -void MacroAssembler::call(Register entry) { - Assembler::call(entry); -} + bind(low); + xorl(x_hi, x_hi); + decrementl(x_hi); -void MacroAssembler::call(AddressLiteral entry) { - if (reachable(entry)) { - Assembler::call_literal(entry.target(), entry.rspec()); - } else { - lea(rscratch1, entry); - Assembler::call(rscratch1); - } -} - -void MacroAssembler::cmp8(AddressLiteral src1, int8_t src2) { - if (reachable(src1)) { - cmpb(as_Address(src1), src2); - } else { - lea(rscratch1, src1); - cmpb(Address(rscratch1, 0), src2); - } -} - -void MacroAssembler::cmp32(AddressLiteral src1, int32_t src2) { - if (reachable(src1)) { - cmpl(as_Address(src1), src2); - } else { - lea(rscratch1, src1); - cmpl(Address(rscratch1, 0), src2); - } -} - -void MacroAssembler::cmp32(Register src1, AddressLiteral src2) { - if (reachable(src2)) { - cmpl(src1, as_Address(src2)); - } else { - lea(rscratch1, src2); - cmpl(src1, Address(rscratch1, 0)); - } -} - -void MacroAssembler::cmpptr(Register src1, AddressLiteral src2) { -#ifdef _LP64 - if (src2.is_lval()) { - movptr(rscratch1, src2); - Assembler::cmpq(src1, rscratch1); - } else if (reachable(src2)) { - cmpq(src1, as_Address(src2)); - } else { - lea(rscratch1, src2); - Assembler::cmpq(src1, Address(rscratch1, 0)); - } -#else - if (src2.is_lval()) { - cmp_literal32(src1, (int32_t) src2.target(), src2.rspec()); - } else { - cmpl(src1, as_Address(src2)); - } -#endif // _LP64 -} - -void MacroAssembler::cmpptr(Address src1, AddressLiteral src2) { - assert(src2.is_lval(), "not a mem-mem compare"); -#ifdef _LP64 - // moves src2's literal address - movptr(rscratch1, src2); - Assembler::cmpq(src1, rscratch1); -#else - cmp_literal32(src1, (int32_t) src2.target(), src2.rspec()); -#endif // _LP64 -} - -void MacroAssembler::cmp64(Register src1, AddressLiteral src2) { - assert(!src2.is_lval(), "should use cmpptr"); - - if (reachable(src2)) { -#ifdef _LP64 - cmpq(src1, as_Address(src2)); -#else - ShouldNotReachHere(); -#endif // _LP64 - } else { - lea(rscratch1, src2); - Assembler::cmpq(src1, Address(rscratch1, 0)); - } -} - -void MacroAssembler::cmpxchgptr(Register reg, AddressLiteral adr) { - if (reachable(adr)) { -#ifdef _LP64 - cmpxchgq(reg, as_Address(adr)); -#else - cmpxchgl(reg, as_Address(adr)); -#endif // _LP64 - } else { - lea(rscratch1, adr); - cmpxchgq(reg, Address(rscratch1, 0)); - } -} - -void MacroAssembler::incrementl(AddressLiteral dst) { - if (reachable(dst)) { - incrementl(as_Address(dst)); - } else { - lea(rscratch1, dst); - incrementl(Address(rscratch1, 0)); - } -} - -void MacroAssembler::incrementl(ArrayAddress dst) { - incrementl(as_Address(dst)); -} - -void MacroAssembler::lea(Register dst, Address src) { -#ifdef _LP64 - leaq(dst, src); -#else - leal(dst, src); -#endif // _LP64 + bind(done); } void MacroAssembler::lea(Register dst, AddressLiteral src) { -#ifdef _LP64 - mov_literal64(dst, (intptr_t)src.target(), src.rspec()); -#else - mov_literal32(dst, (intptr_t)src.target(), src.rspec()); -#endif // _LP64 + mov_literal32(dst, (int32_t)src.target(), src.rspec()); } -void MacroAssembler::mov32(AddressLiteral dst, Register src) { - if (reachable(dst)) { - movl(as_Address(dst), src); - } else { - lea(rscratch1, dst); - movl(Address(rscratch1, 0), src); - } -} - -void MacroAssembler::mov32(Register dst, AddressLiteral src) { - if (reachable(src)) { - movl(dst, as_Address(src)); - } else { - lea(rscratch1, src); - movl(dst, Address(rscratch1, 0)); - } -} - -void MacroAssembler::movdbl(XMMRegister dst, AddressLiteral src) { - if (reachable(src)) { - if (UseXmmLoadAndClearUpper) { - movsd (dst, as_Address(src)); - } else { - movlpd(dst, as_Address(src)); - } - } else { - lea(rscratch1, src); - if (UseXmmLoadAndClearUpper) { - movsd (dst, Address(rscratch1, 0)); - } else { - movlpd(dst, Address(rscratch1, 0)); - } - } -} - -void MacroAssembler::movflt(XMMRegister dst, AddressLiteral src) { - if (reachable(src)) { - movss(dst, as_Address(src)); - } else { - lea(rscratch1, src); - movss(dst, Address(rscratch1, 0)); - } -} - -void MacroAssembler::movoop(Register dst, jobject obj) { - mov_literal64(dst, (intptr_t)obj, oop_Relocation::spec_for_immediate()); -} - -void MacroAssembler::movoop(Address dst, jobject obj) { - mov_literal64(rscratch1, (intptr_t)obj, oop_Relocation::spec_for_immediate()); - movq(dst, rscratch1); -} - -void MacroAssembler::movptr(Register dst, AddressLiteral src) { -#ifdef _LP64 - if (src.is_lval()) { - mov_literal64(dst, (intptr_t)src.target(), src.rspec()); - } else { - if (reachable(src)) { - movq(dst, as_Address(src)); - } else { - lea(rscratch1, src); - movq(dst, Address(rscratch1,0)); - } - } -#else - if (src.is_lval()) { - mov_literal32(dst, (intptr_t)src.target(), src.rspec()); - } else { - movl(dst, as_Address(src)); - } -#endif // LP64 -} - -void MacroAssembler::movptr(ArrayAddress dst, Register src) { -#ifdef _LP64 - movq(as_Address(dst), src); -#else - movl(as_Address(dst), src); -#endif // _LP64 -} - -void MacroAssembler::pushoop(jobject obj) { -#ifdef _LP64 - movoop(rscratch1, obj); - pushq(rscratch1); -#else - push_literal32((int32_t)obj, oop_Relocation::spec_for_immediate()); -#endif // _LP64 -} - -void MacroAssembler::pushptr(AddressLiteral src) { -#ifdef _LP64 - lea(rscratch1, src); - if (src.is_lval()) { - pushq(rscratch1); - } else { - pushq(Address(rscratch1, 0)); - } -#else - if (src.is_lval()) { - push_literal((int32_t)src.target(), src.rspec()); - else { - pushl(as_Address(src)); - } -#endif // _LP64 -} - -void MacroAssembler::ldmxcsr(AddressLiteral src) { - if (reachable(src)) { - Assembler::ldmxcsr(as_Address(src)); - } else { - lea(rscratch1, src); - Assembler::ldmxcsr(Address(rscratch1, 0)); - } -} - -void MacroAssembler::movlpd(XMMRegister dst, AddressLiteral src) { - if (reachable(src)) { - movlpd(dst, as_Address(src)); - } else { - lea(rscratch1, src); - movlpd(dst, Address(rscratch1, 0)); - } -} - -void MacroAssembler::movss(XMMRegister dst, AddressLiteral src) { - if (reachable(src)) { - movss(dst, as_Address(src)); - } else { - lea(rscratch1, src); - movss(dst, Address(rscratch1, 0)); - } -} -void MacroAssembler::xorpd(XMMRegister dst, AddressLiteral src) { - if (reachable(src)) { - xorpd(dst, as_Address(src)); - } else { - lea(rscratch1, src); - xorpd(dst, Address(rscratch1, 0)); - } -} - -void MacroAssembler::xorps(XMMRegister dst, AddressLiteral src) { - if (reachable(src)) { - xorps(dst, as_Address(src)); - } else { - lea(rscratch1, src); - xorps(dst, Address(rscratch1, 0)); - } -} - -void MacroAssembler::null_check(Register reg, int offset) { - if (needs_explicit_null_check(offset)) { - // provoke OS NULL exception if reg = NULL by - // accessing M[reg] w/o changing any (non-CC) registers - cmpq(rax, Address(reg, 0)); - // Note: should probably use testl(rax, Address(reg, 0)); - // may be shorter code (however, this version of - // testl needs to be implemented first) - } else { - // nothing to do, (later) access of M[reg + offset] - // will provoke OS NULL exception if reg = NULL - } -} - -int MacroAssembler::load_unsigned_byte(Register dst, Address src) { - int off = offset(); - movzbl(dst, src); - return off; -} - -int MacroAssembler::load_unsigned_word(Register dst, Address src) { - int off = offset(); - movzwl(dst, src); - return off; -} - -int MacroAssembler::load_signed_byte(Register dst, Address src) { - int off = offset(); - movsbl(dst, src); - return off; -} - -int MacroAssembler::load_signed_word(Register dst, Address src) { - int off = offset(); - movswl(dst, src); - return off; -} - -void MacroAssembler::incrementl(Register reg, int value) { - if (value == min_jint) { addl(reg, value); return; } - if (value < 0) { decrementl(reg, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { incl(reg) ; return; } - /* else */ { addl(reg, value) ; return; } -} - -void MacroAssembler::decrementl(Register reg, int value) { - if (value == min_jint) { subl(reg, value); return; } - if (value < 0) { incrementl(reg, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { decl(reg) ; return; } - /* else */ { subl(reg, value) ; return; } -} - -void MacroAssembler::incrementq(Register reg, int value) { - if (value == min_jint) { addq(reg, value); return; } - if (value < 0) { decrementq(reg, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { incq(reg) ; return; } - /* else */ { addq(reg, value) ; return; } -} - -void MacroAssembler::decrementq(Register reg, int value) { - if (value == min_jint) { subq(reg, value); return; } - if (value < 0) { incrementq(reg, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { decq(reg) ; return; } - /* else */ { subq(reg, value) ; return; } -} - -void MacroAssembler::incrementl(Address dst, int value) { - if (value == min_jint) { addl(dst, value); return; } - if (value < 0) { decrementl(dst, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { incl(dst) ; return; } - /* else */ { addl(dst, value) ; return; } -} - -void MacroAssembler::decrementl(Address dst, int value) { - if (value == min_jint) { subl(dst, value); return; } - if (value < 0) { incrementl(dst, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { decl(dst) ; return; } - /* else */ { subl(dst, value) ; return; } -} - -void MacroAssembler::incrementq(Address dst, int value) { - if (value == min_jint) { addq(dst, value); return; } - if (value < 0) { decrementq(dst, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { incq(dst) ; return; } - /* else */ { addq(dst, value) ; return; } -} - -void MacroAssembler::decrementq(Address dst, int value) { - if (value == min_jint) { subq(dst, value); return; } - if (value < 0) { incrementq(dst, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { decq(dst) ; return; } - /* else */ { subq(dst, value) ; return; } -} - -void MacroAssembler::align(int modulus) { - if (offset() % modulus != 0) { - nop(modulus - (offset() % modulus)); - } -} - -void MacroAssembler::enter() { - pushq(rbp); - movq(rbp, rsp); +void MacroAssembler::lea(Address dst, AddressLiteral adr) { + // leal(dst, as_Address(adr)); + // see note in movl as to why we must use a move + mov_literal32(dst, (int32_t) adr.target(), adr.rspec()); } void MacroAssembler::leave() { - emit_byte(0xC9); // LEAVE + mov(rsp, rbp); + pop(rbp); } -// C++ bool manipulation - -void MacroAssembler::movbool(Register dst, Address src) { - if(sizeof(bool) == 1) - movb(dst, src); - else if(sizeof(bool) == 2) - movw(dst, src); - else if(sizeof(bool) == 4) - movl(dst, src); - else { - // unsupported - ShouldNotReachHere(); - } +void MacroAssembler::lmul(int x_rsp_offset, int y_rsp_offset) { + // Multiplication of two Java long values stored on the stack + // as illustrated below. Result is in rdx:rax. + // + // rsp ---> [ ?? ] \ \ + // .... | y_rsp_offset | + // [ y_lo ] / (in bytes) | x_rsp_offset + // [ y_hi ] | (in bytes) + // .... | + // [ x_lo ] / + // [ x_hi ] + // .... + // + // Basic idea: lo(result) = lo(x_lo * y_lo) + // hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) + lo(x_lo * y_hi) + Address x_hi(rsp, x_rsp_offset + wordSize); Address x_lo(rsp, x_rsp_offset); + Address y_hi(rsp, y_rsp_offset + wordSize); Address y_lo(rsp, y_rsp_offset); + Label quick; + // load x_hi, y_hi and check if quick + // multiplication is possible + movl(rbx, x_hi); + movl(rcx, y_hi); + movl(rax, rbx); + orl(rbx, rcx); // rbx, = 0 <=> x_hi = 0 and y_hi = 0 + jcc(Assembler::zero, quick); // if rbx, = 0 do quick multiply + // do full multiplication + // 1st step + mull(y_lo); // x_hi * y_lo + movl(rbx, rax); // save lo(x_hi * y_lo) in rbx, + // 2nd step + movl(rax, x_lo); + mull(rcx); // x_lo * y_hi + addl(rbx, rax); // add lo(x_lo * y_hi) to rbx, + // 3rd step + bind(quick); // note: rbx, = 0 if quick multiply! + movl(rax, x_lo); + mull(y_lo); // x_lo * y_lo + addl(rdx, rbx); // correct hi(x_lo * y_lo) } -void MacroAssembler::movbool(Address dst, bool boolconst) { - if(sizeof(bool) == 1) - movb(dst, (int) boolconst); - else if(sizeof(bool) == 2) - movw(dst, (int) boolconst); - else if(sizeof(bool) == 4) - movl(dst, (int) boolconst); - else { - // unsupported - ShouldNotReachHere(); - } +void MacroAssembler::lneg(Register hi, Register lo) { + negl(lo); + adcl(hi, 0); + negl(hi); } -void MacroAssembler::movbool(Address dst, Register src) { - if(sizeof(bool) == 1) - movb(dst, src); - else if(sizeof(bool) == 2) - movw(dst, src); - else if(sizeof(bool) == 4) - movl(dst, src); - else { - // unsupported - ShouldNotReachHere(); - } -} - -void MacroAssembler::testbool(Register dst) { - if(sizeof(bool) == 1) - testb(dst, (int) 0xff); - else if(sizeof(bool) == 2) { - // need testw impl - ShouldNotReachHere(); - } else if(sizeof(bool) == 4) - testl(dst, dst); - else { - // unsupported - ShouldNotReachHere(); - } -} - -void MacroAssembler::set_last_Java_frame(Register last_java_sp, - Register last_java_fp, - address last_java_pc) { - // determine last_java_sp register - if (!last_java_sp->is_valid()) { - last_java_sp = rsp; - } - - // last_java_fp is optional - if (last_java_fp->is_valid()) { - movq(Address(r15_thread, JavaThread::last_Java_fp_offset()), - last_java_fp); - } - - // last_java_pc is optional - if (last_java_pc != NULL) { - Address java_pc(r15_thread, - JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset()); - lea(rscratch1, InternalAddress(last_java_pc)); - movq(java_pc, rscratch1); - } - - movq(Address(r15_thread, JavaThread::last_Java_sp_offset()), last_java_sp); -} - -void MacroAssembler::reset_last_Java_frame(bool clear_fp, - bool clear_pc) { - // we must set sp to zero to clear frame - movptr(Address(r15_thread, JavaThread::last_Java_sp_offset()), NULL_WORD); - // must clear fp, so that compiled frames are not confused; it is - // possible that we need it only for debugging - if (clear_fp) { - movptr(Address(r15_thread, JavaThread::last_Java_fp_offset()), NULL_WORD); - } - - if (clear_pc) { - movptr(Address(r15_thread, JavaThread::last_Java_pc_offset()), NULL_WORD); - } +void MacroAssembler::lshl(Register hi, Register lo) { + // Java shift left long support (semantics as described in JVM spec., p.305) + // (basic idea for shift counts s >= n: x << s == (x << n) << (s - n)) + // shift value is in rcx ! + assert(hi != rcx, "must not use rcx"); + assert(lo != rcx, "must not use rcx"); + const Register s = rcx; // shift count + const int n = BitsPerWord; + Label L; + andl(s, 0x3f); // s := s & 0x3f (s < 0x40) + cmpl(s, n); // if (s < n) + jcc(Assembler::less, L); // else (s >= n) + movl(hi, lo); // x := x << n + xorl(lo, lo); + // Note: subl(s, n) is not needed since the Intel shift instructions work rcx mod n! + bind(L); // s (mod n) < n + shldl(hi, lo); // x := x << s + shll(lo); } -// Implementation of call_VM versions - -void MacroAssembler::call_VM_leaf_base(address entry_point, int num_args) { - Label L, E; - -#ifdef _WIN64 - // Windows always allocates space for it's register args - assert(num_args <= 4, "only register arguments supported"); - subq(rsp, frame::arg_reg_save_area_bytes); -#endif - - // Align stack if necessary - testl(rsp, 15); - jcc(Assembler::zero, L); - - subq(rsp, 8); - { - call(RuntimeAddress(entry_point)); - } - addq(rsp, 8); - jmp(E); - - bind(L); - { - call(RuntimeAddress(entry_point)); - } - - bind(E); - -#ifdef _WIN64 - // restore stack pointer - addq(rsp, frame::arg_reg_save_area_bytes); -#endif - +void MacroAssembler::lshr(Register hi, Register lo, bool sign_extension) { + // Java shift right long support (semantics as described in JVM spec., p.306 & p.310) + // (basic idea for shift counts s >= n: x >> s == (x >> n) >> (s - n)) + assert(hi != rcx, "must not use rcx"); + assert(lo != rcx, "must not use rcx"); + const Register s = rcx; // shift count + const int n = BitsPerWord; + Label L; + andl(s, 0x3f); // s := s & 0x3f (s < 0x40) + cmpl(s, n); // if (s < n) + jcc(Assembler::less, L); // else (s >= n) + movl(lo, hi); // x := x >> n + if (sign_extension) sarl(hi, 31); + else xorl(hi, hi); + // Note: subl(s, n) is not needed since the Intel shift instructions work rcx mod n! + bind(L); // s (mod n) < n + shrdl(lo, hi); // x := x >> s + if (sign_extension) sarl(hi); + else shrl(hi); } - -void MacroAssembler::call_VM_base(Register oop_result, - Register java_thread, - Register last_java_sp, - address entry_point, - int num_args, - bool check_exceptions) { - // determine last_java_sp register - if (!last_java_sp->is_valid()) { - last_java_sp = rsp; - } - - // debugging support - assert(num_args >= 0, "cannot have negative number of arguments"); - assert(r15_thread != oop_result, - "cannot use the same register for java_thread & oop_result"); - assert(r15_thread != last_java_sp, - "cannot use the same register for java_thread & last_java_sp"); - - // set last Java frame before call - - // This sets last_Java_fp which is only needed from interpreted frames - // and should really be done only from the interp_masm version before - // calling the underlying call_VM. That doesn't happen yet so we set - // last_Java_fp here even though some callers don't need it and - // also clear it below. - set_last_Java_frame(last_java_sp, rbp, NULL); - - { - Label L, E; - - // Align stack if necessary -#ifdef _WIN64 - assert(num_args <= 4, "only register arguments supported"); - // Windows always allocates space for it's register args - subq(rsp, frame::arg_reg_save_area_bytes); -#endif - testl(rsp, 15); - jcc(Assembler::zero, L); - - subq(rsp, 8); - { - call(RuntimeAddress(entry_point)); - } - addq(rsp, 8); - jmp(E); - - - bind(L); - { - call(RuntimeAddress(entry_point)); - } - - bind(E); - -#ifdef _WIN64 - // restore stack pointer - addq(rsp, frame::arg_reg_save_area_bytes); -#endif - } - -#ifdef ASSERT - pushq(rax); - { - Label L; - get_thread(rax); - cmpq(r15_thread, rax); - jcc(Assembler::equal, L); - stop("MacroAssembler::call_VM_base: register not callee saved?"); - bind(L); - } - popq(rax); -#endif - - // reset last Java frame - // This really shouldn't have to clear fp set note above at the - // call to set_last_Java_frame - reset_last_Java_frame(true, false); - - check_and_handle_popframe(noreg); - check_and_handle_earlyret(noreg); - - if (check_exceptions) { - cmpq(Address(r15_thread, Thread::pending_exception_offset()), (int) NULL); - // This used to conditionally jump to forward_exception however it is - // possible if we relocate that the branch will not reach. So we must jump - // around so we can always reach - Label ok; - jcc(Assembler::equal, ok); - jump(RuntimeAddress(StubRoutines::forward_exception_entry())); - bind(ok); - } - - // get oop result if there is one and reset the value in the thread - if (oop_result->is_valid()) { - movq(oop_result, Address(r15_thread, JavaThread::vm_result_offset())); - movptr(Address(r15_thread, JavaThread::vm_result_offset()), NULL_WORD); - verify_oop(oop_result, "broken oop in call_VM_base"); - } +void MacroAssembler::movoop(Register dst, jobject obj) { + mov_literal32(dst, (int32_t)obj, oop_Relocation::spec_for_immediate()); } -void MacroAssembler::check_and_handle_popframe(Register java_thread) {} -void MacroAssembler::check_and_handle_earlyret(Register java_thread) {} - -void MacroAssembler::call_VM_helper(Register oop_result, - address entry_point, - int num_args, - bool check_exceptions) { - // Java thread becomes first argument of C function - movq(c_rarg0, r15_thread); - - // We've pushed one address, correct last_Java_sp - leaq(rax, Address(rsp, wordSize)); - - call_VM_base(oop_result, noreg, rax, entry_point, num_args, - check_exceptions); +void MacroAssembler::movoop(Address dst, jobject obj) { + mov_literal32(dst, (int32_t)obj, oop_Relocation::spec_for_immediate()); } - -void MacroAssembler::call_VM(Register oop_result, - address entry_point, - bool check_exceptions) { - Label C, E; - Assembler::call(C, relocInfo::none); - jmp(E); - - bind(C); - call_VM_helper(oop_result, entry_point, 0, check_exceptions); - ret(0); - - bind(E); -} - - -void MacroAssembler::call_VM(Register oop_result, - address entry_point, - Register arg_1, - bool check_exceptions) { - assert(rax != arg_1, "smashed argument"); - assert(c_rarg0 != arg_1, "smashed argument"); - - Label C, E; - Assembler::call(C, relocInfo::none); - jmp(E); - - bind(C); - // c_rarg0 is reserved for thread - if (c_rarg1 != arg_1) { - movq(c_rarg1, arg_1); - } - call_VM_helper(oop_result, entry_point, 1, check_exceptions); - ret(0); - - bind(E); -} - -void MacroAssembler::call_VM(Register oop_result, - address entry_point, - Register arg_1, - Register arg_2, - bool check_exceptions) { - assert(rax != arg_1, "smashed argument"); - assert(rax != arg_2, "smashed argument"); - assert(c_rarg0 != arg_1, "smashed argument"); - assert(c_rarg0 != arg_2, "smashed argument"); - assert(c_rarg1 != arg_2, "smashed argument"); - assert(c_rarg2 != arg_1, "smashed argument"); - - Label C, E; - Assembler::call(C, relocInfo::none); - jmp(E); - - bind(C); - // c_rarg0 is reserved for thread - if (c_rarg1 != arg_1) { - movq(c_rarg1, arg_1); - } - if (c_rarg2 != arg_2) { - movq(c_rarg2, arg_2); - } - call_VM_helper(oop_result, entry_point, 2, check_exceptions); - ret(0); - - bind(E); -} - - -void MacroAssembler::call_VM(Register oop_result, - address entry_point, - Register arg_1, - Register arg_2, - Register arg_3, - bool check_exceptions) { - assert(rax != arg_1, "smashed argument"); - assert(rax != arg_2, "smashed argument"); - assert(rax != arg_3, "smashed argument"); - assert(c_rarg0 != arg_1, "smashed argument"); - assert(c_rarg0 != arg_2, "smashed argument"); - assert(c_rarg0 != arg_3, "smashed argument"); - assert(c_rarg1 != arg_2, "smashed argument"); - assert(c_rarg1 != arg_3, "smashed argument"); - assert(c_rarg2 != arg_1, "smashed argument"); - assert(c_rarg2 != arg_3, "smashed argument"); - assert(c_rarg3 != arg_1, "smashed argument"); - assert(c_rarg3 != arg_2, "smashed argument"); - - Label C, E; - Assembler::call(C, relocInfo::none); - jmp(E); - - bind(C); - // c_rarg0 is reserved for thread - if (c_rarg1 != arg_1) { - movq(c_rarg1, arg_1); - } - if (c_rarg2 != arg_2) { - movq(c_rarg2, arg_2); - } - if (c_rarg3 != arg_3) { - movq(c_rarg3, arg_3); - } - call_VM_helper(oop_result, entry_point, 3, check_exceptions); - ret(0); - - bind(E); -} - -void MacroAssembler::call_VM(Register oop_result, - Register last_java_sp, - address entry_point, - int num_args, - bool check_exceptions) { - call_VM_base(oop_result, noreg, last_java_sp, entry_point, num_args, - check_exceptions); -} - -void MacroAssembler::call_VM(Register oop_result, - Register last_java_sp, - address entry_point, - Register arg_1, - bool check_exceptions) { - assert(c_rarg0 != arg_1, "smashed argument"); - assert(c_rarg1 != last_java_sp, "smashed argument"); - // c_rarg0 is reserved for thread - if (c_rarg1 != arg_1) { - movq(c_rarg1, arg_1); - } - call_VM(oop_result, last_java_sp, entry_point, 1, check_exceptions); -} - -void MacroAssembler::call_VM(Register oop_result, - Register last_java_sp, - address entry_point, - Register arg_1, - Register arg_2, - bool check_exceptions) { - assert(c_rarg0 != arg_1, "smashed argument"); - assert(c_rarg0 != arg_2, "smashed argument"); - assert(c_rarg1 != arg_2, "smashed argument"); - assert(c_rarg1 != last_java_sp, "smashed argument"); - assert(c_rarg2 != arg_1, "smashed argument"); - assert(c_rarg2 != last_java_sp, "smashed argument"); - // c_rarg0 is reserved for thread - if (c_rarg1 != arg_1) { - movq(c_rarg1, arg_1); - } - if (c_rarg2 != arg_2) { - movq(c_rarg2, arg_2); - } - call_VM(oop_result, last_java_sp, entry_point, 2, check_exceptions); -} - - -void MacroAssembler::call_VM(Register oop_result, - Register last_java_sp, - address entry_point, - Register arg_1, - Register arg_2, - Register arg_3, - bool check_exceptions) { - assert(c_rarg0 != arg_1, "smashed argument"); - assert(c_rarg0 != arg_2, "smashed argument"); - assert(c_rarg0 != arg_3, "smashed argument"); - assert(c_rarg1 != arg_2, "smashed argument"); - assert(c_rarg1 != arg_3, "smashed argument"); - assert(c_rarg1 != last_java_sp, "smashed argument"); - assert(c_rarg2 != arg_1, "smashed argument"); - assert(c_rarg2 != arg_3, "smashed argument"); - assert(c_rarg2 != last_java_sp, "smashed argument"); - assert(c_rarg3 != arg_1, "smashed argument"); - assert(c_rarg3 != arg_2, "smashed argument"); - assert(c_rarg3 != last_java_sp, "smashed argument"); - // c_rarg0 is reserved for thread - if (c_rarg1 != arg_1) { - movq(c_rarg1, arg_1); - } - if (c_rarg2 != arg_2) { - movq(c_rarg2, arg_2); - } - if (c_rarg3 != arg_3) { - movq(c_rarg2, arg_3); - } - call_VM(oop_result, last_java_sp, entry_point, 3, check_exceptions); -} - -void MacroAssembler::call_VM_leaf(address entry_point, int num_args) { - call_VM_leaf_base(entry_point, num_args); -} - -void MacroAssembler::call_VM_leaf(address entry_point, Register arg_1) { - if (c_rarg0 != arg_1) { - movq(c_rarg0, arg_1); - } - call_VM_leaf(entry_point, 1); -} - -void MacroAssembler::call_VM_leaf(address entry_point, - Register arg_1, - Register arg_2) { - assert(c_rarg0 != arg_2, "smashed argument"); - assert(c_rarg1 != arg_1, "smashed argument"); - if (c_rarg0 != arg_1) { - movq(c_rarg0, arg_1); - } - if (c_rarg1 != arg_2) { - movq(c_rarg1, arg_2); - } - call_VM_leaf(entry_point, 2); -} - -void MacroAssembler::call_VM_leaf(address entry_point, - Register arg_1, - Register arg_2, - Register arg_3) { - assert(c_rarg0 != arg_2, "smashed argument"); - assert(c_rarg0 != arg_3, "smashed argument"); - assert(c_rarg1 != arg_1, "smashed argument"); - assert(c_rarg1 != arg_3, "smashed argument"); - assert(c_rarg2 != arg_1, "smashed argument"); - assert(c_rarg2 != arg_2, "smashed argument"); - if (c_rarg0 != arg_1) { - movq(c_rarg0, arg_1); - } - if (c_rarg1 != arg_2) { - movq(c_rarg1, arg_2); - } - if (c_rarg2 != arg_3) { - movq(c_rarg2, arg_3); - } - call_VM_leaf(entry_point, 3); -} - - -// Calls to C land -// -// When entering C land, the rbp & rsp of the last Java frame have to -// be recorded in the (thread-local) JavaThread object. When leaving C -// land, the last Java fp has to be reset to 0. This is required to -// allow proper stack traversal. -void MacroAssembler::store_check(Register obj) { - // Does a store check for the oop in register obj. The content of - // register obj is destroyed afterwards. - store_check_part_1(obj); - store_check_part_2(obj); -} - -void MacroAssembler::store_check(Register obj, Address dst) { - store_check(obj); -} - -// split the store check operation so that other instructions can be -// scheduled inbetween -void MacroAssembler::store_check_part_1(Register obj) { - BarrierSet* bs = Universe::heap()->barrier_set(); - assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); - shrq(obj, CardTableModRefBS::card_shift); -} - -void MacroAssembler::store_check_part_2(Register obj) { - BarrierSet* bs = Universe::heap()->barrier_set(); - assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); - CardTableModRefBS* ct = (CardTableModRefBS*)bs; - assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); - - // The calculation for byte_map_base is as follows: - // byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift); - // So this essentially converts an address to a displacement and - // it will never need to be relocated. On 64bit however the value may be too - // large for a 32bit displacement - - intptr_t disp = (intptr_t) ct->byte_map_base; - if (is_simm32(disp)) { - Address cardtable(noreg, obj, Address::times_1, disp); - movb(cardtable, 0); +void MacroAssembler::movptr(Register dst, AddressLiteral src) { + if (src.is_lval()) { + mov_literal32(dst, (intptr_t)src.target(), src.rspec()); } else { - // By doing it as an ExternalAddress disp could be converted to a rip-relative - // displacement and done in a single instruction given favorable mapping and - // a smarter version of as_Address. Worst case it is two instructions which - // is no worse off then loading disp into a register and doing as a simple - // Address() as above. - // We can't do as ExternalAddress as the only style since if disp == 0 we'll - // assert since NULL isn't acceptable in a reloci (see 6644928). In any case - // in some cases we'll get a single instruction version. - - ExternalAddress cardtable((address)disp); - Address index(noreg, obj, Address::times_1); - movb(as_Address(ArrayAddress(cardtable, index)), 0); + movl(dst, as_Address(src)); } - } -void MacroAssembler::c2bool(Register x) { - // implements x == 0 ? 0 : 1 - // note: must only look at least-significant byte of x - // since C-style booleans are stored in one byte - // only! (was bug) - andl(x, 0xFF); - setb(Assembler::notZero, x); +void MacroAssembler::movptr(ArrayAddress dst, Register src) { + movl(as_Address(dst), src); } -int MacroAssembler::corrected_idivl(Register reg) { - // Full implementation of Java idiv and irem; checks for special - // case as described in JVM spec., p.243 & p.271. The function - // returns the (pc) offset of the idivl instruction - may be needed - // for implicit exceptions. - // - // normal case special case - // - // input : eax: dividend min_int - // reg: divisor (may not be eax/edx) -1 - // - // output: eax: quotient (= eax idiv reg) min_int - // edx: remainder (= eax irem reg) 0 - assert(reg != rax && reg != rdx, "reg cannot be rax or rdx register"); - const int min_int = 0x80000000; - Label normal_case, special_case; - - // check for special case - cmpl(rax, min_int); - jcc(Assembler::notEqual, normal_case); - xorl(rdx, rdx); // prepare edx for possible special case (where - // remainder = 0) - cmpl(reg, -1); - jcc(Assembler::equal, special_case); - - // handle normal case - bind(normal_case); - cdql(); - int idivl_offset = offset(); - idivl(reg); - - // normal and special case exit - bind(special_case); - - return idivl_offset; +void MacroAssembler::movptr(Register dst, ArrayAddress src) { + movl(dst, as_Address(src)); } -int MacroAssembler::corrected_idivq(Register reg) { - // Full implementation of Java ldiv and lrem; checks for special - // case as described in JVM spec., p.243 & p.271. The function - // returns the (pc) offset of the idivl instruction - may be needed - // for implicit exceptions. - // - // normal case special case - // - // input : rax: dividend min_long - // reg: divisor (may not be eax/edx) -1 - // - // output: rax: quotient (= rax idiv reg) min_long - // rdx: remainder (= rax irem reg) 0 - assert(reg != rax && reg != rdx, "reg cannot be rax or rdx register"); - static const int64_t min_long = 0x8000000000000000; - Label normal_case, special_case; - - // check for special case - cmp64(rax, ExternalAddress((address) &min_long)); - jcc(Assembler::notEqual, normal_case); - xorl(rdx, rdx); // prepare rdx for possible special case (where - // remainder = 0) - cmpq(reg, -1); - jcc(Assembler::equal, special_case); - - // handle normal case - bind(normal_case); - cdqq(); - int idivq_offset = offset(); - idivq(reg); - - // normal and special case exit - bind(special_case); - - return idivq_offset; +// src should NEVER be a real pointer. Use AddressLiteral for true pointers +void MacroAssembler::movptr(Address dst, intptr_t src) { + movl(dst, src); } -void MacroAssembler::push_IU_state() { - pushfq(); // Push flags first because pushaq kills them - subq(rsp, 8); // Make sure rsp stays 16-byte aligned - pushaq(); + +void MacroAssembler::movsd(XMMRegister dst, AddressLiteral src) { + movsd(dst, as_Address(src)); } -void MacroAssembler::pop_IU_state() { - popaq(); - addq(rsp, 8); - popfq(); +void MacroAssembler::pop_callee_saved_registers() { + pop(rcx); + pop(rdx); + pop(rdi); + pop(rsi); } -void MacroAssembler::push_FPU_state() { - subq(rsp, FPUStateSizeInWords * wordSize); - fxsave(Address(rsp, 0)); +void MacroAssembler::pop_fTOS() { + fld_d(Address(rsp, 0)); + addl(rsp, 2 * wordSize); } -void MacroAssembler::pop_FPU_state() { - fxrstor(Address(rsp, 0)); - addq(rsp, FPUStateSizeInWords * wordSize); +void MacroAssembler::push_callee_saved_registers() { + push(rsi); + push(rdi); + push(rdx); + push(rcx); } -// Save Integer and Float state -// Warning: Stack must be 16 byte aligned -void MacroAssembler::push_CPU_state() { - push_IU_state(); - push_FPU_state(); +void MacroAssembler::push_fTOS() { + subl(rsp, 2 * wordSize); + fstp_d(Address(rsp, 0)); } -void MacroAssembler::pop_CPU_state() { - pop_FPU_state(); - pop_IU_state(); + +void MacroAssembler::pushoop(jobject obj) { + push_literal32((int32_t)obj, oop_Relocation::spec_for_immediate()); } -void MacroAssembler::sign_extend_short(Register reg) { - movswl(reg, reg); -} -void MacroAssembler::sign_extend_byte(Register reg) { - movsbl(reg, reg); -} - -void MacroAssembler::division_with_shift(Register reg, int shift_value) { - assert (shift_value > 0, "illegal shift value"); - Label _is_positive; - testl (reg, reg); - jcc (Assembler::positive, _is_positive); - int offset = (1 << shift_value) - 1 ; - - if (offset == 1) { - incrementl(reg); +void MacroAssembler::pushptr(AddressLiteral src) { + if (src.is_lval()) { + push_literal32((int32_t)src.target(), src.rspec()); } else { - addl(reg, offset); + pushl(as_Address(src)); } - - bind (_is_positive); - sarl(reg, shift_value); } -void MacroAssembler::round_to_l(Register reg, int modulus) { - addl(reg, modulus - 1); - andl(reg, -modulus); +void MacroAssembler::set_word_if_not_zero(Register dst) { + xorl(dst, dst); + set_byte_if_not_zero(dst); } -void MacroAssembler::round_to_q(Register reg, int modulus) { - addq(reg, modulus - 1); - andq(reg, -modulus); +static void pass_arg0(MacroAssembler* masm, Register arg) { + masm->push(arg); } -void MacroAssembler::verify_oop(Register reg, const char* s) { - if (!VerifyOops) { - return; - } - - // Pass register number to verify_oop_subroutine - char* b = new char[strlen(s) + 50]; - sprintf(b, "verify_oop: %s: %s", reg->name(), s); - - pushq(rax); // save rax, restored by receiver - - // pass args on stack, only touch rax - pushq(reg); - // avoid using pushptr, as it modifies scratch registers - // and our contract is not to modify anything - ExternalAddress buffer((address)b); - movptr(rax, buffer.addr()); - pushq(rax); - - // call indirectly to solve generation ordering problem - movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address())); - call(rax); // no alignment requirement - // everything popped by receiver +static void pass_arg1(MacroAssembler* masm, Register arg) { + masm->push(arg); } -void MacroAssembler::verify_oop_addr(Address addr, const char* s) { - if (!VerifyOops) return; - // Pass register number to verify_oop_subroutine - char* b = new char[strlen(s) + 50]; - sprintf(b, "verify_oop_addr: %s", s); - pushq(rax); // save rax - movq(addr, rax); - pushq(rax); // pass register argument - - - // avoid using pushptr, as it modifies scratch registers - // and our contract is not to modify anything - ExternalAddress buffer((address)b); - movptr(rax, buffer.addr()); - pushq(rax); - - // call indirectly to solve generation ordering problem - movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address())); - call(rax); // no alignment requirement - // everything popped by receiver +static void pass_arg2(MacroAssembler* masm, Register arg) { + masm->push(arg); } - -void MacroAssembler::stop(const char* msg) { - address rip = pc(); - pushaq(); // get regs on stack - lea(c_rarg0, ExternalAddress((address) msg)); - lea(c_rarg1, InternalAddress(rip)); - movq(c_rarg2, rsp); // pass pointer to regs array - andq(rsp, -16); // align stack as required by ABI - call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug))); - hlt(); -} - -void MacroAssembler::warn(const char* msg) { - pushq(r12); - movq(r12, rsp); - andq(rsp, -16); // align stack as required by push_CPU_state and call - - push_CPU_state(); // keeps alignment at 16 bytes - lea(c_rarg0, ExternalAddress((address) msg)); - call_VM_leaf(CAST_FROM_FN_PTR(address, warning), c_rarg0); - pop_CPU_state(); - - movq(rsp, r12); - popq(r12); +static void pass_arg3(MacroAssembler* masm, Register arg) { + masm->push(arg); } #ifndef PRODUCT extern "C" void findpc(intptr_t x); #endif -void MacroAssembler::debug(char* msg, int64_t pc, int64_t regs[]) { +void MacroAssembler::debug32(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip, char* msg) { // In order to get locks to work, we need to fake a in_VM state - if (ShowMessageBoxOnError ) { + JavaThread* thread = JavaThread::current(); + JavaThreadState saved_state = thread->thread_state(); + thread->set_thread_state(_thread_in_vm); + if (ShowMessageBoxOnError) { JavaThread* thread = JavaThread::current(); JavaThreadState saved_state = thread->thread_state(); thread->set_thread_state(_thread_in_vm); -#ifndef PRODUCT if (CountBytecodes || TraceBytecodes || StopInterpreterAt) { ttyLocker ttyl; BytecodeCounter::print(); } -#endif // To see where a verify_oop failed, get $ebx+40/X for this frame. - // XXX correct this offset for amd64 // This is the value of eip which points to where verify_oop will return. if (os::message_box(msg, "Execution stopped, print registers?")) { ttyLocker ttyl; - tty->print_cr("rip = 0x%016lx", pc); + tty->print_cr("eip = 0x%08x", eip); #ifndef PRODUCT tty->cr(); - findpc(pc); + findpc(eip); tty->cr(); #endif - tty->print_cr("rax = 0x%016lx", regs[15]); - tty->print_cr("rbx = 0x%016lx", regs[12]); - tty->print_cr("rcx = 0x%016lx", regs[14]); - tty->print_cr("rdx = 0x%016lx", regs[13]); - tty->print_cr("rdi = 0x%016lx", regs[8]); - tty->print_cr("rsi = 0x%016lx", regs[9]); - tty->print_cr("rbp = 0x%016lx", regs[10]); - tty->print_cr("rsp = 0x%016lx", regs[11]); - tty->print_cr("r8 = 0x%016lx", regs[7]); - tty->print_cr("r9 = 0x%016lx", regs[6]); - tty->print_cr("r10 = 0x%016lx", regs[5]); - tty->print_cr("r11 = 0x%016lx", regs[4]); - tty->print_cr("r12 = 0x%016lx", regs[3]); - tty->print_cr("r13 = 0x%016lx", regs[2]); - tty->print_cr("r14 = 0x%016lx", regs[1]); - tty->print_cr("r15 = 0x%016lx", regs[0]); + tty->print_cr("rax, = 0x%08x", rax); + tty->print_cr("rbx, = 0x%08x", rbx); + tty->print_cr("rcx = 0x%08x", rcx); + tty->print_cr("rdx = 0x%08x", rdx); + tty->print_cr("rdi = 0x%08x", rdi); + tty->print_cr("rsi = 0x%08x", rsi); + tty->print_cr("rbp, = 0x%08x", rbp); + tty->print_cr("rsp = 0x%08x", rsp); BREAKPOINT; } - ThreadStateTransition::transition(thread, _thread_in_vm, saved_state); } else { ttyLocker ttyl; - ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n", - msg); + ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n", msg); + assert(false, "DEBUG MESSAGE"); } + ThreadStateTransition::transition(thread, _thread_in_vm, saved_state); } -void MacroAssembler::os_breakpoint() { - // instead of directly emitting a breakpoint, call os:breakpoint for - // better debugability - // This shouldn't need alignment, it's an empty function - call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); +void MacroAssembler::stop(const char* msg) { + ExternalAddress message((address)msg); + // push address of message + pushptr(message.addr()); + { Label L; call(L, relocInfo::none); bind(L); } // push eip + pusha(); // push registers + call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug32))); + hlt(); } -// Write serialization page so VM thread can do a pseudo remote membar. -// We use the current thread pointer to calculate a thread specific -// offset to write to within the page. This minimizes bus traffic -// due to cache line collision. -void MacroAssembler::serialize_memory(Register thread, - Register tmp) { +void MacroAssembler::warn(const char* msg) { + push_CPU_state(); - movl(tmp, thread); - shrl(tmp, os::get_serialize_page_shift_count()); - andl(tmp, (os::vm_page_size() - sizeof(int))); + ExternalAddress message((address) msg); + // push address of message + pushptr(message.addr()); - Address index(noreg, tmp, Address::times_1); - ExternalAddress page(os::get_memory_serialize_page()); - - movptr(ArrayAddress(page, index), tmp); + call(RuntimeAddress(CAST_FROM_FN_PTR(address, warning))); + addl(rsp, wordSize); // discard argument + pop_CPU_state(); } -void MacroAssembler::verify_tlab() { -#ifdef ASSERT - if (UseTLAB) { - Label next, ok; - Register t1 = rsi; +#else // _LP64 - pushq(t1); +// 64 bit versions - movq(t1, Address(r15_thread, in_bytes(JavaThread::tlab_top_offset()))); - cmpq(t1, Address(r15_thread, in_bytes(JavaThread::tlab_start_offset()))); - jcc(Assembler::aboveEqual, next); - stop("assert(top >= start)"); - should_not_reach_here(); +Address MacroAssembler::as_Address(AddressLiteral adr) { + // amd64 always does this as a pc-rel + // we can be absolute or disp based on the instruction type + // jmp/call are displacements others are absolute + assert(!adr.is_lval(), "must be rval"); + assert(reachable(adr), "must be"); + return Address((int32_t)(intptr_t)(adr.target() - pc()), adr.target(), adr.reloc()); - bind(next); - movq(t1, Address(r15_thread, in_bytes(JavaThread::tlab_end_offset()))); - cmpq(t1, Address(r15_thread, in_bytes(JavaThread::tlab_top_offset()))); - jcc(Assembler::aboveEqual, ok); - stop("assert(top <= end)"); - should_not_reach_here(); - - bind(ok); - - popq(t1); - } -#endif } -// Defines obj, preserves var_size_in_bytes -void MacroAssembler::eden_allocate(Register obj, - Register var_size_in_bytes, - int con_size_in_bytes, - Register t1, - Label& slow_case) { - assert(obj == rax, "obj must be in rax for cmpxchg"); - assert_different_registers(obj, var_size_in_bytes, t1); - Register end = t1; - Label retry; - bind(retry); - ExternalAddress heap_top((address) Universe::heap()->top_addr()); - movptr(obj, heap_top); - if (var_size_in_bytes == noreg) { - leaq(end, Address(obj, con_size_in_bytes)); - } else { - leaq(end, Address(obj, var_size_in_bytes, Address::times_1)); - } - // if end < obj then we wrapped around => object too long => slow case - cmpq(end, obj); - jcc(Assembler::below, slow_case); - cmpptr(end, ExternalAddress((address) Universe::heap()->end_addr())); - - jcc(Assembler::above, slow_case); - // Compare obj with the top addr, and if still equal, store the new - // top addr in end at the address of the top addr pointer. Sets ZF - // if was equal, and clears it otherwise. Use lock prefix for - // atomicity on MPs. - if (os::is_MP()) { - lock(); - } - cmpxchgptr(end, heap_top); - // if someone beat us on the allocation, try again, otherwise continue - jcc(Assembler::notEqual, retry); +Address MacroAssembler::as_Address(ArrayAddress adr) { + AddressLiteral base = adr.base(); + lea(rscratch1, base); + Address index = adr.index(); + assert(index._disp == 0, "must not have disp"); // maybe it can? + Address array(rscratch1, index._index, index._scale, index._disp); + return array; } -// Defines obj, preserves var_size_in_bytes, okay for t2 == var_size_in_bytes. -void MacroAssembler::tlab_allocate(Register obj, - Register var_size_in_bytes, - int con_size_in_bytes, - Register t1, - Register t2, - Label& slow_case) { - assert_different_registers(obj, t1, t2); - assert_different_registers(obj, var_size_in_bytes, t1); - Register end = t2; - - verify_tlab(); - - movq(obj, Address(r15_thread, JavaThread::tlab_top_offset())); - if (var_size_in_bytes == noreg) { - leaq(end, Address(obj, con_size_in_bytes)); - } else { - leaq(end, Address(obj, var_size_in_bytes, Address::times_1)); - } - cmpq(end, Address(r15_thread, JavaThread::tlab_end_offset())); - jcc(Assembler::above, slow_case); - - // update the tlab top pointer - movq(Address(r15_thread, JavaThread::tlab_top_offset()), end); - - // recover var_size_in_bytes if necessary - if (var_size_in_bytes == end) { - subq(var_size_in_bytes, obj); - } - verify_tlab(); -} - -// Preserves rbx and rdx. -void MacroAssembler::tlab_refill(Label& retry, - Label& try_eden, - Label& slow_case) { - Register top = rax; - Register t1 = rcx; - Register t2 = rsi; - Register t3 = r10; - Register thread_reg = r15_thread; - assert_different_registers(top, thread_reg, t1, t2, t3, - /* preserve: */ rbx, rdx); - Label do_refill, discard_tlab; - - if (CMSIncrementalMode || !Universe::heap()->supports_inline_contig_alloc()) { - // No allocation in the shared eden. - jmp(slow_case); - } - - movq(top, Address(thread_reg, in_bytes(JavaThread::tlab_top_offset()))); - movq(t1, Address(thread_reg, in_bytes(JavaThread::tlab_end_offset()))); - - // calculate amount of free space - subq(t1, top); - shrq(t1, LogHeapWordSize); - - // Retain tlab and allocate object in shared space if - // the amount free in the tlab is too large to discard. - cmpq(t1, Address(thread_reg, // size_t - in_bytes(JavaThread::tlab_refill_waste_limit_offset()))); - jcc(Assembler::lessEqual, discard_tlab); - - // Retain - mov64(t2, ThreadLocalAllocBuffer::refill_waste_limit_increment()); - addq(Address(thread_reg, // size_t - in_bytes(JavaThread::tlab_refill_waste_limit_offset())), - t2); - if (TLABStats) { - // increment number of slow_allocations - addl(Address(thread_reg, // unsigned int - in_bytes(JavaThread::tlab_slow_allocations_offset())), - 1); - } - jmp(try_eden); - - bind(discard_tlab); - if (TLABStats) { - // increment number of refills - addl(Address(thread_reg, // unsigned int - in_bytes(JavaThread::tlab_number_of_refills_offset())), - 1); - // accumulate wastage -- t1 is amount free in tlab - addl(Address(thread_reg, // unsigned int - in_bytes(JavaThread::tlab_fast_refill_waste_offset())), - t1); - } - - // if tlab is currently allocated (top or end != null) then - // fill [top, end + alignment_reserve) with array object - testq(top, top); - jcc(Assembler::zero, do_refill); - - // set up the mark word - mov64(t3, (int64_t) markOopDesc::prototype()->copy_set_hash(0x2)); - movq(Address(top, oopDesc::mark_offset_in_bytes()), t3); - // set the length to the remaining space - subq(t1, typeArrayOopDesc::header_size(T_INT)); - addq(t1, (int)ThreadLocalAllocBuffer::alignment_reserve()); - shlq(t1, log2_intptr(HeapWordSize / sizeof(jint))); - movq(Address(top, arrayOopDesc::length_offset_in_bytes()), t1); - // set klass to intArrayKlass - movptr(t1, ExternalAddress((address) Universe::intArrayKlassObj_addr())); - // store klass last. concurrent gcs assumes klass length is valid if - // klass field is not null. - store_klass(top, t1); - - // refill the tlab with an eden allocation - bind(do_refill); - movq(t1, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset()))); - shlq(t1, LogHeapWordSize); - // add object_size ?? - eden_allocate(top, t1, 0, t2, slow_case); - - // Check that t1 was preserved in eden_allocate. -#ifdef ASSERT - if (UseTLAB) { - Label ok; - Register tsize = rsi; - assert_different_registers(tsize, thread_reg, t1); - pushq(tsize); - movq(tsize, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset()))); - shlq(tsize, LogHeapWordSize); - cmpq(t1, tsize); - jcc(Assembler::equal, ok); - stop("assert(t1 != tlab size)"); - should_not_reach_here(); - - bind(ok); - popq(tsize); - } -#endif - movq(Address(thread_reg, in_bytes(JavaThread::tlab_start_offset())), top); - movq(Address(thread_reg, in_bytes(JavaThread::tlab_top_offset())), top); - addq(top, t1); - subq(top, (int)ThreadLocalAllocBuffer::alignment_reserve_in_bytes()); - movq(Address(thread_reg, in_bytes(JavaThread::tlab_end_offset())), top); - verify_tlab(); - jmp(retry); -} - - -int MacroAssembler::biased_locking_enter(Register lock_reg, Register obj_reg, Register swap_reg, Register tmp_reg, +int MacroAssembler::biased_locking_enter(Register lock_reg, + Register obj_reg, + Register swap_reg, + Register tmp_reg, bool swap_reg_contains_mark, - Label& done, Label* slow_case, + Label& done, + Label* slow_case, BiasedLockingCounters* counters) { assert(UseBiasedLocking, "why call this otherwise?"); assert(swap_reg == rax, "swap_reg must be rax for cmpxchgq"); @@ -5129,6 +4958,426 @@ int MacroAssembler::biased_locking_enter(Register lock_reg, Register obj_reg, Re return null_check_offset; } +void MacroAssembler::call_VM_leaf_base(address entry_point, int num_args) { + Label L, E; + +#ifdef _WIN64 + // Windows always allocates space for it's register args + assert(num_args <= 4, "only register arguments supported"); + subq(rsp, frame::arg_reg_save_area_bytes); +#endif + + // Align stack if necessary + testl(rsp, 15); + jcc(Assembler::zero, L); + + subq(rsp, 8); + { + call(RuntimeAddress(entry_point)); + } + addq(rsp, 8); + jmp(E); + + bind(L); + { + call(RuntimeAddress(entry_point)); + } + + bind(E); + +#ifdef _WIN64 + // restore stack pointer + addq(rsp, frame::arg_reg_save_area_bytes); +#endif + +} + +void MacroAssembler::cmp64(Register src1, AddressLiteral src2) { + assert(!src2.is_lval(), "should use cmpptr"); + + if (reachable(src2)) { + cmpq(src1, as_Address(src2)); + } else { + lea(rscratch1, src2); + Assembler::cmpq(src1, Address(rscratch1, 0)); + } +} + +int MacroAssembler::corrected_idivq(Register reg) { + // Full implementation of Java ldiv and lrem; checks for special + // case as described in JVM spec., p.243 & p.271. The function + // returns the (pc) offset of the idivl instruction - may be needed + // for implicit exceptions. + // + // normal case special case + // + // input : rax: dividend min_long + // reg: divisor (may not be eax/edx) -1 + // + // output: rax: quotient (= rax idiv reg) min_long + // rdx: remainder (= rax irem reg) 0 + assert(reg != rax && reg != rdx, "reg cannot be rax or rdx register"); + static const int64_t min_long = 0x8000000000000000; + Label normal_case, special_case; + + // check for special case + cmp64(rax, ExternalAddress((address) &min_long)); + jcc(Assembler::notEqual, normal_case); + xorl(rdx, rdx); // prepare rdx for possible special case (where + // remainder = 0) + cmpq(reg, -1); + jcc(Assembler::equal, special_case); + + // handle normal case + bind(normal_case); + cdqq(); + int idivq_offset = offset(); + idivq(reg); + + // normal and special case exit + bind(special_case); + + return idivq_offset; +} + +void MacroAssembler::decrementq(Register reg, int value) { + if (value == min_jint) { subq(reg, value); return; } + if (value < 0) { incrementq(reg, -value); return; } + if (value == 0) { ; return; } + if (value == 1 && UseIncDec) { decq(reg) ; return; } + /* else */ { subq(reg, value) ; return; } +} + +void MacroAssembler::decrementq(Address dst, int value) { + if (value == min_jint) { subq(dst, value); return; } + if (value < 0) { incrementq(dst, -value); return; } + if (value == 0) { ; return; } + if (value == 1 && UseIncDec) { decq(dst) ; return; } + /* else */ { subq(dst, value) ; return; } +} + +void MacroAssembler::fat_nop() { + // A 5 byte nop that is safe for patching (see patch_verified_entry) + // Recommened sequence from 'Software Optimization Guide for the AMD + // Hammer Processor' + emit_byte(0x66); + emit_byte(0x66); + emit_byte(0x90); + emit_byte(0x66); + emit_byte(0x90); +} + +void MacroAssembler::incrementq(Register reg, int value) { + if (value == min_jint) { addq(reg, value); return; } + if (value < 0) { decrementq(reg, -value); return; } + if (value == 0) { ; return; } + if (value == 1 && UseIncDec) { incq(reg) ; return; } + /* else */ { addq(reg, value) ; return; } +} + +void MacroAssembler::incrementq(Address dst, int value) { + if (value == min_jint) { addq(dst, value); return; } + if (value < 0) { decrementq(dst, -value); return; } + if (value == 0) { ; return; } + if (value == 1 && UseIncDec) { incq(dst) ; return; } + /* else */ { addq(dst, value) ; return; } +} + +// 32bit can do a case table jump in one instruction but we no longer allow the base +// to be installed in the Address class +void MacroAssembler::jump(ArrayAddress entry) { + lea(rscratch1, entry.base()); + Address dispatch = entry.index(); + assert(dispatch._base == noreg, "must be"); + dispatch._base = rscratch1; + jmp(dispatch); +} + +void MacroAssembler::lcmp2int(Register x_hi, Register x_lo, Register y_hi, Register y_lo) { + ShouldNotReachHere(); // 64bit doesn't use two regs + cmpq(x_lo, y_lo); +} + +void MacroAssembler::lea(Register dst, AddressLiteral src) { + mov_literal64(dst, (intptr_t)src.target(), src.rspec()); +} + +void MacroAssembler::lea(Address dst, AddressLiteral adr) { + mov_literal64(rscratch1, (intptr_t)adr.target(), adr.rspec()); + movptr(dst, rscratch1); +} + +void MacroAssembler::leave() { + // %%% is this really better? Why not on 32bit too? + emit_byte(0xC9); // LEAVE +} + +void MacroAssembler::lneg(Register hi, Register lo) { + ShouldNotReachHere(); // 64bit doesn't use two regs + negq(lo); +} + +void MacroAssembler::movoop(Register dst, jobject obj) { + mov_literal64(dst, (intptr_t)obj, oop_Relocation::spec_for_immediate()); +} + +void MacroAssembler::movoop(Address dst, jobject obj) { + mov_literal64(rscratch1, (intptr_t)obj, oop_Relocation::spec_for_immediate()); + movq(dst, rscratch1); +} + +void MacroAssembler::movptr(Register dst, AddressLiteral src) { + if (src.is_lval()) { + mov_literal64(dst, (intptr_t)src.target(), src.rspec()); + } else { + if (reachable(src)) { + movq(dst, as_Address(src)); + } else { + lea(rscratch1, src); + movq(dst, Address(rscratch1,0)); + } + } +} + +void MacroAssembler::movptr(ArrayAddress dst, Register src) { + movq(as_Address(dst), src); +} + +void MacroAssembler::movptr(Register dst, ArrayAddress src) { + movq(dst, as_Address(src)); +} + +// src should NEVER be a real pointer. Use AddressLiteral for true pointers +void MacroAssembler::movptr(Address dst, intptr_t src) { + mov64(rscratch1, src); + movq(dst, rscratch1); +} + +// These are mostly for initializing NULL +void MacroAssembler::movptr(Address dst, int32_t src) { + movslq(dst, src); +} + +void MacroAssembler::movptr(Register dst, int32_t src) { + mov64(dst, (intptr_t)src); +} + +void MacroAssembler::pushoop(jobject obj) { + movoop(rscratch1, obj); + push(rscratch1); +} + +void MacroAssembler::pushptr(AddressLiteral src) { + lea(rscratch1, src); + if (src.is_lval()) { + push(rscratch1); + } else { + pushq(Address(rscratch1, 0)); + } +} + +void MacroAssembler::reset_last_Java_frame(bool clear_fp, + bool clear_pc) { + // we must set sp to zero to clear frame + movptr(Address(r15_thread, JavaThread::last_Java_sp_offset()), (int32_t)NULL_WORD); + // must clear fp, so that compiled frames are not confused; it is + // possible that we need it only for debugging + if (clear_fp) { + movptr(Address(r15_thread, JavaThread::last_Java_fp_offset()), (int32_t)NULL_WORD); + } + + if (clear_pc) { + movptr(Address(r15_thread, JavaThread::last_Java_pc_offset()), (int32_t)NULL_WORD); + } +} + +void MacroAssembler::set_last_Java_frame(Register last_java_sp, + Register last_java_fp, + address last_java_pc) { + // determine last_java_sp register + if (!last_java_sp->is_valid()) { + last_java_sp = rsp; + } + + // last_java_fp is optional + if (last_java_fp->is_valid()) { + movptr(Address(r15_thread, JavaThread::last_Java_fp_offset()), + last_java_fp); + } + + // last_java_pc is optional + if (last_java_pc != NULL) { + Address java_pc(r15_thread, + JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset()); + lea(rscratch1, InternalAddress(last_java_pc)); + movptr(java_pc, rscratch1); + } + + movptr(Address(r15_thread, JavaThread::last_Java_sp_offset()), last_java_sp); +} + +static void pass_arg0(MacroAssembler* masm, Register arg) { + if (c_rarg0 != arg ) { + masm->mov(c_rarg0, arg); + } +} + +static void pass_arg1(MacroAssembler* masm, Register arg) { + if (c_rarg1 != arg ) { + masm->mov(c_rarg1, arg); + } +} + +static void pass_arg2(MacroAssembler* masm, Register arg) { + if (c_rarg2 != arg ) { + masm->mov(c_rarg2, arg); + } +} + +static void pass_arg3(MacroAssembler* masm, Register arg) { + if (c_rarg3 != arg ) { + masm->mov(c_rarg3, arg); + } +} + +void MacroAssembler::stop(const char* msg) { + address rip = pc(); + pusha(); // get regs on stack + lea(c_rarg0, ExternalAddress((address) msg)); + lea(c_rarg1, InternalAddress(rip)); + movq(c_rarg2, rsp); // pass pointer to regs array + andq(rsp, -16); // align stack as required by ABI + call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug64))); + hlt(); +} + +void MacroAssembler::warn(const char* msg) { + push(r12); + movq(r12, rsp); + andq(rsp, -16); // align stack as required by push_CPU_state and call + + push_CPU_state(); // keeps alignment at 16 bytes + lea(c_rarg0, ExternalAddress((address) msg)); + call_VM_leaf(CAST_FROM_FN_PTR(address, warning), c_rarg0); + pop_CPU_state(); + + movq(rsp, r12); + pop(r12); +} + +#ifndef PRODUCT +extern "C" void findpc(intptr_t x); +#endif + +void MacroAssembler::debug64(char* msg, int64_t pc, int64_t regs[]) { + // In order to get locks to work, we need to fake a in_VM state + if (ShowMessageBoxOnError ) { + JavaThread* thread = JavaThread::current(); + JavaThreadState saved_state = thread->thread_state(); + thread->set_thread_state(_thread_in_vm); +#ifndef PRODUCT + if (CountBytecodes || TraceBytecodes || StopInterpreterAt) { + ttyLocker ttyl; + BytecodeCounter::print(); + } +#endif + // To see where a verify_oop failed, get $ebx+40/X for this frame. + // XXX correct this offset for amd64 + // This is the value of eip which points to where verify_oop will return. + if (os::message_box(msg, "Execution stopped, print registers?")) { + ttyLocker ttyl; + tty->print_cr("rip = 0x%016lx", pc); +#ifndef PRODUCT + tty->cr(); + findpc(pc); + tty->cr(); +#endif + tty->print_cr("rax = 0x%016lx", regs[15]); + tty->print_cr("rbx = 0x%016lx", regs[12]); + tty->print_cr("rcx = 0x%016lx", regs[14]); + tty->print_cr("rdx = 0x%016lx", regs[13]); + tty->print_cr("rdi = 0x%016lx", regs[8]); + tty->print_cr("rsi = 0x%016lx", regs[9]); + tty->print_cr("rbp = 0x%016lx", regs[10]); + tty->print_cr("rsp = 0x%016lx", regs[11]); + tty->print_cr("r8 = 0x%016lx", regs[7]); + tty->print_cr("r9 = 0x%016lx", regs[6]); + tty->print_cr("r10 = 0x%016lx", regs[5]); + tty->print_cr("r11 = 0x%016lx", regs[4]); + tty->print_cr("r12 = 0x%016lx", regs[3]); + tty->print_cr("r13 = 0x%016lx", regs[2]); + tty->print_cr("r14 = 0x%016lx", regs[1]); + tty->print_cr("r15 = 0x%016lx", regs[0]); + BREAKPOINT; + } + ThreadStateTransition::transition(thread, _thread_in_vm, saved_state); + } else { + ttyLocker ttyl; + ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n", + msg); + } +} + +#endif // _LP64 + +// Now versions that are common to 32/64 bit + +void MacroAssembler::addptr(Register dst, int32_t imm32) { + LP64_ONLY(addq(dst, imm32)) NOT_LP64(addl(dst, imm32)); +} + +void MacroAssembler::addptr(Register dst, Register src) { + LP64_ONLY(addq(dst, src)) NOT_LP64(addl(dst, src)); +} + +void MacroAssembler::addptr(Address dst, Register src) { + LP64_ONLY(addq(dst, src)) NOT_LP64(addl(dst, src)); +} + +void MacroAssembler::align(int modulus) { + if (offset() % modulus != 0) { + nop(modulus - (offset() % modulus)); + } +} + +void MacroAssembler::andpd(XMMRegister dst, AddressLiteral src) { + andpd(dst, as_Address(src)); +} + +void MacroAssembler::andptr(Register dst, int32_t imm32) { + LP64_ONLY(andq(dst, imm32)) NOT_LP64(andl(dst, imm32)); +} + +void MacroAssembler::atomic_incl(AddressLiteral counter_addr) { + pushf(); + if (os::is_MP()) + lock(); + incrementl(counter_addr); + popf(); +} + +// Writes to stack successive pages until offset reached to check for +// stack overflow + shadow pages. This clobbers tmp. +void MacroAssembler::bang_stack_size(Register size, Register tmp) { + movptr(tmp, rsp); + // Bang stack for total size given plus shadow page size. + // Bang one page at a time because large size can bang beyond yellow and + // red zones. + Label loop; + bind(loop); + movl(Address(tmp, (-os::vm_page_size())), size ); + subptr(tmp, os::vm_page_size()); + subl(size, os::vm_page_size()); + jcc(Assembler::greater, loop); + + // Bang down shadow pages too. + // The -1 because we already subtracted 1 page. + for (int i = 0; i< StackShadowPages-1; i++) { + // this could be any sized move but this is can be a debugging crumb + // so the bigger the better. + movptr(Address(tmp, (-i*os::vm_page_size())), size ); + } +} void MacroAssembler::biased_locking_exit(Register obj_reg, Register temp_reg, Label& done) { assert(UseBiasedLocking, "why call this otherwise?"); @@ -5139,41 +5388,1943 @@ void MacroAssembler::biased_locking_exit(Register obj_reg, Register temp_reg, La // a higher level. Second, if the bias was revoked while we held the // lock, the object could not be rebiased toward another thread, so // the bias bit would be clear. - movq(temp_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); - andq(temp_reg, markOopDesc::biased_lock_mask_in_place); - cmpq(temp_reg, markOopDesc::biased_lock_pattern); + movptr(temp_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); + andptr(temp_reg, markOopDesc::biased_lock_mask_in_place); + cmpptr(temp_reg, markOopDesc::biased_lock_pattern); jcc(Assembler::equal, done); } +void MacroAssembler::c2bool(Register x) { + // implements x == 0 ? 0 : 1 + // note: must only look at least-significant byte of x + // since C-style booleans are stored in one byte + // only! (was bug) + andl(x, 0xFF); + setb(Assembler::notZero, x); +} + +// Wouldn't need if AddressLiteral version had new name +void MacroAssembler::call(Label& L, relocInfo::relocType rtype) { + Assembler::call(L, rtype); +} + +void MacroAssembler::call(Register entry) { + Assembler::call(entry); +} + +void MacroAssembler::call(AddressLiteral entry) { + if (reachable(entry)) { + Assembler::call_literal(entry.target(), entry.rspec()); + } else { + lea(rscratch1, entry); + Assembler::call(rscratch1); + } +} + +// Implementation of call_VM versions + +void MacroAssembler::call_VM(Register oop_result, + address entry_point, + bool check_exceptions) { + Label C, E; + call(C, relocInfo::none); + jmp(E); + + bind(C); + call_VM_helper(oop_result, entry_point, 0, check_exceptions); + ret(0); + + bind(E); +} + +void MacroAssembler::call_VM(Register oop_result, + address entry_point, + Register arg_1, + bool check_exceptions) { + Label C, E; + call(C, relocInfo::none); + jmp(E); + + bind(C); + pass_arg1(this, arg_1); + call_VM_helper(oop_result, entry_point, 1, check_exceptions); + ret(0); + + bind(E); +} + +void MacroAssembler::call_VM(Register oop_result, + address entry_point, + Register arg_1, + Register arg_2, + bool check_exceptions) { + Label C, E; + call(C, relocInfo::none); + jmp(E); + + bind(C); + + LP64_ONLY(assert(arg_1 != c_rarg2, "smashed arg")); + + pass_arg2(this, arg_2); + pass_arg1(this, arg_1); + call_VM_helper(oop_result, entry_point, 2, check_exceptions); + ret(0); + + bind(E); +} + +void MacroAssembler::call_VM(Register oop_result, + address entry_point, + Register arg_1, + Register arg_2, + Register arg_3, + bool check_exceptions) { + Label C, E; + call(C, relocInfo::none); + jmp(E); + + bind(C); + + LP64_ONLY(assert(arg_1 != c_rarg3, "smashed arg")); + LP64_ONLY(assert(arg_2 != c_rarg3, "smashed arg")); + pass_arg3(this, arg_3); + + LP64_ONLY(assert(arg_1 != c_rarg2, "smashed arg")); + pass_arg2(this, arg_2); + + pass_arg1(this, arg_1); + call_VM_helper(oop_result, entry_point, 3, check_exceptions); + ret(0); + + bind(E); +} + +void MacroAssembler::call_VM(Register oop_result, + Register last_java_sp, + address entry_point, + int number_of_arguments, + bool check_exceptions) { + Register thread = LP64_ONLY(r15_thread) NOT_LP64(noreg); + call_VM_base(oop_result, thread, last_java_sp, entry_point, number_of_arguments, check_exceptions); +} + +void MacroAssembler::call_VM(Register oop_result, + Register last_java_sp, + address entry_point, + Register arg_1, + bool check_exceptions) { + pass_arg1(this, arg_1); + call_VM(oop_result, last_java_sp, entry_point, 1, check_exceptions); +} + +void MacroAssembler::call_VM(Register oop_result, + Register last_java_sp, + address entry_point, + Register arg_1, + Register arg_2, + bool check_exceptions) { + + LP64_ONLY(assert(arg_1 != c_rarg2, "smashed arg")); + pass_arg2(this, arg_2); + pass_arg1(this, arg_1); + call_VM(oop_result, last_java_sp, entry_point, 2, check_exceptions); +} + +void MacroAssembler::call_VM(Register oop_result, + Register last_java_sp, + address entry_point, + Register arg_1, + Register arg_2, + Register arg_3, + bool check_exceptions) { + LP64_ONLY(assert(arg_1 != c_rarg3, "smashed arg")); + LP64_ONLY(assert(arg_2 != c_rarg3, "smashed arg")); + pass_arg3(this, arg_3); + LP64_ONLY(assert(arg_1 != c_rarg2, "smashed arg")); + pass_arg2(this, arg_2); + pass_arg1(this, arg_1); + call_VM(oop_result, last_java_sp, entry_point, 3, check_exceptions); +} + +void MacroAssembler::call_VM_base(Register oop_result, + Register java_thread, + Register last_java_sp, + address entry_point, + int number_of_arguments, + bool check_exceptions) { + // determine java_thread register + if (!java_thread->is_valid()) { +#ifdef _LP64 + java_thread = r15_thread; +#else + java_thread = rdi; + get_thread(java_thread); +#endif // LP64 + } + // determine last_java_sp register + if (!last_java_sp->is_valid()) { + last_java_sp = rsp; + } + // debugging support + assert(number_of_arguments >= 0 , "cannot have negative number of arguments"); + LP64_ONLY(assert(java_thread == r15_thread, "unexpected register")); + assert(java_thread != oop_result , "cannot use the same register for java_thread & oop_result"); + assert(java_thread != last_java_sp, "cannot use the same register for java_thread & last_java_sp"); + + // push java thread (becomes first argument of C function) + + NOT_LP64(push(java_thread); number_of_arguments++); + LP64_ONLY(mov(c_rarg0, r15_thread)); + + // set last Java frame before call + assert(last_java_sp != rbp, "can't use ebp/rbp"); + + // Only interpreter should have to set fp + set_last_Java_frame(java_thread, last_java_sp, rbp, NULL); + + // do the call, remove parameters + MacroAssembler::call_VM_leaf_base(entry_point, number_of_arguments); + + // restore the thread (cannot use the pushed argument since arguments + // may be overwritten by C code generated by an optimizing compiler); + // however can use the register value directly if it is callee saved. + if (LP64_ONLY(true ||) java_thread == rdi || java_thread == rsi) { + // rdi & rsi (also r15) are callee saved -> nothing to do +#ifdef ASSERT + guarantee(java_thread != rax, "change this code"); + push(rax); + { Label L; + get_thread(rax); + cmpptr(java_thread, rax); + jcc(Assembler::equal, L); + stop("MacroAssembler::call_VM_base: rdi not callee saved?"); + bind(L); + } + pop(rax); +#endif + } else { + get_thread(java_thread); + } + // reset last Java frame + // Only interpreter should have to clear fp + reset_last_Java_frame(java_thread, true, false); + +#ifndef CC_INTERP + // C++ interp handles this in the interpreter + check_and_handle_popframe(java_thread); + check_and_handle_earlyret(java_thread); +#endif /* CC_INTERP */ + + if (check_exceptions) { + // check for pending exceptions (java_thread is set upon return) + cmpptr(Address(java_thread, Thread::pending_exception_offset()), (int32_t) NULL_WORD); +#ifndef _LP64 + jump_cc(Assembler::notEqual, + RuntimeAddress(StubRoutines::forward_exception_entry())); +#else + // This used to conditionally jump to forward_exception however it is + // possible if we relocate that the branch will not reach. So we must jump + // around so we can always reach + + Label ok; + jcc(Assembler::equal, ok); + jump(RuntimeAddress(StubRoutines::forward_exception_entry())); + bind(ok); +#endif // LP64 + } + + // get oop result if there is one and reset the value in the thread + if (oop_result->is_valid()) { + movptr(oop_result, Address(java_thread, JavaThread::vm_result_offset())); + movptr(Address(java_thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD); + verify_oop(oop_result, "broken oop in call_VM_base"); + } +} + +void MacroAssembler::call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions) { + + // Calculate the value for last_Java_sp + // somewhat subtle. call_VM does an intermediate call + // which places a return address on the stack just under the + // stack pointer as the user finsihed with it. This allows + // use to retrieve last_Java_pc from last_Java_sp[-1]. + // On 32bit we then have to push additional args on the stack to accomplish + // the actual requested call. On 64bit call_VM only can use register args + // so the only extra space is the return address that call_VM created. + // This hopefully explains the calculations here. + +#ifdef _LP64 + // We've pushed one address, correct last_Java_sp + lea(rax, Address(rsp, wordSize)); +#else + lea(rax, Address(rsp, (1 + number_of_arguments) * wordSize)); +#endif // LP64 + + call_VM_base(oop_result, noreg, rax, entry_point, number_of_arguments, check_exceptions); + +} + +void MacroAssembler::call_VM_leaf(address entry_point, int number_of_arguments) { + call_VM_leaf_base(entry_point, number_of_arguments); +} + +void MacroAssembler::call_VM_leaf(address entry_point, Register arg_0) { + pass_arg0(this, arg_0); + call_VM_leaf(entry_point, 1); +} + +void MacroAssembler::call_VM_leaf(address entry_point, Register arg_0, Register arg_1) { + + LP64_ONLY(assert(arg_0 != c_rarg1, "smashed arg")); + pass_arg1(this, arg_1); + pass_arg0(this, arg_0); + call_VM_leaf(entry_point, 2); +} + +void MacroAssembler::call_VM_leaf(address entry_point, Register arg_0, Register arg_1, Register arg_2) { + LP64_ONLY(assert(arg_0 != c_rarg2, "smashed arg")); + LP64_ONLY(assert(arg_1 != c_rarg2, "smashed arg")); + pass_arg2(this, arg_2); + LP64_ONLY(assert(arg_0 != c_rarg1, "smashed arg")); + pass_arg1(this, arg_1); + pass_arg0(this, arg_0); + call_VM_leaf(entry_point, 3); +} + +void MacroAssembler::check_and_handle_earlyret(Register java_thread) { +} + +void MacroAssembler::check_and_handle_popframe(Register java_thread) { +} + +void MacroAssembler::cmp32(AddressLiteral src1, int32_t imm) { + if (reachable(src1)) { + cmpl(as_Address(src1), imm); + } else { + lea(rscratch1, src1); + cmpl(Address(rscratch1, 0), imm); + } +} + +void MacroAssembler::cmp32(Register src1, AddressLiteral src2) { + assert(!src2.is_lval(), "use cmpptr"); + if (reachable(src2)) { + cmpl(src1, as_Address(src2)); + } else { + lea(rscratch1, src2); + cmpl(src1, Address(rscratch1, 0)); + } +} + +void MacroAssembler::cmp32(Register src1, int32_t imm) { + Assembler::cmpl(src1, imm); +} + +void MacroAssembler::cmp32(Register src1, Address src2) { + Assembler::cmpl(src1, src2); +} + +void MacroAssembler::cmpsd2int(XMMRegister opr1, XMMRegister opr2, Register dst, bool unordered_is_less) { + ucomisd(opr1, opr2); + + Label L; + if (unordered_is_less) { + movl(dst, -1); + jcc(Assembler::parity, L); + jcc(Assembler::below , L); + movl(dst, 0); + jcc(Assembler::equal , L); + increment(dst); + } else { // unordered is greater + movl(dst, 1); + jcc(Assembler::parity, L); + jcc(Assembler::above , L); + movl(dst, 0); + jcc(Assembler::equal , L); + decrementl(dst); + } + bind(L); +} + +void MacroAssembler::cmpss2int(XMMRegister opr1, XMMRegister opr2, Register dst, bool unordered_is_less) { + ucomiss(opr1, opr2); + + Label L; + if (unordered_is_less) { + movl(dst, -1); + jcc(Assembler::parity, L); + jcc(Assembler::below , L); + movl(dst, 0); + jcc(Assembler::equal , L); + increment(dst); + } else { // unordered is greater + movl(dst, 1); + jcc(Assembler::parity, L); + jcc(Assembler::above , L); + movl(dst, 0); + jcc(Assembler::equal , L); + decrementl(dst); + } + bind(L); +} + + +void MacroAssembler::cmp8(AddressLiteral src1, int imm) { + if (reachable(src1)) { + cmpb(as_Address(src1), imm); + } else { + lea(rscratch1, src1); + cmpb(Address(rscratch1, 0), imm); + } +} + +void MacroAssembler::cmpptr(Register src1, AddressLiteral src2) { +#ifdef _LP64 + if (src2.is_lval()) { + movptr(rscratch1, src2); + Assembler::cmpq(src1, rscratch1); + } else if (reachable(src2)) { + cmpq(src1, as_Address(src2)); + } else { + lea(rscratch1, src2); + Assembler::cmpq(src1, Address(rscratch1, 0)); + } +#else + if (src2.is_lval()) { + cmp_literal32(src1, (int32_t) src2.target(), src2.rspec()); + } else { + cmpl(src1, as_Address(src2)); + } +#endif // _LP64 +} + +void MacroAssembler::cmpptr(Address src1, AddressLiteral src2) { + assert(src2.is_lval(), "not a mem-mem compare"); +#ifdef _LP64 + // moves src2's literal address + movptr(rscratch1, src2); + Assembler::cmpq(src1, rscratch1); +#else + cmp_literal32(src1, (int32_t) src2.target(), src2.rspec()); +#endif // _LP64 +} + +void MacroAssembler::locked_cmpxchgptr(Register reg, AddressLiteral adr) { + if (reachable(adr)) { + if (os::is_MP()) + lock(); + cmpxchgptr(reg, as_Address(adr)); + } else { + lea(rscratch1, adr); + if (os::is_MP()) + lock(); + cmpxchgptr(reg, Address(rscratch1, 0)); + } +} + +void MacroAssembler::cmpxchgptr(Register reg, Address adr) { + LP64_ONLY(cmpxchgq(reg, adr)) NOT_LP64(cmpxchgl(reg, adr)); +} + +void MacroAssembler::comisd(XMMRegister dst, AddressLiteral src) { + comisd(dst, as_Address(src)); +} + +void MacroAssembler::comiss(XMMRegister dst, AddressLiteral src) { + comiss(dst, as_Address(src)); +} + + +void MacroAssembler::cond_inc32(Condition cond, AddressLiteral counter_addr) { + Condition negated_cond = negate_condition(cond); + Label L; + jcc(negated_cond, L); + atomic_incl(counter_addr); + bind(L); +} + +int MacroAssembler::corrected_idivl(Register reg) { + // Full implementation of Java idiv and irem; checks for + // special case as described in JVM spec., p.243 & p.271. + // The function returns the (pc) offset of the idivl + // instruction - may be needed for implicit exceptions. + // + // normal case special case + // + // input : rax,: dividend min_int + // reg: divisor (may not be rax,/rdx) -1 + // + // output: rax,: quotient (= rax, idiv reg) min_int + // rdx: remainder (= rax, irem reg) 0 + assert(reg != rax && reg != rdx, "reg cannot be rax, or rdx register"); + const int min_int = 0x80000000; + Label normal_case, special_case; + + // check for special case + cmpl(rax, min_int); + jcc(Assembler::notEqual, normal_case); + xorl(rdx, rdx); // prepare rdx for possible special case (where remainder = 0) + cmpl(reg, -1); + jcc(Assembler::equal, special_case); + + // handle normal case + bind(normal_case); + cdql(); + int idivl_offset = offset(); + idivl(reg); + + // normal and special case exit + bind(special_case); + + return idivl_offset; +} + + + +void MacroAssembler::decrementl(Register reg, int value) { + if (value == min_jint) {subl(reg, value) ; return; } + if (value < 0) { incrementl(reg, -value); return; } + if (value == 0) { ; return; } + if (value == 1 && UseIncDec) { decl(reg) ; return; } + /* else */ { subl(reg, value) ; return; } +} + +void MacroAssembler::decrementl(Address dst, int value) { + if (value == min_jint) {subl(dst, value) ; return; } + if (value < 0) { incrementl(dst, -value); return; } + if (value == 0) { ; return; } + if (value == 1 && UseIncDec) { decl(dst) ; return; } + /* else */ { subl(dst, value) ; return; } +} + +void MacroAssembler::division_with_shift (Register reg, int shift_value) { + assert (shift_value > 0, "illegal shift value"); + Label _is_positive; + testl (reg, reg); + jcc (Assembler::positive, _is_positive); + int offset = (1 << shift_value) - 1 ; + + if (offset == 1) { + incrementl(reg); + } else { + addl(reg, offset); + } + + bind (_is_positive); + sarl(reg, shift_value); +} + +// !defined(COMPILER2) is because of stupid core builds +#if !defined(_LP64) || defined(COMPILER1) || !defined(COMPILER2) +void MacroAssembler::empty_FPU_stack() { + if (VM_Version::supports_mmx()) { + emms(); + } else { + for (int i = 8; i-- > 0; ) ffree(i); + } +} +#endif // !LP64 || C1 || !C2 + + +// Defines obj, preserves var_size_in_bytes +void MacroAssembler::eden_allocate(Register obj, + Register var_size_in_bytes, + int con_size_in_bytes, + Register t1, + Label& slow_case) { + assert(obj == rax, "obj must be in rax, for cmpxchg"); + assert_different_registers(obj, var_size_in_bytes, t1); + Register end = t1; + Label retry; + bind(retry); + ExternalAddress heap_top((address) Universe::heap()->top_addr()); + movptr(obj, heap_top); + if (var_size_in_bytes == noreg) { + lea(end, Address(obj, con_size_in_bytes)); + } else { + lea(end, Address(obj, var_size_in_bytes, Address::times_1)); + } + // if end < obj then we wrapped around => object too long => slow case + cmpptr(end, obj); + jcc(Assembler::below, slow_case); + cmpptr(end, ExternalAddress((address) Universe::heap()->end_addr())); + jcc(Assembler::above, slow_case); + // Compare obj with the top addr, and if still equal, store the new top addr in + // end at the address of the top addr pointer. Sets ZF if was equal, and clears + // it otherwise. Use lock prefix for atomicity on MPs. + locked_cmpxchgptr(end, heap_top); + jcc(Assembler::notEqual, retry); +} + +void MacroAssembler::enter() { + push(rbp); + mov(rbp, rsp); +} + +void MacroAssembler::fcmp(Register tmp) { + fcmp(tmp, 1, true, true); +} + +void MacroAssembler::fcmp(Register tmp, int index, bool pop_left, bool pop_right) { + assert(!pop_right || pop_left, "usage error"); + if (VM_Version::supports_cmov()) { + assert(tmp == noreg, "unneeded temp"); + if (pop_left) { + fucomip(index); + } else { + fucomi(index); + } + if (pop_right) { + fpop(); + } + } else { + assert(tmp != noreg, "need temp"); + if (pop_left) { + if (pop_right) { + fcompp(); + } else { + fcomp(index); + } + } else { + fcom(index); + } + // convert FPU condition into eflags condition via rax, + save_rax(tmp); + fwait(); fnstsw_ax(); + sahf(); + restore_rax(tmp); + } + // condition codes set as follows: + // + // CF (corresponds to C0) if x < y + // PF (corresponds to C2) if unordered + // ZF (corresponds to C3) if x = y +} + +void MacroAssembler::fcmp2int(Register dst, bool unordered_is_less) { + fcmp2int(dst, unordered_is_less, 1, true, true); +} + +void MacroAssembler::fcmp2int(Register dst, bool unordered_is_less, int index, bool pop_left, bool pop_right) { + fcmp(VM_Version::supports_cmov() ? noreg : dst, index, pop_left, pop_right); + Label L; + if (unordered_is_less) { + movl(dst, -1); + jcc(Assembler::parity, L); + jcc(Assembler::below , L); + movl(dst, 0); + jcc(Assembler::equal , L); + increment(dst); + } else { // unordered is greater + movl(dst, 1); + jcc(Assembler::parity, L); + jcc(Assembler::above , L); + movl(dst, 0); + jcc(Assembler::equal , L); + decrementl(dst); + } + bind(L); +} + +void MacroAssembler::fld_d(AddressLiteral src) { + fld_d(as_Address(src)); +} + +void MacroAssembler::fld_s(AddressLiteral src) { + fld_s(as_Address(src)); +} + +void MacroAssembler::fld_x(AddressLiteral src) { + Assembler::fld_x(as_Address(src)); +} + +void MacroAssembler::fldcw(AddressLiteral src) { + Assembler::fldcw(as_Address(src)); +} + +void MacroAssembler::fpop() { + ffree(); + fincstp(); +} + +void MacroAssembler::fremr(Register tmp) { + save_rax(tmp); + { Label L; + bind(L); + fprem(); + fwait(); fnstsw_ax(); +#ifdef _LP64 + testl(rax, 0x400); + jcc(Assembler::notEqual, L); +#else + sahf(); + jcc(Assembler::parity, L); +#endif // _LP64 + } + restore_rax(tmp); + // Result is in ST0. + // Note: fxch & fpop to get rid of ST1 + // (otherwise FPU stack could overflow eventually) + fxch(1); + fpop(); +} + + +void MacroAssembler::incrementl(AddressLiteral dst) { + if (reachable(dst)) { + incrementl(as_Address(dst)); + } else { + lea(rscratch1, dst); + incrementl(Address(rscratch1, 0)); + } +} + +void MacroAssembler::incrementl(ArrayAddress dst) { + incrementl(as_Address(dst)); +} + +void MacroAssembler::incrementl(Register reg, int value) { + if (value == min_jint) {addl(reg, value) ; return; } + if (value < 0) { decrementl(reg, -value); return; } + if (value == 0) { ; return; } + if (value == 1 && UseIncDec) { incl(reg) ; return; } + /* else */ { addl(reg, value) ; return; } +} + +void MacroAssembler::incrementl(Address dst, int value) { + if (value == min_jint) {addl(dst, value) ; return; } + if (value < 0) { decrementl(dst, -value); return; } + if (value == 0) { ; return; } + if (value == 1 && UseIncDec) { incl(dst) ; return; } + /* else */ { addl(dst, value) ; return; } +} + +void MacroAssembler::jump(AddressLiteral dst) { + if (reachable(dst)) { + jmp_literal(dst.target(), dst.rspec()); + } else { + lea(rscratch1, dst); + jmp(rscratch1); + } +} + +void MacroAssembler::jump_cc(Condition cc, AddressLiteral dst) { + if (reachable(dst)) { + InstructionMark im(this); + relocate(dst.reloc()); + const int short_size = 2; + const int long_size = 6; + int offs = (intptr_t)dst.target() - ((intptr_t)_code_pos); + if (dst.reloc() == relocInfo::none && is8bit(offs - short_size)) { + // 0111 tttn #8-bit disp + emit_byte(0x70 | cc); + emit_byte((offs - short_size) & 0xFF); + } else { + // 0000 1111 1000 tttn #32-bit disp + emit_byte(0x0F); + emit_byte(0x80 | cc); + emit_long(offs - long_size); + } + } else { +#ifdef ASSERT + warning("reversing conditional branch"); +#endif /* ASSERT */ + Label skip; + jccb(reverse[cc], skip); + lea(rscratch1, dst); + Assembler::jmp(rscratch1); + bind(skip); + } +} + +void MacroAssembler::ldmxcsr(AddressLiteral src) { + if (reachable(src)) { + Assembler::ldmxcsr(as_Address(src)); + } else { + lea(rscratch1, src); + Assembler::ldmxcsr(Address(rscratch1, 0)); + } +} + +int MacroAssembler::load_signed_byte(Register dst, Address src) { + int off; + if (LP64_ONLY(true ||) VM_Version::is_P6()) { + off = offset(); + movsbl(dst, src); // movsxb + } else { + off = load_unsigned_byte(dst, src); + shll(dst, 24); + sarl(dst, 24); + } + return off; +} + +// word => int32 which seems bad for 64bit +int MacroAssembler::load_signed_word(Register dst, Address src) { + int off; + if (LP64_ONLY(true ||) VM_Version::is_P6()) { + // This is dubious to me since it seems safe to do a signed 16 => 64 bit + // version but this is what 64bit has always done. This seems to imply + // that users are only using 32bits worth. + off = offset(); + movswl(dst, src); // movsxw + } else { + off = load_unsigned_word(dst, src); + shll(dst, 16); + sarl(dst, 16); + } + return off; +} + +int MacroAssembler::load_unsigned_byte(Register dst, Address src) { + // According to Intel Doc. AP-526, "Zero-Extension of Short", p.16, + // and "3.9 Partial Register Penalties", p. 22). + int off; + if (LP64_ONLY(true || ) VM_Version::is_P6() || src.uses(dst)) { + off = offset(); + movzbl(dst, src); // movzxb + } else { + xorl(dst, dst); + off = offset(); + movb(dst, src); + } + return off; +} + +int MacroAssembler::load_unsigned_word(Register dst, Address src) { + // According to Intel Doc. AP-526, "Zero-Extension of Short", p.16, + // and "3.9 Partial Register Penalties", p. 22). + int off; + if (LP64_ONLY(true ||) VM_Version::is_P6() || src.uses(dst)) { + off = offset(); + movzwl(dst, src); // movzxw + } else { + xorl(dst, dst); + off = offset(); + movw(dst, src); + } + return off; +} + +void MacroAssembler::mov32(AddressLiteral dst, Register src) { + if (reachable(dst)) { + movl(as_Address(dst), src); + } else { + lea(rscratch1, dst); + movl(Address(rscratch1, 0), src); + } +} + +void MacroAssembler::mov32(Register dst, AddressLiteral src) { + if (reachable(src)) { + movl(dst, as_Address(src)); + } else { + lea(rscratch1, src); + movl(dst, Address(rscratch1, 0)); + } +} + +// C++ bool manipulation + +void MacroAssembler::movbool(Register dst, Address src) { + if(sizeof(bool) == 1) + movb(dst, src); + else if(sizeof(bool) == 2) + movw(dst, src); + else if(sizeof(bool) == 4) + movl(dst, src); + else + // unsupported + ShouldNotReachHere(); +} + +void MacroAssembler::movbool(Address dst, bool boolconst) { + if(sizeof(bool) == 1) + movb(dst, (int) boolconst); + else if(sizeof(bool) == 2) + movw(dst, (int) boolconst); + else if(sizeof(bool) == 4) + movl(dst, (int) boolconst); + else + // unsupported + ShouldNotReachHere(); +} + +void MacroAssembler::movbool(Address dst, Register src) { + if(sizeof(bool) == 1) + movb(dst, src); + else if(sizeof(bool) == 2) + movw(dst, src); + else if(sizeof(bool) == 4) + movl(dst, src); + else + // unsupported + ShouldNotReachHere(); +} + +void MacroAssembler::movbyte(ArrayAddress dst, int src) { + movb(as_Address(dst), src); +} + +void MacroAssembler::movdbl(XMMRegister dst, AddressLiteral src) { + if (reachable(src)) { + if (UseXmmLoadAndClearUpper) { + movsd (dst, as_Address(src)); + } else { + movlpd(dst, as_Address(src)); + } + } else { + lea(rscratch1, src); + if (UseXmmLoadAndClearUpper) { + movsd (dst, Address(rscratch1, 0)); + } else { + movlpd(dst, Address(rscratch1, 0)); + } + } +} + +void MacroAssembler::movflt(XMMRegister dst, AddressLiteral src) { + if (reachable(src)) { + movss(dst, as_Address(src)); + } else { + lea(rscratch1, src); + movss(dst, Address(rscratch1, 0)); + } +} + +void MacroAssembler::movptr(Register dst, Register src) { + LP64_ONLY(movq(dst, src)) NOT_LP64(movl(dst, src)); +} + +void MacroAssembler::movptr(Register dst, Address src) { + LP64_ONLY(movq(dst, src)) NOT_LP64(movl(dst, src)); +} + +// src should NEVER be a real pointer. Use AddressLiteral for true pointers +void MacroAssembler::movptr(Register dst, intptr_t src) { + LP64_ONLY(mov64(dst, src)) NOT_LP64(movl(dst, src)); +} + +void MacroAssembler::movptr(Address dst, Register src) { + LP64_ONLY(movq(dst, src)) NOT_LP64(movl(dst, src)); +} + +void MacroAssembler::movss(XMMRegister dst, AddressLiteral src) { + if (reachable(src)) { + movss(dst, as_Address(src)); + } else { + lea(rscratch1, src); + movss(dst, Address(rscratch1, 0)); + } +} + +void MacroAssembler::null_check(Register reg, int offset) { + if (needs_explicit_null_check(offset)) { + // provoke OS NULL exception if reg = NULL by + // accessing M[reg] w/o changing any (non-CC) registers + // NOTE: cmpl is plenty here to provoke a segv + cmpptr(rax, Address(reg, 0)); + // Note: should probably use testl(rax, Address(reg, 0)); + // may be shorter code (however, this version of + // testl needs to be implemented first) + } else { + // nothing to do, (later) access of M[reg + offset] + // will provoke OS NULL exception if reg = NULL + } +} + +void MacroAssembler::os_breakpoint() { + // instead of directly emitting a breakpoint, call os:breakpoint for better debugability + // (e.g., MSVC can't call ps() otherwise) + call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); +} + +void MacroAssembler::pop_CPU_state() { + pop_FPU_state(); + pop_IU_state(); +} + +void MacroAssembler::pop_FPU_state() { + NOT_LP64(frstor(Address(rsp, 0));) + LP64_ONLY(fxrstor(Address(rsp, 0));) + addptr(rsp, FPUStateSizeInWords * wordSize); +} + +void MacroAssembler::pop_IU_state() { + popa(); + LP64_ONLY(addq(rsp, 8)); + popf(); +} + +// Save Integer and Float state +// Warning: Stack must be 16 byte aligned (64bit) +void MacroAssembler::push_CPU_state() { + push_IU_state(); + push_FPU_state(); +} + +void MacroAssembler::push_FPU_state() { + subptr(rsp, FPUStateSizeInWords * wordSize); +#ifndef _LP64 + fnsave(Address(rsp, 0)); + fwait(); +#else + fxsave(Address(rsp, 0)); +#endif // LP64 +} + +void MacroAssembler::push_IU_state() { + // Push flags first because pusha kills them + pushf(); + // Make sure rsp stays 16-byte aligned + LP64_ONLY(subq(rsp, 8)); + pusha(); +} + +void MacroAssembler::reset_last_Java_frame(Register java_thread, bool clear_fp, bool clear_pc) { + // determine java_thread register + if (!java_thread->is_valid()) { + java_thread = rdi; + get_thread(java_thread); + } + // we must set sp to zero to clear frame + movptr(Address(java_thread, JavaThread::last_Java_sp_offset()), (int32_t)NULL_WORD); + if (clear_fp) { + movptr(Address(java_thread, JavaThread::last_Java_fp_offset()), (int32_t)NULL_WORD); + } + + if (clear_pc) + movptr(Address(java_thread, JavaThread::last_Java_pc_offset()), (int32_t)NULL_WORD); + +} + +void MacroAssembler::restore_rax(Register tmp) { + if (tmp == noreg) pop(rax); + else if (tmp != rax) mov(rax, tmp); +} + +void MacroAssembler::round_to(Register reg, int modulus) { + addptr(reg, modulus - 1); + andptr(reg, -modulus); +} + +void MacroAssembler::save_rax(Register tmp) { + if (tmp == noreg) push(rax); + else if (tmp != rax) mov(tmp, rax); +} + +// Write serialization page so VM thread can do a pseudo remote membar. +// We use the current thread pointer to calculate a thread specific +// offset to write to within the page. This minimizes bus traffic +// due to cache line collision. +void MacroAssembler::serialize_memory(Register thread, Register tmp) { + movl(tmp, thread); + shrl(tmp, os::get_serialize_page_shift_count()); + andl(tmp, (os::vm_page_size() - sizeof(int))); + + Address index(noreg, tmp, Address::times_1); + ExternalAddress page(os::get_memory_serialize_page()); + + movptr(ArrayAddress(page, index), tmp); +} + +// Calls to C land +// +// When entering C land, the rbp, & rsp of the last Java frame have to be recorded +// in the (thread-local) JavaThread object. When leaving C land, the last Java fp +// has to be reset to 0. This is required to allow proper stack traversal. +void MacroAssembler::set_last_Java_frame(Register java_thread, + Register last_java_sp, + Register last_java_fp, + address last_java_pc) { + // determine java_thread register + if (!java_thread->is_valid()) { + java_thread = rdi; + get_thread(java_thread); + } + // determine last_java_sp register + if (!last_java_sp->is_valid()) { + last_java_sp = rsp; + } + + // last_java_fp is optional + + if (last_java_fp->is_valid()) { + movptr(Address(java_thread, JavaThread::last_Java_fp_offset()), last_java_fp); + } + + // last_java_pc is optional + + if (last_java_pc != NULL) { + lea(Address(java_thread, + JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset()), + InternalAddress(last_java_pc)); + + } + movptr(Address(java_thread, JavaThread::last_Java_sp_offset()), last_java_sp); +} + +void MacroAssembler::shlptr(Register dst, int imm8) { + LP64_ONLY(shlq(dst, imm8)) NOT_LP64(shll(dst, imm8)); +} + +void MacroAssembler::shrptr(Register dst, int imm8) { + LP64_ONLY(shrq(dst, imm8)) NOT_LP64(shrl(dst, imm8)); +} + +void MacroAssembler::sign_extend_byte(Register reg) { + if (LP64_ONLY(true ||) (VM_Version::is_P6() && reg->has_byte_register())) { + movsbl(reg, reg); // movsxb + } else { + shll(reg, 24); + sarl(reg, 24); + } +} + +void MacroAssembler::sign_extend_short(Register reg) { + if (LP64_ONLY(true ||) VM_Version::is_P6()) { + movswl(reg, reg); // movsxw + } else { + shll(reg, 16); + sarl(reg, 16); + } +} + +void MacroAssembler::store_check(Register obj) { + // Does a store check for the oop in register obj. The content of + // register obj is destroyed afterwards. + store_check_part_1(obj); + store_check_part_2(obj); +} + +void MacroAssembler::store_check(Register obj, Address dst) { + store_check(obj); +} + + +// split the store check operation so that other instructions can be scheduled inbetween +void MacroAssembler::store_check_part_1(Register obj) { + BarrierSet* bs = Universe::heap()->barrier_set(); + assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); + shrptr(obj, CardTableModRefBS::card_shift); +} + +void MacroAssembler::store_check_part_2(Register obj) { + BarrierSet* bs = Universe::heap()->barrier_set(); + assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); + CardTableModRefBS* ct = (CardTableModRefBS*)bs; + assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); + + // The calculation for byte_map_base is as follows: + // byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift); + // So this essentially converts an address to a displacement and + // it will never need to be relocated. On 64bit however the value may be too + // large for a 32bit displacement + + intptr_t disp = (intptr_t) ct->byte_map_base; + if (is_simm32(disp)) { + Address cardtable(noreg, obj, Address::times_1, disp); + movb(cardtable, 0); + } else { + // By doing it as an ExternalAddress disp could be converted to a rip-relative + // displacement and done in a single instruction given favorable mapping and + // a smarter version of as_Address. Worst case it is two instructions which + // is no worse off then loading disp into a register and doing as a simple + // Address() as above. + // We can't do as ExternalAddress as the only style since if disp == 0 we'll + // assert since NULL isn't acceptable in a reloci (see 6644928). In any case + // in some cases we'll get a single instruction version. + + ExternalAddress cardtable((address)disp); + Address index(noreg, obj, Address::times_1); + movb(as_Address(ArrayAddress(cardtable, index)), 0); + } +} + +void MacroAssembler::subptr(Register dst, int32_t imm32) { + LP64_ONLY(subq(dst, imm32)) NOT_LP64(subl(dst, imm32)); +} + +void MacroAssembler::subptr(Register dst, Register src) { + LP64_ONLY(subq(dst, src)) NOT_LP64(subl(dst, src)); +} + +void MacroAssembler::test32(Register src1, AddressLiteral src2) { + // src2 must be rval + + if (reachable(src2)) { + testl(src1, as_Address(src2)); + } else { + lea(rscratch1, src2); + testl(src1, Address(rscratch1, 0)); + } +} + +// C++ bool manipulation +void MacroAssembler::testbool(Register dst) { + if(sizeof(bool) == 1) + testb(dst, 0xff); + else if(sizeof(bool) == 2) { + // testw implementation needed for two byte bools + ShouldNotReachHere(); + } else if(sizeof(bool) == 4) + testl(dst, dst); + else + // unsupported + ShouldNotReachHere(); +} + +void MacroAssembler::testptr(Register dst, Register src) { + LP64_ONLY(testq(dst, src)) NOT_LP64(testl(dst, src)); +} + +// Defines obj, preserves var_size_in_bytes, okay for t2 == var_size_in_bytes. +void MacroAssembler::tlab_allocate(Register obj, + Register var_size_in_bytes, + int con_size_in_bytes, + Register t1, + Register t2, + Label& slow_case) { + assert_different_registers(obj, t1, t2); + assert_different_registers(obj, var_size_in_bytes, t1); + Register end = t2; + Register thread = NOT_LP64(t1) LP64_ONLY(r15_thread); + + verify_tlab(); + + NOT_LP64(get_thread(thread)); + + movptr(obj, Address(thread, JavaThread::tlab_top_offset())); + if (var_size_in_bytes == noreg) { + lea(end, Address(obj, con_size_in_bytes)); + } else { + lea(end, Address(obj, var_size_in_bytes, Address::times_1)); + } + cmpptr(end, Address(thread, JavaThread::tlab_end_offset())); + jcc(Assembler::above, slow_case); + + // update the tlab top pointer + movptr(Address(thread, JavaThread::tlab_top_offset()), end); + + // recover var_size_in_bytes if necessary + if (var_size_in_bytes == end) { + subptr(var_size_in_bytes, obj); + } + verify_tlab(); +} + +// Preserves rbx, and rdx. +void MacroAssembler::tlab_refill(Label& retry, + Label& try_eden, + Label& slow_case) { + Register top = rax; + Register t1 = rcx; + Register t2 = rsi; + Register thread_reg = NOT_LP64(rdi) LP64_ONLY(r15_thread); + assert_different_registers(top, thread_reg, t1, t2, /* preserve: */ rbx, rdx); + Label do_refill, discard_tlab; + + if (CMSIncrementalMode || !Universe::heap()->supports_inline_contig_alloc()) { + // No allocation in the shared eden. + jmp(slow_case); + } + + NOT_LP64(get_thread(thread_reg)); + + movptr(top, Address(thread_reg, in_bytes(JavaThread::tlab_top_offset()))); + movptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_end_offset()))); + + // calculate amount of free space + subptr(t1, top); + shrptr(t1, LogHeapWordSize); + + // Retain tlab and allocate object in shared space if + // the amount free in the tlab is too large to discard. + cmpptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_refill_waste_limit_offset()))); + jcc(Assembler::lessEqual, discard_tlab); + + // Retain + // %%% yuck as movptr... + movptr(t2, (int32_t) ThreadLocalAllocBuffer::refill_waste_limit_increment()); + addptr(Address(thread_reg, in_bytes(JavaThread::tlab_refill_waste_limit_offset())), t2); + if (TLABStats) { + // increment number of slow_allocations + addl(Address(thread_reg, in_bytes(JavaThread::tlab_slow_allocations_offset())), 1); + } + jmp(try_eden); + + bind(discard_tlab); + if (TLABStats) { + // increment number of refills + addl(Address(thread_reg, in_bytes(JavaThread::tlab_number_of_refills_offset())), 1); + // accumulate wastage -- t1 is amount free in tlab + addl(Address(thread_reg, in_bytes(JavaThread::tlab_fast_refill_waste_offset())), t1); + } + + // if tlab is currently allocated (top or end != null) then + // fill [top, end + alignment_reserve) with array object + testptr (top, top); + jcc(Assembler::zero, do_refill); + + // set up the mark word + movptr(Address(top, oopDesc::mark_offset_in_bytes()), (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2)); + // set the length to the remaining space + subptr(t1, typeArrayOopDesc::header_size(T_INT)); + addptr(t1, (int32_t)ThreadLocalAllocBuffer::alignment_reserve()); + shlptr(t1, log2_intptr(HeapWordSize/sizeof(jint))); + movptr(Address(top, arrayOopDesc::length_offset_in_bytes()), t1); + // set klass to intArrayKlass + // dubious reloc why not an oop reloc? + movptr(t1, ExternalAddress((address) Universe::intArrayKlassObj_addr())); + // store klass last. concurrent gcs assumes klass length is valid if + // klass field is not null. + store_klass(top, t1); + + // refill the tlab with an eden allocation + bind(do_refill); + movptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset()))); + shlptr(t1, LogHeapWordSize); + // add object_size ?? + eden_allocate(top, t1, 0, t2, slow_case); + + // Check that t1 was preserved in eden_allocate. +#ifdef ASSERT + if (UseTLAB) { + Label ok; + Register tsize = rsi; + assert_different_registers(tsize, thread_reg, t1); + push(tsize); + movptr(tsize, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset()))); + shlptr(tsize, LogHeapWordSize); + cmpptr(t1, tsize); + jcc(Assembler::equal, ok); + stop("assert(t1 != tlab size)"); + should_not_reach_here(); + + bind(ok); + pop(tsize); + } +#endif + movptr(Address(thread_reg, in_bytes(JavaThread::tlab_start_offset())), top); + movptr(Address(thread_reg, in_bytes(JavaThread::tlab_top_offset())), top); + addptr(top, t1); + subptr(top, (int32_t)ThreadLocalAllocBuffer::alignment_reserve_in_bytes()); + movptr(Address(thread_reg, in_bytes(JavaThread::tlab_end_offset())), top); + verify_tlab(); + jmp(retry); +} + +static const double pi_4 = 0.7853981633974483; + +void MacroAssembler::trigfunc(char trig, int num_fpu_regs_in_use) { + // A hand-coded argument reduction for values in fabs(pi/4, pi/2) + // was attempted in this code; unfortunately it appears that the + // switch to 80-bit precision and back causes this to be + // unprofitable compared with simply performing a runtime call if + // the argument is out of the (-pi/4, pi/4) range. + + Register tmp = noreg; + if (!VM_Version::supports_cmov()) { + // fcmp needs a temporary so preserve rbx, + tmp = rbx; + push(tmp); + } + + Label slow_case, done; + + // x ?<= pi/4 + fld_d(ExternalAddress((address)&pi_4)); + fld_s(1); // Stack: X PI/4 X + fabs(); // Stack: |X| PI/4 X + fcmp(tmp); + jcc(Assembler::above, slow_case); + + // fastest case: -pi/4 <= x <= pi/4 + switch(trig) { + case 's': + fsin(); + break; + case 'c': + fcos(); + break; + case 't': + ftan(); + break; + default: + assert(false, "bad intrinsic"); + break; + } + jmp(done); + + // slow case: runtime call + bind(slow_case); + // Preserve registers across runtime call + pusha(); + int incoming_argument_and_return_value_offset = -1; + if (num_fpu_regs_in_use > 1) { + // Must preserve all other FPU regs (could alternatively convert + // SharedRuntime::dsin and dcos into assembly routines known not to trash + // FPU state, but can not trust C compiler) + NEEDS_CLEANUP; + // NOTE that in this case we also push the incoming argument to + // the stack and restore it later; we also use this stack slot to + // hold the return value from dsin or dcos. + for (int i = 0; i < num_fpu_regs_in_use; i++) { + subptr(rsp, sizeof(jdouble)); + fstp_d(Address(rsp, 0)); + } + incoming_argument_and_return_value_offset = sizeof(jdouble)*(num_fpu_regs_in_use-1); + fld_d(Address(rsp, incoming_argument_and_return_value_offset)); + } + subptr(rsp, sizeof(jdouble)); + fstp_d(Address(rsp, 0)); +#ifdef _LP64 + movdbl(xmm0, Address(rsp, 0)); +#endif // _LP64 + + // NOTE: we must not use call_VM_leaf here because that requires a + // complete interpreter frame in debug mode -- same bug as 4387334 + // MacroAssembler::call_VM_leaf_base is perfectly safe and will + // do proper 64bit abi + + NEEDS_CLEANUP; + // Need to add stack banging before this runtime call if it needs to + // be taken; however, there is no generic stack banging routine at + // the MacroAssembler level + switch(trig) { + case 's': + { + MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, SharedRuntime::dsin), 0); + } + break; + case 'c': + { + MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, SharedRuntime::dcos), 0); + } + break; + case 't': + { + MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, SharedRuntime::dtan), 0); + } + break; + default: + assert(false, "bad intrinsic"); + break; + } +#ifdef _LP64 + movsd(Address(rsp, 0), xmm0); + fld_d(Address(rsp, 0)); +#endif // _LP64 + addptr(rsp, sizeof(jdouble)); + if (num_fpu_regs_in_use > 1) { + // Must save return value to stack and then restore entire FPU stack + fstp_d(Address(rsp, incoming_argument_and_return_value_offset)); + for (int i = 0; i < num_fpu_regs_in_use; i++) { + fld_d(Address(rsp, 0)); + addptr(rsp, sizeof(jdouble)); + } + } + popa(); + + // Come here with result in F-TOS + bind(done); + + if (tmp != noreg) { + pop(tmp); + } +} + + +void MacroAssembler::ucomisd(XMMRegister dst, AddressLiteral src) { + ucomisd(dst, as_Address(src)); +} + +void MacroAssembler::ucomiss(XMMRegister dst, AddressLiteral src) { + ucomiss(dst, as_Address(src)); +} + +void MacroAssembler::xorpd(XMMRegister dst, AddressLiteral src) { + if (reachable(src)) { + xorpd(dst, as_Address(src)); + } else { + lea(rscratch1, src); + xorpd(dst, Address(rscratch1, 0)); + } +} + +void MacroAssembler::xorps(XMMRegister dst, AddressLiteral src) { + if (reachable(src)) { + xorps(dst, as_Address(src)); + } else { + lea(rscratch1, src); + xorps(dst, Address(rscratch1, 0)); + } +} + +void MacroAssembler::verify_oop(Register reg, const char* s) { + if (!VerifyOops) return; + + // Pass register number to verify_oop_subroutine + char* b = new char[strlen(s) + 50]; + sprintf(b, "verify_oop: %s: %s", reg->name(), s); + push(rax); // save rax, + push(reg); // pass register argument + ExternalAddress buffer((address) b); + // avoid using pushptr, as it modifies scratch registers + // and our contract is not to modify anything + movptr(rax, buffer.addr()); + push(rax); + // call indirectly to solve generation ordering problem + movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address())); + call(rax); +} + + +void MacroAssembler::verify_oop_addr(Address addr, const char* s) { + if (!VerifyOops) return; + + // Address adjust(addr.base(), addr.index(), addr.scale(), addr.disp() + BytesPerWord); + // Pass register number to verify_oop_subroutine + char* b = new char[strlen(s) + 50]; + sprintf(b, "verify_oop_addr: %s", s); + + push(rax); // save rax, + // addr may contain rsp so we will have to adjust it based on the push + // we just did + // NOTE: 64bit seemed to have had a bug in that it did movq(addr, rax); which + // stores rax into addr which is backwards of what was intended. + if (addr.uses(rsp)) { + lea(rax, addr); + pushptr(Address(rax, BytesPerWord)); + } else { + pushptr(addr); + } + + ExternalAddress buffer((address) b); + // pass msg argument + // avoid using pushptr, as it modifies scratch registers + // and our contract is not to modify anything + movptr(rax, buffer.addr()); + push(rax); + + // call indirectly to solve generation ordering problem + movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address())); + call(rax); + // Caller pops the arguments and restores rax, from the stack +} + +void MacroAssembler::verify_tlab() { +#ifdef ASSERT + if (UseTLAB && VerifyOops) { + Label next, ok; + Register t1 = rsi; + Register thread_reg = NOT_LP64(rbx) LP64_ONLY(r15_thread); + + push(t1); + NOT_LP64(push(thread_reg)); + NOT_LP64(get_thread(thread_reg)); + + movptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_top_offset()))); + cmpptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_start_offset()))); + jcc(Assembler::aboveEqual, next); + stop("assert(top >= start)"); + should_not_reach_here(); + + bind(next); + movptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_end_offset()))); + cmpptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_top_offset()))); + jcc(Assembler::aboveEqual, ok); + stop("assert(top <= end)"); + should_not_reach_here(); + + bind(ok); + NOT_LP64(pop(thread_reg)); + pop(t1); + } +#endif +} + +class ControlWord { + public: + int32_t _value; + + int rounding_control() const { return (_value >> 10) & 3 ; } + int precision_control() const { return (_value >> 8) & 3 ; } + bool precision() const { return ((_value >> 5) & 1) != 0; } + bool underflow() const { return ((_value >> 4) & 1) != 0; } + bool overflow() const { return ((_value >> 3) & 1) != 0; } + bool zero_divide() const { return ((_value >> 2) & 1) != 0; } + bool denormalized() const { return ((_value >> 1) & 1) != 0; } + bool invalid() const { return ((_value >> 0) & 1) != 0; } + + void print() const { + // rounding control + const char* rc; + switch (rounding_control()) { + case 0: rc = "round near"; break; + case 1: rc = "round down"; break; + case 2: rc = "round up "; break; + case 3: rc = "chop "; break; + }; + // precision control + const char* pc; + switch (precision_control()) { + case 0: pc = "24 bits "; break; + case 1: pc = "reserved"; break; + case 2: pc = "53 bits "; break; + case 3: pc = "64 bits "; break; + }; + // flags + char f[9]; + f[0] = ' '; + f[1] = ' '; + f[2] = (precision ()) ? 'P' : 'p'; + f[3] = (underflow ()) ? 'U' : 'u'; + f[4] = (overflow ()) ? 'O' : 'o'; + f[5] = (zero_divide ()) ? 'Z' : 'z'; + f[6] = (denormalized()) ? 'D' : 'd'; + f[7] = (invalid ()) ? 'I' : 'i'; + f[8] = '\x0'; + // output + printf("%04x masks = %s, %s, %s", _value & 0xFFFF, f, rc, pc); + } + +}; + +class StatusWord { + public: + int32_t _value; + + bool busy() const { return ((_value >> 15) & 1) != 0; } + bool C3() const { return ((_value >> 14) & 1) != 0; } + bool C2() const { return ((_value >> 10) & 1) != 0; } + bool C1() const { return ((_value >> 9) & 1) != 0; } + bool C0() const { return ((_value >> 8) & 1) != 0; } + int top() const { return (_value >> 11) & 7 ; } + bool error_status() const { return ((_value >> 7) & 1) != 0; } + bool stack_fault() const { return ((_value >> 6) & 1) != 0; } + bool precision() const { return ((_value >> 5) & 1) != 0; } + bool underflow() const { return ((_value >> 4) & 1) != 0; } + bool overflow() const { return ((_value >> 3) & 1) != 0; } + bool zero_divide() const { return ((_value >> 2) & 1) != 0; } + bool denormalized() const { return ((_value >> 1) & 1) != 0; } + bool invalid() const { return ((_value >> 0) & 1) != 0; } + + void print() const { + // condition codes + char c[5]; + c[0] = (C3()) ? '3' : '-'; + c[1] = (C2()) ? '2' : '-'; + c[2] = (C1()) ? '1' : '-'; + c[3] = (C0()) ? '0' : '-'; + c[4] = '\x0'; + // flags + char f[9]; + f[0] = (error_status()) ? 'E' : '-'; + f[1] = (stack_fault ()) ? 'S' : '-'; + f[2] = (precision ()) ? 'P' : '-'; + f[3] = (underflow ()) ? 'U' : '-'; + f[4] = (overflow ()) ? 'O' : '-'; + f[5] = (zero_divide ()) ? 'Z' : '-'; + f[6] = (denormalized()) ? 'D' : '-'; + f[7] = (invalid ()) ? 'I' : '-'; + f[8] = '\x0'; + // output + printf("%04x flags = %s, cc = %s, top = %d", _value & 0xFFFF, f, c, top()); + } + +}; + +class TagWord { + public: + int32_t _value; + + int tag_at(int i) const { return (_value >> (i*2)) & 3; } + + void print() const { + printf("%04x", _value & 0xFFFF); + } + +}; + +class FPU_Register { + public: + int32_t _m0; + int32_t _m1; + int16_t _ex; + + bool is_indefinite() const { + return _ex == -1 && _m1 == (int32_t)0xC0000000 && _m0 == 0; + } + + void print() const { + char sign = (_ex < 0) ? '-' : '+'; + const char* kind = (_ex == 0x7FFF || _ex == (int16_t)-1) ? "NaN" : " "; + printf("%c%04hx.%08x%08x %s", sign, _ex, _m1, _m0, kind); + }; + +}; + +class FPU_State { + public: + enum { + register_size = 10, + number_of_registers = 8, + register_mask = 7 + }; + + ControlWord _control_word; + StatusWord _status_word; + TagWord _tag_word; + int32_t _error_offset; + int32_t _error_selector; + int32_t _data_offset; + int32_t _data_selector; + int8_t _register[register_size * number_of_registers]; + + int tag_for_st(int i) const { return _tag_word.tag_at((_status_word.top() + i) & register_mask); } + FPU_Register* st(int i) const { return (FPU_Register*)&_register[register_size * i]; } + + const char* tag_as_string(int tag) const { + switch (tag) { + case 0: return "valid"; + case 1: return "zero"; + case 2: return "special"; + case 3: return "empty"; + } + ShouldNotReachHere() + return NULL; + } + + void print() const { + // print computation registers + { int t = _status_word.top(); + for (int i = 0; i < number_of_registers; i++) { + int j = (i - t) & register_mask; + printf("%c r%d = ST%d = ", (j == 0 ? '*' : ' '), i, j); + st(j)->print(); + printf(" %s\n", tag_as_string(_tag_word.tag_at(i))); + } + } + printf("\n"); + // print control registers + printf("ctrl = "); _control_word.print(); printf("\n"); + printf("stat = "); _status_word .print(); printf("\n"); + printf("tags = "); _tag_word .print(); printf("\n"); + } + +}; + +class Flag_Register { + public: + int32_t _value; + + bool overflow() const { return ((_value >> 11) & 1) != 0; } + bool direction() const { return ((_value >> 10) & 1) != 0; } + bool sign() const { return ((_value >> 7) & 1) != 0; } + bool zero() const { return ((_value >> 6) & 1) != 0; } + bool auxiliary_carry() const { return ((_value >> 4) & 1) != 0; } + bool parity() const { return ((_value >> 2) & 1) != 0; } + bool carry() const { return ((_value >> 0) & 1) != 0; } + + void print() const { + // flags + char f[8]; + f[0] = (overflow ()) ? 'O' : '-'; + f[1] = (direction ()) ? 'D' : '-'; + f[2] = (sign ()) ? 'S' : '-'; + f[3] = (zero ()) ? 'Z' : '-'; + f[4] = (auxiliary_carry()) ? 'A' : '-'; + f[5] = (parity ()) ? 'P' : '-'; + f[6] = (carry ()) ? 'C' : '-'; + f[7] = '\x0'; + // output + printf("%08x flags = %s", _value, f); + } + +}; + +class IU_Register { + public: + int32_t _value; + + void print() const { + printf("%08x %11d", _value, _value); + } + +}; + +class IU_State { + public: + Flag_Register _eflags; + IU_Register _rdi; + IU_Register _rsi; + IU_Register _rbp; + IU_Register _rsp; + IU_Register _rbx; + IU_Register _rdx; + IU_Register _rcx; + IU_Register _rax; + + void print() const { + // computation registers + printf("rax, = "); _rax.print(); printf("\n"); + printf("rbx, = "); _rbx.print(); printf("\n"); + printf("rcx = "); _rcx.print(); printf("\n"); + printf("rdx = "); _rdx.print(); printf("\n"); + printf("rdi = "); _rdi.print(); printf("\n"); + printf("rsi = "); _rsi.print(); printf("\n"); + printf("rbp, = "); _rbp.print(); printf("\n"); + printf("rsp = "); _rsp.print(); printf("\n"); + printf("\n"); + // control registers + printf("flgs = "); _eflags.print(); printf("\n"); + } +}; + + +class CPU_State { + public: + FPU_State _fpu_state; + IU_State _iu_state; + + void print() const { + printf("--------------------------------------------------\n"); + _iu_state .print(); + printf("\n"); + _fpu_state.print(); + printf("--------------------------------------------------\n"); + } + +}; + + +static void _print_CPU_state(CPU_State* state) { + state->print(); +}; + + +void MacroAssembler::print_CPU_state() { + push_CPU_state(); + push(rsp); // pass CPU state + call(RuntimeAddress(CAST_FROM_FN_PTR(address, _print_CPU_state))); + addptr(rsp, wordSize); // discard argument + pop_CPU_state(); +} + + +static bool _verify_FPU(int stack_depth, char* s, CPU_State* state) { + static int counter = 0; + FPU_State* fs = &state->_fpu_state; + counter++; + // For leaf calls, only verify that the top few elements remain empty. + // We only need 1 empty at the top for C2 code. + if( stack_depth < 0 ) { + if( fs->tag_for_st(7) != 3 ) { + printf("FPR7 not empty\n"); + state->print(); + assert(false, "error"); + return false; + } + return true; // All other stack states do not matter + } + + assert((fs->_control_word._value & 0xffff) == StubRoutines::_fpu_cntrl_wrd_std, + "bad FPU control word"); + + // compute stack depth + int i = 0; + while (i < FPU_State::number_of_registers && fs->tag_for_st(i) < 3) i++; + int d = i; + while (i < FPU_State::number_of_registers && fs->tag_for_st(i) == 3) i++; + // verify findings + if (i != FPU_State::number_of_registers) { + // stack not contiguous + printf("%s: stack not contiguous at ST%d\n", s, i); + state->print(); + assert(false, "error"); + return false; + } + // check if computed stack depth corresponds to expected stack depth + if (stack_depth < 0) { + // expected stack depth is -stack_depth or less + if (d > -stack_depth) { + // too many elements on the stack + printf("%s: <= %d stack elements expected but found %d\n", s, -stack_depth, d); + state->print(); + assert(false, "error"); + return false; + } + } else { + // expected stack depth is stack_depth + if (d != stack_depth) { + // wrong stack depth + printf("%s: %d stack elements expected but found %d\n", s, stack_depth, d); + state->print(); + assert(false, "error"); + return false; + } + } + // everything is cool + return true; +} + + +void MacroAssembler::verify_FPU(int stack_depth, const char* s) { + if (!VerifyFPU) return; + push_CPU_state(); + push(rsp); // pass CPU state + ExternalAddress msg((address) s); + // pass message string s + pushptr(msg.addr()); + push(stack_depth); // pass stack depth + call(RuntimeAddress(CAST_FROM_FN_PTR(address, _verify_FPU))); + addptr(rsp, 3 * wordSize); // discard arguments + // check for error + { Label L; + testl(rax, rax); + jcc(Assembler::notZero, L); + int3(); // break if error condition + bind(L); + } + pop_CPU_state(); +} void MacroAssembler::load_klass(Register dst, Register src) { +#ifdef _LP64 if (UseCompressedOops) { movl(dst, Address(src, oopDesc::klass_offset_in_bytes())); decode_heap_oop_not_null(dst); - } else { - movq(dst, Address(src, oopDesc::klass_offset_in_bytes())); - } + } else +#endif + movptr(dst, Address(src, oopDesc::klass_offset_in_bytes())); } void MacroAssembler::load_prototype_header(Register dst, Register src) { +#ifdef _LP64 if (UseCompressedOops) { movl(dst, Address(src, oopDesc::klass_offset_in_bytes())); movq(dst, Address(r12_heapbase, dst, Address::times_8, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); - } else { - movq(dst, Address(src, oopDesc::klass_offset_in_bytes())); - movq(dst, Address(dst, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); - } + } else +#endif + { + movptr(dst, Address(src, oopDesc::klass_offset_in_bytes())); + movptr(dst, Address(dst, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + } } void MacroAssembler::store_klass(Register dst, Register src) { +#ifdef _LP64 if (UseCompressedOops) { encode_heap_oop_not_null(src); movl(Address(dst, oopDesc::klass_offset_in_bytes()), src); - } else { - movq(Address(dst, oopDesc::klass_offset_in_bytes()), src); - } + } else +#endif + movptr(Address(dst, oopDesc::klass_offset_in_bytes()), src); } +#ifdef _LP64 void MacroAssembler::store_klass_gap(Register dst, Register src) { if (UseCompressedOops) { // Store to klass gap in destination @@ -5206,12 +7357,12 @@ void MacroAssembler::encode_heap_oop(Register r) { #ifdef ASSERT if (CheckCompressedOops) { Label ok; - pushq(rscratch1); // cmpptr trashes rscratch1 + push(rscratch1); // cmpptr trashes rscratch1 cmpptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr())); jcc(Assembler::equal, ok); stop("MacroAssembler::encode_heap_oop: heap base corrupted?"); bind(ok); - popq(rscratch1); + pop(rscratch1); } #endif verify_oop(r, "broken oop in encode_heap_oop"); @@ -5261,13 +7412,13 @@ void MacroAssembler::decode_heap_oop(Register r) { #ifdef ASSERT if (CheckCompressedOops) { Label ok; - pushq(rscratch1); + push(rscratch1); cmpptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr())); jcc(Assembler::equal, ok); stop("MacroAssembler::decode_heap_oop: heap base corrupted?"); bind(ok); - popq(rscratch1); + pop(rscratch1); } #endif @@ -5307,14 +7458,15 @@ void MacroAssembler::set_narrow_oop(Register dst, jobject obj) { assert(oop_recorder() != NULL, "this assembler needs an OopRecorder"); int oop_index = oop_recorder()->find_index(obj); RelocationHolder rspec = oop_Relocation::spec(oop_index); - - // movl dst,obj - InstructionMark im(this); - int encode = prefix_and_encode(dst->encoding()); - emit_byte(0xB8 | encode); - emit_data(oop_index, rspec, narrow_oop_operand); + mov_literal32(dst, oop_index, rspec, narrow_oop_operand); } +void MacroAssembler::reinit_heapbase() { + if (UseCompressedOops) { + movptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr())); + } +} +#endif // _LP64 Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) { switch (cond) { @@ -5339,23 +7491,6 @@ Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) ShouldNotReachHere(); return Assembler::overflow; } - -void MacroAssembler::cond_inc32(Condition cond, AddressLiteral counter_addr) { - Condition negated_cond = negate_condition(cond); - Label L; - jcc(negated_cond, L); - atomic_incl(counter_addr); - bind(L); -} - -void MacroAssembler::atomic_incl(AddressLiteral counter_addr) { - pushfq(); - if (os::is_MP()) - lock(); - incrementl(counter_addr); - popfq(); -} - SkipIfEqual::SkipIfEqual( MacroAssembler* masm, const bool* flag_addr, bool value) { _masm = masm; @@ -5366,28 +7501,3 @@ SkipIfEqual::SkipIfEqual( SkipIfEqual::~SkipIfEqual() { _masm->bind(_label); } - -void MacroAssembler::bang_stack_size(Register size, Register tmp) { - movq(tmp, rsp); - // Bang stack for total size given plus shadow page size. - // Bang one page at a time because large size can bang beyond yellow and - // red zones. - Label loop; - bind(loop); - movl(Address(tmp, (-os::vm_page_size())), size ); - subq(tmp, os::vm_page_size()); - subl(size, os::vm_page_size()); - jcc(Assembler::greater, loop); - - // Bang down shadow pages too. - // The -1 because we already subtracted 1 page. - for (int i = 0; i< StackShadowPages-1; i++) { - movq(Address(tmp, (-i*os::vm_page_size())), size ); - } -} - -void MacroAssembler::reinit_heapbase() { - if (UseCompressedOops) { - movptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr())); - } -} diff --git a/hotspot/src/cpu/x86/vm/assembler_x86_32.hpp b/hotspot/src/cpu/x86/vm/assembler_x86.hpp similarity index 63% rename from hotspot/src/cpu/x86/vm/assembler_x86_32.hpp rename to hotspot/src/cpu/x86/vm/assembler_x86.hpp index 9588449955c..d9637ffc9e2 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86_32.hpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp @@ -58,10 +58,10 @@ REGISTER_DECLARATION(Register, c_rarg1, rdx); REGISTER_DECLARATION(Register, c_rarg2, r8); REGISTER_DECLARATION(Register, c_rarg3, r9); -REGISTER_DECLARATION(FloatRegister, c_farg0, xmm0); -REGISTER_DECLARATION(FloatRegister, c_farg1, xmm1); -REGISTER_DECLARATION(FloatRegister, c_farg2, xmm2); -REGISTER_DECLARATION(FloatRegister, c_farg3, xmm3); +REGISTER_DECLARATION(XMMRegister, c_farg0, xmm0); +REGISTER_DECLARATION(XMMRegister, c_farg1, xmm1); +REGISTER_DECLARATION(XMMRegister, c_farg2, xmm2); +REGISTER_DECLARATION(XMMRegister, c_farg3, xmm3); #else @@ -72,14 +72,14 @@ REGISTER_DECLARATION(Register, c_rarg3, rcx); REGISTER_DECLARATION(Register, c_rarg4, r8); REGISTER_DECLARATION(Register, c_rarg5, r9); -REGISTER_DECLARATION(FloatRegister, c_farg0, xmm0); -REGISTER_DECLARATION(FloatRegister, c_farg1, xmm1); -REGISTER_DECLARATION(FloatRegister, c_farg2, xmm2); -REGISTER_DECLARATION(FloatRegister, c_farg3, xmm3); -REGISTER_DECLARATION(FloatRegister, c_farg4, xmm4); -REGISTER_DECLARATION(FloatRegister, c_farg5, xmm5); -REGISTER_DECLARATION(FloatRegister, c_farg6, xmm6); -REGISTER_DECLARATION(FloatRegister, c_farg7, xmm7); +REGISTER_DECLARATION(XMMRegister, c_farg0, xmm0); +REGISTER_DECLARATION(XMMRegister, c_farg1, xmm1); +REGISTER_DECLARATION(XMMRegister, c_farg2, xmm2); +REGISTER_DECLARATION(XMMRegister, c_farg3, xmm3); +REGISTER_DECLARATION(XMMRegister, c_farg4, xmm4); +REGISTER_DECLARATION(XMMRegister, c_farg5, xmm5); +REGISTER_DECLARATION(XMMRegister, c_farg6, xmm6); +REGISTER_DECLARATION(XMMRegister, c_farg7, xmm7); #endif // _WIN64 @@ -112,20 +112,27 @@ REGISTER_DECLARATION(Register, j_rarg4, c_rarg5); #endif /* _WIN64 */ REGISTER_DECLARATION(Register, j_rarg5, c_rarg0); -REGISTER_DECLARATION(FloatRegister, j_farg0, xmm0); -REGISTER_DECLARATION(FloatRegister, j_farg1, xmm1); -REGISTER_DECLARATION(FloatRegister, j_farg2, xmm2); -REGISTER_DECLARATION(FloatRegister, j_farg3, xmm3); -REGISTER_DECLARATION(FloatRegister, j_farg4, xmm4); -REGISTER_DECLARATION(FloatRegister, j_farg5, xmm5); -REGISTER_DECLARATION(FloatRegister, j_farg6, xmm6); -REGISTER_DECLARATION(FloatRegister, j_farg7, xmm7); +REGISTER_DECLARATION(XMMRegister, j_farg0, xmm0); +REGISTER_DECLARATION(XMMRegister, j_farg1, xmm1); +REGISTER_DECLARATION(XMMRegister, j_farg2, xmm2); +REGISTER_DECLARATION(XMMRegister, j_farg3, xmm3); +REGISTER_DECLARATION(XMMRegister, j_farg4, xmm4); +REGISTER_DECLARATION(XMMRegister, j_farg5, xmm5); +REGISTER_DECLARATION(XMMRegister, j_farg6, xmm6); +REGISTER_DECLARATION(XMMRegister, j_farg7, xmm7); REGISTER_DECLARATION(Register, rscratch1, r10); // volatile REGISTER_DECLARATION(Register, rscratch2, r11); // volatile +REGISTER_DECLARATION(Register, r12_heapbase, r12); // callee-saved REGISTER_DECLARATION(Register, r15_thread, r15); // callee-saved +#else +// rscratch1 will apear in 32bit code that is dead but of course must compile +// Using noreg ensures if the dead code is incorrectly live and executed it +// will cause an assertion failure +#define rscratch1 noreg + #endif // _LP64 // Address is an abstraction used to represent a memory location @@ -143,7 +150,8 @@ class Address VALUE_OBJ_CLASS_SPEC { times_1 = 0, times_2 = 1, times_4 = 2, - times_8 = 3 + times_8 = 3, + times_ptr = LP64_ONLY(times_8) NOT_LP64(times_4) }; private: @@ -153,12 +161,15 @@ class Address VALUE_OBJ_CLASS_SPEC { int _disp; RelocationHolder _rspec; - // Easily misused constructor make them private -#ifndef _LP64 - Address(address loc, RelocationHolder spec); -#endif // _LP64 + // Easily misused constructors make them private + // %%% can we make these go away? + NOT_LP64(Address(address loc, RelocationHolder spec);) + Address(int disp, address loc, relocInfo::relocType rtype); + Address(int disp, address loc, RelocationHolder spec); public: + + int disp() { return _disp; } // creation Address() : _base(noreg), @@ -358,11 +369,7 @@ class ArrayAddress VALUE_OBJ_CLASS_SPEC { }; -#ifndef _LP64 -const int FPUStateSizeInWords = 27; -#else -const int FPUStateSizeInWords = 512 / wordSize; -#endif // _LP64 +const int FPUStateSizeInWords = NOT_LP64(27) LP64_ONLY( 512 / wordSize); // The Intel x86/Amd64 Assembler: Pure assembler doing NO optimizations on the instruction // level (e.g. mov rax, 0 is not translated into xor rax, rax!); i.e., what you write @@ -371,62 +378,7 @@ const int FPUStateSizeInWords = 512 / wordSize; class Assembler : public AbstractAssembler { friend class AbstractAssembler; // for the non-virtual hack friend class LIR_Assembler; // as_Address() - - protected: - #ifdef ASSERT - void check_relocation(RelocationHolder const& rspec, int format); - #endif - - inline void emit_long64(jlong x); - - void emit_data(jint data, relocInfo::relocType rtype, int format /* = 0 */); - void emit_data(jint data, RelocationHolder const& rspec, int format /* = 0 */); - void emit_data64(jlong data, relocInfo::relocType rtype, int format = 0); - void emit_data64(jlong data, RelocationHolder const& rspec, int format = 0); - - // Helper functions for groups of instructions - void emit_arith_b(int op1, int op2, Register dst, int imm8); - - void emit_arith(int op1, int op2, Register dst, int imm32); - // only x86?? - void emit_arith(int op1, int op2, Register dst, jobject obj); - void emit_arith(int op1, int op2, Register dst, Register src); - - void emit_operand(Register reg, - Register base, Register index, Address::ScaleFactor scale, - int disp, - RelocationHolder const& rspec); - void emit_operand(Register reg, Address adr); - - // Immediate-to-memory forms - void emit_arith_operand(int op1, Register rm, Address adr, int imm32); - - void emit_farith(int b1, int b2, int i); - - // macroassembler?? QQQ - bool reachable(AddressLiteral adr) { return true; } - - // These are all easily abused and hence protected - - // Make these disappear in 64bit mode since they would never be correct -#ifndef _LP64 - void cmp_literal32(Register src1, int32_t imm32, RelocationHolder const& rspec); - void cmp_literal32(Address src1, int32_t imm32, RelocationHolder const& rspec); - - void mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec); - void mov_literal32(Address dst, int32_t imm32, RelocationHolder const& rspec); - - void push_literal32(int32_t imm32, RelocationHolder const& rspec); -#endif // _LP64 - - // These are unique in that we are ensured by the caller that the 32bit - // relative in these instructions will always be able to reach the potentially - // 64bit address described by entry. Since they can take a 64bit address they - // don't have the 32 suffix like the other instructions in this class. - - void call_literal(address entry, RelocationHolder const& rspec); - void jmp_literal(address entry, RelocationHolder const& rspec); - + friend class StubGenerator; public: enum Condition { // The x86 condition codes used for conditional jumps/moves. @@ -484,12 +436,177 @@ class Assembler : public AbstractAssembler { enum WhichOperand { // input to locate_operand, and format code for relocations - imm32_operand = 0, // embedded 32-bit immediate operand + imm_operand = 0, // embedded 32-bit|64-bit immediate operand disp32_operand = 1, // embedded 32-bit displacement or address call32_operand = 2, // embedded 32-bit self-relative displacement +#ifndef _LP64 _WhichOperand_limit = 3 +#else + narrow_oop_operand = 3, // embedded 32-bit immediate narrow oop + _WhichOperand_limit = 4 +#endif }; + + + // NOTE: The general philopsophy of the declarations here is that 64bit versions + // of instructions are freely declared without the need for wrapping them an ifdef. + // (Some dangerous instructions are ifdef's out of inappropriate jvm's.) + // In the .cpp file the implementations are wrapped so that they are dropped out + // of the resulting jvm. This is done mostly to keep the footprint of KERNEL + // to the size it was prior to merging up the 32bit and 64bit assemblers. + // + // This does mean you'll get a linker/runtime error if you use a 64bit only instruction + // in a 32bit vm. This is somewhat unfortunate but keeps the ifdef noise down. + +private: + + + // 64bit prefixes + int prefix_and_encode(int reg_enc, bool byteinst = false); + int prefixq_and_encode(int reg_enc); + + int prefix_and_encode(int dst_enc, int src_enc, bool byteinst = false); + int prefixq_and_encode(int dst_enc, int src_enc); + + void prefix(Register reg); + void prefix(Address adr); + void prefixq(Address adr); + + void prefix(Address adr, Register reg, bool byteinst = false); + void prefixq(Address adr, Register reg); + + void prefix(Address adr, XMMRegister reg); + + void prefetch_prefix(Address src); + + // Helper functions for groups of instructions + void emit_arith_b(int op1, int op2, Register dst, int imm8); + + void emit_arith(int op1, int op2, Register dst, int32_t imm32); + // only 32bit?? + void emit_arith(int op1, int op2, Register dst, jobject obj); + void emit_arith(int op1, int op2, Register dst, Register src); + + void emit_operand(Register reg, + Register base, Register index, Address::ScaleFactor scale, + int disp, + RelocationHolder const& rspec, + int rip_relative_correction = 0); + + void emit_operand(Register reg, Address adr, int rip_relative_correction = 0); + + // operands that only take the original 32bit registers + void emit_operand32(Register reg, Address adr); + + void emit_operand(XMMRegister reg, + Register base, Register index, Address::ScaleFactor scale, + int disp, + RelocationHolder const& rspec); + + void emit_operand(XMMRegister reg, Address adr); + + void emit_operand(MMXRegister reg, Address adr); + + // workaround gcc (3.2.1-7) bug + void emit_operand(Address adr, MMXRegister reg); + + + // Immediate-to-memory forms + void emit_arith_operand(int op1, Register rm, Address adr, int32_t imm32); + + void emit_farith(int b1, int b2, int i); + + + protected: + #ifdef ASSERT + void check_relocation(RelocationHolder const& rspec, int format); + #endif + + inline void emit_long64(jlong x); + + void emit_data(jint data, relocInfo::relocType rtype, int format); + void emit_data(jint data, RelocationHolder const& rspec, int format); + void emit_data64(jlong data, relocInfo::relocType rtype, int format = 0); + void emit_data64(jlong data, RelocationHolder const& rspec, int format = 0); + + + bool reachable(AddressLiteral adr) NOT_LP64({ return true;}); + + // These are all easily abused and hence protected + + void mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec, int format = 0); + + // 32BIT ONLY SECTION +#ifndef _LP64 + // Make these disappear in 64bit mode since they would never be correct + void cmp_literal32(Register src1, int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY + void cmp_literal32(Address src1, int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY + + void mov_literal32(Address dst, int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY + + void push_literal32(int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY +#else + // 64BIT ONLY SECTION + void mov_literal64(Register dst, intptr_t imm64, RelocationHolder const& rspec); // 64BIT ONLY +#endif // _LP64 + + // These are unique in that we are ensured by the caller that the 32bit + // relative in these instructions will always be able to reach the potentially + // 64bit address described by entry. Since they can take a 64bit address they + // don't have the 32 suffix like the other instructions in this class. + + void call_literal(address entry, RelocationHolder const& rspec); + void jmp_literal(address entry, RelocationHolder const& rspec); + + // Avoid using directly section + // Instructions in this section are actually usable by anyone without danger + // of failure but have performance issues that are addressed my enhanced + // instructions which will do the proper thing base on the particular cpu. + // We protect them because we don't trust you... + + // Don't use next inc() and dec() methods directly. INC & DEC instructions + // could cause a partial flag stall since they don't set CF flag. + // Use MacroAssembler::decrement() & MacroAssembler::increment() methods + // which call inc() & dec() or add() & sub() in accordance with + // the product flag UseIncDec value. + + void decl(Register dst); + void decl(Address dst); + void decq(Register dst); + void decq(Address dst); + + void incl(Register dst); + void incl(Address dst); + void incq(Register dst); + void incq(Address dst); + + // New cpus require use of movsd and movss to avoid partial register stall + // when loading from memory. But for old Opteron use movlpd instead of movsd. + // The selection is done in MacroAssembler::movdbl() and movflt(). + + // Move Scalar Single-Precision Floating-Point Values + void movss(XMMRegister dst, Address src); + void movss(XMMRegister dst, XMMRegister src); + void movss(Address dst, XMMRegister src); + + // Move Scalar Double-Precision Floating-Point Values + void movsd(XMMRegister dst, Address src); + void movsd(XMMRegister dst, XMMRegister src); + void movsd(Address dst, XMMRegister src); + void movlpd(XMMRegister dst, Address src); + + // New cpus require use of movaps and movapd to avoid partial register stall + // when moving between registers. + void movaps(XMMRegister dst, XMMRegister src); + void movapd(XMMRegister dst, XMMRegister src); + + // End avoid using directly + + + // Instruction prefixes + void prefix(Prefix p); + public: // Creation @@ -499,219 +616,351 @@ class Assembler : public AbstractAssembler { static address locate_operand(address inst, WhichOperand which); static address locate_next_instruction(address inst); - // Stack - void pushad(); - void popad(); + // Utilities - void pushfd(); - void popfd(); +#ifdef _LP64 + static bool is_simm(int64_t x, int nbits) { return -( CONST64(1) << (nbits-1) ) <= x && x < ( CONST64(1) << (nbits-1) ); } + static bool is_simm32(int64_t x) { return x == (int64_t)(int32_t)x; } +#else + static bool is_simm(int32_t x, int nbits) { return -( 1 << (nbits-1) ) <= x && x < ( 1 << (nbits-1) ); } + static bool is_simm32(int32_t x) { return true; } +#endif // LP64 - void pushl(int imm32); - void pushoop(jobject obj); + // Generic instructions + // Does 32bit or 64bit as needed for the platform. In some sense these + // belong in macro assembler but there is no need for both varieties to exist - void pushl(Register src); - void pushl(Address src); - // void pushl(Label& L, relocInfo::relocType rtype); ? needed? + void lea(Register dst, Address src); - // dummy to prevent NULL being converted to Register - void pushl(void* dummy); + void mov(Register dst, Register src); - void popl(Register dst); - void popl(Address dst); + void pusha(); + void popa(); - // Instruction prefixes - void prefix(Prefix p); + void pushf(); + void popf(); - // Moves - void movb(Register dst, Address src); - void movb(Address dst, int imm8); - void movb(Address dst, Register src); + void push(int32_t imm32); - void movw(Address dst, int imm16); - void movw(Register dst, Address src); - void movw(Address dst, Register src); + void push(Register src); - // these are dummies used to catch attempting to convert NULL to Register - void movl(Register dst, void* junk); - void movl(Address dst, void* junk); + void pop(Register dst); - void movl(Register dst, int imm32); - void movl(Address dst, int imm32); - void movl(Register dst, Register src); - void movl(Register dst, Address src); - void movl(Address dst, Register src); + // These are dummies to prevent surprise implicit conversions to Register + void push(void* v); + void pop(void* v); - void movsxb(Register dst, Address src); - void movsxb(Register dst, Register src); - void movsxw(Register dst, Address src); - void movsxw(Register dst, Register src); + // These do register sized moves/scans + void rep_mov(); + void rep_set(); + void repne_scan(); +#ifdef _LP64 + void repne_scanl(); +#endif - void movzxb(Register dst, Address src); - void movzxb(Register dst, Register src); + // Vanilla instructions in lexical order - void movzxw(Register dst, Address src); - void movzxw(Register dst, Register src); - - // Conditional moves (P6 only) - void cmovl(Condition cc, Register dst, Register src); - void cmovl(Condition cc, Register dst, Address src); - - // Prefetches (SSE, SSE2, 3DNOW only) - void prefetcht0(Address src); - void prefetcht1(Address src); - void prefetcht2(Address src); - void prefetchnta(Address src); - void prefetchw(Address src); - void prefetchr(Address src); - - // Arithmetics - void adcl(Register dst, int imm32); + void adcl(Register dst, int32_t imm32); void adcl(Register dst, Address src); void adcl(Register dst, Register src); - void addl(Address dst, int imm32); + void adcq(Register dst, int32_t imm32); + void adcq(Register dst, Address src); + void adcq(Register dst, Register src); + + + void addl(Address dst, int32_t imm32); void addl(Address dst, Register src); - void addl(Register dst, int imm32); + void addl(Register dst, int32_t imm32); void addl(Register dst, Address src); void addl(Register dst, Register src); - void andl(Register dst, int imm32); - void andl(Register dst, Address src); - void andl(Register dst, Register src); + void addq(Address dst, int32_t imm32); + void addq(Address dst, Register src); + void addq(Register dst, int32_t imm32); + void addq(Register dst, Address src); + void addq(Register dst, Register src); - void cmpb(Address dst, int imm8); - void cmpw(Address dst, int imm16); - void cmpl(Address dst, int imm32); - void cmpl(Register dst, int imm32); - void cmpl(Register dst, Register src); - void cmpl(Register dst, Address src); - // this is a dummy used to catch attempting to convert NULL to Register - void cmpl(Register dst, void* junk); - - protected: - // Don't use next inc() and dec() methods directly. INC & DEC instructions - // could cause a partial flag stall since they don't set CF flag. - // Use MacroAssembler::decrement() & MacroAssembler::increment() methods - // which call inc() & dec() or add() & sub() in accordance with - // the product flag UseIncDec value. - - void decl(Register dst); - void decl(Address dst); - - void incl(Register dst); - void incl(Address dst); - - public: - void idivl(Register src); - void cdql(); - - void imull(Register dst, Register src); - void imull(Register dst, Register src, int value); - - void leal(Register dst, Address src); - - void mull(Address src); - void mull(Register src); - - void negl(Register dst); - - void notl(Register dst); - - void orl(Address dst, int imm32); - void orl(Register dst, int imm32); - void orl(Register dst, Address src); - void orl(Register dst, Register src); - - void rcll(Register dst, int imm8); - - void sarl(Register dst, int imm8); - void sarl(Register dst); - - void sbbl(Address dst, int imm32); - void sbbl(Register dst, int imm32); - void sbbl(Register dst, Address src); - void sbbl(Register dst, Register src); - - void shldl(Register dst, Register src); - - void shll(Register dst, int imm8); - void shll(Register dst); - - void shrdl(Register dst, Register src); - - void shrl(Register dst, int imm8); - void shrl(Register dst); - - void subl(Address dst, int imm32); - void subl(Address dst, Register src); - void subl(Register dst, int imm32); - void subl(Register dst, Address src); - void subl(Register dst, Register src); - - void testb(Register dst, int imm8); - void testl(Register dst, int imm32); - void testl(Register dst, Address src); - void testl(Register dst, Register src); - - void xaddl(Address dst, Register src); - - void xorl(Register dst, int imm32); - void xorl(Register dst, Address src); - void xorl(Register dst, Register src); - - // Miscellaneous - void bswap(Register reg); - void lock(); - - void xchg (Register reg, Address adr); - void xchgl(Register dst, Register src); - - void cmpxchg (Register reg, Address adr); - void cmpxchg8 (Address adr); - - void nop(int i = 1); void addr_nop_4(); void addr_nop_5(); void addr_nop_7(); void addr_nop_8(); - void hlt(); - void ret(int imm16); - void set_byte_if_not_zero(Register dst); // sets reg to 1 if not zero, otherwise 0 - void smovl(); - void rep_movl(); - void rep_set(); - void repne_scan(); - void setb(Condition cc, Register dst); - void membar(); // Serializing memory-fence - void cpuid(); - void cld(); - void std(); + // Add Scalar Double-Precision Floating-Point Values + void addsd(XMMRegister dst, Address src); + void addsd(XMMRegister dst, XMMRegister src); - void emit_raw (unsigned char); + // Add Scalar Single-Precision Floating-Point Values + void addss(XMMRegister dst, Address src); + void addss(XMMRegister dst, XMMRegister src); + + void andl(Register dst, int32_t imm32); + void andl(Register dst, Address src); + void andl(Register dst, Register src); + + void andq(Register dst, int32_t imm32); + void andq(Register dst, Address src); + void andq(Register dst, Register src); + + + // Bitwise Logical AND of Packed Double-Precision Floating-Point Values + void andpd(XMMRegister dst, Address src); + void andpd(XMMRegister dst, XMMRegister src); + + void bswapl(Register reg); + + void bswapq(Register reg); - // Calls void call(Label& L, relocInfo::relocType rtype); void call(Register reg); // push pc; pc <- reg void call(Address adr); // push pc; pc <- adr - // Jumps - void jmp(Address entry); // pc <- entry - void jmp(Register entry); // pc <- entry + void cdql(); - // Label operations & relative jumps (PPUM Appendix D) - void jmp(Label& L, relocInfo::relocType rtype = relocInfo::none); // unconditional jump to L + void cdqq(); - // Force an 8-bit jump offset - // void jmpb(address entry); + void cld() { emit_byte(0xfc); } + + void clflush(Address adr); + + void cmovl(Condition cc, Register dst, Register src); + void cmovl(Condition cc, Register dst, Address src); + + void cmovq(Condition cc, Register dst, Register src); + void cmovq(Condition cc, Register dst, Address src); + + + void cmpb(Address dst, int imm8); + + void cmpl(Address dst, int32_t imm32); + + void cmpl(Register dst, int32_t imm32); + void cmpl(Register dst, Register src); + void cmpl(Register dst, Address src); + + void cmpq(Address dst, int32_t imm32); + void cmpq(Address dst, Register src); + + void cmpq(Register dst, int32_t imm32); + void cmpq(Register dst, Register src); + void cmpq(Register dst, Address src); + + // these are dummies used to catch attempting to convert NULL to Register + void cmpl(Register dst, void* junk); // dummy + void cmpq(Register dst, void* junk); // dummy + + void cmpw(Address dst, int imm16); + + void cmpxchg8 (Address adr); + + void cmpxchgl(Register reg, Address adr); + + void cmpxchgq(Register reg, Address adr); + + // Ordered Compare Scalar Double-Precision Floating-Point Values and set EFLAGS + void comisd(XMMRegister dst, Address src); + + // Ordered Compare Scalar Single-Precision Floating-Point Values and set EFLAGS + void comiss(XMMRegister dst, Address src); + + // Identify processor type and features + void cpuid() { + emit_byte(0x0F); + emit_byte(0xA2); + } + + // Convert Scalar Double-Precision Floating-Point Value to Scalar Single-Precision Floating-Point Value + void cvtsd2ss(XMMRegister dst, XMMRegister src); + + // Convert Doubleword Integer to Scalar Double-Precision Floating-Point Value + void cvtsi2sdl(XMMRegister dst, Register src); + void cvtsi2sdq(XMMRegister dst, Register src); + + // Convert Doubleword Integer to Scalar Single-Precision Floating-Point Value + void cvtsi2ssl(XMMRegister dst, Register src); + void cvtsi2ssq(XMMRegister dst, Register src); + + // Convert Packed Signed Doubleword Integers to Packed Double-Precision Floating-Point Value + void cvtdq2pd(XMMRegister dst, XMMRegister src); + + // Convert Packed Signed Doubleword Integers to Packed Single-Precision Floating-Point Value + void cvtdq2ps(XMMRegister dst, XMMRegister src); + + // Convert Scalar Single-Precision Floating-Point Value to Scalar Double-Precision Floating-Point Value + void cvtss2sd(XMMRegister dst, XMMRegister src); + + // Convert with Truncation Scalar Double-Precision Floating-Point Value to Doubleword Integer + void cvttsd2sil(Register dst, Address src); + void cvttsd2sil(Register dst, XMMRegister src); + void cvttsd2siq(Register dst, XMMRegister src); + + // Convert with Truncation Scalar Single-Precision Floating-Point Value to Doubleword Integer + void cvttss2sil(Register dst, XMMRegister src); + void cvttss2siq(Register dst, XMMRegister src); + + // Divide Scalar Double-Precision Floating-Point Values + void divsd(XMMRegister dst, Address src); + void divsd(XMMRegister dst, XMMRegister src); + + // Divide Scalar Single-Precision Floating-Point Values + void divss(XMMRegister dst, Address src); + void divss(XMMRegister dst, XMMRegister src); + + void emms(); + + void fabs(); + + void fadd(int i); + + void fadd_d(Address src); + void fadd_s(Address src); + + // "Alternate" versions of x87 instructions place result down in FPU + // stack instead of on TOS + + void fadda(int i); // "alternate" fadd + void faddp(int i = 1); + + void fchs(); + + void fcom(int i); + + void fcomp(int i = 1); + void fcomp_d(Address src); + void fcomp_s(Address src); + + void fcompp(); + + void fcos(); + + void fdecstp(); + + void fdiv(int i); + void fdiv_d(Address src); + void fdivr_s(Address src); + void fdiva(int i); // "alternate" fdiv + void fdivp(int i = 1); + + void fdivr(int i); + void fdivr_d(Address src); + void fdiv_s(Address src); + + void fdivra(int i); // "alternate" reversed fdiv + + void fdivrp(int i = 1); + + void ffree(int i = 0); + + void fild_d(Address adr); + void fild_s(Address adr); + + void fincstp(); + + void finit(); + + void fist_s (Address adr); + void fistp_d(Address adr); + void fistp_s(Address adr); + + void fld1(); + + void fld_d(Address adr); + void fld_s(Address adr); + void fld_s(int index); + void fld_x(Address adr); // extended-precision (80-bit) format + + void fldcw(Address src); + + void fldenv(Address src); + + void fldlg2(); + + void fldln2(); + + void fldz(); + + void flog(); + void flog10(); + + void fmul(int i); + + void fmul_d(Address src); + void fmul_s(Address src); + + void fmula(int i); // "alternate" fmul + + void fmulp(int i = 1); + + void fnsave(Address dst); + + void fnstcw(Address src); + + void fnstsw_ax(); + + void fprem(); + void fprem1(); + + void frstor(Address src); + + void fsin(); + + void fsqrt(); + + void fst_d(Address adr); + void fst_s(Address adr); + + void fstp_d(Address adr); + void fstp_d(int index); + void fstp_s(Address adr); + void fstp_x(Address adr); // extended-precision (80-bit) format + + void fsub(int i); + void fsub_d(Address src); + void fsub_s(Address src); + + void fsuba(int i); // "alternate" fsub + + void fsubp(int i = 1); + + void fsubr(int i); + void fsubr_d(Address src); + void fsubr_s(Address src); + + void fsubra(int i); // "alternate" reversed fsub + + void fsubrp(int i = 1); + + void ftan(); + + void ftst(); + + void fucomi(int i = 1); + void fucomip(int i = 1); + + void fwait(); + + void fxch(int i = 1); + + void fxrstor(Address src); + + void fxsave(Address dst); + + void fyl2x(); + + void hlt(); + + void idivl(Register src); + + void idivq(Register src); + + void imull(Register dst, Register src); + void imull(Register dst, Register src, int value); + + void imulq(Register dst, Register src); + void imulq(Register dst, Register src, int value); - // Unconditional 8-bit offset jump to L. - // WARNING: be very careful using this for forward jumps. If the label is - // not bound within an 8-bit offset of this instruction, a run-time error - // will occur. - void jmpb(Label& L); // jcc is the generic conditional branch generator to run- // time routines, jcc is used for branches to labels. jcc @@ -737,250 +986,321 @@ class Assembler : public AbstractAssembler { // will occur. void jccb(Condition cc, Label& L); - // Floating-point operations - void fld1(); - void fldz(); + void jmp(Address entry); // pc <- entry - void fld_s(Address adr); - void fld_s(int index); - void fld_d(Address adr); - void fld_x(Address adr); // extended-precision (80-bit) format + // Label operations & relative jumps (PPUM Appendix D) + void jmp(Label& L, relocInfo::relocType rtype = relocInfo::none); // unconditional jump to L - void fst_s(Address adr); - void fst_d(Address adr); + void jmp(Register entry); // pc <- entry - void fstp_s(Address adr); - void fstp_d(Address adr); - void fstp_d(int index); - void fstp_x(Address adr); // extended-precision (80-bit) format + // Unconditional 8-bit offset jump to L. + // WARNING: be very careful using this for forward jumps. If the label is + // not bound within an 8-bit offset of this instruction, a run-time error + // will occur. + void jmpb(Label& L); - void fild_s(Address adr); - void fild_d(Address adr); + void ldmxcsr( Address src ); - void fist_s (Address adr); - void fistp_s(Address adr); - void fistp_d(Address adr); + void leal(Register dst, Address src); - void fabs(); - void fchs(); + void leaq(Register dst, Address src); - void flog(); - void flog10(); + void lfence() { + emit_byte(0x0F); + emit_byte(0xAE); + emit_byte(0xE8); + } - void fldln2(); - void fyl2x(); - void fldlg2(); + void lock(); - void fcos(); - void fsin(); - void ftan(); - void fsqrt(); + enum Membar_mask_bits { + StoreStore = 1 << 3, + LoadStore = 1 << 2, + StoreLoad = 1 << 1, + LoadLoad = 1 << 0 + }; - // "Alternate" versions of instructions place result down in FPU - // stack instead of on TOS - void fadd_s(Address src); - void fadd_d(Address src); - void fadd(int i); - void fadda(int i); // "alternate" fadd + // Serializes memory. + void membar(Membar_mask_bits order_constraint) { + // We only have to handle StoreLoad and LoadLoad + if (order_constraint & StoreLoad) { + // MFENCE subsumes LFENCE + mfence(); + } /* [jk] not needed currently: else if (order_constraint & LoadLoad) { + lfence(); + } */ + } - void fsub_s(Address src); - void fsub_d(Address src); - void fsubr_s(Address src); - void fsubr_d(Address src); + void mfence(); - void fmul_s(Address src); - void fmul_d(Address src); - void fmul(int i); - void fmula(int i); // "alternate" fmul + // Moves - void fdiv_s(Address src); - void fdiv_d(Address src); - void fdivr_s(Address src); - void fdivr_d(Address src); + void mov64(Register dst, int64_t imm64); - void fsub(int i); - void fsuba(int i); // "alternate" fsub - void fsubr(int i); - void fsubra(int i); // "alternate" reversed fsub - void fdiv(int i); - void fdiva(int i); // "alternate" fdiv - void fdivr(int i); - void fdivra(int i); // "alternate" reversed fdiv + void movb(Address dst, Register src); + void movb(Address dst, int imm8); + void movb(Register dst, Address src); - void faddp(int i = 1); - void fsubp(int i = 1); - void fsubrp(int i = 1); - void fmulp(int i = 1); - void fdivp(int i = 1); - void fdivrp(int i = 1); - void fprem(); - void fprem1(); + void movdl(XMMRegister dst, Register src); + void movdl(Register dst, XMMRegister src); - void fxch(int i = 1); - void fincstp(); - void fdecstp(); - void ffree(int i = 0); + // Move Double Quadword + void movdq(XMMRegister dst, Register src); + void movdq(Register dst, XMMRegister src); - void fcomp_s(Address src); - void fcomp_d(Address src); - void fcom(int i); - void fcomp(int i = 1); - void fcompp(); + // Move Aligned Double Quadword + void movdqa(Address dst, XMMRegister src); + void movdqa(XMMRegister dst, Address src); + void movdqa(XMMRegister dst, XMMRegister src); - void fucomi(int i = 1); - void fucomip(int i = 1); + void movl(Register dst, int32_t imm32); + void movl(Address dst, int32_t imm32); + void movl(Register dst, Register src); + void movl(Register dst, Address src); + void movl(Address dst, Register src); - void ftst(); - void fnstsw_ax(); - void fwait(); - void finit(); - void fldcw(Address src); - void fnstcw(Address src); + // These dummies prevent using movl from converting a zero (like NULL) into Register + // by giving the compiler two choices it can't resolve - void fnsave(Address dst); - void frstor(Address src); - void fldenv(Address src); + void movl(Address dst, void* junk); + void movl(Register dst, void* junk); + +#ifdef _LP64 + void movq(Register dst, Register src); + void movq(Register dst, Address src); + void movq(Address dst, Register src); +#endif + + void movq(Address dst, MMXRegister src ); + void movq(MMXRegister dst, Address src ); + +#ifdef _LP64 + // These dummies prevent using movq from converting a zero (like NULL) into Register + // by giving the compiler two choices it can't resolve + + void movq(Address dst, void* dummy); + void movq(Register dst, void* dummy); +#endif + + // Move Quadword + void movq(Address dst, XMMRegister src); + void movq(XMMRegister dst, Address src); + + void movsbl(Register dst, Address src); + void movsbl(Register dst, Register src); + +#ifdef _LP64 + // Move signed 32bit immediate to 64bit extending sign + void movslq(Address dst, int32_t imm64); + void movslq(Register dst, int32_t imm64); + + void movslq(Register dst, Address src); + void movslq(Register dst, Register src); + void movslq(Register dst, void* src); // Dummy declaration to cause NULL to be ambiguous +#endif + + void movswl(Register dst, Address src); + void movswl(Register dst, Register src); + + void movw(Address dst, int imm16); + void movw(Register dst, Address src); + void movw(Address dst, Register src); + + void movzbl(Register dst, Address src); + void movzbl(Register dst, Register src); + + void movzwl(Register dst, Address src); + void movzwl(Register dst, Register src); + + void mull(Address src); + void mull(Register src); + + // Multiply Scalar Double-Precision Floating-Point Values + void mulsd(XMMRegister dst, Address src); + void mulsd(XMMRegister dst, XMMRegister src); + + // Multiply Scalar Single-Precision Floating-Point Values + void mulss(XMMRegister dst, Address src); + void mulss(XMMRegister dst, XMMRegister src); + + void negl(Register dst); + +#ifdef _LP64 + void negq(Register dst); +#endif + + void nop(int i = 1); + + void notl(Register dst); + +#ifdef _LP64 + void notq(Register dst); +#endif + + void orl(Address dst, int32_t imm32); + void orl(Register dst, int32_t imm32); + void orl(Register dst, Address src); + void orl(Register dst, Register src); + + void orq(Address dst, int32_t imm32); + void orq(Register dst, int32_t imm32); + void orq(Register dst, Address src); + void orq(Register dst, Register src); + + void popl(Address dst); + +#ifdef _LP64 + void popq(Address dst); +#endif + + // Prefetches (SSE, SSE2, 3DNOW only) + + void prefetchnta(Address src); + void prefetchr(Address src); + void prefetcht0(Address src); + void prefetcht1(Address src); + void prefetcht2(Address src); + void prefetchw(Address src); + + // Shuffle Packed Doublewords + void pshufd(XMMRegister dst, XMMRegister src, int mode); + void pshufd(XMMRegister dst, Address src, int mode); + + // Shuffle Packed Low Words + void pshuflw(XMMRegister dst, XMMRegister src, int mode); + void pshuflw(XMMRegister dst, Address src, int mode); + + // Shift Right Logical Quadword Immediate + void psrlq(XMMRegister dst, int shift); + + // Interleave Low Bytes + void punpcklbw(XMMRegister dst, XMMRegister src); + + void pushl(Address src); + + void pushq(Address src); + + // Xor Packed Byte Integer Values + void pxor(XMMRegister dst, Address src); + void pxor(XMMRegister dst, XMMRegister src); + + void rcll(Register dst, int imm8); + + void rclq(Register dst, int imm8); + + void ret(int imm16); void sahf(); - protected: - void emit_sse_operand(XMMRegister reg, Address adr); - void emit_sse_operand(Register reg, Address adr); - void emit_sse_operand(XMMRegister dst, XMMRegister src); - void emit_sse_operand(XMMRegister dst, Register src); - void emit_sse_operand(Register dst, XMMRegister src); + void sarl(Register dst, int imm8); + void sarl(Register dst); - void emit_operand(MMXRegister reg, Address adr); + void sarq(Register dst, int imm8); + void sarq(Register dst); - public: - // mmx operations - void movq( MMXRegister dst, Address src ); - void movq( Address dst, MMXRegister src ); - void emms(); + void sbbl(Address dst, int32_t imm32); + void sbbl(Register dst, int32_t imm32); + void sbbl(Register dst, Address src); + void sbbl(Register dst, Register src); - // xmm operations - void addss(XMMRegister dst, Address src); // Add Scalar Single-Precision Floating-Point Values - void addss(XMMRegister dst, XMMRegister src); - void addsd(XMMRegister dst, Address src); // Add Scalar Double-Precision Floating-Point Values - void addsd(XMMRegister dst, XMMRegister src); + void sbbq(Address dst, int32_t imm32); + void sbbq(Register dst, int32_t imm32); + void sbbq(Register dst, Address src); + void sbbq(Register dst, Register src); - void subss(XMMRegister dst, Address src); // Subtract Scalar Single-Precision Floating-Point Values - void subss(XMMRegister dst, XMMRegister src); - void subsd(XMMRegister dst, Address src); // Subtract Scalar Double-Precision Floating-Point Values - void subsd(XMMRegister dst, XMMRegister src); + void setb(Condition cc, Register dst); - void mulss(XMMRegister dst, Address src); // Multiply Scalar Single-Precision Floating-Point Values - void mulss(XMMRegister dst, XMMRegister src); - void mulsd(XMMRegister dst, Address src); // Multiply Scalar Double-Precision Floating-Point Values - void mulsd(XMMRegister dst, XMMRegister src); + void shldl(Register dst, Register src); - void divss(XMMRegister dst, Address src); // Divide Scalar Single-Precision Floating-Point Values - void divss(XMMRegister dst, XMMRegister src); - void divsd(XMMRegister dst, Address src); // Divide Scalar Double-Precision Floating-Point Values - void divsd(XMMRegister dst, XMMRegister src); + void shll(Register dst, int imm8); + void shll(Register dst); - void sqrtss(XMMRegister dst, Address src); // Compute Square Root of Scalar Single-Precision Floating-Point Value - void sqrtss(XMMRegister dst, XMMRegister src); - void sqrtsd(XMMRegister dst, Address src); // Compute Square Root of Scalar Double-Precision Floating-Point Value + void shlq(Register dst, int imm8); + void shlq(Register dst); + + void shrdl(Register dst, Register src); + + void shrl(Register dst, int imm8); + void shrl(Register dst); + + void shrq(Register dst, int imm8); + void shrq(Register dst); + + void smovl(); // QQQ generic? + + // Compute Square Root of Scalar Double-Precision Floating-Point Value + void sqrtsd(XMMRegister dst, Address src); void sqrtsd(XMMRegister dst, XMMRegister src); - void pxor(XMMRegister dst, Address src); // Xor Packed Byte Integer Values - void pxor(XMMRegister dst, XMMRegister src); // Xor Packed Byte Integer Values + void std() { emit_byte(0xfd); } - void comiss(XMMRegister dst, Address src); // Ordered Compare Scalar Single-Precision Floating-Point Values and set EFLAGS - void comiss(XMMRegister dst, XMMRegister src); - void comisd(XMMRegister dst, Address src); // Ordered Compare Scalar Double-Precision Floating-Point Values and set EFLAGS - void comisd(XMMRegister dst, XMMRegister src); + void stmxcsr( Address dst ); - void ucomiss(XMMRegister dst, Address src); // Unordered Compare Scalar Single-Precision Floating-Point Values and set EFLAGS - void ucomiss(XMMRegister dst, XMMRegister src); - void ucomisd(XMMRegister dst, Address src); // Unordered Compare Scalar Double-Precision Floating-Point Values and set EFLAGS + void subl(Address dst, int32_t imm32); + void subl(Address dst, Register src); + void subl(Register dst, int32_t imm32); + void subl(Register dst, Address src); + void subl(Register dst, Register src); + + void subq(Address dst, int32_t imm32); + void subq(Address dst, Register src); + void subq(Register dst, int32_t imm32); + void subq(Register dst, Address src); + void subq(Register dst, Register src); + + + // Subtract Scalar Double-Precision Floating-Point Values + void subsd(XMMRegister dst, Address src); + void subsd(XMMRegister dst, XMMRegister src); + + // Subtract Scalar Single-Precision Floating-Point Values + void subss(XMMRegister dst, Address src); + void subss(XMMRegister dst, XMMRegister src); + + void testb(Register dst, int imm8); + + void testl(Register dst, int32_t imm32); + void testl(Register dst, Register src); + void testl(Register dst, Address src); + + void testq(Register dst, int32_t imm32); + void testq(Register dst, Register src); + + + // Unordered Compare Scalar Double-Precision Floating-Point Values and set EFLAGS + void ucomisd(XMMRegister dst, Address src); void ucomisd(XMMRegister dst, XMMRegister src); - void cvtss2sd(XMMRegister dst, Address src); // Convert Scalar Single-Precision Floating-Point Value to Scalar Double-Precision Floating-Point Value - void cvtss2sd(XMMRegister dst, XMMRegister src); - void cvtsd2ss(XMMRegister dst, Address src); // Convert Scalar Double-Precision Floating-Point Value to Scalar Single-Precision Floating-Point Value - void cvtsd2ss(XMMRegister dst, XMMRegister src); - void cvtdq2pd(XMMRegister dst, XMMRegister src); - void cvtdq2ps(XMMRegister dst, XMMRegister src); + // Unordered Compare Scalar Single-Precision Floating-Point Values and set EFLAGS + void ucomiss(XMMRegister dst, Address src); + void ucomiss(XMMRegister dst, XMMRegister src); - void cvtsi2ss(XMMRegister dst, Address src); // Convert Doubleword Integer to Scalar Single-Precision Floating-Point Value - void cvtsi2ss(XMMRegister dst, Register src); - void cvtsi2sd(XMMRegister dst, Address src); // Convert Doubleword Integer to Scalar Double-Precision Floating-Point Value - void cvtsi2sd(XMMRegister dst, Register src); + void xaddl(Address dst, Register src); - void cvtss2si(Register dst, Address src); // Convert Scalar Single-Precision Floating-Point Value to Doubleword Integer - void cvtss2si(Register dst, XMMRegister src); - void cvtsd2si(Register dst, Address src); // Convert Scalar Double-Precision Floating-Point Value to Doubleword Integer - void cvtsd2si(Register dst, XMMRegister src); + void xaddq(Address dst, Register src); - void cvttss2si(Register dst, Address src); // Convert with Truncation Scalar Single-Precision Floating-Point Value to Doubleword Integer - void cvttss2si(Register dst, XMMRegister src); - void cvttsd2si(Register dst, Address src); // Convert with Truncation Scalar Double-Precision Floating-Point Value to Doubleword Integer - void cvttsd2si(Register dst, XMMRegister src); + void xchgl(Register reg, Address adr); + void xchgl(Register dst, Register src); - protected: // Avoid using the next instructions directly. - // New cpus require use of movsd and movss to avoid partial register stall - // when loading from memory. But for old Opteron use movlpd instead of movsd. - // The selection is done in MacroAssembler::movdbl() and movflt(). - void movss(XMMRegister dst, Address src); // Move Scalar Single-Precision Floating-Point Values - void movss(XMMRegister dst, XMMRegister src); - void movss(Address dst, XMMRegister src); - void movsd(XMMRegister dst, Address src); // Move Scalar Double-Precision Floating-Point Values - void movsd(XMMRegister dst, XMMRegister src); - void movsd(Address dst, XMMRegister src); - void movlpd(XMMRegister dst, Address src); - // New cpus require use of movaps and movapd to avoid partial register stall - // when moving between registers. - void movaps(XMMRegister dst, XMMRegister src); - void movapd(XMMRegister dst, XMMRegister src); - public: + void xchgq(Register reg, Address adr); + void xchgq(Register dst, Register src); - void andps(XMMRegister dst, Address src); // Bitwise Logical AND of Packed Single-Precision Floating-Point Values - void andps(XMMRegister dst, XMMRegister src); - void andpd(XMMRegister dst, Address src); // Bitwise Logical AND of Packed Double-Precision Floating-Point Values - void andpd(XMMRegister dst, XMMRegister src); + void xorl(Register dst, int32_t imm32); + void xorl(Register dst, Address src); + void xorl(Register dst, Register src); - void andnps(XMMRegister dst, Address src); // Bitwise Logical AND NOT of Packed Single-Precision Floating-Point Values - void andnps(XMMRegister dst, XMMRegister src); - void andnpd(XMMRegister dst, Address src); // Bitwise Logical AND NOT of Packed Double-Precision Floating-Point Values - void andnpd(XMMRegister dst, XMMRegister src); + void xorq(Register dst, Address src); + void xorq(Register dst, Register src); - void orps(XMMRegister dst, Address src); // Bitwise Logical OR of Packed Single-Precision Floating-Point Values - void orps(XMMRegister dst, XMMRegister src); - void orpd(XMMRegister dst, Address src); // Bitwise Logical OR of Packed Double-Precision Floating-Point Values - void orpd(XMMRegister dst, XMMRegister src); - - void xorps(XMMRegister dst, Address src); // Bitwise Logical XOR of Packed Single-Precision Floating-Point Values - void xorps(XMMRegister dst, XMMRegister src); - void xorpd(XMMRegister dst, Address src); // Bitwise Logical XOR of Packed Double-Precision Floating-Point Values + // Bitwise Logical XOR of Packed Double-Precision Floating-Point Values + void xorpd(XMMRegister dst, Address src); void xorpd(XMMRegister dst, XMMRegister src); - void movq(XMMRegister dst, Address src); // Move Quadword - void movq(XMMRegister dst, XMMRegister src); - void movq(Address dst, XMMRegister src); + // Bitwise Logical XOR of Packed Single-Precision Floating-Point Values + void xorps(XMMRegister dst, Address src); + void xorps(XMMRegister dst, XMMRegister src); - void movd(XMMRegister dst, Address src); // Move Doubleword - void movd(XMMRegister dst, Register src); - void movd(Register dst, XMMRegister src); - void movd(Address dst, XMMRegister src); - - void movdqa(XMMRegister dst, Address src); // Move Aligned Double Quadword - void movdqa(XMMRegister dst, XMMRegister src); - void movdqa(Address dst, XMMRegister src); - - void pshufd(XMMRegister dst, XMMRegister src, int mode); // Shuffle Packed Doublewords - void pshufd(XMMRegister dst, Address src, int mode); - void pshuflw(XMMRegister dst, XMMRegister src, int mode); // Shuffle Packed Low Words - void pshuflw(XMMRegister dst, Address src, int mode); - - void psrlq(XMMRegister dst, int shift); // Shift Right Logical Quadword Immediate - - void punpcklbw(XMMRegister dst, XMMRegister src); // Interleave Low Bytes - void punpcklbw(XMMRegister dst, Address src); - - void ldmxcsr( Address src ); - void stmxcsr( Address dst ); + void set_byte_if_not_zero(Register dst); // sets reg to 1 if not zero, otherwise 0 }; @@ -1077,10 +1397,22 @@ class MacroAssembler: public Assembler { void extend_sign(Register hi, Register lo); // Support for inc/dec with optimal instruction selection depending on value - void increment(Register reg, int value = 1); - void decrement(Register reg, int value = 1); - void increment(Address dst, int value = 1); - void decrement(Address dst, int value = 1); + + void increment(Register reg, int value = 1) { LP64_ONLY(incrementq(reg, value)) NOT_LP64(incrementl(reg, value)) ; } + void decrement(Register reg, int value = 1) { LP64_ONLY(decrementq(reg, value)) NOT_LP64(decrementl(reg, value)) ; } + + void decrementl(Address dst, int value = 1); + void decrementl(Register reg, int value = 1); + + void decrementq(Register reg, int value = 1); + void decrementq(Address dst, int value = 1); + + void incrementl(Address dst, int value = 1); + void incrementl(Register reg, int value = 1); + + void incrementq(Register reg, int value = 1); + void incrementq(Address dst, int value = 1); + // Support optimal SSE move instructions. void movflt(XMMRegister dst, XMMRegister src) { @@ -1104,9 +1436,8 @@ class MacroAssembler: public Assembler { } void movdbl(Address dst, XMMRegister src) { movsd(dst, src); } - void increment(AddressLiteral dst); - void increment(ArrayAddress dst); - + void incrementl(AddressLiteral dst); + void incrementl(ArrayAddress dst); // Alignment void align(int modulus); @@ -1128,25 +1459,70 @@ class MacroAssembler: public Assembler { // They make sure that the stack linkage is setup correctly. call_VM's correspond // to ENTRY/ENTRY_X entry points while call_VM_leaf's correspond to LEAF entry points. - void call_VM(Register oop_result, address entry_point, bool check_exceptions = true); - void call_VM(Register oop_result, address entry_point, Register arg_1, bool check_exceptions = true); - void call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, bool check_exceptions = true); - void call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, Register arg_3, bool check_exceptions = true); - void call_VM(Register oop_result, Register last_java_sp, address entry_point, int number_of_arguments = 0, bool check_exceptions = true); - void call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, bool check_exceptions = true); - void call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, bool check_exceptions = true); - void call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, Register arg_3, bool check_exceptions = true); + void call_VM(Register oop_result, + address entry_point, + bool check_exceptions = true); + void call_VM(Register oop_result, + address entry_point, + Register arg_1, + bool check_exceptions = true); + void call_VM(Register oop_result, + address entry_point, + Register arg_1, Register arg_2, + bool check_exceptions = true); + void call_VM(Register oop_result, + address entry_point, + Register arg_1, Register arg_2, Register arg_3, + bool check_exceptions = true); - void call_VM_leaf(address entry_point, int number_of_arguments = 0); - void call_VM_leaf(address entry_point, Register arg_1); - void call_VM_leaf(address entry_point, Register arg_1, Register arg_2); - void call_VM_leaf(address entry_point, Register arg_1, Register arg_2, Register arg_3); + // Overloadings with last_Java_sp + void call_VM(Register oop_result, + Register last_java_sp, + address entry_point, + int number_of_arguments = 0, + bool check_exceptions = true); + void call_VM(Register oop_result, + Register last_java_sp, + address entry_point, + Register arg_1, bool + check_exceptions = true); + void call_VM(Register oop_result, + Register last_java_sp, + address entry_point, + Register arg_1, Register arg_2, + bool check_exceptions = true); + void call_VM(Register oop_result, + Register last_java_sp, + address entry_point, + Register arg_1, Register arg_2, Register arg_3, + bool check_exceptions = true); + + void call_VM_leaf(address entry_point, + int number_of_arguments = 0); + void call_VM_leaf(address entry_point, + Register arg_1); + void call_VM_leaf(address entry_point, + Register arg_1, Register arg_2); + void call_VM_leaf(address entry_point, + Register arg_1, Register arg_2, Register arg_3); // last Java Frame (fills frame anchor) - void set_last_Java_frame(Register thread, Register last_java_sp, Register last_java_fp, address last_java_pc); + void set_last_Java_frame(Register thread, + Register last_java_sp, + Register last_java_fp, + address last_java_pc); + + // thread in the default location (r15_thread on 64bit) + void set_last_Java_frame(Register last_java_sp, + Register last_java_fp, + address last_java_pc); + void reset_last_Java_frame(Register thread, bool clear_fp, bool clear_pc); + // thread in the default location (r15_thread on 64bit) + void reset_last_Java_frame(bool clear_fp, bool clear_pc); + // Stores void store_check(Register obj); // store check for obj - register is destroyed afterwards void store_check(Register obj, Address dst); // same as above, dst is exact store location (reg. is destroyed) @@ -1165,18 +1541,48 @@ class MacroAssembler: public Assembler { void movbool(Address dst, Register src); void testbool(Register dst); - // Int division/reminder for Java + // oop manipulations + void load_klass(Register dst, Register src); + void store_klass(Register dst, Register src); + + void load_prototype_header(Register dst, Register src); + +#ifdef _LP64 + void store_klass_gap(Register dst, Register src); + + void load_heap_oop(Register dst, Address src); + void store_heap_oop(Address dst, Register src); + void encode_heap_oop(Register r); + void decode_heap_oop(Register r); + void encode_heap_oop_not_null(Register r); + void decode_heap_oop_not_null(Register r); + void encode_heap_oop_not_null(Register dst, Register src); + void decode_heap_oop_not_null(Register dst, Register src); + + void set_narrow_oop(Register dst, jobject obj); + + // if heap base register is used - reinit it with the correct value + void reinit_heapbase(); +#endif // _LP64 + + // Int division/remainder for Java // (as idivl, but checks for special case as described in JVM spec.) // returns idivl instruction offset for implicit exception handling int corrected_idivl(Register reg); + // Long division/remainder for Java + // (as idivq, but checks for special case as described in JVM spec.) + // returns idivq instruction offset for implicit exception handling + int corrected_idivq(Register reg); + void int3(); + // Long operation macros for a 32bit cpu // Long negation for Java void lneg(Register hi, Register lo); // Long multiplication for Java - // (destroys contents of rax, rbx, rcx and rdx) + // (destroys contents of eax, ebx, ecx and edx) void lmul(int x_rsp_offset, int y_rsp_offset); // rdx:rax = x * y // Long shifts for Java @@ -1188,6 +1594,16 @@ class MacroAssembler: public Assembler { // (semantics as described in JVM spec.) void lcmp2int(Register x_hi, Register x_lo, Register y_hi, Register y_lo); // x_hi = lcmp(x, y) + + // misc + + // Sign extension + void sign_extend_short(Register reg); + void sign_extend_byte(Register reg); + + // Division by power of 2, rounding towards 0 + void division_with_shift(Register reg, int shift_value); + // Compares the top-most stack entries on the FPU stack and sets the eflags as follows: // // CF (corresponds to C0) if x < y @@ -1255,13 +1671,6 @@ class MacroAssembler: public Assembler { void push_CPU_state(); void pop_CPU_state(); - // Sign extension - void sign_extend_short(Register reg); - void sign_extend_byte(Register reg); - - // Division by power of 2, rounding towards 0 - void division_with_shift(Register reg, int shift_value); - // Round up to a power of two void round_to(Register reg, int modulus); @@ -1291,17 +1700,31 @@ class MacroAssembler: public Assembler { void set_word_if_not_zero(Register reg); // sets reg to 1 if not zero, otherwise 0 // Debugging - void verify_oop(Register reg, const char* s = "broken oop"); // only if +VerifyOops + + // only if +VerifyOops + void verify_oop(Register reg, const char* s = "broken oop"); void verify_oop_addr(Address addr, const char * s = "broken oop addr"); - void verify_FPU(int stack_depth, const char* s = "illegal FPU state"); // only if +VerifyFPU - void stop(const char* msg); // prints msg, dumps registers and stops execution - void warn(const char* msg); // prints msg and continues - static void debug(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip, char* msg); + // only if +VerifyFPU + void verify_FPU(int stack_depth, const char* s = "illegal FPU state"); + + // prints msg, dumps registers and stops execution + void stop(const char* msg); + + // prints msg and continues + void warn(const char* msg); + + static void debug32(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip, char* msg); + static void debug64(char* msg, int64_t pc, int64_t regs[]); + void os_breakpoint(); + void untested() { stop("untested"); } + void unimplemented(const char* what = "") { char* b = new char[1024]; jio_snprintf(b, sizeof(b), "unimplemented: %s", what); stop(b); } + void should_not_reach_here() { stop("should not reach here"); } + void print_CPU_state(); // Stack overflow checking @@ -1348,9 +1771,20 @@ class MacroAssembler: public Assembler { // Arithmetics - void cmp8(AddressLiteral src1, int8_t imm); - // QQQ renamed to drag out the casting of address to int32_t/intptr_t + void addptr(Address dst, int32_t src) { LP64_ONLY(addq(dst, src)) NOT_LP64(addl(dst, src)) ; } + void addptr(Address dst, Register src); + + void addptr(Register dst, Address src) { LP64_ONLY(addq(dst, src)) NOT_LP64(addl(dst, src)); } + void addptr(Register dst, int32_t src); + void addptr(Register dst, Register src); + + void andptr(Register dst, int32_t src); + void andptr(Register src1, Register src2) { LP64_ONLY(andq(src1, src2)) NOT_LP64(andl(src1, src2)) ; } + + void cmp8(AddressLiteral src1, int imm); + + // renamed to drag out the casting of address to int32_t/intptr_t void cmp32(Register src1, int32_t imm); void cmp32(AddressLiteral src1, int32_t imm); @@ -1359,16 +1793,63 @@ class MacroAssembler: public Assembler { void cmp32(Register src1, Address src2); +#ifndef _LP64 + void cmpoop(Address dst, jobject obj); + void cmpoop(Register dst, jobject obj); +#endif // _LP64 + // NOTE src2 must be the lval. This is NOT an mem-mem compare void cmpptr(Address src1, AddressLiteral src2); void cmpptr(Register src1, AddressLiteral src2); - void cmpoop(Address dst, jobject obj); - void cmpoop(Register dst, jobject obj); + void cmpptr(Register src1, Register src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } + void cmpptr(Register src1, Address src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } + // void cmpptr(Address src1, Register src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } + + void cmpptr(Register src1, int32_t src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } + void cmpptr(Address src1, int32_t src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } + + // cmp64 to avoild hiding cmpq + void cmp64(Register src1, AddressLiteral src); + + void cmpxchgptr(Register reg, Address adr); + + void locked_cmpxchgptr(Register reg, AddressLiteral adr); + + + void imulptr(Register dst, Register src) { LP64_ONLY(imulq(dst, src)) NOT_LP64(imull(dst, src)); } + + + void negptr(Register dst) { LP64_ONLY(negq(dst)) NOT_LP64(negl(dst)); } + + void notptr(Register dst) { LP64_ONLY(notq(dst)) NOT_LP64(notl(dst)); } + + void shlptr(Register dst, int32_t shift); + void shlptr(Register dst) { LP64_ONLY(shlq(dst)) NOT_LP64(shll(dst)); } + + void shrptr(Register dst, int32_t shift); + void shrptr(Register dst) { LP64_ONLY(shrq(dst)) NOT_LP64(shrl(dst)); } + + void sarptr(Register dst) { LP64_ONLY(sarq(dst)) NOT_LP64(sarl(dst)); } + void sarptr(Register dst, int32_t src) { LP64_ONLY(sarq(dst, src)) NOT_LP64(sarl(dst, src)); } + + void subptr(Address dst, int32_t src) { LP64_ONLY(subq(dst, src)) NOT_LP64(subl(dst, src)); } + + void subptr(Register dst, Address src) { LP64_ONLY(subq(dst, src)) NOT_LP64(subl(dst, src)); } + void subptr(Register dst, int32_t src); + void subptr(Register dst, Register src); + + + void sbbptr(Address dst, int32_t src) { LP64_ONLY(sbbq(dst, src)) NOT_LP64(sbbl(dst, src)); } + void sbbptr(Register dst, int32_t src) { LP64_ONLY(sbbq(dst, src)) NOT_LP64(sbbl(dst, src)); } + + void xchgptr(Register src1, Register src2) { LP64_ONLY(xchgq(src1, src2)) NOT_LP64(xchgl(src1, src2)) ; } + void xchgptr(Register src1, Address src2) { LP64_ONLY(xchgq(src1, src2)) NOT_LP64(xchgl(src1, src2)) ; } + + void xaddptr(Address src1, Register src2) { LP64_ONLY(xaddq(src1, src2)) NOT_LP64(xaddl(src1, src2)) ; } - void cmpxchgptr(Register reg, AddressLiteral adr); // Helper functions for statistics gathering. // Conditionally (atomically, on MPs) increments passed counter address, preserving condition codes. @@ -1378,8 +1859,21 @@ class MacroAssembler: public Assembler { void lea(Register dst, AddressLiteral adr); void lea(Address dst, AddressLiteral adr); + void lea(Register dst, Address adr) { Assembler::lea(dst, adr); } - void test32(Register dst, AddressLiteral src); + void leal32(Register dst, Address src) { leal(dst, src); } + + void test32(Register src1, AddressLiteral src2); + + void orptr(Register dst, Address src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); } + void orptr(Register dst, Register src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); } + void orptr(Register dst, int32_t src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); } + + void testptr(Register src, int32_t imm32) { LP64_ONLY(testq(src, imm32)) NOT_LP64(testl(src, imm32)); } + void testptr(Register src1, Register src2); + + void xorptr(Register dst, Register src) { LP64_ONLY(xorq(dst, src)) NOT_LP64(xorl(dst, src)); } + void xorptr(Register dst, Address src) { LP64_ONLY(xorq(dst, src)) NOT_LP64(xorl(dst, src)); } // Calls @@ -1431,11 +1925,19 @@ class MacroAssembler: public Assembler { void ldmxcsr(Address src) { Assembler::ldmxcsr(src); } void ldmxcsr(AddressLiteral src); +private: + // these are private because users should be doing movflt/movdbl + void movss(Address dst, XMMRegister src) { Assembler::movss(dst, src); } void movss(XMMRegister dst, XMMRegister src) { Assembler::movss(dst, src); } void movss(XMMRegister dst, Address src) { Assembler::movss(dst, src); } void movss(XMMRegister dst, AddressLiteral src); + void movlpd(XMMRegister dst, Address src) {Assembler::movlpd(dst, src); } + void movlpd(XMMRegister dst, AddressLiteral src); + +public: + void movsd(XMMRegister dst, XMMRegister src) { Assembler::movsd(dst, src); } void movsd(Address dst, XMMRegister src) { Assembler::movsd(dst, src); } void movsd(XMMRegister dst, Address src) { Assembler::movsd(dst, src); } @@ -1461,6 +1963,11 @@ class MacroAssembler: public Assembler { // Data + void cmov(Condition cc, Register dst, Register src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); } + + void cmovptr(Condition cc, Register dst, Address src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); } + void cmovptr(Condition cc, Register dst, Register src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); } + void movoop(Register dst, jobject obj); void movoop(Address dst, jobject obj); @@ -1468,17 +1975,48 @@ class MacroAssembler: public Assembler { // can this do an lea? void movptr(Register dst, ArrayAddress src); + void movptr(Register dst, Address src); + void movptr(Register dst, AddressLiteral src); + void movptr(Register dst, intptr_t src); + void movptr(Register dst, Register src); + void movptr(Address dst, intptr_t src); + + void movptr(Address dst, Register src); + +#ifdef _LP64 + // Generally the next two are only used for moving NULL + // Although there are situations in initializing the mark word where + // they could be used. They are dangerous. + + // They only exist on LP64 so that int32_t and intptr_t are not the same + // and we have ambiguous declarations. + + void movptr(Address dst, int32_t imm32); + void movptr(Register dst, int32_t imm32); +#endif // _LP64 + // to avoid hiding movl void mov32(AddressLiteral dst, Register src); void mov32(Register dst, AddressLiteral src); + // to avoid hiding movb void movbyte(ArrayAddress dst, int src); // Can push value or effective address void pushptr(AddressLiteral src); + void pushptr(Address src) { LP64_ONLY(pushq(src)) NOT_LP64(pushl(src)); } + void popptr(Address src) { LP64_ONLY(popq(src)) NOT_LP64(popl(src)); } + + void pushoop(jobject obj); + + // sign extend as need a l to ptr sized element + void movl2ptr(Register dst, Address src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(movl(dst, src)); } + void movl2ptr(Register dst, Register src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(if (dst != src) movl(dst, src)); } + + #undef VIRTUAL }; diff --git a/hotspot/src/cpu/x86/vm/assembler_x86_64.inline.hpp b/hotspot/src/cpu/x86/vm/assembler_x86.inline.hpp similarity index 74% rename from hotspot/src/cpu/x86/vm/assembler_x86_64.inline.hpp rename to hotspot/src/cpu/x86/vm/assembler_x86.inline.hpp index 3a705ea3ea1..c4fe7df6dee 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86_64.inline.hpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,12 +22,6 @@ * */ -inline void Assembler::emit_long64(jlong x) { - *(jlong*) _code_pos = x; - _code_pos += sizeof(jlong); - code_section()->set_end(_code_pos); -} - inline void MacroAssembler::pd_patch_instruction(address branch, address target) { unsigned char op = branch[0]; assert(op == 0xE8 /* call */ || @@ -69,18 +63,25 @@ inline void MacroAssembler::pd_print_patched_instruction(address branch) { } #endif // ndef PRODUCT -inline void MacroAssembler::movptr(Address dst, intptr_t src) { -#ifdef _LP64 - Assembler::mov64(dst, src); -#else - Assembler::movl(dst, src); -#endif // _LP64 -} +#ifndef _LP64 +inline int Assembler::prefix_and_encode(int reg_enc, bool byteinst) { return reg_enc; } +inline int Assembler::prefixq_and_encode(int reg_enc) { return reg_enc; } -inline void MacroAssembler::movptr(Register dst, intptr_t src) { -#ifdef _LP64 - Assembler::mov64(dst, src); +inline int Assembler::prefix_and_encode(int dst_enc, int src_enc, bool byteinst) { return dst_enc << 3 | src_enc; } +inline int Assembler::prefixq_and_encode(int dst_enc, int src_enc) { return dst_enc << 3 | src_enc; } + +inline void Assembler::prefix(Register reg) {} +inline void Assembler::prefix(Address adr) {} +inline void Assembler::prefixq(Address adr) {} + +inline void Assembler::prefix(Address adr, Register reg, bool byteinst) {} +inline void Assembler::prefixq(Address adr, Register reg) {} + +inline void Assembler::prefix(Address adr, XMMRegister reg) {} #else - Assembler::movl(dst, src); -#endif // _LP64 +inline void Assembler::emit_long64(jlong x) { + *(jlong*) _code_pos = x; + _code_pos += sizeof(jlong); + code_section()->set_end(_code_pos); } +#endif // _LP64 diff --git a/hotspot/src/cpu/x86/vm/assembler_x86_32.cpp b/hotspot/src/cpu/x86/vm/assembler_x86_32.cpp deleted file mode 100644 index 91c2e9ab193..00000000000 --- a/hotspot/src/cpu/x86/vm/assembler_x86_32.cpp +++ /dev/null @@ -1,5001 +0,0 @@ -/* - * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -#include "incls/_precompiled.incl" -#include "incls/_assembler_x86_32.cpp.incl" - -// Implementation of AddressLiteral - -AddressLiteral::AddressLiteral(address target, relocInfo::relocType rtype) { - _is_lval = false; - _target = target; - switch (rtype) { - case relocInfo::oop_type: - // Oops are a special case. Normally they would be their own section - // but in cases like icBuffer they are literals in the code stream that - // we don't have a section for. We use none so that we get a literal address - // which is always patchable. - break; - case relocInfo::external_word_type: - _rspec = external_word_Relocation::spec(target); - break; - case relocInfo::internal_word_type: - _rspec = internal_word_Relocation::spec(target); - break; - case relocInfo::opt_virtual_call_type: - _rspec = opt_virtual_call_Relocation::spec(); - break; - case relocInfo::static_call_type: - _rspec = static_call_Relocation::spec(); - break; - case relocInfo::runtime_call_type: - _rspec = runtime_call_Relocation::spec(); - break; - case relocInfo::poll_type: - case relocInfo::poll_return_type: - _rspec = Relocation::spec_simple(rtype); - break; - case relocInfo::none: - break; - default: - ShouldNotReachHere(); - break; - } -} - -// Implementation of Address - -Address Address::make_array(ArrayAddress adr) { -#ifdef _LP64 - // Not implementable on 64bit machines - // Should have been handled higher up the call chain. - ShouldNotReachHere(); -#else - AddressLiteral base = adr.base(); - Address index = adr.index(); - assert(index._disp == 0, "must not have disp"); // maybe it can? - Address array(index._base, index._index, index._scale, (intptr_t) base.target()); - array._rspec = base._rspec; - return array; -#endif // _LP64 -} - -#ifndef _LP64 - -// exceedingly dangerous constructor -Address::Address(address loc, RelocationHolder spec) { - _base = noreg; - _index = noreg; - _scale = no_scale; - _disp = (intptr_t) loc; - _rspec = spec; -} -#endif // _LP64 - -// Convert the raw encoding form into the form expected by the constructor for -// Address. An index of 4 (rsp) corresponds to having no index, so convert -// that to noreg for the Address constructor. -Address Address::make_raw(int base, int index, int scale, int disp) { - bool valid_index = index != rsp->encoding(); - if (valid_index) { - Address madr(as_Register(base), as_Register(index), (Address::ScaleFactor)scale, in_ByteSize(disp)); - return madr; - } else { - Address madr(as_Register(base), noreg, Address::no_scale, in_ByteSize(disp)); - return madr; - } -} - -// Implementation of Assembler - -int AbstractAssembler::code_fill_byte() { - return (u_char)'\xF4'; // hlt -} - -// make this go away someday -void Assembler::emit_data(jint data, relocInfo::relocType rtype, int format) { - if (rtype == relocInfo::none) - emit_long(data); - else emit_data(data, Relocation::spec_simple(rtype), format); -} - - -void Assembler::emit_data(jint data, RelocationHolder const& rspec, int format) { - assert(imm32_operand == 0, "default format must be imm32 in this file"); - assert(inst_mark() != NULL, "must be inside InstructionMark"); - if (rspec.type() != relocInfo::none) { - #ifdef ASSERT - check_relocation(rspec, format); - #endif - // Do not use AbstractAssembler::relocate, which is not intended for - // embedded words. Instead, relocate to the enclosing instruction. - - // hack. call32 is too wide for mask so use disp32 - if (format == call32_operand) - code_section()->relocate(inst_mark(), rspec, disp32_operand); - else - code_section()->relocate(inst_mark(), rspec, format); - } - emit_long(data); -} - - -void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) { - assert(dst->has_byte_register(), "must have byte register"); - assert(isByte(op1) && isByte(op2), "wrong opcode"); - assert(isByte(imm8), "not a byte"); - assert((op1 & 0x01) == 0, "should be 8bit operation"); - emit_byte(op1); - emit_byte(op2 | dst->encoding()); - emit_byte(imm8); -} - - -void Assembler::emit_arith(int op1, int op2, Register dst, int imm32) { - assert(isByte(op1) && isByte(op2), "wrong opcode"); - assert((op1 & 0x01) == 1, "should be 32bit operation"); - assert((op1 & 0x02) == 0, "sign-extension bit should not be set"); - if (is8bit(imm32)) { - emit_byte(op1 | 0x02); // set sign bit - emit_byte(op2 | dst->encoding()); - emit_byte(imm32 & 0xFF); - } else { - emit_byte(op1); - emit_byte(op2 | dst->encoding()); - emit_long(imm32); - } -} - -// immediate-to-memory forms -void Assembler::emit_arith_operand(int op1, Register rm, Address adr, int imm32) { - assert((op1 & 0x01) == 1, "should be 32bit operation"); - assert((op1 & 0x02) == 0, "sign-extension bit should not be set"); - if (is8bit(imm32)) { - emit_byte(op1 | 0x02); // set sign bit - emit_operand(rm,adr); - emit_byte(imm32 & 0xFF); - } else { - emit_byte(op1); - emit_operand(rm,adr); - emit_long(imm32); - } -} - -void Assembler::emit_arith(int op1, int op2, Register dst, jobject obj) { - assert(isByte(op1) && isByte(op2), "wrong opcode"); - assert((op1 & 0x01) == 1, "should be 32bit operation"); - assert((op1 & 0x02) == 0, "sign-extension bit should not be set"); - InstructionMark im(this); - emit_byte(op1); - emit_byte(op2 | dst->encoding()); - emit_data((int)obj, relocInfo::oop_type, 0); -} - - -void Assembler::emit_arith(int op1, int op2, Register dst, Register src) { - assert(isByte(op1) && isByte(op2), "wrong opcode"); - emit_byte(op1); - emit_byte(op2 | dst->encoding() << 3 | src->encoding()); -} - - -void Assembler::emit_operand(Register reg, - Register base, - Register index, - Address::ScaleFactor scale, - int disp, - RelocationHolder const& rspec) { - - relocInfo::relocType rtype = (relocInfo::relocType) rspec.type(); - if (base->is_valid()) { - if (index->is_valid()) { - assert(scale != Address::no_scale, "inconsistent address"); - // [base + index*scale + disp] - if (disp == 0 && rtype == relocInfo::none && base != rbp) { - // [base + index*scale] - // [00 reg 100][ss index base] - assert(index != rsp, "illegal addressing mode"); - emit_byte(0x04 | reg->encoding() << 3); - emit_byte(scale << 6 | index->encoding() << 3 | base->encoding()); - } else if (is8bit(disp) && rtype == relocInfo::none) { - // [base + index*scale + imm8] - // [01 reg 100][ss index base] imm8 - assert(index != rsp, "illegal addressing mode"); - emit_byte(0x44 | reg->encoding() << 3); - emit_byte(scale << 6 | index->encoding() << 3 | base->encoding()); - emit_byte(disp & 0xFF); - } else { - // [base + index*scale + imm32] - // [10 reg 100][ss index base] imm32 - assert(index != rsp, "illegal addressing mode"); - emit_byte(0x84 | reg->encoding() << 3); - emit_byte(scale << 6 | index->encoding() << 3 | base->encoding()); - emit_data(disp, rspec, disp32_operand); - } - } else if (base == rsp) { - // [esp + disp] - if (disp == 0 && rtype == relocInfo::none) { - // [esp] - // [00 reg 100][00 100 100] - emit_byte(0x04 | reg->encoding() << 3); - emit_byte(0x24); - } else if (is8bit(disp) && rtype == relocInfo::none) { - // [esp + imm8] - // [01 reg 100][00 100 100] imm8 - emit_byte(0x44 | reg->encoding() << 3); - emit_byte(0x24); - emit_byte(disp & 0xFF); - } else { - // [esp + imm32] - // [10 reg 100][00 100 100] imm32 - emit_byte(0x84 | reg->encoding() << 3); - emit_byte(0x24); - emit_data(disp, rspec, disp32_operand); - } - } else { - // [base + disp] - assert(base != rsp, "illegal addressing mode"); - if (disp == 0 && rtype == relocInfo::none && base != rbp) { - // [base] - // [00 reg base] - assert(base != rbp, "illegal addressing mode"); - emit_byte(0x00 | reg->encoding() << 3 | base->encoding()); - } else if (is8bit(disp) && rtype == relocInfo::none) { - // [base + imm8] - // [01 reg base] imm8 - emit_byte(0x40 | reg->encoding() << 3 | base->encoding()); - emit_byte(disp & 0xFF); - } else { - // [base + imm32] - // [10 reg base] imm32 - emit_byte(0x80 | reg->encoding() << 3 | base->encoding()); - emit_data(disp, rspec, disp32_operand); - } - } - } else { - if (index->is_valid()) { - assert(scale != Address::no_scale, "inconsistent address"); - // [index*scale + disp] - // [00 reg 100][ss index 101] imm32 - assert(index != rsp, "illegal addressing mode"); - emit_byte(0x04 | reg->encoding() << 3); - emit_byte(scale << 6 | index->encoding() << 3 | 0x05); - emit_data(disp, rspec, disp32_operand); - } else { - // [disp] - // [00 reg 101] imm32 - emit_byte(0x05 | reg->encoding() << 3); - emit_data(disp, rspec, disp32_operand); - } - } -} - -// Secret local extension to Assembler::WhichOperand: -#define end_pc_operand (_WhichOperand_limit) - -address Assembler::locate_operand(address inst, WhichOperand which) { - // Decode the given instruction, and return the address of - // an embedded 32-bit operand word. - - // If "which" is disp32_operand, selects the displacement portion - // of an effective address specifier. - // If "which" is imm32_operand, selects the trailing immediate constant. - // If "which" is call32_operand, selects the displacement of a call or jump. - // Caller is responsible for ensuring that there is such an operand, - // and that it is 32 bits wide. - - // If "which" is end_pc_operand, find the end of the instruction. - - address ip = inst; - - debug_only(bool has_imm32 = false); - int tail_size = 0; // other random bytes (#32, #16, etc.) at end of insn - - again_after_prefix: - switch (0xFF & *ip++) { - - // These convenience macros generate groups of "case" labels for the switch. - #define REP4(x) (x)+0: case (x)+1: case (x)+2: case (x)+3 - #define REP8(x) (x)+0: case (x)+1: case (x)+2: case (x)+3: \ - case (x)+4: case (x)+5: case (x)+6: case (x)+7 - #define REP16(x) REP8((x)+0): \ - case REP8((x)+8) - - case CS_segment: - case SS_segment: - case DS_segment: - case ES_segment: - case FS_segment: - case GS_segment: - assert(ip == inst+1, "only one prefix allowed"); - goto again_after_prefix; - - case 0xFF: // pushl a; decl a; incl a; call a; jmp a - case 0x88: // movb a, r - case 0x89: // movl a, r - case 0x8A: // movb r, a - case 0x8B: // movl r, a - case 0x8F: // popl a - break; - - case 0x68: // pushl #32(oop?) - if (which == end_pc_operand) return ip + 4; - assert(which == imm32_operand, "pushl has no disp32"); - return ip; // not produced by emit_operand - - case 0x66: // movw ... (size prefix) - switch (0xFF & *ip++) { - case 0x8B: // movw r, a - case 0x89: // movw a, r - break; - case 0xC7: // movw a, #16 - tail_size = 2; // the imm16 - break; - case 0x0F: // several SSE/SSE2 variants - ip--; // reparse the 0x0F - goto again_after_prefix; - default: - ShouldNotReachHere(); - } - break; - - case REP8(0xB8): // movl r, #32(oop?) - if (which == end_pc_operand) return ip + 4; - assert(which == imm32_operand || which == disp32_operand, ""); - return ip; - - case 0x69: // imul r, a, #32 - case 0xC7: // movl a, #32(oop?) - tail_size = 4; - debug_only(has_imm32 = true); // has both kinds of operands! - break; - - case 0x0F: // movx..., etc. - switch (0xFF & *ip++) { - case 0x12: // movlps - case 0x28: // movaps - case 0x2E: // ucomiss - case 0x2F: // comiss - case 0x54: // andps - case 0x55: // andnps - case 0x56: // orps - case 0x57: // xorps - case 0x6E: // movd - case 0x7E: // movd - case 0xAE: // ldmxcsr a - // amd side says it these have both operands but that doesn't - // appear to be true. - // debug_only(has_imm32 = true); // has both kinds of operands! - break; - - case 0xAD: // shrd r, a, %cl - case 0xAF: // imul r, a - case 0xBE: // movsxb r, a - case 0xBF: // movsxw r, a - case 0xB6: // movzxb r, a - case 0xB7: // movzxw r, a - case REP16(0x40): // cmovl cc, r, a - case 0xB0: // cmpxchgb - case 0xB1: // cmpxchg - case 0xC1: // xaddl - case 0xC7: // cmpxchg8 - case REP16(0x90): // setcc a - // fall out of the switch to decode the address - break; - case 0xAC: // shrd r, a, #8 - tail_size = 1; // the imm8 - break; - case REP16(0x80): // jcc rdisp32 - if (which == end_pc_operand) return ip + 4; - assert(which == call32_operand, "jcc has no disp32 or imm32"); - return ip; - default: - ShouldNotReachHere(); - } - break; - - case 0x81: // addl a, #32; addl r, #32 - // also: orl, adcl, sbbl, andl, subl, xorl, cmpl - // in the case of cmpl, the imm32 might be an oop - tail_size = 4; - debug_only(has_imm32 = true); // has both kinds of operands! - break; - - case 0x85: // test r/m, r - break; - - case 0x83: // addl a, #8; addl r, #8 - // also: orl, adcl, sbbl, andl, subl, xorl, cmpl - tail_size = 1; - break; - - case 0x9B: - switch (0xFF & *ip++) { - case 0xD9: // fnstcw a - break; - default: - ShouldNotReachHere(); - } - break; - - case REP4(0x00): // addb a, r; addl a, r; addb r, a; addl r, a - case REP4(0x10): // adc... - case REP4(0x20): // and... - case REP4(0x30): // xor... - case REP4(0x08): // or... - case REP4(0x18): // sbb... - case REP4(0x28): // sub... - case REP4(0x38): // cmp... - case 0xF7: // mull a - case 0x8D: // leal r, a - case 0x87: // xchg r, a - break; - - case 0xC1: // sal a, #8; sar a, #8; shl a, #8; shr a, #8 - case 0xC6: // movb a, #8 - case 0x80: // cmpb a, #8 - case 0x6B: // imul r, a, #8 - tail_size = 1; // the imm8 - break; - - case 0xE8: // call rdisp32 - case 0xE9: // jmp rdisp32 - if (which == end_pc_operand) return ip + 4; - assert(which == call32_operand, "call has no disp32 or imm32"); - return ip; - - case 0xD1: // sal a, 1; sar a, 1; shl a, 1; shr a, 1 - case 0xD3: // sal a, %cl; sar a, %cl; shl a, %cl; shr a, %cl - case 0xD9: // fld_s a; fst_s a; fstp_s a; fldcw a - case 0xDD: // fld_d a; fst_d a; fstp_d a - case 0xDB: // fild_s a; fistp_s a; fld_x a; fstp_x a - case 0xDF: // fild_d a; fistp_d a - case 0xD8: // fadd_s a; fsubr_s a; fmul_s a; fdivr_s a; fcomp_s a - case 0xDC: // fadd_d a; fsubr_d a; fmul_d a; fdivr_d a; fcomp_d a - case 0xDE: // faddp_d a; fsubrp_d a; fmulp_d a; fdivrp_d a; fcompp_d a - break; - - case 0xF3: // For SSE - case 0xF2: // For SSE2 - ip++; ip++; - break; - - default: - ShouldNotReachHere(); - - #undef REP8 - #undef REP16 - } - - assert(which != call32_operand, "instruction is not a call, jmp, or jcc"); - assert(which != imm32_operand || has_imm32, "instruction has no imm32 field"); - - // parse the output of emit_operand - int op2 = 0xFF & *ip++; - int base = op2 & 0x07; - int op3 = -1; - const int b100 = 4; - const int b101 = 5; - if (base == b100 && (op2 >> 6) != 3) { - op3 = 0xFF & *ip++; - base = op3 & 0x07; // refetch the base - } - // now ip points at the disp (if any) - - switch (op2 >> 6) { - case 0: - // [00 reg 100][ss index base] - // [00 reg 100][00 100 rsp] - // [00 reg base] - // [00 reg 100][ss index 101][disp32] - // [00 reg 101] [disp32] - - if (base == b101) { - if (which == disp32_operand) - return ip; // caller wants the disp32 - ip += 4; // skip the disp32 - } - break; - - case 1: - // [01 reg 100][ss index base][disp8] - // [01 reg 100][00 100 rsp][disp8] - // [01 reg base] [disp8] - ip += 1; // skip the disp8 - break; - - case 2: - // [10 reg 100][ss index base][disp32] - // [10 reg 100][00 100 rsp][disp32] - // [10 reg base] [disp32] - if (which == disp32_operand) - return ip; // caller wants the disp32 - ip += 4; // skip the disp32 - break; - - case 3: - // [11 reg base] (not a memory addressing mode) - break; - } - - if (which == end_pc_operand) { - return ip + tail_size; - } - - assert(which == imm32_operand, "instruction has only an imm32 field"); - return ip; -} - -address Assembler::locate_next_instruction(address inst) { - // Secretly share code with locate_operand: - return locate_operand(inst, end_pc_operand); -} - - -#ifdef ASSERT -void Assembler::check_relocation(RelocationHolder const& rspec, int format) { - address inst = inst_mark(); - assert(inst != NULL && inst < pc(), "must point to beginning of instruction"); - address opnd; - - Relocation* r = rspec.reloc(); - if (r->type() == relocInfo::none) { - return; - } else if (r->is_call() || format == call32_operand) { - // assert(format == imm32_operand, "cannot specify a nonzero format"); - opnd = locate_operand(inst, call32_operand); - } else if (r->is_data()) { - assert(format == imm32_operand || format == disp32_operand, "format ok"); - opnd = locate_operand(inst, (WhichOperand)format); - } else { - assert(format == imm32_operand, "cannot specify a format"); - return; - } - assert(opnd == pc(), "must put operand where relocs can find it"); -} -#endif - - - -void Assembler::emit_operand(Register reg, Address adr) { - emit_operand(reg, adr._base, adr._index, adr._scale, adr._disp, adr._rspec); -} - - -void Assembler::emit_farith(int b1, int b2, int i) { - assert(isByte(b1) && isByte(b2), "wrong opcode"); - assert(0 <= i && i < 8, "illegal stack offset"); - emit_byte(b1); - emit_byte(b2 + i); -} - - -void Assembler::pushad() { - emit_byte(0x60); -} - -void Assembler::popad() { - emit_byte(0x61); -} - -void Assembler::pushfd() { - emit_byte(0x9C); -} - -void Assembler::popfd() { - emit_byte(0x9D); -} - -void Assembler::pushl(int imm32) { - emit_byte(0x68); - emit_long(imm32); -} - -#ifndef _LP64 -void Assembler::push_literal32(int32_t imm32, RelocationHolder const& rspec) { - InstructionMark im(this); - emit_byte(0x68); - emit_data(imm32, rspec, 0); -} -#endif // _LP64 - -void Assembler::pushl(Register src) { - emit_byte(0x50 | src->encoding()); -} - - -void Assembler::pushl(Address src) { - InstructionMark im(this); - emit_byte(0xFF); - emit_operand(rsi, src); -} - -void Assembler::popl(Register dst) { - emit_byte(0x58 | dst->encoding()); -} - - -void Assembler::popl(Address dst) { - InstructionMark im(this); - emit_byte(0x8F); - emit_operand(rax, dst); -} - - -void Assembler::prefix(Prefix p) { - a_byte(p); -} - - -void Assembler::movb(Register dst, Address src) { - assert(dst->has_byte_register(), "must have byte register"); - InstructionMark im(this); - emit_byte(0x8A); - emit_operand(dst, src); -} - - -void Assembler::movb(Address dst, int imm8) { - InstructionMark im(this); - emit_byte(0xC6); - emit_operand(rax, dst); - emit_byte(imm8); -} - - -void Assembler::movb(Address dst, Register src) { - assert(src->has_byte_register(), "must have byte register"); - InstructionMark im(this); - emit_byte(0x88); - emit_operand(src, dst); -} - - -void Assembler::movw(Address dst, int imm16) { - InstructionMark im(this); - - emit_byte(0x66); // switch to 16-bit mode - emit_byte(0xC7); - emit_operand(rax, dst); - emit_word(imm16); -} - - -void Assembler::movw(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x66); - emit_byte(0x8B); - emit_operand(dst, src); -} - - -void Assembler::movw(Address dst, Register src) { - InstructionMark im(this); - emit_byte(0x66); - emit_byte(0x89); - emit_operand(src, dst); -} - - -void Assembler::movl(Register dst, int imm32) { - emit_byte(0xB8 | dst->encoding()); - emit_long(imm32); -} - -#ifndef _LP64 -void Assembler::mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec) { - - InstructionMark im(this); - emit_byte(0xB8 | dst->encoding()); - emit_data((int)imm32, rspec, 0); -} -#endif // _LP64 - -void Assembler::movl(Register dst, Register src) { - emit_byte(0x8B); - emit_byte(0xC0 | (dst->encoding() << 3) | src->encoding()); -} - - -void Assembler::movl(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x8B); - emit_operand(dst, src); -} - - -void Assembler::movl(Address dst, int imm32) { - InstructionMark im(this); - emit_byte(0xC7); - emit_operand(rax, dst); - emit_long(imm32); -} - -#ifndef _LP64 -void Assembler::mov_literal32(Address dst, int32_t imm32, RelocationHolder const& rspec) { - InstructionMark im(this); - emit_byte(0xC7); - emit_operand(rax, dst); - emit_data((int)imm32, rspec, 0); -} -#endif // _LP64 - -void Assembler::movl(Address dst, Register src) { - InstructionMark im(this); - emit_byte(0x89); - emit_operand(src, dst); -} - -void Assembler::movsxb(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0xBE); - emit_operand(dst, src); -} - -void Assembler::movsxb(Register dst, Register src) { - assert(src->has_byte_register(), "must have byte register"); - emit_byte(0x0F); - emit_byte(0xBE); - emit_byte(0xC0 | (dst->encoding() << 3) | src->encoding()); -} - - -void Assembler::movsxw(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0xBF); - emit_operand(dst, src); -} - - -void Assembler::movsxw(Register dst, Register src) { - emit_byte(0x0F); - emit_byte(0xBF); - emit_byte(0xC0 | (dst->encoding() << 3) | src->encoding()); -} - - -void Assembler::movzxb(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0xB6); - emit_operand(dst, src); -} - - -void Assembler::movzxb(Register dst, Register src) { - assert(src->has_byte_register(), "must have byte register"); - emit_byte(0x0F); - emit_byte(0xB6); - emit_byte(0xC0 | (dst->encoding() << 3) | src->encoding()); -} - - -void Assembler::movzxw(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0xB7); - emit_operand(dst, src); -} - - -void Assembler::movzxw(Register dst, Register src) { - emit_byte(0x0F); - emit_byte(0xB7); - emit_byte(0xC0 | (dst->encoding() << 3) | src->encoding()); -} - - -void Assembler::cmovl(Condition cc, Register dst, Register src) { - guarantee(VM_Version::supports_cmov(), "illegal instruction"); - emit_byte(0x0F); - emit_byte(0x40 | cc); - emit_byte(0xC0 | (dst->encoding() << 3) | src->encoding()); -} - - -void Assembler::cmovl(Condition cc, Register dst, Address src) { - guarantee(VM_Version::supports_cmov(), "illegal instruction"); - // The code below seems to be wrong - however the manual is inconclusive - // do not use for now (remember to enable all callers when fixing this) - Unimplemented(); - // wrong bytes? - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0x40 | cc); - emit_operand(dst, src); -} - - -void Assembler::prefetcht0(Address src) { - assert(VM_Version::supports_sse(), "must support"); - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0x18); - emit_operand(rcx, src); // 1, src -} - - -void Assembler::prefetcht1(Address src) { - assert(VM_Version::supports_sse(), "must support"); - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0x18); - emit_operand(rdx, src); // 2, src -} - - -void Assembler::prefetcht2(Address src) { - assert(VM_Version::supports_sse(), "must support"); - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0x18); - emit_operand(rbx, src); // 3, src -} - - -void Assembler::prefetchnta(Address src) { - assert(VM_Version::supports_sse2(), "must support"); - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0x18); - emit_operand(rax, src); // 0, src -} - - -void Assembler::prefetchw(Address src) { - assert(VM_Version::supports_3dnow(), "must support"); - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0x0D); - emit_operand(rcx, src); // 1, src -} - - -void Assembler::prefetchr(Address src) { - assert(VM_Version::supports_3dnow(), "must support"); - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0x0D); - emit_operand(rax, src); // 0, src -} - - -void Assembler::adcl(Register dst, int imm32) { - emit_arith(0x81, 0xD0, dst, imm32); -} - - -void Assembler::adcl(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x13); - emit_operand(dst, src); -} - - -void Assembler::adcl(Register dst, Register src) { - emit_arith(0x13, 0xC0, dst, src); -} - - -void Assembler::addl(Address dst, int imm32) { - InstructionMark im(this); - emit_arith_operand(0x81,rax,dst,imm32); -} - - -void Assembler::addl(Address dst, Register src) { - InstructionMark im(this); - emit_byte(0x01); - emit_operand(src, dst); -} - - -void Assembler::addl(Register dst, int imm32) { - emit_arith(0x81, 0xC0, dst, imm32); -} - - -void Assembler::addl(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x03); - emit_operand(dst, src); -} - - -void Assembler::addl(Register dst, Register src) { - emit_arith(0x03, 0xC0, dst, src); -} - - -void Assembler::andl(Register dst, int imm32) { - emit_arith(0x81, 0xE0, dst, imm32); -} - - -void Assembler::andl(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x23); - emit_operand(dst, src); -} - - -void Assembler::andl(Register dst, Register src) { - emit_arith(0x23, 0xC0, dst, src); -} - - -void Assembler::cmpb(Address dst, int imm8) { - InstructionMark im(this); - emit_byte(0x80); - emit_operand(rdi, dst); - emit_byte(imm8); -} - -void Assembler::cmpw(Address dst, int imm16) { - InstructionMark im(this); - emit_byte(0x66); - emit_byte(0x81); - emit_operand(rdi, dst); - emit_word(imm16); -} - -void Assembler::cmpl(Address dst, int imm32) { - InstructionMark im(this); - emit_byte(0x81); - emit_operand(rdi, dst); - emit_long(imm32); -} - -#ifndef _LP64 -void Assembler::cmp_literal32(Register src1, int32_t imm32, RelocationHolder const& rspec) { - InstructionMark im(this); - emit_byte(0x81); - emit_byte(0xF8 | src1->encoding()); - emit_data(imm32, rspec, 0); -} - -void Assembler::cmp_literal32(Address src1, int32_t imm32, RelocationHolder const& rspec) { - InstructionMark im(this); - emit_byte(0x81); - emit_operand(rdi, src1); - emit_data(imm32, rspec, 0); -} -#endif // _LP64 - - -void Assembler::cmpl(Register dst, int imm32) { - emit_arith(0x81, 0xF8, dst, imm32); -} - - -void Assembler::cmpl(Register dst, Register src) { - emit_arith(0x3B, 0xC0, dst, src); -} - - -void Assembler::cmpl(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x3B); - emit_operand(dst, src); -} - - -void Assembler::decl(Register dst) { - // Don't use it directly. Use MacroAssembler::decrement() instead. - emit_byte(0x48 | dst->encoding()); -} - - -void Assembler::decl(Address dst) { - // Don't use it directly. Use MacroAssembler::decrement() instead. - InstructionMark im(this); - emit_byte(0xFF); - emit_operand(rcx, dst); -} - - -void Assembler::idivl(Register src) { - emit_byte(0xF7); - emit_byte(0xF8 | src->encoding()); -} - - -void Assembler::cdql() { - emit_byte(0x99); -} - - -void Assembler::imull(Register dst, Register src) { - emit_byte(0x0F); - emit_byte(0xAF); - emit_byte(0xC0 | dst->encoding() << 3 | src->encoding()); -} - - -void Assembler::imull(Register dst, Register src, int value) { - if (is8bit(value)) { - emit_byte(0x6B); - emit_byte(0xC0 | dst->encoding() << 3 | src->encoding()); - emit_byte(value); - } else { - emit_byte(0x69); - emit_byte(0xC0 | dst->encoding() << 3 | src->encoding()); - emit_long(value); - } -} - - -void Assembler::incl(Register dst) { - // Don't use it directly. Use MacroAssembler::increment() instead. - emit_byte(0x40 | dst->encoding()); -} - - -void Assembler::incl(Address dst) { - // Don't use it directly. Use MacroAssembler::increment() instead. - InstructionMark im(this); - emit_byte(0xFF); - emit_operand(rax, dst); -} - - -void Assembler::leal(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x8D); - emit_operand(dst, src); -} - -void Assembler::mull(Address src) { - InstructionMark im(this); - emit_byte(0xF7); - emit_operand(rsp, src); -} - - -void Assembler::mull(Register src) { - emit_byte(0xF7); - emit_byte(0xE0 | src->encoding()); -} - - -void Assembler::negl(Register dst) { - emit_byte(0xF7); - emit_byte(0xD8 | dst->encoding()); -} - - -void Assembler::notl(Register dst) { - emit_byte(0xF7); - emit_byte(0xD0 | dst->encoding()); -} - - -void Assembler::orl(Address dst, int imm32) { - InstructionMark im(this); - emit_byte(0x81); - emit_operand(rcx, dst); - emit_long(imm32); -} - -void Assembler::orl(Register dst, int imm32) { - emit_arith(0x81, 0xC8, dst, imm32); -} - - -void Assembler::orl(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x0B); - emit_operand(dst, src); -} - - -void Assembler::orl(Register dst, Register src) { - emit_arith(0x0B, 0xC0, dst, src); -} - - -void Assembler::rcll(Register dst, int imm8) { - assert(isShiftCount(imm8), "illegal shift count"); - if (imm8 == 1) { - emit_byte(0xD1); - emit_byte(0xD0 | dst->encoding()); - } else { - emit_byte(0xC1); - emit_byte(0xD0 | dst->encoding()); - emit_byte(imm8); - } -} - - -void Assembler::sarl(Register dst, int imm8) { - assert(isShiftCount(imm8), "illegal shift count"); - if (imm8 == 1) { - emit_byte(0xD1); - emit_byte(0xF8 | dst->encoding()); - } else { - emit_byte(0xC1); - emit_byte(0xF8 | dst->encoding()); - emit_byte(imm8); - } -} - - -void Assembler::sarl(Register dst) { - emit_byte(0xD3); - emit_byte(0xF8 | dst->encoding()); -} - - -void Assembler::sbbl(Address dst, int imm32) { - InstructionMark im(this); - emit_arith_operand(0x81,rbx,dst,imm32); -} - - -void Assembler::sbbl(Register dst, int imm32) { - emit_arith(0x81, 0xD8, dst, imm32); -} - - -void Assembler::sbbl(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x1B); - emit_operand(dst, src); -} - - -void Assembler::sbbl(Register dst, Register src) { - emit_arith(0x1B, 0xC0, dst, src); -} - - -void Assembler::shldl(Register dst, Register src) { - emit_byte(0x0F); - emit_byte(0xA5); - emit_byte(0xC0 | src->encoding() << 3 | dst->encoding()); -} - - -void Assembler::shll(Register dst, int imm8) { - assert(isShiftCount(imm8), "illegal shift count"); - if (imm8 == 1 ) { - emit_byte(0xD1); - emit_byte(0xE0 | dst->encoding()); - } else { - emit_byte(0xC1); - emit_byte(0xE0 | dst->encoding()); - emit_byte(imm8); - } -} - - -void Assembler::shll(Register dst) { - emit_byte(0xD3); - emit_byte(0xE0 | dst->encoding()); -} - - -void Assembler::shrdl(Register dst, Register src) { - emit_byte(0x0F); - emit_byte(0xAD); - emit_byte(0xC0 | src->encoding() << 3 | dst->encoding()); -} - - -void Assembler::shrl(Register dst, int imm8) { - assert(isShiftCount(imm8), "illegal shift count"); - emit_byte(0xC1); - emit_byte(0xE8 | dst->encoding()); - emit_byte(imm8); -} - - -void Assembler::shrl(Register dst) { - emit_byte(0xD3); - emit_byte(0xE8 | dst->encoding()); -} - - -void Assembler::subl(Address dst, int imm32) { - if (is8bit(imm32)) { - InstructionMark im(this); - emit_byte(0x83); - emit_operand(rbp, dst); - emit_byte(imm32 & 0xFF); - } else { - InstructionMark im(this); - emit_byte(0x81); - emit_operand(rbp, dst); - emit_long(imm32); - } -} - - -void Assembler::subl(Register dst, int imm32) { - emit_arith(0x81, 0xE8, dst, imm32); -} - - -void Assembler::subl(Address dst, Register src) { - InstructionMark im(this); - emit_byte(0x29); - emit_operand(src, dst); -} - - -void Assembler::subl(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x2B); - emit_operand(dst, src); -} - - -void Assembler::subl(Register dst, Register src) { - emit_arith(0x2B, 0xC0, dst, src); -} - - -void Assembler::testb(Register dst, int imm8) { - assert(dst->has_byte_register(), "must have byte register"); - emit_arith_b(0xF6, 0xC0, dst, imm8); -} - - -void Assembler::testl(Register dst, int imm32) { - // not using emit_arith because test - // doesn't support sign-extension of - // 8bit operands - if (dst->encoding() == 0) { - emit_byte(0xA9); - } else { - emit_byte(0xF7); - emit_byte(0xC0 | dst->encoding()); - } - emit_long(imm32); -} - - -void Assembler::testl(Register dst, Register src) { - emit_arith(0x85, 0xC0, dst, src); -} - -void Assembler::testl(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x85); - emit_operand(dst, src); -} - -void Assembler::xaddl(Address dst, Register src) { - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0xC1); - emit_operand(src, dst); -} - -void Assembler::xorl(Register dst, int imm32) { - emit_arith(0x81, 0xF0, dst, imm32); -} - - -void Assembler::xorl(Register dst, Address src) { - InstructionMark im(this); - emit_byte(0x33); - emit_operand(dst, src); -} - - -void Assembler::xorl(Register dst, Register src) { - emit_arith(0x33, 0xC0, dst, src); -} - - -void Assembler::bswap(Register reg) { - emit_byte(0x0F); - emit_byte(0xC8 | reg->encoding()); -} - - -void Assembler::lock() { - if (Atomics & 1) { - // Emit either nothing, a NOP, or a NOP: prefix - emit_byte(0x90) ; - } else { - emit_byte(0xF0); - } -} - - -void Assembler::xchg(Register reg, Address adr) { - InstructionMark im(this); - emit_byte(0x87); - emit_operand(reg, adr); -} - - -void Assembler::xchgl(Register dst, Register src) { - emit_byte(0x87); - emit_byte(0xc0 | dst->encoding() << 3 | src->encoding()); -} - - -// The 32-bit cmpxchg compares the value at adr with the contents of rax, -// and stores reg into adr if so; otherwise, the value at adr is loaded into rax,. -// The ZF is set if the compared values were equal, and cleared otherwise. -void Assembler::cmpxchg(Register reg, Address adr) { - if (Atomics & 2) { - // caveat: no instructionmark, so this isn't relocatable. - // Emit a synthetic, non-atomic, CAS equivalent. - // Beware. The synthetic form sets all ICCs, not just ZF. - // cmpxchg r,[m] is equivalent to rax, = CAS (m, rax, r) - cmpl (rax, adr) ; - movl (rax, adr) ; - if (reg != rax) { - Label L ; - jcc (Assembler::notEqual, L) ; - movl (adr, reg) ; - bind (L) ; - } - } else { - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0xB1); - emit_operand(reg, adr); - } -} - -// The 64-bit cmpxchg compares the value at adr with the contents of rdx:rax, -// and stores rcx:rbx into adr if so; otherwise, the value at adr is loaded -// into rdx:rax. The ZF is set if the compared values were equal, and cleared otherwise. -void Assembler::cmpxchg8(Address adr) { - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0xc7); - emit_operand(rcx, adr); -} - -void Assembler::hlt() { - emit_byte(0xF4); -} - - -void Assembler::addr_nop_4() { - // 4 bytes: NOP DWORD PTR [EAX+0] - emit_byte(0x0F); - emit_byte(0x1F); - emit_byte(0x40); // emit_rm(cbuf, 0x1, EAX_enc, EAX_enc); - emit_byte(0); // 8-bits offset (1 byte) -} - -void Assembler::addr_nop_5() { - // 5 bytes: NOP DWORD PTR [EAX+EAX*0+0] 8-bits offset - emit_byte(0x0F); - emit_byte(0x1F); - emit_byte(0x44); // emit_rm(cbuf, 0x1, EAX_enc, 0x4); - emit_byte(0x00); // emit_rm(cbuf, 0x0, EAX_enc, EAX_enc); - emit_byte(0); // 8-bits offset (1 byte) -} - -void Assembler::addr_nop_7() { - // 7 bytes: NOP DWORD PTR [EAX+0] 32-bits offset - emit_byte(0x0F); - emit_byte(0x1F); - emit_byte(0x80); // emit_rm(cbuf, 0x2, EAX_enc, EAX_enc); - emit_long(0); // 32-bits offset (4 bytes) -} - -void Assembler::addr_nop_8() { - // 8 bytes: NOP DWORD PTR [EAX+EAX*0+0] 32-bits offset - emit_byte(0x0F); - emit_byte(0x1F); - emit_byte(0x84); // emit_rm(cbuf, 0x2, EAX_enc, 0x4); - emit_byte(0x00); // emit_rm(cbuf, 0x0, EAX_enc, EAX_enc); - emit_long(0); // 32-bits offset (4 bytes) -} - -void Assembler::nop(int i) { - assert(i > 0, " "); - if (UseAddressNop && VM_Version::is_intel()) { - // - // Using multi-bytes nops "0x0F 0x1F [address]" for Intel - // 1: 0x90 - // 2: 0x66 0x90 - // 3: 0x66 0x66 0x90 (don't use "0x0F 0x1F 0x00" - need patching safe padding) - // 4: 0x0F 0x1F 0x40 0x00 - // 5: 0x0F 0x1F 0x44 0x00 0x00 - // 6: 0x66 0x0F 0x1F 0x44 0x00 0x00 - // 7: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 - // 8: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - // 9: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - // 10: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - // 11: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - - // The rest coding is Intel specific - don't use consecutive address nops - - // 12: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90 - // 13: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90 - // 14: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90 - // 15: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90 - - while(i >= 15) { - // For Intel don't generate consecutive addess nops (mix with regular nops) - i -= 15; - emit_byte(0x66); // size prefix - emit_byte(0x66); // size prefix - emit_byte(0x66); // size prefix - addr_nop_8(); - emit_byte(0x66); // size prefix - emit_byte(0x66); // size prefix - emit_byte(0x66); // size prefix - emit_byte(0x90); // nop - } - switch (i) { - case 14: - emit_byte(0x66); // size prefix - case 13: - emit_byte(0x66); // size prefix - case 12: - addr_nop_8(); - emit_byte(0x66); // size prefix - emit_byte(0x66); // size prefix - emit_byte(0x66); // size prefix - emit_byte(0x90); // nop - break; - case 11: - emit_byte(0x66); // size prefix - case 10: - emit_byte(0x66); // size prefix - case 9: - emit_byte(0x66); // size prefix - case 8: - addr_nop_8(); - break; - case 7: - addr_nop_7(); - break; - case 6: - emit_byte(0x66); // size prefix - case 5: - addr_nop_5(); - break; - case 4: - addr_nop_4(); - break; - case 3: - // Don't use "0x0F 0x1F 0x00" - need patching safe padding - emit_byte(0x66); // size prefix - case 2: - emit_byte(0x66); // size prefix - case 1: - emit_byte(0x90); // nop - break; - default: - assert(i == 0, " "); - } - return; - } - if (UseAddressNop && VM_Version::is_amd()) { - // - // Using multi-bytes nops "0x0F 0x1F [address]" for AMD. - // 1: 0x90 - // 2: 0x66 0x90 - // 3: 0x66 0x66 0x90 (don't use "0x0F 0x1F 0x00" - need patching safe padding) - // 4: 0x0F 0x1F 0x40 0x00 - // 5: 0x0F 0x1F 0x44 0x00 0x00 - // 6: 0x66 0x0F 0x1F 0x44 0x00 0x00 - // 7: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 - // 8: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - // 9: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - // 10: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - // 11: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - - // The rest coding is AMD specific - use consecutive address nops - - // 12: 0x66 0x0F 0x1F 0x44 0x00 0x00 0x66 0x0F 0x1F 0x44 0x00 0x00 - // 13: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 0x66 0x0F 0x1F 0x44 0x00 0x00 - // 14: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 - // 15: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 - // 16: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - // Size prefixes (0x66) are added for larger sizes - - while(i >= 22) { - i -= 11; - emit_byte(0x66); // size prefix - emit_byte(0x66); // size prefix - emit_byte(0x66); // size prefix - addr_nop_8(); - } - // Generate first nop for size between 21-12 - switch (i) { - case 21: - i -= 1; - emit_byte(0x66); // size prefix - case 20: - case 19: - i -= 1; - emit_byte(0x66); // size prefix - case 18: - case 17: - i -= 1; - emit_byte(0x66); // size prefix - case 16: - case 15: - i -= 8; - addr_nop_8(); - break; - case 14: - case 13: - i -= 7; - addr_nop_7(); - break; - case 12: - i -= 6; - emit_byte(0x66); // size prefix - addr_nop_5(); - break; - default: - assert(i < 12, " "); - } - - // Generate second nop for size between 11-1 - switch (i) { - case 11: - emit_byte(0x66); // size prefix - case 10: - emit_byte(0x66); // size prefix - case 9: - emit_byte(0x66); // size prefix - case 8: - addr_nop_8(); - break; - case 7: - addr_nop_7(); - break; - case 6: - emit_byte(0x66); // size prefix - case 5: - addr_nop_5(); - break; - case 4: - addr_nop_4(); - break; - case 3: - // Don't use "0x0F 0x1F 0x00" - need patching safe padding - emit_byte(0x66); // size prefix - case 2: - emit_byte(0x66); // size prefix - case 1: - emit_byte(0x90); // nop - break; - default: - assert(i == 0, " "); - } - return; - } - - // Using nops with size prefixes "0x66 0x90". - // From AMD Optimization Guide: - // 1: 0x90 - // 2: 0x66 0x90 - // 3: 0x66 0x66 0x90 - // 4: 0x66 0x66 0x66 0x90 - // 5: 0x66 0x66 0x90 0x66 0x90 - // 6: 0x66 0x66 0x90 0x66 0x66 0x90 - // 7: 0x66 0x66 0x66 0x90 0x66 0x66 0x90 - // 8: 0x66 0x66 0x66 0x90 0x66 0x66 0x66 0x90 - // 9: 0x66 0x66 0x90 0x66 0x66 0x90 0x66 0x66 0x90 - // 10: 0x66 0x66 0x66 0x90 0x66 0x66 0x90 0x66 0x66 0x90 - // - while(i > 12) { - i -= 4; - emit_byte(0x66); // size prefix - emit_byte(0x66); - emit_byte(0x66); - emit_byte(0x90); // nop - } - // 1 - 12 nops - if(i > 8) { - if(i > 9) { - i -= 1; - emit_byte(0x66); - } - i -= 3; - emit_byte(0x66); - emit_byte(0x66); - emit_byte(0x90); - } - // 1 - 8 nops - if(i > 4) { - if(i > 6) { - i -= 1; - emit_byte(0x66); - } - i -= 3; - emit_byte(0x66); - emit_byte(0x66); - emit_byte(0x90); - } - switch (i) { - case 4: - emit_byte(0x66); - case 3: - emit_byte(0x66); - case 2: - emit_byte(0x66); - case 1: - emit_byte(0x90); - break; - default: - assert(i == 0, " "); - } -} - -void Assembler::ret(int imm16) { - if (imm16 == 0) { - emit_byte(0xC3); - } else { - emit_byte(0xC2); - emit_word(imm16); - } -} - - -void Assembler::set_byte_if_not_zero(Register dst) { - emit_byte(0x0F); - emit_byte(0x95); - emit_byte(0xE0 | dst->encoding()); -} - - -// copies a single word from [esi] to [edi] -void Assembler::smovl() { - emit_byte(0xA5); -} - -// copies data from [esi] to [edi] using rcx double words (m32) -void Assembler::rep_movl() { - emit_byte(0xF3); - emit_byte(0xA5); -} - - -// sets rcx double words (m32) with rax, value at [edi] -void Assembler::rep_set() { - emit_byte(0xF3); - emit_byte(0xAB); -} - -// scans rcx double words (m32) at [edi] for occurance of rax, -void Assembler::repne_scan() { - emit_byte(0xF2); - emit_byte(0xAF); -} - - -void Assembler::setb(Condition cc, Register dst) { - assert(0 <= cc && cc < 16, "illegal cc"); - emit_byte(0x0F); - emit_byte(0x90 | cc); - emit_byte(0xC0 | dst->encoding()); -} - -void Assembler::cld() { - emit_byte(0xfc); -} - -void Assembler::std() { - emit_byte(0xfd); -} - -void Assembler::emit_raw (unsigned char b) { - emit_byte (b) ; -} - -// Serializes memory. -void Assembler::membar() { - // Memory barriers are only needed on multiprocessors - if (os::is_MP()) { - if( VM_Version::supports_sse2() ) { - emit_byte( 0x0F ); // MFENCE; faster blows no regs - emit_byte( 0xAE ); - emit_byte( 0xF0 ); - } else { - // All usable chips support "locked" instructions which suffice - // as barriers, and are much faster than the alternative of - // using cpuid instruction. We use here a locked add [esp],0. - // This is conveniently otherwise a no-op except for blowing - // flags (which we save and restore.) - pushfd(); // Save eflags register - lock(); - addl(Address(rsp, 0), 0);// Assert the lock# signal here - popfd(); // Restore eflags register - } - } -} - -// Identify processor type and features -void Assembler::cpuid() { - // Note: we can't assert VM_Version::supports_cpuid() here - // because this instruction is used in the processor - // identification code. - emit_byte( 0x0F ); - emit_byte( 0xA2 ); -} - -void Assembler::call(Label& L, relocInfo::relocType rtype) { - if (L.is_bound()) { - const int long_size = 5; - int offs = target(L) - pc(); - assert(offs <= 0, "assembler error"); - InstructionMark im(this); - // 1110 1000 #32-bit disp - emit_byte(0xE8); - emit_data(offs - long_size, rtype, 0); - } else { - InstructionMark im(this); - // 1110 1000 #32-bit disp - L.add_patch_at(code(), locator()); - emit_byte(0xE8); - emit_data(int(0), rtype, 0); - } -} - -void Assembler::call(Register dst) { - emit_byte(0xFF); - emit_byte(0xD0 | dst->encoding()); -} - - -void Assembler::call(Address adr) { - InstructionMark im(this); - relocInfo::relocType rtype = adr.reloc(); - if (rtype != relocInfo::runtime_call_type) { - emit_byte(0xFF); - emit_operand(rdx, adr); - } else { - assert(false, "ack"); - } - -} - -void Assembler::call_literal(address dest, RelocationHolder const& rspec) { - InstructionMark im(this); - emit_byte(0xE8); - intptr_t disp = dest - (_code_pos + sizeof(int32_t)); - assert(dest != NULL, "must have a target"); - emit_data(disp, rspec, call32_operand); - -} - -void Assembler::jmp(Register entry) { - emit_byte(0xFF); - emit_byte(0xE0 | entry->encoding()); -} - - -void Assembler::jmp(Address adr) { - InstructionMark im(this); - emit_byte(0xFF); - emit_operand(rsp, adr); -} - -void Assembler::jmp_literal(address dest, RelocationHolder const& rspec) { - InstructionMark im(this); - emit_byte(0xE9); - assert(dest != NULL, "must have a target"); - intptr_t disp = dest - (_code_pos + sizeof(int32_t)); - emit_data(disp, rspec.reloc(), call32_operand); -} - -void Assembler::jmp(Label& L, relocInfo::relocType rtype) { - if (L.is_bound()) { - address entry = target(L); - assert(entry != NULL, "jmp most probably wrong"); - InstructionMark im(this); - const int short_size = 2; - const int long_size = 5; - intptr_t offs = entry - _code_pos; - if (rtype == relocInfo::none && is8bit(offs - short_size)) { - emit_byte(0xEB); - emit_byte((offs - short_size) & 0xFF); - } else { - emit_byte(0xE9); - emit_long(offs - long_size); - } - } else { - // By default, forward jumps are always 32-bit displacements, since - // we can't yet know where the label will be bound. If you're sure that - // the forward jump will not run beyond 256 bytes, use jmpb to - // force an 8-bit displacement. - InstructionMark im(this); - relocate(rtype); - L.add_patch_at(code(), locator()); - emit_byte(0xE9); - emit_long(0); - } -} - -void Assembler::jmpb(Label& L) { - if (L.is_bound()) { - const int short_size = 2; - address entry = target(L); - assert(is8bit((entry - _code_pos) + short_size), - "Dispacement too large for a short jmp"); - assert(entry != NULL, "jmp most probably wrong"); - intptr_t offs = entry - _code_pos; - emit_byte(0xEB); - emit_byte((offs - short_size) & 0xFF); - } else { - InstructionMark im(this); - L.add_patch_at(code(), locator()); - emit_byte(0xEB); - emit_byte(0); - } -} - -void Assembler::jcc(Condition cc, Label& L, relocInfo::relocType rtype) { - InstructionMark im(this); - relocate(rtype); - assert((0 <= cc) && (cc < 16), "illegal cc"); - if (L.is_bound()) { - address dst = target(L); - assert(dst != NULL, "jcc most probably wrong"); - - const int short_size = 2; - const int long_size = 6; - int offs = (int)dst - ((int)_code_pos); - if (rtype == relocInfo::none && is8bit(offs - short_size)) { - // 0111 tttn #8-bit disp - emit_byte(0x70 | cc); - emit_byte((offs - short_size) & 0xFF); - } else { - // 0000 1111 1000 tttn #32-bit disp - emit_byte(0x0F); - emit_byte(0x80 | cc); - emit_long(offs - long_size); - } - } else { - // Note: could eliminate cond. jumps to this jump if condition - // is the same however, seems to be rather unlikely case. - // Note: use jccb() if label to be bound is very close to get - // an 8-bit displacement - L.add_patch_at(code(), locator()); - emit_byte(0x0F); - emit_byte(0x80 | cc); - emit_long(0); - } -} - -void Assembler::jccb(Condition cc, Label& L) { - if (L.is_bound()) { - const int short_size = 2; - address entry = target(L); - assert(is8bit((intptr_t)entry - ((intptr_t)_code_pos + short_size)), - "Dispacement too large for a short jmp"); - intptr_t offs = (intptr_t)entry - (intptr_t)_code_pos; - // 0111 tttn #8-bit disp - emit_byte(0x70 | cc); - emit_byte((offs - short_size) & 0xFF); - jcc(cc, L); - } else { - InstructionMark im(this); - L.add_patch_at(code(), locator()); - emit_byte(0x70 | cc); - emit_byte(0); - } -} - -// FPU instructions - -void Assembler::fld1() { - emit_byte(0xD9); - emit_byte(0xE8); -} - - -void Assembler::fldz() { - emit_byte(0xD9); - emit_byte(0xEE); -} - - -void Assembler::fld_s(Address adr) { - InstructionMark im(this); - emit_byte(0xD9); - emit_operand(rax, adr); -} - - -void Assembler::fld_s (int index) { - emit_farith(0xD9, 0xC0, index); -} - - -void Assembler::fld_d(Address adr) { - InstructionMark im(this); - emit_byte(0xDD); - emit_operand(rax, adr); -} - - -void Assembler::fld_x(Address adr) { - InstructionMark im(this); - emit_byte(0xDB); - emit_operand(rbp, adr); -} - - -void Assembler::fst_s(Address adr) { - InstructionMark im(this); - emit_byte(0xD9); - emit_operand(rdx, adr); -} - - -void Assembler::fst_d(Address adr) { - InstructionMark im(this); - emit_byte(0xDD); - emit_operand(rdx, adr); -} - - -void Assembler::fstp_s(Address adr) { - InstructionMark im(this); - emit_byte(0xD9); - emit_operand(rbx, adr); -} - - -void Assembler::fstp_d(Address adr) { - InstructionMark im(this); - emit_byte(0xDD); - emit_operand(rbx, adr); -} - - -void Assembler::fstp_x(Address adr) { - InstructionMark im(this); - emit_byte(0xDB); - emit_operand(rdi, adr); -} - - -void Assembler::fstp_d(int index) { - emit_farith(0xDD, 0xD8, index); -} - - -void Assembler::fild_s(Address adr) { - InstructionMark im(this); - emit_byte(0xDB); - emit_operand(rax, adr); -} - - -void Assembler::fild_d(Address adr) { - InstructionMark im(this); - emit_byte(0xDF); - emit_operand(rbp, adr); -} - - -void Assembler::fistp_s(Address adr) { - InstructionMark im(this); - emit_byte(0xDB); - emit_operand(rbx, adr); -} - - -void Assembler::fistp_d(Address adr) { - InstructionMark im(this); - emit_byte(0xDF); - emit_operand(rdi, adr); -} - - -void Assembler::fist_s(Address adr) { - InstructionMark im(this); - emit_byte(0xDB); - emit_operand(rdx, adr); -} - - -void Assembler::fabs() { - emit_byte(0xD9); - emit_byte(0xE1); -} - - -void Assembler::fldln2() { - emit_byte(0xD9); - emit_byte(0xED); -} - -void Assembler::fyl2x() { - emit_byte(0xD9); - emit_byte(0xF1); -} - - -void Assembler::fldlg2() { - emit_byte(0xD9); - emit_byte(0xEC); -} - - -void Assembler::flog() { - fldln2(); - fxch(); - fyl2x(); -} - - -void Assembler::flog10() { - fldlg2(); - fxch(); - fyl2x(); -} - - -void Assembler::fsin() { - emit_byte(0xD9); - emit_byte(0xFE); -} - - -void Assembler::fcos() { - emit_byte(0xD9); - emit_byte(0xFF); -} - -void Assembler::ftan() { - emit_byte(0xD9); - emit_byte(0xF2); - emit_byte(0xDD); - emit_byte(0xD8); -} - -void Assembler::fsqrt() { - emit_byte(0xD9); - emit_byte(0xFA); -} - - -void Assembler::fchs() { - emit_byte(0xD9); - emit_byte(0xE0); -} - - -void Assembler::fadd_s(Address src) { - InstructionMark im(this); - emit_byte(0xD8); - emit_operand(rax, src); -} - - -void Assembler::fadd_d(Address src) { - InstructionMark im(this); - emit_byte(0xDC); - emit_operand(rax, src); -} - - -void Assembler::fadd(int i) { - emit_farith(0xD8, 0xC0, i); -} - - -void Assembler::fadda(int i) { - emit_farith(0xDC, 0xC0, i); -} - - -void Assembler::fsub_d(Address src) { - InstructionMark im(this); - emit_byte(0xDC); - emit_operand(rsp, src); -} - - -void Assembler::fsub_s(Address src) { - InstructionMark im(this); - emit_byte(0xD8); - emit_operand(rsp, src); -} - - -void Assembler::fsubr_s(Address src) { - InstructionMark im(this); - emit_byte(0xD8); - emit_operand(rbp, src); -} - - -void Assembler::fsubr_d(Address src) { - InstructionMark im(this); - emit_byte(0xDC); - emit_operand(rbp, src); -} - - -void Assembler::fmul_s(Address src) { - InstructionMark im(this); - emit_byte(0xD8); - emit_operand(rcx, src); -} - - -void Assembler::fmul_d(Address src) { - InstructionMark im(this); - emit_byte(0xDC); - emit_operand(rcx, src); -} - - -void Assembler::fmul(int i) { - emit_farith(0xD8, 0xC8, i); -} - - -void Assembler::fmula(int i) { - emit_farith(0xDC, 0xC8, i); -} - - -void Assembler::fdiv_s(Address src) { - InstructionMark im(this); - emit_byte(0xD8); - emit_operand(rsi, src); -} - - -void Assembler::fdiv_d(Address src) { - InstructionMark im(this); - emit_byte(0xDC); - emit_operand(rsi, src); -} - - -void Assembler::fdivr_s(Address src) { - InstructionMark im(this); - emit_byte(0xD8); - emit_operand(rdi, src); -} - - -void Assembler::fdivr_d(Address src) { - InstructionMark im(this); - emit_byte(0xDC); - emit_operand(rdi, src); -} - - -void Assembler::fsub(int i) { - emit_farith(0xD8, 0xE0, i); -} - - -void Assembler::fsuba(int i) { - emit_farith(0xDC, 0xE8, i); -} - - -void Assembler::fsubr(int i) { - emit_farith(0xD8, 0xE8, i); -} - - -void Assembler::fsubra(int i) { - emit_farith(0xDC, 0xE0, i); -} - - -void Assembler::fdiv(int i) { - emit_farith(0xD8, 0xF0, i); -} - - -void Assembler::fdiva(int i) { - emit_farith(0xDC, 0xF8, i); -} - - -void Assembler::fdivr(int i) { - emit_farith(0xD8, 0xF8, i); -} - - -void Assembler::fdivra(int i) { - emit_farith(0xDC, 0xF0, i); -} - - -// Note: The Intel manual (Pentium Processor User's Manual, Vol.3, 1994) -// is erroneous for some of the floating-point instructions below. - -void Assembler::fdivp(int i) { - emit_farith(0xDE, 0xF8, i); // ST(0) <- ST(0) / ST(1) and pop (Intel manual wrong) -} - - -void Assembler::fdivrp(int i) { - emit_farith(0xDE, 0xF0, i); // ST(0) <- ST(1) / ST(0) and pop (Intel manual wrong) -} - - -void Assembler::fsubp(int i) { - emit_farith(0xDE, 0xE8, i); // ST(0) <- ST(0) - ST(1) and pop (Intel manual wrong) -} - - -void Assembler::fsubrp(int i) { - emit_farith(0xDE, 0xE0, i); // ST(0) <- ST(1) - ST(0) and pop (Intel manual wrong) -} - - -void Assembler::faddp(int i) { - emit_farith(0xDE, 0xC0, i); -} - - -void Assembler::fmulp(int i) { - emit_farith(0xDE, 0xC8, i); -} - - -void Assembler::fprem() { - emit_byte(0xD9); - emit_byte(0xF8); -} - - -void Assembler::fprem1() { - emit_byte(0xD9); - emit_byte(0xF5); -} - - -void Assembler::fxch(int i) { - emit_farith(0xD9, 0xC8, i); -} - - -void Assembler::fincstp() { - emit_byte(0xD9); - emit_byte(0xF7); -} - - -void Assembler::fdecstp() { - emit_byte(0xD9); - emit_byte(0xF6); -} - - -void Assembler::ffree(int i) { - emit_farith(0xDD, 0xC0, i); -} - - -void Assembler::fcomp_s(Address src) { - InstructionMark im(this); - emit_byte(0xD8); - emit_operand(rbx, src); -} - - -void Assembler::fcomp_d(Address src) { - InstructionMark im(this); - emit_byte(0xDC); - emit_operand(rbx, src); -} - - -void Assembler::fcom(int i) { - emit_farith(0xD8, 0xD0, i); -} - - -void Assembler::fcomp(int i) { - emit_farith(0xD8, 0xD8, i); -} - - -void Assembler::fcompp() { - emit_byte(0xDE); - emit_byte(0xD9); -} - - -void Assembler::fucomi(int i) { - // make sure the instruction is supported (introduced for P6, together with cmov) - guarantee(VM_Version::supports_cmov(), "illegal instruction"); - emit_farith(0xDB, 0xE8, i); -} - - -void Assembler::fucomip(int i) { - // make sure the instruction is supported (introduced for P6, together with cmov) - guarantee(VM_Version::supports_cmov(), "illegal instruction"); - emit_farith(0xDF, 0xE8, i); -} - - -void Assembler::ftst() { - emit_byte(0xD9); - emit_byte(0xE4); -} - - -void Assembler::fnstsw_ax() { - emit_byte(0xdF); - emit_byte(0xE0); -} - - -void Assembler::fwait() { - emit_byte(0x9B); -} - - -void Assembler::finit() { - emit_byte(0x9B); - emit_byte(0xDB); - emit_byte(0xE3); -} - - -void Assembler::fldcw(Address src) { - InstructionMark im(this); - emit_byte(0xd9); - emit_operand(rbp, src); -} - - -void Assembler::fnstcw(Address src) { - InstructionMark im(this); - emit_byte(0x9B); - emit_byte(0xD9); - emit_operand(rdi, src); -} - -void Assembler::fnsave(Address dst) { - InstructionMark im(this); - emit_byte(0xDD); - emit_operand(rsi, dst); -} - - -void Assembler::frstor(Address src) { - InstructionMark im(this); - emit_byte(0xDD); - emit_operand(rsp, src); -} - - -void Assembler::fldenv(Address src) { - InstructionMark im(this); - emit_byte(0xD9); - emit_operand(rsp, src); -} - - -void Assembler::sahf() { - emit_byte(0x9E); -} - -// MMX operations -void Assembler::emit_operand(MMXRegister reg, Address adr) { - emit_operand((Register)reg, adr._base, adr._index, adr._scale, adr._disp, adr._rspec); -} - -void Assembler::movq( MMXRegister dst, Address src ) { - assert( VM_Version::supports_mmx(), "" ); - emit_byte(0x0F); - emit_byte(0x6F); - emit_operand(dst,src); -} - -void Assembler::movq( Address dst, MMXRegister src ) { - assert( VM_Version::supports_mmx(), "" ); - emit_byte(0x0F); - emit_byte(0x7F); - emit_operand(src,dst); -} - -void Assembler::emms() { - emit_byte(0x0F); - emit_byte(0x77); -} - - - - -// SSE and SSE2 instructions -inline void Assembler::emit_sse_operand(XMMRegister reg, Address adr) { - assert(((Register)reg)->encoding() == reg->encoding(), "otherwise typecast is invalid"); - emit_operand((Register)reg, adr._base, adr._index, adr._scale, adr._disp, adr._rspec); -} -inline void Assembler::emit_sse_operand(Register reg, Address adr) { - emit_operand(reg, adr._base, adr._index, adr._scale, adr._disp, adr._rspec); -} - -inline void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) { - emit_byte(0xC0 | dst->encoding() << 3 | src->encoding()); -} -inline void Assembler::emit_sse_operand(XMMRegister dst, Register src) { - emit_byte(0xC0 | dst->encoding() << 3 | src->encoding()); -} -inline void Assembler::emit_sse_operand(Register dst, XMMRegister src) { - emit_byte(0xC0 | dst->encoding() << 3 | src->encoding()); -} - - -// Macro for creation of SSE2 instructions -// The SSE2 instricution set is highly regular, so this macro saves -// a lot of cut&paste -// Each macro expansion creates two methods (same name with different -// parameter list) -// -// Macro parameters: -// * name: name of the created methods -// * sse_version: either sse or sse2 for the assertion if instruction supported by processor -// * prefix: first opcode byte of the instruction (or 0 if no prefix byte) -// * opcode: last opcode byte of the instruction -// * conversion instruction have parameters of type Register instead of XMMRegister, -// so this can also configured with macro parameters -#define emit_sse_instruction(name, sse_version, prefix, opcode, dst_register_type, src_register_type) \ - \ - void Assembler:: name (dst_register_type dst, Address src) { \ - assert(VM_Version::supports_##sse_version(), ""); \ - \ - InstructionMark im(this); \ - if (prefix != 0) emit_byte(prefix); \ - emit_byte(0x0F); \ - emit_byte(opcode); \ - emit_sse_operand(dst, src); \ - } \ - \ - void Assembler:: name (dst_register_type dst, src_register_type src) { \ - assert(VM_Version::supports_##sse_version(), ""); \ - \ - if (prefix != 0) emit_byte(prefix); \ - emit_byte(0x0F); \ - emit_byte(opcode); \ - emit_sse_operand(dst, src); \ - } \ - -emit_sse_instruction(addss, sse, 0xF3, 0x58, XMMRegister, XMMRegister); -emit_sse_instruction(addsd, sse2, 0xF2, 0x58, XMMRegister, XMMRegister) -emit_sse_instruction(subss, sse, 0xF3, 0x5C, XMMRegister, XMMRegister) -emit_sse_instruction(subsd, sse2, 0xF2, 0x5C, XMMRegister, XMMRegister) -emit_sse_instruction(mulss, sse, 0xF3, 0x59, XMMRegister, XMMRegister) -emit_sse_instruction(mulsd, sse2, 0xF2, 0x59, XMMRegister, XMMRegister) -emit_sse_instruction(divss, sse, 0xF3, 0x5E, XMMRegister, XMMRegister) -emit_sse_instruction(divsd, sse2, 0xF2, 0x5E, XMMRegister, XMMRegister) -emit_sse_instruction(sqrtss, sse, 0xF3, 0x51, XMMRegister, XMMRegister) -emit_sse_instruction(sqrtsd, sse2, 0xF2, 0x51, XMMRegister, XMMRegister) - -emit_sse_instruction(pxor, sse2, 0x66, 0xEF, XMMRegister, XMMRegister) - -emit_sse_instruction(comiss, sse, 0, 0x2F, XMMRegister, XMMRegister) -emit_sse_instruction(comisd, sse2, 0x66, 0x2F, XMMRegister, XMMRegister) -emit_sse_instruction(ucomiss, sse, 0, 0x2E, XMMRegister, XMMRegister) -emit_sse_instruction(ucomisd, sse2, 0x66, 0x2E, XMMRegister, XMMRegister) - -emit_sse_instruction(cvtss2sd, sse2, 0xF3, 0x5A, XMMRegister, XMMRegister); -emit_sse_instruction(cvtsd2ss, sse2, 0xF2, 0x5A, XMMRegister, XMMRegister) -emit_sse_instruction(cvtsi2ss, sse, 0xF3, 0x2A, XMMRegister, Register); -emit_sse_instruction(cvtsi2sd, sse2, 0xF2, 0x2A, XMMRegister, Register) -emit_sse_instruction(cvtss2si, sse, 0xF3, 0x2D, Register, XMMRegister); -emit_sse_instruction(cvtsd2si, sse2, 0xF2, 0x2D, Register, XMMRegister) -emit_sse_instruction(cvttss2si, sse, 0xF3, 0x2C, Register, XMMRegister); -emit_sse_instruction(cvttsd2si, sse2, 0xF2, 0x2C, Register, XMMRegister) - -emit_sse_instruction(movss, sse, 0xF3, 0x10, XMMRegister, XMMRegister) -emit_sse_instruction(movsd, sse2, 0xF2, 0x10, XMMRegister, XMMRegister) - -emit_sse_instruction(movq, sse2, 0xF3, 0x7E, XMMRegister, XMMRegister); -emit_sse_instruction(movd, sse2, 0x66, 0x6E, XMMRegister, Register); -emit_sse_instruction(movdqa, sse2, 0x66, 0x6F, XMMRegister, XMMRegister); - -emit_sse_instruction(punpcklbw, sse2, 0x66, 0x60, XMMRegister, XMMRegister); - - -// Instruction not covered by macro -void Assembler::movq(Address dst, XMMRegister src) { - assert(VM_Version::supports_sse2(), ""); - - InstructionMark im(this); - emit_byte(0x66); - emit_byte(0x0F); - emit_byte(0xD6); - emit_sse_operand(src, dst); -} - -void Assembler::movd(Address dst, XMMRegister src) { - assert(VM_Version::supports_sse2(), ""); - - InstructionMark im(this); - emit_byte(0x66); - emit_byte(0x0F); - emit_byte(0x7E); - emit_sse_operand(src, dst); -} - -void Assembler::movd(Register dst, XMMRegister src) { - assert(VM_Version::supports_sse2(), ""); - - emit_byte(0x66); - emit_byte(0x0F); - emit_byte(0x7E); - emit_sse_operand(src, dst); -} - -void Assembler::movdqa(Address dst, XMMRegister src) { - assert(VM_Version::supports_sse2(), ""); - - InstructionMark im(this); - emit_byte(0x66); - emit_byte(0x0F); - emit_byte(0x7F); - emit_sse_operand(src, dst); -} - -void Assembler::pshufd(XMMRegister dst, XMMRegister src, int mode) { - assert(isByte(mode), "invalid value"); - assert(VM_Version::supports_sse2(), ""); - - emit_byte(0x66); - emit_byte(0x0F); - emit_byte(0x70); - emit_sse_operand(dst, src); - emit_byte(mode & 0xFF); -} - -void Assembler::pshufd(XMMRegister dst, Address src, int mode) { - assert(isByte(mode), "invalid value"); - assert(VM_Version::supports_sse2(), ""); - - InstructionMark im(this); - emit_byte(0x66); - emit_byte(0x0F); - emit_byte(0x70); - emit_sse_operand(dst, src); - emit_byte(mode & 0xFF); -} - -void Assembler::pshuflw(XMMRegister dst, XMMRegister src, int mode) { - assert(isByte(mode), "invalid value"); - assert(VM_Version::supports_sse2(), ""); - - emit_byte(0xF2); - emit_byte(0x0F); - emit_byte(0x70); - emit_sse_operand(dst, src); - emit_byte(mode & 0xFF); -} - -void Assembler::pshuflw(XMMRegister dst, Address src, int mode) { - assert(isByte(mode), "invalid value"); - assert(VM_Version::supports_sse2(), ""); - - InstructionMark im(this); - emit_byte(0xF2); - emit_byte(0x0F); - emit_byte(0x70); - emit_sse_operand(dst, src); - emit_byte(mode & 0xFF); -} - -void Assembler::psrlq(XMMRegister dst, int shift) { - assert(VM_Version::supports_sse2(), ""); - - emit_byte(0x66); - emit_byte(0x0F); - emit_byte(0x73); - emit_sse_operand(xmm2, dst); - emit_byte(shift); -} - -void Assembler::movss( Address dst, XMMRegister src ) { - assert(VM_Version::supports_sse(), ""); - - InstructionMark im(this); - emit_byte(0xF3); // single - emit_byte(0x0F); - emit_byte(0x11); // store - emit_sse_operand(src, dst); -} - -void Assembler::movsd( Address dst, XMMRegister src ) { - assert(VM_Version::supports_sse2(), ""); - - InstructionMark im(this); - emit_byte(0xF2); // double - emit_byte(0x0F); - emit_byte(0x11); // store - emit_sse_operand(src,dst); -} - -// New cpus require to use movaps and movapd to avoid partial register stall -// when moving between registers. -void Assembler::movaps(XMMRegister dst, XMMRegister src) { - assert(VM_Version::supports_sse(), ""); - - emit_byte(0x0F); - emit_byte(0x28); - emit_sse_operand(dst, src); -} -void Assembler::movapd(XMMRegister dst, XMMRegister src) { - assert(VM_Version::supports_sse2(), ""); - - emit_byte(0x66); - emit_byte(0x0F); - emit_byte(0x28); - emit_sse_operand(dst, src); -} - -// New cpus require to use movsd and movss to avoid partial register stall -// when loading from memory. But for old Opteron use movlpd instead of movsd. -// The selection is done in MacroAssembler::movdbl() and movflt(). -void Assembler::movlpd(XMMRegister dst, Address src) { - assert(VM_Version::supports_sse(), ""); - - InstructionMark im(this); - emit_byte(0x66); - emit_byte(0x0F); - emit_byte(0x12); - emit_sse_operand(dst, src); -} - -void Assembler::cvtdq2pd(XMMRegister dst, XMMRegister src) { - assert(VM_Version::supports_sse2(), ""); - - emit_byte(0xF3); - emit_byte(0x0F); - emit_byte(0xE6); - emit_sse_operand(dst, src); -} - -void Assembler::cvtdq2ps(XMMRegister dst, XMMRegister src) { - assert(VM_Version::supports_sse2(), ""); - - emit_byte(0x0F); - emit_byte(0x5B); - emit_sse_operand(dst, src); -} - -emit_sse_instruction(andps, sse, 0, 0x54, XMMRegister, XMMRegister); -emit_sse_instruction(andpd, sse2, 0x66, 0x54, XMMRegister, XMMRegister); -emit_sse_instruction(andnps, sse, 0, 0x55, XMMRegister, XMMRegister); -emit_sse_instruction(andnpd, sse2, 0x66, 0x55, XMMRegister, XMMRegister); -emit_sse_instruction(orps, sse, 0, 0x56, XMMRegister, XMMRegister); -emit_sse_instruction(orpd, sse2, 0x66, 0x56, XMMRegister, XMMRegister); -emit_sse_instruction(xorps, sse, 0, 0x57, XMMRegister, XMMRegister); -emit_sse_instruction(xorpd, sse2, 0x66, 0x57, XMMRegister, XMMRegister); - - -void Assembler::ldmxcsr( Address src) { - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0xAE); - emit_operand(rdx /* 2 */, src); -} - -void Assembler::stmxcsr( Address dst) { - InstructionMark im(this); - emit_byte(0x0F); - emit_byte(0xAE); - emit_operand(rbx /* 3 */, dst); -} - -// Implementation of MacroAssembler - -Address MacroAssembler::as_Address(AddressLiteral adr) { - // amd64 always does this as a pc-rel - // we can be absolute or disp based on the instruction type - // jmp/call are displacements others are absolute - assert(!adr.is_lval(), "must be rval"); - - return Address(adr.target(), adr.rspec()); -} - -Address MacroAssembler::as_Address(ArrayAddress adr) { - return Address::make_array(adr); -} - -void MacroAssembler::fat_nop() { - // A 5 byte nop that is safe for patching (see patch_verified_entry) - emit_byte(0x26); // es: - emit_byte(0x2e); // cs: - emit_byte(0x64); // fs: - emit_byte(0x65); // gs: - emit_byte(0x90); -} - -// 32bit can do a case table jump in one instruction but we no longer allow the base -// to be installed in the Address class -void MacroAssembler::jump(ArrayAddress entry) { - jmp(as_Address(entry)); -} - -void MacroAssembler::jump(AddressLiteral dst) { - jmp_literal(dst.target(), dst.rspec()); -} - -void MacroAssembler::jump_cc(Condition cc, AddressLiteral dst) { - assert((0 <= cc) && (cc < 16), "illegal cc"); - - InstructionMark im(this); - - relocInfo::relocType rtype = dst.reloc(); - relocate(rtype); - const int short_size = 2; - const int long_size = 6; - int offs = (int)dst.target() - ((int)_code_pos); - if (rtype == relocInfo::none && is8bit(offs - short_size)) { - // 0111 tttn #8-bit disp - emit_byte(0x70 | cc); - emit_byte((offs - short_size) & 0xFF); - } else { - // 0000 1111 1000 tttn #32-bit disp - emit_byte(0x0F); - emit_byte(0x80 | cc); - emit_long(offs - long_size); - } -} - -// Calls -void MacroAssembler::call(Label& L, relocInfo::relocType rtype) { - Assembler::call(L, rtype); -} - -void MacroAssembler::call(Register entry) { - Assembler::call(entry); -} - -void MacroAssembler::call(AddressLiteral entry) { - Assembler::call_literal(entry.target(), entry.rspec()); -} - - -void MacroAssembler::cmp8(AddressLiteral src1, int8_t imm) { - Assembler::cmpb(as_Address(src1), imm); -} - -void MacroAssembler::cmp32(AddressLiteral src1, int32_t imm) { - Assembler::cmpl(as_Address(src1), imm); -} - -void MacroAssembler::cmp32(Register src1, AddressLiteral src2) { - if (src2.is_lval()) { - cmp_literal32(src1, (int32_t) src2.target(), src2.rspec()); - } else { - Assembler::cmpl(src1, as_Address(src2)); - } -} - -void MacroAssembler::cmp32(Register src1, int32_t imm) { - Assembler::cmpl(src1, imm); -} - -void MacroAssembler::cmp32(Register src1, Address src2) { - Assembler::cmpl(src1, src2); -} - -void MacroAssembler::cmpoop(Address src1, jobject obj) { - cmp_literal32(src1, (int32_t)obj, oop_Relocation::spec_for_immediate()); -} - -void MacroAssembler::cmpoop(Register src1, jobject obj) { - cmp_literal32(src1, (int32_t)obj, oop_Relocation::spec_for_immediate()); -} - -void MacroAssembler::cmpptr(Register src1, AddressLiteral src2) { - if (src2.is_lval()) { - // compare the effect address of src2 to src1 - cmp_literal32(src1, (int32_t)src2.target(), src2.rspec()); - } else { - Assembler::cmpl(src1, as_Address(src2)); - } -} - -void MacroAssembler::cmpptr(Address src1, AddressLiteral src2) { - assert(src2.is_lval(), "not a mem-mem compare"); - cmp_literal32(src1, (int32_t) src2.target(), src2.rspec()); -} - - -void MacroAssembler::cmpxchgptr(Register reg, AddressLiteral adr) { - cmpxchg(reg, as_Address(adr)); -} - -void MacroAssembler::increment(AddressLiteral dst) { - increment(as_Address(dst)); -} - -void MacroAssembler::increment(ArrayAddress dst) { - increment(as_Address(dst)); -} - -void MacroAssembler::lea(Register dst, AddressLiteral adr) { - // leal(dst, as_Address(adr)); - // see note in movl as to why we musr use a move - mov_literal32(dst, (int32_t) adr.target(), adr.rspec()); -} - -void MacroAssembler::lea(Address dst, AddressLiteral adr) { - // leal(dst, as_Address(adr)); - // see note in movl as to why we musr use a move - mov_literal32(dst, (int32_t) adr.target(), adr.rspec()); -} - -void MacroAssembler::mov32(AddressLiteral dst, Register src) { - Assembler::movl(as_Address(dst), src); -} - -void MacroAssembler::mov32(Register dst, AddressLiteral src) { - Assembler::movl(dst, as_Address(src)); -} - -void MacroAssembler::movbyte(ArrayAddress dst, int src) { - movb(as_Address(dst), src); -} - -void MacroAssembler::movoop(Address dst, jobject obj) { - mov_literal32(dst, (int32_t)obj, oop_Relocation::spec_for_immediate()); -} - -void MacroAssembler::movoop(Register dst, jobject obj) { - mov_literal32(dst, (int32_t)obj, oop_Relocation::spec_for_immediate()); -} - -void MacroAssembler::movptr(Register dst, AddressLiteral src) { - if (src.is_lval()) { - // essentially an lea - mov_literal32(dst, (int32_t) src.target(), src.rspec()); - } else { - // mov 32bits from an absolute address - movl(dst, as_Address(src)); - } -} - -void MacroAssembler::movptr(ArrayAddress dst, Register src) { - movl(as_Address(dst), src); -} - -void MacroAssembler::movptr(Register dst, ArrayAddress src) { - movl(dst, as_Address(src)); -} - -void MacroAssembler::movflt(XMMRegister dst, AddressLiteral src) { - movss(dst, as_Address(src)); -} - -void MacroAssembler::movdbl(XMMRegister dst, AddressLiteral src) { - if (UseXmmLoadAndClearUpper) { movsd (dst, as_Address(src)); return; } - else { movlpd(dst, as_Address(src)); return; } -} - -void Assembler::pushoop(jobject obj) { - push_literal32((int32_t)obj, oop_Relocation::spec_for_immediate()); -} - - -void MacroAssembler::pushptr(AddressLiteral src) { - if (src.is_lval()) { - push_literal32((int32_t)src.target(), src.rspec()); - } else { - pushl(as_Address(src)); - } -} - -void MacroAssembler::test32(Register src1, AddressLiteral src2) { - // src2 must be rval - testl(src1, as_Address(src2)); -} - -// FPU - -void MacroAssembler::fld_x(AddressLiteral src) { - Assembler::fld_x(as_Address(src)); -} - -void MacroAssembler::fld_d(AddressLiteral src) { - fld_d(as_Address(src)); -} - -void MacroAssembler::fld_s(AddressLiteral src) { - fld_s(as_Address(src)); -} - -void MacroAssembler::fldcw(AddressLiteral src) { - Assembler::fldcw(as_Address(src)); -} - -void MacroAssembler::ldmxcsr(AddressLiteral src) { - Assembler::ldmxcsr(as_Address(src)); -} - -// SSE - -void MacroAssembler::andpd(XMMRegister dst, AddressLiteral src) { - andpd(dst, as_Address(src)); -} - -void MacroAssembler::comisd(XMMRegister dst, AddressLiteral src) { - comisd(dst, as_Address(src)); -} - -void MacroAssembler::comiss(XMMRegister dst, AddressLiteral src) { - comiss(dst, as_Address(src)); -} - -void MacroAssembler::movsd(XMMRegister dst, AddressLiteral src) { - movsd(dst, as_Address(src)); -} - -void MacroAssembler::movss(XMMRegister dst, AddressLiteral src) { - movss(dst, as_Address(src)); -} - -void MacroAssembler::xorpd(XMMRegister dst, AddressLiteral src) { - xorpd(dst, as_Address(src)); -} - -void MacroAssembler::xorps(XMMRegister dst, AddressLiteral src) { - xorps(dst, as_Address(src)); -} - -void MacroAssembler::ucomisd(XMMRegister dst, AddressLiteral src) { - ucomisd(dst, as_Address(src)); -} - -void MacroAssembler::ucomiss(XMMRegister dst, AddressLiteral src) { - ucomiss(dst, as_Address(src)); -} - -void MacroAssembler::null_check(Register reg, int offset) { - if (needs_explicit_null_check(offset)) { - // provoke OS NULL exception if reg = NULL by - // accessing M[reg] w/o changing any (non-CC) registers - cmpl(rax, Address(reg, 0)); - // Note: should probably use testl(rax, Address(reg, 0)); - // may be shorter code (however, this version of - // testl needs to be implemented first) - } else { - // nothing to do, (later) access of M[reg + offset] - // will provoke OS NULL exception if reg = NULL - } -} - - -int MacroAssembler::load_unsigned_byte(Register dst, Address src) { - // According to Intel Doc. AP-526, "Zero-Extension of Short", p.16, - // and "3.9 Partial Register Penalties", p. 22). - int off; - if (VM_Version::is_P6() || src.uses(dst)) { - off = offset(); - movzxb(dst, src); - } else { - xorl(dst, dst); - off = offset(); - movb(dst, src); - } - return off; -} - - -int MacroAssembler::load_unsigned_word(Register dst, Address src) { - // According to Intel Doc. AP-526, "Zero-Extension of Short", p.16, - // and "3.9 Partial Register Penalties", p. 22). - int off; - if (VM_Version::is_P6() || src.uses(dst)) { - off = offset(); - movzxw(dst, src); - } else { - xorl(dst, dst); - off = offset(); - movw(dst, src); - } - return off; -} - - -int MacroAssembler::load_signed_byte(Register dst, Address src) { - int off; - if (VM_Version::is_P6()) { - off = offset(); - movsxb(dst, src); - } else { - off = load_unsigned_byte(dst, src); - shll(dst, 24); - sarl(dst, 24); - } - return off; -} - - -int MacroAssembler::load_signed_word(Register dst, Address src) { - int off; - if (VM_Version::is_P6()) { - off = offset(); - movsxw(dst, src); - } else { - off = load_unsigned_word(dst, src); - shll(dst, 16); - sarl(dst, 16); - } - return off; -} - - -void MacroAssembler::extend_sign(Register hi, Register lo) { - // According to Intel Doc. AP-526, "Integer Divide", p.18. - if (VM_Version::is_P6() && hi == rdx && lo == rax) { - cdql(); - } else { - movl(hi, lo); - sarl(hi, 31); - } -} - - -void MacroAssembler::increment(Register reg, int value) { - if (value == min_jint) {addl(reg, value); return; } - if (value < 0) { decrement(reg, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { incl(reg); return; } - /* else */ { addl(reg, value) ; return; } -} - -void MacroAssembler::increment(Address dst, int value) { - if (value == min_jint) {addl(dst, value); return; } - if (value < 0) { decrement(dst, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { incl(dst); return; } - /* else */ { addl(dst, value) ; return; } -} - -void MacroAssembler::decrement(Register reg, int value) { - if (value == min_jint) {subl(reg, value); return; } - if (value < 0) { increment(reg, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { decl(reg); return; } - /* else */ { subl(reg, value) ; return; } -} - -void MacroAssembler::decrement(Address dst, int value) { - if (value == min_jint) {subl(dst, value); return; } - if (value < 0) { increment(dst, -value); return; } - if (value == 0) { ; return; } - if (value == 1 && UseIncDec) { decl(dst); return; } - /* else */ { subl(dst, value) ; return; } -} - -void MacroAssembler::align(int modulus) { - if (offset() % modulus != 0) nop(modulus - (offset() % modulus)); -} - - -void MacroAssembler::enter() { - pushl(rbp); - movl(rbp, rsp); -} - - -void MacroAssembler::leave() { - movl(rsp, rbp); - popl(rbp); -} - -void MacroAssembler::set_last_Java_frame(Register java_thread, - Register last_java_sp, - Register last_java_fp, - address last_java_pc) { - // determine java_thread register - if (!java_thread->is_valid()) { - java_thread = rdi; - get_thread(java_thread); - } - // determine last_java_sp register - if (!last_java_sp->is_valid()) { - last_java_sp = rsp; - } - - // last_java_fp is optional - - if (last_java_fp->is_valid()) { - movl(Address(java_thread, JavaThread::last_Java_fp_offset()), last_java_fp); - } - - // last_java_pc is optional - - if (last_java_pc != NULL) { - lea(Address(java_thread, - JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset()), - InternalAddress(last_java_pc)); - - } - movl(Address(java_thread, JavaThread::last_Java_sp_offset()), last_java_sp); -} - -void MacroAssembler::reset_last_Java_frame(Register java_thread, bool clear_fp, bool clear_pc) { - // determine java_thread register - if (!java_thread->is_valid()) { - java_thread = rdi; - get_thread(java_thread); - } - // we must set sp to zero to clear frame - movl(Address(java_thread, JavaThread::last_Java_sp_offset()), 0); - if (clear_fp) { - movl(Address(java_thread, JavaThread::last_Java_fp_offset()), 0); - } - - if (clear_pc) - movl(Address(java_thread, JavaThread::last_Java_pc_offset()), 0); - -} - - - -// Implementation of call_VM versions - -void MacroAssembler::call_VM_leaf_base( - address entry_point, - int number_of_arguments -) { - call(RuntimeAddress(entry_point)); - increment(rsp, number_of_arguments * wordSize); -} - - -void MacroAssembler::call_VM_base( - Register oop_result, - Register java_thread, - Register last_java_sp, - address entry_point, - int number_of_arguments, - bool check_exceptions -) { - // determine java_thread register - if (!java_thread->is_valid()) { - java_thread = rdi; - get_thread(java_thread); - } - // determine last_java_sp register - if (!last_java_sp->is_valid()) { - last_java_sp = rsp; - } - // debugging support - assert(number_of_arguments >= 0 , "cannot have negative number of arguments"); - assert(java_thread != oop_result , "cannot use the same register for java_thread & oop_result"); - assert(java_thread != last_java_sp, "cannot use the same register for java_thread & last_java_sp"); - // push java thread (becomes first argument of C function) - pushl(java_thread); - // set last Java frame before call - assert(last_java_sp != rbp, "this code doesn't work for last_java_sp == rbp, which currently can't portably work anyway since C2 doesn't save rbp,"); - // Only interpreter should have to set fp - set_last_Java_frame(java_thread, last_java_sp, rbp, NULL); - // do the call - call(RuntimeAddress(entry_point)); - // restore the thread (cannot use the pushed argument since arguments - // may be overwritten by C code generated by an optimizing compiler); - // however can use the register value directly if it is callee saved. - if (java_thread == rdi || java_thread == rsi) { - // rdi & rsi are callee saved -> nothing to do -#ifdef ASSERT - guarantee(java_thread != rax, "change this code"); - pushl(rax); - { Label L; - get_thread(rax); - cmpl(java_thread, rax); - jcc(Assembler::equal, L); - stop("MacroAssembler::call_VM_base: rdi not callee saved?"); - bind(L); - } - popl(rax); -#endif - } else { - get_thread(java_thread); - } - // reset last Java frame - // Only interpreter should have to clear fp - reset_last_Java_frame(java_thread, true, false); - // discard thread and arguments - addl(rsp, (1 + number_of_arguments)*wordSize); - -#ifndef CC_INTERP - // C++ interp handles this in the interpreter - check_and_handle_popframe(java_thread); - check_and_handle_earlyret(java_thread); -#endif /* CC_INTERP */ - - if (check_exceptions) { - // check for pending exceptions (java_thread is set upon return) - cmpl(Address(java_thread, Thread::pending_exception_offset()), NULL_WORD); - jump_cc(Assembler::notEqual, - RuntimeAddress(StubRoutines::forward_exception_entry())); - } - - // get oop result if there is one and reset the value in the thread - if (oop_result->is_valid()) { - movl(oop_result, Address(java_thread, JavaThread::vm_result_offset())); - movl(Address(java_thread, JavaThread::vm_result_offset()), NULL_WORD); - verify_oop(oop_result); - } -} - - -void MacroAssembler::check_and_handle_popframe(Register java_thread) { -} - -void MacroAssembler::check_and_handle_earlyret(Register java_thread) { -} - -void MacroAssembler::call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions) { - leal(rax, Address(rsp, (1 + number_of_arguments) * wordSize)); - call_VM_base(oop_result, noreg, rax, entry_point, number_of_arguments, check_exceptions); -} - - -void MacroAssembler::call_VM(Register oop_result, address entry_point, bool check_exceptions) { - Label C, E; - call(C, relocInfo::none); - jmp(E); - - bind(C); - call_VM_helper(oop_result, entry_point, 0, check_exceptions); - ret(0); - - bind(E); -} - - -void MacroAssembler::call_VM(Register oop_result, address entry_point, Register arg_1, bool check_exceptions) { - Label C, E; - call(C, relocInfo::none); - jmp(E); - - bind(C); - pushl(arg_1); - call_VM_helper(oop_result, entry_point, 1, check_exceptions); - ret(0); - - bind(E); -} - - -void MacroAssembler::call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, bool check_exceptions) { - Label C, E; - call(C, relocInfo::none); - jmp(E); - - bind(C); - pushl(arg_2); - pushl(arg_1); - call_VM_helper(oop_result, entry_point, 2, check_exceptions); - ret(0); - - bind(E); -} - - -void MacroAssembler::call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, Register arg_3, bool check_exceptions) { - Label C, E; - call(C, relocInfo::none); - jmp(E); - - bind(C); - pushl(arg_3); - pushl(arg_2); - pushl(arg_1); - call_VM_helper(oop_result, entry_point, 3, check_exceptions); - ret(0); - - bind(E); -} - - -void MacroAssembler::call_VM(Register oop_result, Register last_java_sp, address entry_point, int number_of_arguments, bool check_exceptions) { - call_VM_base(oop_result, noreg, last_java_sp, entry_point, number_of_arguments, check_exceptions); -} - - -void MacroAssembler::call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, bool check_exceptions) { - pushl(arg_1); - call_VM(oop_result, last_java_sp, entry_point, 1, check_exceptions); -} - - -void MacroAssembler::call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, bool check_exceptions) { - pushl(arg_2); - pushl(arg_1); - call_VM(oop_result, last_java_sp, entry_point, 2, check_exceptions); -} - - -void MacroAssembler::call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, Register arg_3, bool check_exceptions) { - pushl(arg_3); - pushl(arg_2); - pushl(arg_1); - call_VM(oop_result, last_java_sp, entry_point, 3, check_exceptions); -} - - -void MacroAssembler::call_VM_leaf(address entry_point, int number_of_arguments) { - call_VM_leaf_base(entry_point, number_of_arguments); -} - - -void MacroAssembler::call_VM_leaf(address entry_point, Register arg_1) { - pushl(arg_1); - call_VM_leaf(entry_point, 1); -} - - -void MacroAssembler::call_VM_leaf(address entry_point, Register arg_1, Register arg_2) { - pushl(arg_2); - pushl(arg_1); - call_VM_leaf(entry_point, 2); -} - - -void MacroAssembler::call_VM_leaf(address entry_point, Register arg_1, Register arg_2, Register arg_3) { - pushl(arg_3); - pushl(arg_2); - pushl(arg_1); - call_VM_leaf(entry_point, 3); -} - - -// Calls to C land -// -// When entering C land, the rbp, & rsp of the last Java frame have to be recorded -// in the (thread-local) JavaThread object. When leaving C land, the last Java fp -// has to be reset to 0. This is required to allow proper stack traversal. - -void MacroAssembler::store_check(Register obj) { - // Does a store check for the oop in register obj. The content of - // register obj is destroyed afterwards. - store_check_part_1(obj); - store_check_part_2(obj); -} - - -void MacroAssembler::store_check(Register obj, Address dst) { - store_check(obj); -} - - -// split the store check operation so that other instructions can be scheduled inbetween -void MacroAssembler::store_check_part_1(Register obj) { - BarrierSet* bs = Universe::heap()->barrier_set(); - assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); - shrl(obj, CardTableModRefBS::card_shift); -} - - -void MacroAssembler::store_check_part_2(Register obj) { - BarrierSet* bs = Universe::heap()->barrier_set(); - assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); - CardTableModRefBS* ct = (CardTableModRefBS*)bs; - assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); - - // The calculation for byte_map_base is as follows: - // byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift); - // So this essentially converts an address to a displacement and - // it will never need to be relocated. On 64bit however the value may be too - // large for a 32bit displacement - - intptr_t disp = (intptr_t) ct->byte_map_base; - Address cardtable(noreg, obj, Address::times_1, disp); - movb(cardtable, 0); -} - - -void MacroAssembler::c2bool(Register x) { - // implements x == 0 ? 0 : 1 - // note: must only look at least-significant byte of x - // since C-style booleans are stored in one byte - // only! (was bug) - andl(x, 0xFF); - setb(Assembler::notZero, x); -} - - -int MacroAssembler::corrected_idivl(Register reg) { - // Full implementation of Java idiv and irem; checks for - // special case as described in JVM spec., p.243 & p.271. - // The function returns the (pc) offset of the idivl - // instruction - may be needed for implicit exceptions. - // - // normal case special case - // - // input : rax,: dividend min_int - // reg: divisor (may not be rax,/rdx) -1 - // - // output: rax,: quotient (= rax, idiv reg) min_int - // rdx: remainder (= rax, irem reg) 0 - assert(reg != rax && reg != rdx, "reg cannot be rax, or rdx register"); - const int min_int = 0x80000000; - Label normal_case, special_case; - - // check for special case - cmpl(rax, min_int); - jcc(Assembler::notEqual, normal_case); - xorl(rdx, rdx); // prepare rdx for possible special case (where remainder = 0) - cmpl(reg, -1); - jcc(Assembler::equal, special_case); - - // handle normal case - bind(normal_case); - cdql(); - int idivl_offset = offset(); - idivl(reg); - - // normal and special case exit - bind(special_case); - - return idivl_offset; -} - - -void MacroAssembler::lneg(Register hi, Register lo) { - negl(lo); - adcl(hi, 0); - negl(hi); -} - - -void MacroAssembler::lmul(int x_rsp_offset, int y_rsp_offset) { - // Multiplication of two Java long values stored on the stack - // as illustrated below. Result is in rdx:rax. - // - // rsp ---> [ ?? ] \ \ - // .... | y_rsp_offset | - // [ y_lo ] / (in bytes) | x_rsp_offset - // [ y_hi ] | (in bytes) - // .... | - // [ x_lo ] / - // [ x_hi ] - // .... - // - // Basic idea: lo(result) = lo(x_lo * y_lo) - // hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) + lo(x_lo * y_hi) - Address x_hi(rsp, x_rsp_offset + wordSize); Address x_lo(rsp, x_rsp_offset); - Address y_hi(rsp, y_rsp_offset + wordSize); Address y_lo(rsp, y_rsp_offset); - Label quick; - // load x_hi, y_hi and check if quick - // multiplication is possible - movl(rbx, x_hi); - movl(rcx, y_hi); - movl(rax, rbx); - orl(rbx, rcx); // rbx, = 0 <=> x_hi = 0 and y_hi = 0 - jcc(Assembler::zero, quick); // if rbx, = 0 do quick multiply - // do full multiplication - // 1st step - mull(y_lo); // x_hi * y_lo - movl(rbx, rax); // save lo(x_hi * y_lo) in rbx, - // 2nd step - movl(rax, x_lo); - mull(rcx); // x_lo * y_hi - addl(rbx, rax); // add lo(x_lo * y_hi) to rbx, - // 3rd step - bind(quick); // note: rbx, = 0 if quick multiply! - movl(rax, x_lo); - mull(y_lo); // x_lo * y_lo - addl(rdx, rbx); // correct hi(x_lo * y_lo) -} - - -void MacroAssembler::lshl(Register hi, Register lo) { - // Java shift left long support (semantics as described in JVM spec., p.305) - // (basic idea for shift counts s >= n: x << s == (x << n) << (s - n)) - // shift value is in rcx ! - assert(hi != rcx, "must not use rcx"); - assert(lo != rcx, "must not use rcx"); - const Register s = rcx; // shift count - const int n = BitsPerWord; - Label L; - andl(s, 0x3f); // s := s & 0x3f (s < 0x40) - cmpl(s, n); // if (s < n) - jcc(Assembler::less, L); // else (s >= n) - movl(hi, lo); // x := x << n - xorl(lo, lo); - // Note: subl(s, n) is not needed since the Intel shift instructions work rcx mod n! - bind(L); // s (mod n) < n - shldl(hi, lo); // x := x << s - shll(lo); -} - - -void MacroAssembler::lshr(Register hi, Register lo, bool sign_extension) { - // Java shift right long support (semantics as described in JVM spec., p.306 & p.310) - // (basic idea for shift counts s >= n: x >> s == (x >> n) >> (s - n)) - assert(hi != rcx, "must not use rcx"); - assert(lo != rcx, "must not use rcx"); - const Register s = rcx; // shift count - const int n = BitsPerWord; - Label L; - andl(s, 0x3f); // s := s & 0x3f (s < 0x40) - cmpl(s, n); // if (s < n) - jcc(Assembler::less, L); // else (s >= n) - movl(lo, hi); // x := x >> n - if (sign_extension) sarl(hi, 31); - else xorl(hi, hi); - // Note: subl(s, n) is not needed since the Intel shift instructions work rcx mod n! - bind(L); // s (mod n) < n - shrdl(lo, hi); // x := x >> s - if (sign_extension) sarl(hi); - else shrl(hi); -} - - -// Note: y_lo will be destroyed -void MacroAssembler::lcmp2int(Register x_hi, Register x_lo, Register y_hi, Register y_lo) { - // Long compare for Java (semantics as described in JVM spec.) - Label high, low, done; - - cmpl(x_hi, y_hi); - jcc(Assembler::less, low); - jcc(Assembler::greater, high); - // x_hi is the return register - xorl(x_hi, x_hi); - cmpl(x_lo, y_lo); - jcc(Assembler::below, low); - jcc(Assembler::equal, done); - - bind(high); - xorl(x_hi, x_hi); - increment(x_hi); - jmp(done); - - bind(low); - xorl(x_hi, x_hi); - decrement(x_hi); - - bind(done); -} - - -void MacroAssembler::save_rax(Register tmp) { - if (tmp == noreg) pushl(rax); - else if (tmp != rax) movl(tmp, rax); -} - - -void MacroAssembler::restore_rax(Register tmp) { - if (tmp == noreg) popl(rax); - else if (tmp != rax) movl(rax, tmp); -} - - -void MacroAssembler::fremr(Register tmp) { - save_rax(tmp); - { Label L; - bind(L); - fprem(); - fwait(); fnstsw_ax(); - sahf(); - jcc(Assembler::parity, L); - } - restore_rax(tmp); - // Result is in ST0. - // Note: fxch & fpop to get rid of ST1 - // (otherwise FPU stack could overflow eventually) - fxch(1); - fpop(); -} - - -static const double pi_4 = 0.7853981633974483; - -void MacroAssembler::trigfunc(char trig, int num_fpu_regs_in_use) { - // A hand-coded argument reduction for values in fabs(pi/4, pi/2) - // was attempted in this code; unfortunately it appears that the - // switch to 80-bit precision and back causes this to be - // unprofitable compared with simply performing a runtime call if - // the argument is out of the (-pi/4, pi/4) range. - - Register tmp = noreg; - if (!VM_Version::supports_cmov()) { - // fcmp needs a temporary so preserve rbx, - tmp = rbx; - pushl(tmp); - } - - Label slow_case, done; - - // x ?<= pi/4 - fld_d(ExternalAddress((address)&pi_4)); - fld_s(1); // Stack: X PI/4 X - fabs(); // Stack: |X| PI/4 X - fcmp(tmp); - jcc(Assembler::above, slow_case); - - // fastest case: -pi/4 <= x <= pi/4 - switch(trig) { - case 's': - fsin(); - break; - case 'c': - fcos(); - break; - case 't': - ftan(); - break; - default: - assert(false, "bad intrinsic"); - break; - } - jmp(done); - - // slow case: runtime call - bind(slow_case); - // Preserve registers across runtime call - pushad(); - int incoming_argument_and_return_value_offset = -1; - if (num_fpu_regs_in_use > 1) { - // Must preserve all other FPU regs (could alternatively convert - // SharedRuntime::dsin and dcos into assembly routines known not to trash - // FPU state, but can not trust C compiler) - NEEDS_CLEANUP; - // NOTE that in this case we also push the incoming argument to - // the stack and restore it later; we also use this stack slot to - // hold the return value from dsin or dcos. - for (int i = 0; i < num_fpu_regs_in_use; i++) { - subl(rsp, wordSize*2); - fstp_d(Address(rsp, 0)); - } - incoming_argument_and_return_value_offset = 2*wordSize*(num_fpu_regs_in_use-1); - fld_d(Address(rsp, incoming_argument_and_return_value_offset)); - } - subl(rsp, wordSize*2); - fstp_d(Address(rsp, 0)); - // NOTE: we must not use call_VM_leaf here because that requires a - // complete interpreter frame in debug mode -- same bug as 4387334 - NEEDS_CLEANUP; - // Need to add stack banging before this runtime call if it needs to - // be taken; however, there is no generic stack banging routine at - // the MacroAssembler level - switch(trig) { - case 's': - { - call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dsin))); - } - break; - case 'c': - { - call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dcos))); - } - break; - case 't': - { - call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtan))); - } - break; - default: - assert(false, "bad intrinsic"); - break; - } - addl(rsp, wordSize * 2); - if (num_fpu_regs_in_use > 1) { - // Must save return value to stack and then restore entire FPU stack - fstp_d(Address(rsp, incoming_argument_and_return_value_offset)); - for (int i = 0; i < num_fpu_regs_in_use; i++) { - fld_d(Address(rsp, 0)); - addl(rsp, wordSize*2); - } - } - popad(); - - // Come here with result in F-TOS - bind(done); - - if (tmp != noreg) { - popl(tmp); - } -} - -void MacroAssembler::jC2(Register tmp, Label& L) { - // set parity bit if FPU flag C2 is set (via rax) - save_rax(tmp); - fwait(); fnstsw_ax(); - sahf(); - restore_rax(tmp); - // branch - jcc(Assembler::parity, L); -} - - -void MacroAssembler::jnC2(Register tmp, Label& L) { - // set parity bit if FPU flag C2 is set (via rax) - save_rax(tmp); - fwait(); fnstsw_ax(); - sahf(); - restore_rax(tmp); - // branch - jcc(Assembler::noParity, L); -} - - -void MacroAssembler::fcmp(Register tmp) { - fcmp(tmp, 1, true, true); -} - - -void MacroAssembler::fcmp(Register tmp, int index, bool pop_left, bool pop_right) { - assert(!pop_right || pop_left, "usage error"); - if (VM_Version::supports_cmov()) { - assert(tmp == noreg, "unneeded temp"); - if (pop_left) { - fucomip(index); - } else { - fucomi(index); - } - if (pop_right) { - fpop(); - } - } else { - assert(tmp != noreg, "need temp"); - if (pop_left) { - if (pop_right) { - fcompp(); - } else { - fcomp(index); - } - } else { - fcom(index); - } - // convert FPU condition into eflags condition via rax, - save_rax(tmp); - fwait(); fnstsw_ax(); - sahf(); - restore_rax(tmp); - } - // condition codes set as follows: - // - // CF (corresponds to C0) if x < y - // PF (corresponds to C2) if unordered - // ZF (corresponds to C3) if x = y -} - - -void MacroAssembler::fcmp2int(Register dst, bool unordered_is_less) { - fcmp2int(dst, unordered_is_less, 1, true, true); -} - - -void MacroAssembler::fcmp2int(Register dst, bool unordered_is_less, int index, bool pop_left, bool pop_right) { - fcmp(VM_Version::supports_cmov() ? noreg : dst, index, pop_left, pop_right); - Label L; - if (unordered_is_less) { - movl(dst, -1); - jcc(Assembler::parity, L); - jcc(Assembler::below , L); - movl(dst, 0); - jcc(Assembler::equal , L); - increment(dst); - } else { // unordered is greater - movl(dst, 1); - jcc(Assembler::parity, L); - jcc(Assembler::above , L); - movl(dst, 0); - jcc(Assembler::equal , L); - decrement(dst); - } - bind(L); -} - -void MacroAssembler::cmpss2int(XMMRegister opr1, XMMRegister opr2, Register dst, bool unordered_is_less) { - ucomiss(opr1, opr2); - - Label L; - if (unordered_is_less) { - movl(dst, -1); - jcc(Assembler::parity, L); - jcc(Assembler::below , L); - movl(dst, 0); - jcc(Assembler::equal , L); - increment(dst); - } else { // unordered is greater - movl(dst, 1); - jcc(Assembler::parity, L); - jcc(Assembler::above , L); - movl(dst, 0); - jcc(Assembler::equal , L); - decrement(dst); - } - bind(L); -} - -void MacroAssembler::cmpsd2int(XMMRegister opr1, XMMRegister opr2, Register dst, bool unordered_is_less) { - ucomisd(opr1, opr2); - - Label L; - if (unordered_is_less) { - movl(dst, -1); - jcc(Assembler::parity, L); - jcc(Assembler::below , L); - movl(dst, 0); - jcc(Assembler::equal , L); - increment(dst); - } else { // unordered is greater - movl(dst, 1); - jcc(Assembler::parity, L); - jcc(Assembler::above , L); - movl(dst, 0); - jcc(Assembler::equal , L); - decrement(dst); - } - bind(L); -} - - - -void MacroAssembler::fpop() { - ffree(); - fincstp(); -} - - -void MacroAssembler::sign_extend_short(Register reg) { - if (VM_Version::is_P6()) { - movsxw(reg, reg); - } else { - shll(reg, 16); - sarl(reg, 16); - } -} - - -void MacroAssembler::sign_extend_byte(Register reg) { - if (VM_Version::is_P6() && reg->has_byte_register()) { - movsxb(reg, reg); - } else { - shll(reg, 24); - sarl(reg, 24); - } -} - - -void MacroAssembler::division_with_shift (Register reg, int shift_value) { - assert (shift_value > 0, "illegal shift value"); - Label _is_positive; - testl (reg, reg); - jcc (Assembler::positive, _is_positive); - int offset = (1 << shift_value) - 1 ; - - increment(reg, offset); - - bind (_is_positive); - sarl(reg, shift_value); -} - - -void MacroAssembler::round_to(Register reg, int modulus) { - addl(reg, modulus - 1); - andl(reg, -modulus); -} - -// C++ bool manipulation - -void MacroAssembler::movbool(Register dst, Address src) { - if(sizeof(bool) == 1) - movb(dst, src); - else if(sizeof(bool) == 2) - movw(dst, src); - else if(sizeof(bool) == 4) - movl(dst, src); - else - // unsupported - ShouldNotReachHere(); -} - -void MacroAssembler::movbool(Address dst, bool boolconst) { - if(sizeof(bool) == 1) - movb(dst, (int) boolconst); - else if(sizeof(bool) == 2) - movw(dst, (int) boolconst); - else if(sizeof(bool) == 4) - movl(dst, (int) boolconst); - else - // unsupported - ShouldNotReachHere(); -} - -void MacroAssembler::movbool(Address dst, Register src) { - if(sizeof(bool) == 1) - movb(dst, src); - else if(sizeof(bool) == 2) - movw(dst, src); - else if(sizeof(bool) == 4) - movl(dst, src); - else - // unsupported - ShouldNotReachHere(); -} - -void MacroAssembler::testbool(Register dst) { - if(sizeof(bool) == 1) - testb(dst, (int) 0xff); - else if(sizeof(bool) == 2) { - // testw implementation needed for two byte bools - ShouldNotReachHere(); - } else if(sizeof(bool) == 4) - testl(dst, dst); - else - // unsupported - ShouldNotReachHere(); -} - -void MacroAssembler::verify_oop(Register reg, const char* s) { - if (!VerifyOops) return; - // Pass register number to verify_oop_subroutine - char* b = new char[strlen(s) + 50]; - sprintf(b, "verify_oop: %s: %s", reg->name(), s); - pushl(rax); // save rax, - pushl(reg); // pass register argument - ExternalAddress buffer((address) b); - pushptr(buffer.addr()); - // call indirectly to solve generation ordering problem - movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address())); - call(rax); -} - - -void MacroAssembler::verify_oop_addr(Address addr, const char* s) { - if (!VerifyOops) return; - // QQQ fix this - // Address adjust(addr.base(), addr.index(), addr.scale(), addr.disp() + BytesPerWord); - // Pass register number to verify_oop_subroutine - char* b = new char[strlen(s) + 50]; - sprintf(b, "verify_oop_addr: %s", s); - pushl(rax); // save rax, - // addr may contain rsp so we will have to adjust it based on the push - // we just did - if (addr.uses(rsp)) { - leal(rax, addr); - pushl(Address(rax, BytesPerWord)); - } else { - pushl(addr); - } - ExternalAddress buffer((address) b); - // pass msg argument - pushptr(buffer.addr()); - // call indirectly to solve generation ordering problem - movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address())); - call(rax); - // Caller pops the arguments and restores rax, from the stack -} - - -void MacroAssembler::stop(const char* msg) { - ExternalAddress message((address)msg); - // push address of message - pushptr(message.addr()); - { Label L; call(L, relocInfo::none); bind(L); } // push eip - pushad(); // push registers - call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug))); - hlt(); -} - - -void MacroAssembler::warn(const char* msg) { - push_CPU_state(); - - ExternalAddress message((address) msg); - // push address of message - pushptr(message.addr()); - - call(RuntimeAddress(CAST_FROM_FN_PTR(address, warning))); - addl(rsp, wordSize); // discard argument - pop_CPU_state(); -} - - -void MacroAssembler::debug(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip, char* msg) { - // In order to get locks to work, we need to fake a in_VM state - JavaThread* thread = JavaThread::current(); - JavaThreadState saved_state = thread->thread_state(); - thread->set_thread_state(_thread_in_vm); - if (ShowMessageBoxOnError) { - JavaThread* thread = JavaThread::current(); - JavaThreadState saved_state = thread->thread_state(); - thread->set_thread_state(_thread_in_vm); - ttyLocker ttyl; - if (CountBytecodes || TraceBytecodes || StopInterpreterAt) { - BytecodeCounter::print(); - } - // To see where a verify_oop failed, get $ebx+40/X for this frame. - // This is the value of eip which points to where verify_oop will return. - if (os::message_box(msg, "Execution stopped, print registers?")) { - tty->print_cr("eip = 0x%08x", eip); - tty->print_cr("rax, = 0x%08x", rax); - tty->print_cr("rbx, = 0x%08x", rbx); - tty->print_cr("rcx = 0x%08x", rcx); - tty->print_cr("rdx = 0x%08x", rdx); - tty->print_cr("rdi = 0x%08x", rdi); - tty->print_cr("rsi = 0x%08x", rsi); - tty->print_cr("rbp, = 0x%08x", rbp); - tty->print_cr("rsp = 0x%08x", rsp); - BREAKPOINT; - } - } else { - ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n", msg); - assert(false, "DEBUG MESSAGE"); - } - ThreadStateTransition::transition(thread, _thread_in_vm, saved_state); -} - - - -void MacroAssembler::os_breakpoint() { - // instead of directly emitting a breakpoint, call os:breakpoint for better debugability - // (e.g., MSVC can't call ps() otherwise) - call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); -} - - -void MacroAssembler::push_fTOS() { - subl(rsp, 2 * wordSize); - fstp_d(Address(rsp, 0)); -} - - -void MacroAssembler::pop_fTOS() { - fld_d(Address(rsp, 0)); - addl(rsp, 2 * wordSize); -} - - -void MacroAssembler::empty_FPU_stack() { - if (VM_Version::supports_mmx()) { - emms(); - } else { - for (int i = 8; i-- > 0; ) ffree(i); - } -} - - -class ControlWord { - public: - int32_t _value; - - int rounding_control() const { return (_value >> 10) & 3 ; } - int precision_control() const { return (_value >> 8) & 3 ; } - bool precision() const { return ((_value >> 5) & 1) != 0; } - bool underflow() const { return ((_value >> 4) & 1) != 0; } - bool overflow() const { return ((_value >> 3) & 1) != 0; } - bool zero_divide() const { return ((_value >> 2) & 1) != 0; } - bool denormalized() const { return ((_value >> 1) & 1) != 0; } - bool invalid() const { return ((_value >> 0) & 1) != 0; } - - void print() const { - // rounding control - const char* rc; - switch (rounding_control()) { - case 0: rc = "round near"; break; - case 1: rc = "round down"; break; - case 2: rc = "round up "; break; - case 3: rc = "chop "; break; - }; - // precision control - const char* pc; - switch (precision_control()) { - case 0: pc = "24 bits "; break; - case 1: pc = "reserved"; break; - case 2: pc = "53 bits "; break; - case 3: pc = "64 bits "; break; - }; - // flags - char f[9]; - f[0] = ' '; - f[1] = ' '; - f[2] = (precision ()) ? 'P' : 'p'; - f[3] = (underflow ()) ? 'U' : 'u'; - f[4] = (overflow ()) ? 'O' : 'o'; - f[5] = (zero_divide ()) ? 'Z' : 'z'; - f[6] = (denormalized()) ? 'D' : 'd'; - f[7] = (invalid ()) ? 'I' : 'i'; - f[8] = '\x0'; - // output - printf("%04x masks = %s, %s, %s", _value & 0xFFFF, f, rc, pc); - } - -}; - - -class StatusWord { - public: - int32_t _value; - - bool busy() const { return ((_value >> 15) & 1) != 0; } - bool C3() const { return ((_value >> 14) & 1) != 0; } - bool C2() const { return ((_value >> 10) & 1) != 0; } - bool C1() const { return ((_value >> 9) & 1) != 0; } - bool C0() const { return ((_value >> 8) & 1) != 0; } - int top() const { return (_value >> 11) & 7 ; } - bool error_status() const { return ((_value >> 7) & 1) != 0; } - bool stack_fault() const { return ((_value >> 6) & 1) != 0; } - bool precision() const { return ((_value >> 5) & 1) != 0; } - bool underflow() const { return ((_value >> 4) & 1) != 0; } - bool overflow() const { return ((_value >> 3) & 1) != 0; } - bool zero_divide() const { return ((_value >> 2) & 1) != 0; } - bool denormalized() const { return ((_value >> 1) & 1) != 0; } - bool invalid() const { return ((_value >> 0) & 1) != 0; } - - void print() const { - // condition codes - char c[5]; - c[0] = (C3()) ? '3' : '-'; - c[1] = (C2()) ? '2' : '-'; - c[2] = (C1()) ? '1' : '-'; - c[3] = (C0()) ? '0' : '-'; - c[4] = '\x0'; - // flags - char f[9]; - f[0] = (error_status()) ? 'E' : '-'; - f[1] = (stack_fault ()) ? 'S' : '-'; - f[2] = (precision ()) ? 'P' : '-'; - f[3] = (underflow ()) ? 'U' : '-'; - f[4] = (overflow ()) ? 'O' : '-'; - f[5] = (zero_divide ()) ? 'Z' : '-'; - f[6] = (denormalized()) ? 'D' : '-'; - f[7] = (invalid ()) ? 'I' : '-'; - f[8] = '\x0'; - // output - printf("%04x flags = %s, cc = %s, top = %d", _value & 0xFFFF, f, c, top()); - } - -}; - - -class TagWord { - public: - int32_t _value; - - int tag_at(int i) const { return (_value >> (i*2)) & 3; } - - void print() const { - printf("%04x", _value & 0xFFFF); - } - -}; - - -class FPU_Register { - public: - int32_t _m0; - int32_t _m1; - int16_t _ex; - - bool is_indefinite() const { - return _ex == -1 && _m1 == (int32_t)0xC0000000 && _m0 == 0; - } - - void print() const { - char sign = (_ex < 0) ? '-' : '+'; - const char* kind = (_ex == 0x7FFF || _ex == (int16_t)-1) ? "NaN" : " "; - printf("%c%04hx.%08x%08x %s", sign, _ex, _m1, _m0, kind); - }; - -}; - - -class FPU_State { - public: - enum { - register_size = 10, - number_of_registers = 8, - register_mask = 7 - }; - - ControlWord _control_word; - StatusWord _status_word; - TagWord _tag_word; - int32_t _error_offset; - int32_t _error_selector; - int32_t _data_offset; - int32_t _data_selector; - int8_t _register[register_size * number_of_registers]; - - int tag_for_st(int i) const { return _tag_word.tag_at((_status_word.top() + i) & register_mask); } - FPU_Register* st(int i) const { return (FPU_Register*)&_register[register_size * i]; } - - const char* tag_as_string(int tag) const { - switch (tag) { - case 0: return "valid"; - case 1: return "zero"; - case 2: return "special"; - case 3: return "empty"; - } - ShouldNotReachHere() - return NULL; - } - - void print() const { - // print computation registers - { int t = _status_word.top(); - for (int i = 0; i < number_of_registers; i++) { - int j = (i - t) & register_mask; - printf("%c r%d = ST%d = ", (j == 0 ? '*' : ' '), i, j); - st(j)->print(); - printf(" %s\n", tag_as_string(_tag_word.tag_at(i))); - } - } - printf("\n"); - // print control registers - printf("ctrl = "); _control_word.print(); printf("\n"); - printf("stat = "); _status_word .print(); printf("\n"); - printf("tags = "); _tag_word .print(); printf("\n"); - } - -}; - - -class Flag_Register { - public: - int32_t _value; - - bool overflow() const { return ((_value >> 11) & 1) != 0; } - bool direction() const { return ((_value >> 10) & 1) != 0; } - bool sign() const { return ((_value >> 7) & 1) != 0; } - bool zero() const { return ((_value >> 6) & 1) != 0; } - bool auxiliary_carry() const { return ((_value >> 4) & 1) != 0; } - bool parity() const { return ((_value >> 2) & 1) != 0; } - bool carry() const { return ((_value >> 0) & 1) != 0; } - - void print() const { - // flags - char f[8]; - f[0] = (overflow ()) ? 'O' : '-'; - f[1] = (direction ()) ? 'D' : '-'; - f[2] = (sign ()) ? 'S' : '-'; - f[3] = (zero ()) ? 'Z' : '-'; - f[4] = (auxiliary_carry()) ? 'A' : '-'; - f[5] = (parity ()) ? 'P' : '-'; - f[6] = (carry ()) ? 'C' : '-'; - f[7] = '\x0'; - // output - printf("%08x flags = %s", _value, f); - } - -}; - - -class IU_Register { - public: - int32_t _value; - - void print() const { - printf("%08x %11d", _value, _value); - } - -}; - - -class IU_State { - public: - Flag_Register _eflags; - IU_Register _rdi; - IU_Register _rsi; - IU_Register _rbp; - IU_Register _rsp; - IU_Register _rbx; - IU_Register _rdx; - IU_Register _rcx; - IU_Register _rax; - - void print() const { - // computation registers - printf("rax, = "); _rax.print(); printf("\n"); - printf("rbx, = "); _rbx.print(); printf("\n"); - printf("rcx = "); _rcx.print(); printf("\n"); - printf("rdx = "); _rdx.print(); printf("\n"); - printf("rdi = "); _rdi.print(); printf("\n"); - printf("rsi = "); _rsi.print(); printf("\n"); - printf("rbp, = "); _rbp.print(); printf("\n"); - printf("rsp = "); _rsp.print(); printf("\n"); - printf("\n"); - // control registers - printf("flgs = "); _eflags.print(); printf("\n"); - } -}; - - -class CPU_State { - public: - FPU_State _fpu_state; - IU_State _iu_state; - - void print() const { - printf("--------------------------------------------------\n"); - _iu_state .print(); - printf("\n"); - _fpu_state.print(); - printf("--------------------------------------------------\n"); - } - -}; - - -static void _print_CPU_state(CPU_State* state) { - state->print(); -}; - - -void MacroAssembler::print_CPU_state() { - push_CPU_state(); - pushl(rsp); // pass CPU state - call(RuntimeAddress(CAST_FROM_FN_PTR(address, _print_CPU_state))); - addl(rsp, wordSize); // discard argument - pop_CPU_state(); -} - - -static bool _verify_FPU(int stack_depth, char* s, CPU_State* state) { - static int counter = 0; - FPU_State* fs = &state->_fpu_state; - counter++; - // For leaf calls, only verify that the top few elements remain empty. - // We only need 1 empty at the top for C2 code. - if( stack_depth < 0 ) { - if( fs->tag_for_st(7) != 3 ) { - printf("FPR7 not empty\n"); - state->print(); - assert(false, "error"); - return false; - } - return true; // All other stack states do not matter - } - - assert((fs->_control_word._value & 0xffff) == StubRoutines::_fpu_cntrl_wrd_std, - "bad FPU control word"); - - // compute stack depth - int i = 0; - while (i < FPU_State::number_of_registers && fs->tag_for_st(i) < 3) i++; - int d = i; - while (i < FPU_State::number_of_registers && fs->tag_for_st(i) == 3) i++; - // verify findings - if (i != FPU_State::number_of_registers) { - // stack not contiguous - printf("%s: stack not contiguous at ST%d\n", s, i); - state->print(); - assert(false, "error"); - return false; - } - // check if computed stack depth corresponds to expected stack depth - if (stack_depth < 0) { - // expected stack depth is -stack_depth or less - if (d > -stack_depth) { - // too many elements on the stack - printf("%s: <= %d stack elements expected but found %d\n", s, -stack_depth, d); - state->print(); - assert(false, "error"); - return false; - } - } else { - // expected stack depth is stack_depth - if (d != stack_depth) { - // wrong stack depth - printf("%s: %d stack elements expected but found %d\n", s, stack_depth, d); - state->print(); - assert(false, "error"); - return false; - } - } - // everything is cool - return true; -} - - -void MacroAssembler::verify_FPU(int stack_depth, const char* s) { - if (!VerifyFPU) return; - push_CPU_state(); - pushl(rsp); // pass CPU state - ExternalAddress msg((address) s); - // pass message string s - pushptr(msg.addr()); - pushl(stack_depth); // pass stack depth - call(RuntimeAddress(CAST_FROM_FN_PTR(address, _verify_FPU))); - addl(rsp, 3 * wordSize); // discard arguments - // check for error - { Label L; - testl(rax, rax); - jcc(Assembler::notZero, L); - int3(); // break if error condition - bind(L); - } - pop_CPU_state(); -} - - -void MacroAssembler::push_IU_state() { - pushad(); - pushfd(); -} - - -void MacroAssembler::pop_IU_state() { - popfd(); - popad(); -} - - -void MacroAssembler::push_FPU_state() { - subl(rsp, FPUStateSizeInWords * wordSize); - fnsave(Address(rsp, 0)); - fwait(); -} - - -void MacroAssembler::pop_FPU_state() { - frstor(Address(rsp, 0)); - addl(rsp, FPUStateSizeInWords * wordSize); -} - - -void MacroAssembler::push_CPU_state() { - push_IU_state(); - push_FPU_state(); -} - - -void MacroAssembler::pop_CPU_state() { - pop_FPU_state(); - pop_IU_state(); -} - - -void MacroAssembler::push_callee_saved_registers() { - pushl(rsi); - pushl(rdi); - pushl(rdx); - pushl(rcx); -} - - -void MacroAssembler::pop_callee_saved_registers() { - popl(rcx); - popl(rdx); - popl(rdi); - popl(rsi); -} - - -void MacroAssembler::set_word_if_not_zero(Register dst) { - xorl(dst, dst); - set_byte_if_not_zero(dst); -} - -// Write serialization page so VM thread can do a pseudo remote membar. -// We use the current thread pointer to calculate a thread specific -// offset to write to within the page. This minimizes bus traffic -// due to cache line collision. -void MacroAssembler::serialize_memory(Register thread, Register tmp) { - movl(tmp, thread); - shrl(tmp, os::get_serialize_page_shift_count()); - andl(tmp, (os::vm_page_size() - sizeof(int))); - - Address index(noreg, tmp, Address::times_1); - ExternalAddress page(os::get_memory_serialize_page()); - - movptr(ArrayAddress(page, index), tmp); -} - - -void MacroAssembler::verify_tlab() { -#ifdef ASSERT - if (UseTLAB && VerifyOops) { - Label next, ok; - Register t1 = rsi; - Register thread_reg = rbx; - - pushl(t1); - pushl(thread_reg); - get_thread(thread_reg); - - movl(t1, Address(thread_reg, in_bytes(JavaThread::tlab_top_offset()))); - cmpl(t1, Address(thread_reg, in_bytes(JavaThread::tlab_start_offset()))); - jcc(Assembler::aboveEqual, next); - stop("assert(top >= start)"); - should_not_reach_here(); - - bind(next); - movl(t1, Address(thread_reg, in_bytes(JavaThread::tlab_end_offset()))); - cmpl(t1, Address(thread_reg, in_bytes(JavaThread::tlab_top_offset()))); - jcc(Assembler::aboveEqual, ok); - stop("assert(top <= end)"); - should_not_reach_here(); - - bind(ok); - popl(thread_reg); - popl(t1); - } -#endif -} - - -// Defines obj, preserves var_size_in_bytes -void MacroAssembler::eden_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, - Register t1, Label& slow_case) { - assert(obj == rax, "obj must be in rax, for cmpxchg"); - assert_different_registers(obj, var_size_in_bytes, t1); - Register end = t1; - Label retry; - bind(retry); - ExternalAddress heap_top((address) Universe::heap()->top_addr()); - movptr(obj, heap_top); - if (var_size_in_bytes == noreg) { - leal(end, Address(obj, con_size_in_bytes)); - } else { - leal(end, Address(obj, var_size_in_bytes, Address::times_1)); - } - // if end < obj then we wrapped around => object too long => slow case - cmpl(end, obj); - jcc(Assembler::below, slow_case); - cmpptr(end, ExternalAddress((address) Universe::heap()->end_addr())); - jcc(Assembler::above, slow_case); - // Compare obj with the top addr, and if still equal, store the new top addr in - // end at the address of the top addr pointer. Sets ZF if was equal, and clears - // it otherwise. Use lock prefix for atomicity on MPs. - if (os::is_MP()) { - lock(); - } - cmpxchgptr(end, heap_top); - jcc(Assembler::notEqual, retry); -} - - -// Defines obj, preserves var_size_in_bytes, okay for t2 == var_size_in_bytes. -void MacroAssembler::tlab_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, - Register t1, Register t2, Label& slow_case) { - assert_different_registers(obj, t1, t2); - assert_different_registers(obj, var_size_in_bytes, t1); - Register end = t2; - Register thread = t1; - - verify_tlab(); - - get_thread(thread); - - movl(obj, Address(thread, JavaThread::tlab_top_offset())); - if (var_size_in_bytes == noreg) { - leal(end, Address(obj, con_size_in_bytes)); - } else { - leal(end, Address(obj, var_size_in_bytes, Address::times_1)); - } - cmpl(end, Address(thread, JavaThread::tlab_end_offset())); - jcc(Assembler::above, slow_case); - - // update the tlab top pointer - movl(Address(thread, JavaThread::tlab_top_offset()), end); - - // recover var_size_in_bytes if necessary - if (var_size_in_bytes == end) { - subl(var_size_in_bytes, obj); - } - verify_tlab(); -} - -// Preserves rbx, and rdx. -void MacroAssembler::tlab_refill(Label& retry, Label& try_eden, Label& slow_case) { - Register top = rax; - Register t1 = rcx; - Register t2 = rsi; - Register thread_reg = rdi; - assert_different_registers(top, thread_reg, t1, t2, /* preserve: */ rbx, rdx); - Label do_refill, discard_tlab; - - if (CMSIncrementalMode || !Universe::heap()->supports_inline_contig_alloc()) { - // No allocation in the shared eden. - jmp(slow_case); - } - - get_thread(thread_reg); - - movl(top, Address(thread_reg, in_bytes(JavaThread::tlab_top_offset()))); - movl(t1, Address(thread_reg, in_bytes(JavaThread::tlab_end_offset()))); - - // calculate amount of free space - subl(t1, top); - shrl(t1, LogHeapWordSize); - - // Retain tlab and allocate object in shared space if - // the amount free in the tlab is too large to discard. - cmpl(t1, Address(thread_reg, in_bytes(JavaThread::tlab_refill_waste_limit_offset()))); - jcc(Assembler::lessEqual, discard_tlab); - - // Retain - movl(t2, ThreadLocalAllocBuffer::refill_waste_limit_increment()); - addl(Address(thread_reg, in_bytes(JavaThread::tlab_refill_waste_limit_offset())), t2); - if (TLABStats) { - // increment number of slow_allocations - addl(Address(thread_reg, in_bytes(JavaThread::tlab_slow_allocations_offset())), 1); - } - jmp(try_eden); - - bind(discard_tlab); - if (TLABStats) { - // increment number of refills - addl(Address(thread_reg, in_bytes(JavaThread::tlab_number_of_refills_offset())), 1); - // accumulate wastage -- t1 is amount free in tlab - addl(Address(thread_reg, in_bytes(JavaThread::tlab_fast_refill_waste_offset())), t1); - } - - // if tlab is currently allocated (top or end != null) then - // fill [top, end + alignment_reserve) with array object - testl (top, top); - jcc(Assembler::zero, do_refill); - - // set up the mark word - movl(Address(top, oopDesc::mark_offset_in_bytes()), (int)markOopDesc::prototype()->copy_set_hash(0x2)); - // set the length to the remaining space - subl(t1, typeArrayOopDesc::header_size(T_INT)); - addl(t1, ThreadLocalAllocBuffer::alignment_reserve()); - shll(t1, log2_intptr(HeapWordSize/sizeof(jint))); - movl(Address(top, arrayOopDesc::length_offset_in_bytes()), t1); - // set klass to intArrayKlass - // dubious reloc why not an oop reloc? - movptr(t1, ExternalAddress((address) Universe::intArrayKlassObj_addr())); - movl(Address(top, oopDesc::klass_offset_in_bytes()), t1); - - // refill the tlab with an eden allocation - bind(do_refill); - movl(t1, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset()))); - shll(t1, LogHeapWordSize); - // add object_size ?? - eden_allocate(top, t1, 0, t2, slow_case); - - // Check that t1 was preserved in eden_allocate. -#ifdef ASSERT - if (UseTLAB) { - Label ok; - Register tsize = rsi; - assert_different_registers(tsize, thread_reg, t1); - pushl(tsize); - movl(tsize, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset()))); - shll(tsize, LogHeapWordSize); - cmpl(t1, tsize); - jcc(Assembler::equal, ok); - stop("assert(t1 != tlab size)"); - should_not_reach_here(); - - bind(ok); - popl(tsize); - } -#endif - movl(Address(thread_reg, in_bytes(JavaThread::tlab_start_offset())), top); - movl(Address(thread_reg, in_bytes(JavaThread::tlab_top_offset())), top); - addl(top, t1); - subl(top, ThreadLocalAllocBuffer::alignment_reserve_in_bytes()); - movl(Address(thread_reg, in_bytes(JavaThread::tlab_end_offset())), top); - verify_tlab(); - jmp(retry); -} - - -int MacroAssembler::biased_locking_enter(Register lock_reg, Register obj_reg, Register swap_reg, Register tmp_reg, - bool swap_reg_contains_mark, - Label& done, Label* slow_case, - BiasedLockingCounters* counters) { - assert(UseBiasedLocking, "why call this otherwise?"); - assert(swap_reg == rax, "swap_reg must be rax, for cmpxchg"); - assert_different_registers(lock_reg, obj_reg, swap_reg); - - if (PrintBiasedLockingStatistics && counters == NULL) - counters = BiasedLocking::counters(); - - bool need_tmp_reg = false; - if (tmp_reg == noreg) { - need_tmp_reg = true; - tmp_reg = lock_reg; - } else { - assert_different_registers(lock_reg, obj_reg, swap_reg, tmp_reg); - } - assert(markOopDesc::age_shift == markOopDesc::lock_bits + markOopDesc::biased_lock_bits, "biased locking makes assumptions about bit layout"); - Address mark_addr (obj_reg, oopDesc::mark_offset_in_bytes()); - Address klass_addr (obj_reg, oopDesc::klass_offset_in_bytes()); - Address saved_mark_addr(lock_reg, 0); - - // Biased locking - // See whether the lock is currently biased toward our thread and - // whether the epoch is still valid - // Note that the runtime guarantees sufficient alignment of JavaThread - // pointers to allow age to be placed into low bits - // First check to see whether biasing is even enabled for this object - Label cas_label; - int null_check_offset = -1; - if (!swap_reg_contains_mark) { - null_check_offset = offset(); - movl(swap_reg, mark_addr); - } - if (need_tmp_reg) { - pushl(tmp_reg); - } - movl(tmp_reg, swap_reg); - andl(tmp_reg, markOopDesc::biased_lock_mask_in_place); - cmpl(tmp_reg, markOopDesc::biased_lock_pattern); - if (need_tmp_reg) { - popl(tmp_reg); - } - jcc(Assembler::notEqual, cas_label); - // The bias pattern is present in the object's header. Need to check - // whether the bias owner and the epoch are both still current. - // Note that because there is no current thread register on x86 we - // need to store off the mark word we read out of the object to - // avoid reloading it and needing to recheck invariants below. This - // store is unfortunate but it makes the overall code shorter and - // simpler. - movl(saved_mark_addr, swap_reg); - if (need_tmp_reg) { - pushl(tmp_reg); - } - get_thread(tmp_reg); - xorl(swap_reg, tmp_reg); - if (swap_reg_contains_mark) { - null_check_offset = offset(); - } - movl(tmp_reg, klass_addr); - xorl(swap_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); - andl(swap_reg, ~((int) markOopDesc::age_mask_in_place)); - if (need_tmp_reg) { - popl(tmp_reg); - } - if (counters != NULL) { - cond_inc32(Assembler::zero, - ExternalAddress((address)counters->biased_lock_entry_count_addr())); - } - jcc(Assembler::equal, done); - - Label try_revoke_bias; - Label try_rebias; - - // At this point we know that the header has the bias pattern and - // that we are not the bias owner in the current epoch. We need to - // figure out more details about the state of the header in order to - // know what operations can be legally performed on the object's - // header. - - // If the low three bits in the xor result aren't clear, that means - // the prototype header is no longer biased and we have to revoke - // the bias on this object. - testl(swap_reg, markOopDesc::biased_lock_mask_in_place); - jcc(Assembler::notZero, try_revoke_bias); - - // Biasing is still enabled for this data type. See whether the - // epoch of the current bias is still valid, meaning that the epoch - // bits of the mark word are equal to the epoch bits of the - // prototype header. (Note that the prototype header's epoch bits - // only change at a safepoint.) If not, attempt to rebias the object - // toward the current thread. Note that we must be absolutely sure - // that the current epoch is invalid in order to do this because - // otherwise the manipulations it performs on the mark word are - // illegal. - testl(swap_reg, markOopDesc::epoch_mask_in_place); - jcc(Assembler::notZero, try_rebias); - - // The epoch of the current bias is still valid but we know nothing - // about the owner; it might be set or it might be clear. Try to - // acquire the bias of the object using an atomic operation. If this - // fails we will go in to the runtime to revoke the object's bias. - // Note that we first construct the presumed unbiased header so we - // don't accidentally blow away another thread's valid bias. - movl(swap_reg, saved_mark_addr); - andl(swap_reg, - markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place); - if (need_tmp_reg) { - pushl(tmp_reg); - } - get_thread(tmp_reg); - orl(tmp_reg, swap_reg); - if (os::is_MP()) { - lock(); - } - cmpxchg(tmp_reg, Address(obj_reg, 0)); - if (need_tmp_reg) { - popl(tmp_reg); - } - // If the biasing toward our thread failed, this means that - // another thread succeeded in biasing it toward itself and we - // need to revoke that bias. The revocation will occur in the - // interpreter runtime in the slow case. - if (counters != NULL) { - cond_inc32(Assembler::zero, - ExternalAddress((address)counters->anonymously_biased_lock_entry_count_addr())); - } - if (slow_case != NULL) { - jcc(Assembler::notZero, *slow_case); - } - jmp(done); - - bind(try_rebias); - // At this point we know the epoch has expired, meaning that the - // current "bias owner", if any, is actually invalid. Under these - // circumstances _only_, we are allowed to use the current header's - // value as the comparison value when doing the cas to acquire the - // bias in the current epoch. In other words, we allow transfer of - // the bias from one thread to another directly in this situation. - // - // FIXME: due to a lack of registers we currently blow away the age - // bits in this situation. Should attempt to preserve them. - if (need_tmp_reg) { - pushl(tmp_reg); - } - get_thread(tmp_reg); - movl(swap_reg, klass_addr); - orl(tmp_reg, Address(swap_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); - movl(swap_reg, saved_mark_addr); - if (os::is_MP()) { - lock(); - } - cmpxchg(tmp_reg, Address(obj_reg, 0)); - if (need_tmp_reg) { - popl(tmp_reg); - } - // If the biasing toward our thread failed, then another thread - // succeeded in biasing it toward itself and we need to revoke that - // bias. The revocation will occur in the runtime in the slow case. - if (counters != NULL) { - cond_inc32(Assembler::zero, - ExternalAddress((address)counters->rebiased_lock_entry_count_addr())); - } - if (slow_case != NULL) { - jcc(Assembler::notZero, *slow_case); - } - jmp(done); - - bind(try_revoke_bias); - // The prototype mark in the klass doesn't have the bias bit set any - // more, indicating that objects of this data type are not supposed - // to be biased any more. We are going to try to reset the mark of - // this object to the prototype value and fall through to the - // CAS-based locking scheme. Note that if our CAS fails, it means - // that another thread raced us for the privilege of revoking the - // bias of this particular object, so it's okay to continue in the - // normal locking code. - // - // FIXME: due to a lack of registers we currently blow away the age - // bits in this situation. Should attempt to preserve them. - movl(swap_reg, saved_mark_addr); - if (need_tmp_reg) { - pushl(tmp_reg); - } - movl(tmp_reg, klass_addr); - movl(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); - if (os::is_MP()) { - lock(); - } - cmpxchg(tmp_reg, Address(obj_reg, 0)); - if (need_tmp_reg) { - popl(tmp_reg); - } - // Fall through to the normal CAS-based lock, because no matter what - // the result of the above CAS, some thread must have succeeded in - // removing the bias bit from the object's header. - if (counters != NULL) { - cond_inc32(Assembler::zero, - ExternalAddress((address)counters->revoked_lock_entry_count_addr())); - } - - bind(cas_label); - - return null_check_offset; -} - - -void MacroAssembler::biased_locking_exit(Register obj_reg, Register temp_reg, Label& done) { - assert(UseBiasedLocking, "why call this otherwise?"); - - // Check for biased locking unlock case, which is a no-op - // Note: we do not have to check the thread ID for two reasons. - // First, the interpreter checks for IllegalMonitorStateException at - // a higher level. Second, if the bias was revoked while we held the - // lock, the object could not be rebiased toward another thread, so - // the bias bit would be clear. - movl(temp_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); - andl(temp_reg, markOopDesc::biased_lock_mask_in_place); - cmpl(temp_reg, markOopDesc::biased_lock_pattern); - jcc(Assembler::equal, done); -} - - -Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) { - switch (cond) { - // Note some conditions are synonyms for others - case Assembler::zero: return Assembler::notZero; - case Assembler::notZero: return Assembler::zero; - case Assembler::less: return Assembler::greaterEqual; - case Assembler::lessEqual: return Assembler::greater; - case Assembler::greater: return Assembler::lessEqual; - case Assembler::greaterEqual: return Assembler::less; - case Assembler::below: return Assembler::aboveEqual; - case Assembler::belowEqual: return Assembler::above; - case Assembler::above: return Assembler::belowEqual; - case Assembler::aboveEqual: return Assembler::below; - case Assembler::overflow: return Assembler::noOverflow; - case Assembler::noOverflow: return Assembler::overflow; - case Assembler::negative: return Assembler::positive; - case Assembler::positive: return Assembler::negative; - case Assembler::parity: return Assembler::noParity; - case Assembler::noParity: return Assembler::parity; - } - ShouldNotReachHere(); return Assembler::overflow; -} - - -void MacroAssembler::cond_inc32(Condition cond, AddressLiteral counter_addr) { - Condition negated_cond = negate_condition(cond); - Label L; - jcc(negated_cond, L); - atomic_incl(counter_addr); - bind(L); -} - -void MacroAssembler::atomic_incl(AddressLiteral counter_addr) { - pushfd(); - if (os::is_MP()) - lock(); - increment(counter_addr); - popfd(); -} - -SkipIfEqual::SkipIfEqual( - MacroAssembler* masm, const bool* flag_addr, bool value) { - _masm = masm; - _masm->cmp8(ExternalAddress((address)flag_addr), value); - _masm->jcc(Assembler::equal, _label); -} - -SkipIfEqual::~SkipIfEqual() { - _masm->bind(_label); -} - - -// Writes to stack successive pages until offset reached to check for -// stack overflow + shadow pages. This clobbers tmp. -void MacroAssembler::bang_stack_size(Register size, Register tmp) { - movl(tmp, rsp); - // Bang stack for total size given plus shadow page size. - // Bang one page at a time because large size can bang beyond yellow and - // red zones. - Label loop; - bind(loop); - movl(Address(tmp, (-os::vm_page_size())), size ); - subl(tmp, os::vm_page_size()); - subl(size, os::vm_page_size()); - jcc(Assembler::greater, loop); - - // Bang down shadow pages too. - // The -1 because we already subtracted 1 page. - for (int i = 0; i< StackShadowPages-1; i++) { - movl(Address(tmp, (-i*os::vm_page_size())), size ); - } -} diff --git a/hotspot/src/cpu/x86/vm/assembler_x86_32.inline.hpp b/hotspot/src/cpu/x86/vm/assembler_x86_32.inline.hpp deleted file mode 100644 index 8e20a2e0620..00000000000 --- a/hotspot/src/cpu/x86/vm/assembler_x86_32.inline.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -inline void MacroAssembler::pd_patch_instruction(address branch, address target) { - unsigned char op = branch[0]; - assert(op == 0xE8 /* call */ || - op == 0xE9 /* jmp */ || - op == 0xEB /* short jmp */ || - (op & 0xF0) == 0x70 /* short jcc */ || - op == 0x0F && (branch[1] & 0xF0) == 0x80 /* jcc */, - "Invalid opcode at patch point"); - - if (op == 0xEB || (op & 0xF0) == 0x70) { - // short offset operators (jmp and jcc) - char* disp = (char*) &branch[1]; - int imm8 = target - (address) &disp[1]; - guarantee(this->is8bit(imm8), "Short forward jump exceeds 8-bit offset"); - *disp = imm8; - } else { - int* disp = (int*) &branch[(op == 0x0F)? 2: 1]; - int imm32 = target - (address) &disp[1]; - *disp = imm32; - } -} - -#ifndef PRODUCT -inline void MacroAssembler::pd_print_patched_instruction(address branch) { - const char* s; - unsigned char op = branch[0]; - if (op == 0xE8) { - s = "call"; - } else if (op == 0xE9 || op == 0xEB) { - s = "jmp"; - } else if ((op & 0xF0) == 0x70) { - s = "jcc"; - } else if (op == 0x0F) { - s = "jcc"; - } else { - s = "????"; - } - tty->print("%s (unresolved)", s); -} -#endif // ndef PRODUCT diff --git a/hotspot/src/cpu/x86/vm/assembler_x86_64.hpp b/hotspot/src/cpu/x86/vm/assembler_x86_64.hpp deleted file mode 100644 index bf509e02b22..00000000000 --- a/hotspot/src/cpu/x86/vm/assembler_x86_64.hpp +++ /dev/null @@ -1,1477 +0,0 @@ -/* - * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -class BiasedLockingCounters; - -// Contains all the definitions needed for amd64 assembly code generation. - -#ifdef _LP64 -// Calling convention -class Argument VALUE_OBJ_CLASS_SPEC { - public: - enum { -#ifdef _WIN64 - n_int_register_parameters_c = 4, // rcx, rdx, r8, r9 (c_rarg0, c_rarg1, ...) - n_float_register_parameters_c = 4, // xmm0 - xmm3 (c_farg0, c_farg1, ... ) -#else - n_int_register_parameters_c = 6, // rdi, rsi, rdx, rcx, r8, r9 (c_rarg0, c_rarg1, ...) - n_float_register_parameters_c = 8, // xmm0 - xmm7 (c_farg0, c_farg1, ... ) -#endif // _WIN64 - n_int_register_parameters_j = 6, // j_rarg0, j_rarg1, ... - n_float_register_parameters_j = 8 // j_farg0, j_farg1, ... - }; -}; - - -// Symbolically name the register arguments used by the c calling convention. -// Windows is different from linux/solaris. So much for standards... - -#ifdef _WIN64 - -REGISTER_DECLARATION(Register, c_rarg0, rcx); -REGISTER_DECLARATION(Register, c_rarg1, rdx); -REGISTER_DECLARATION(Register, c_rarg2, r8); -REGISTER_DECLARATION(Register, c_rarg3, r9); - -REGISTER_DECLARATION(XMMRegister, c_farg0, xmm0); -REGISTER_DECLARATION(XMMRegister, c_farg1, xmm1); -REGISTER_DECLARATION(XMMRegister, c_farg2, xmm2); -REGISTER_DECLARATION(XMMRegister, c_farg3, xmm3); - -#else - -REGISTER_DECLARATION(Register, c_rarg0, rdi); -REGISTER_DECLARATION(Register, c_rarg1, rsi); -REGISTER_DECLARATION(Register, c_rarg2, rdx); -REGISTER_DECLARATION(Register, c_rarg3, rcx); -REGISTER_DECLARATION(Register, c_rarg4, r8); -REGISTER_DECLARATION(Register, c_rarg5, r9); - -REGISTER_DECLARATION(XMMRegister, c_farg0, xmm0); -REGISTER_DECLARATION(XMMRegister, c_farg1, xmm1); -REGISTER_DECLARATION(XMMRegister, c_farg2, xmm2); -REGISTER_DECLARATION(XMMRegister, c_farg3, xmm3); -REGISTER_DECLARATION(XMMRegister, c_farg4, xmm4); -REGISTER_DECLARATION(XMMRegister, c_farg5, xmm5); -REGISTER_DECLARATION(XMMRegister, c_farg6, xmm6); -REGISTER_DECLARATION(XMMRegister, c_farg7, xmm7); - -#endif // _WIN64 - -// Symbolically name the register arguments used by the Java calling convention. -// We have control over the convention for java so we can do what we please. -// What pleases us is to offset the java calling convention so that when -// we call a suitable jni method the arguments are lined up and we don't -// have to do little shuffling. A suitable jni method is non-static and a -// small number of arguments (two fewer args on windows) -// -// |-------------------------------------------------------| -// | c_rarg0 c_rarg1 c_rarg2 c_rarg3 c_rarg4 c_rarg5 | -// |-------------------------------------------------------| -// | rcx rdx r8 r9 rdi* rsi* | windows (* not a c_rarg) -// | rdi rsi rdx rcx r8 r9 | solaris/linux -// |-------------------------------------------------------| -// | j_rarg5 j_rarg0 j_rarg1 j_rarg2 j_rarg3 j_rarg4 | -// |-------------------------------------------------------| - -REGISTER_DECLARATION(Register, j_rarg0, c_rarg1); -REGISTER_DECLARATION(Register, j_rarg1, c_rarg2); -REGISTER_DECLARATION(Register, j_rarg2, c_rarg3); -// Windows runs out of register args here -#ifdef _WIN64 -REGISTER_DECLARATION(Register, j_rarg3, rdi); -REGISTER_DECLARATION(Register, j_rarg4, rsi); -#else -REGISTER_DECLARATION(Register, j_rarg3, c_rarg4); -REGISTER_DECLARATION(Register, j_rarg4, c_rarg5); -#endif // _WIN64 -REGISTER_DECLARATION(Register, j_rarg5, c_rarg0); - -REGISTER_DECLARATION(XMMRegister, j_farg0, xmm0); -REGISTER_DECLARATION(XMMRegister, j_farg1, xmm1); -REGISTER_DECLARATION(XMMRegister, j_farg2, xmm2); -REGISTER_DECLARATION(XMMRegister, j_farg3, xmm3); -REGISTER_DECLARATION(XMMRegister, j_farg4, xmm4); -REGISTER_DECLARATION(XMMRegister, j_farg5, xmm5); -REGISTER_DECLARATION(XMMRegister, j_farg6, xmm6); -REGISTER_DECLARATION(XMMRegister, j_farg7, xmm7); - -REGISTER_DECLARATION(Register, rscratch1, r10); // volatile -REGISTER_DECLARATION(Register, rscratch2, r11); // volatile - -REGISTER_DECLARATION(Register, r12_heapbase, r12); // callee-saved -REGISTER_DECLARATION(Register, r15_thread, r15); // callee-saved - -#endif // _LP64 - -// Address is an abstraction used to represent a memory location -// using any of the amd64 addressing modes with one object. -// -// Note: A register location is represented via a Register, not -// via an address for efficiency & simplicity reasons. - -class ArrayAddress; - -class Address VALUE_OBJ_CLASS_SPEC { - public: - enum ScaleFactor { - no_scale = -1, - times_1 = 0, - times_2 = 1, - times_4 = 2, - times_8 = 3 - }; - - private: - Register _base; - Register _index; - ScaleFactor _scale; - int _disp; - RelocationHolder _rspec; - - // Easily misused constructors make them private - Address(int disp, address loc, relocInfo::relocType rtype); - Address(int disp, address loc, RelocationHolder spec); - - public: - // creation - Address() - : _base(noreg), - _index(noreg), - _scale(no_scale), - _disp(0) { - } - - // No default displacement otherwise Register can be implicitly - // converted to 0(Register) which is quite a different animal. - - Address(Register base, int disp) - : _base(base), - _index(noreg), - _scale(no_scale), - _disp(disp) { - } - - Address(Register base, Register index, ScaleFactor scale, int disp = 0) - : _base (base), - _index(index), - _scale(scale), - _disp (disp) { - assert(!index->is_valid() == (scale == Address::no_scale), - "inconsistent address"); - } - - // The following two overloads are used in connection with the - // ByteSize type (see sizes.hpp). They simplify the use of - // ByteSize'd arguments in assembly code. Note that their equivalent - // for the optimized build are the member functions with int disp - // argument since ByteSize is mapped to an int type in that case. - // - // Note: DO NOT introduce similar overloaded functions for WordSize - // arguments as in the optimized mode, both ByteSize and WordSize - // are mapped to the same type and thus the compiler cannot make a - // distinction anymore (=> compiler errors). - -#ifdef ASSERT - Address(Register base, ByteSize disp) - : _base(base), - _index(noreg), - _scale(no_scale), - _disp(in_bytes(disp)) { - } - - Address(Register base, Register index, ScaleFactor scale, ByteSize disp) - : _base(base), - _index(index), - _scale(scale), - _disp(in_bytes(disp)) { - assert(!index->is_valid() == (scale == Address::no_scale), - "inconsistent address"); - } -#endif // ASSERT - - // accessors - bool uses(Register reg) const { - return _base == reg || _index == reg; - } - - // Convert the raw encoding form into the form expected by the constructor for - // Address. An index of 4 (rsp) corresponds to having no index, so convert - // that to noreg for the Address constructor. - static Address make_raw(int base, int index, int scale, int disp); - - static Address make_array(ArrayAddress); - - private: - bool base_needs_rex() const { - return _base != noreg && _base->encoding() >= 8; - } - - bool index_needs_rex() const { - return _index != noreg &&_index->encoding() >= 8; - } - - relocInfo::relocType reloc() const { return _rspec.type(); } - - friend class Assembler; - friend class MacroAssembler; - friend class LIR_Assembler; // base/index/scale/disp -}; - -// -// AddressLiteral has been split out from Address because operands of this type -// need to be treated specially on 32bit vs. 64bit platforms. By splitting it out -// the few instructions that need to deal with address literals are unique and the -// MacroAssembler does not have to implement every instruction in the Assembler -// in order to search for address literals that may need special handling depending -// on the instruction and the platform. As small step on the way to merging i486/amd64 -// directories. -// -class AddressLiteral VALUE_OBJ_CLASS_SPEC { - friend class ArrayAddress; - RelocationHolder _rspec; - // Typically we use AddressLiterals we want to use their rval - // However in some situations we want the lval (effect address) of the item. - // We provide a special factory for making those lvals. - bool _is_lval; - - // If the target is far we'll need to load the ea of this to - // a register to reach it. Otherwise if near we can do rip - // relative addressing. - - address _target; - - protected: - // creation - AddressLiteral() - : _is_lval(false), - _target(NULL) - {} - - public: - - - AddressLiteral(address target, relocInfo::relocType rtype); - - AddressLiteral(address target, RelocationHolder const& rspec) - : _rspec(rspec), - _is_lval(false), - _target(target) - {} - - AddressLiteral addr() { - AddressLiteral ret = *this; - ret._is_lval = true; - return ret; - } - - - private: - - address target() { return _target; } - bool is_lval() { return _is_lval; } - - relocInfo::relocType reloc() const { return _rspec.type(); } - const RelocationHolder& rspec() const { return _rspec; } - - friend class Assembler; - friend class MacroAssembler; - friend class Address; - friend class LIR_Assembler; -}; - -// Convience classes -class RuntimeAddress: public AddressLiteral { - - public: - - RuntimeAddress(address target) : AddressLiteral(target, relocInfo::runtime_call_type) {} - -}; - -class OopAddress: public AddressLiteral { - - public: - - OopAddress(address target) : AddressLiteral(target, relocInfo::oop_type){} - -}; - -class ExternalAddress: public AddressLiteral { - - public: - - ExternalAddress(address target) : AddressLiteral(target, relocInfo::external_word_type){} - -}; - -class InternalAddress: public AddressLiteral { - - public: - - InternalAddress(address target) : AddressLiteral(target, relocInfo::internal_word_type) {} - -}; - -// x86 can do array addressing as a single operation since disp can be an absolute -// address but amd64 can't [e.g. array_base(rx, ry:width) ]. We create a class -// that expresses the concept but does extra magic on amd64 to get the final result - -class ArrayAddress VALUE_OBJ_CLASS_SPEC { - private: - - AddressLiteral _base; - Address _index; - - public: - - ArrayAddress() {}; - ArrayAddress(AddressLiteral base, Address index): _base(base), _index(index) {}; - AddressLiteral base() { return _base; } - Address index() { return _index; } - -}; - -// The amd64 Assembler: Pure assembler doing NO optimizations on -// the instruction level (e.g. mov rax, 0 is not translated into xor -// rax, rax!); i.e., what you write is what you get. The Assembler is -// generating code into a CodeBuffer. - -const int FPUStateSizeInWords = 512 / wordSize; - -class Assembler : public AbstractAssembler { - friend class AbstractAssembler; // for the non-virtual hack - friend class StubGenerator; - - - protected: -#ifdef ASSERT - void check_relocation(RelocationHolder const& rspec, int format); -#endif - - inline void emit_long64(jlong x); - - void emit_data(jint data, relocInfo::relocType rtype, int format /* = 1 */); - void emit_data(jint data, RelocationHolder const& rspec, int format /* = 1 */); - void emit_data64(jlong data, relocInfo::relocType rtype, int format = 0); - void emit_data64(jlong data, RelocationHolder const& rspec, int format = 0); - - // Helper functions for groups of instructions - void emit_arith_b(int op1, int op2, Register dst, int imm8); - - void emit_arith(int op1, int op2, Register dst, int imm32); - // only x86?? - void emit_arith(int op1, int op2, Register dst, jobject obj); - void emit_arith(int op1, int op2, Register dst, Register src); - - void emit_operand(Register reg, - Register base, Register index, Address::ScaleFactor scale, - int disp, - RelocationHolder const& rspec, - int rip_relative_correction = 0); - void emit_operand(Register reg, Address adr, - int rip_relative_correction = 0); - void emit_operand(XMMRegister reg, - Register base, Register index, Address::ScaleFactor scale, - int disp, - RelocationHolder const& rspec, - int rip_relative_correction = 0); - void emit_operand(XMMRegister reg, Address adr, - int rip_relative_correction = 0); - - // Immediate-to-memory forms - void emit_arith_operand(int op1, Register rm, Address adr, int imm32); - - void emit_farith(int b1, int b2, int i); - - bool reachable(AddressLiteral adr); - - // These are all easily abused and hence protected - - // Make these disappear in 64bit mode since they would never be correct -#ifndef _LP64 - void cmp_literal32(Register src1, int32_t imm32, RelocationHolder const& rspec); - void cmp_literal32(Address src1, int32_t imm32, RelocationHolder const& rspec); - - void mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec); - void mov_literal32(Address dst, int32_t imm32, RelocationHolder const& rspec); - - void push_literal32(int32_t imm32, RelocationHolder const& rspec); -#endif // _LP64 - - - void mov_literal64(Register dst, intptr_t imm64, RelocationHolder const& rspec); - - // These are unique in that we are ensured by the caller that the 32bit - // relative in these instructions will always be able to reach the potentially - // 64bit address described by entry. Since they can take a 64bit address they - // don't have the 32 suffix like the other instructions in this class. - void jmp_literal(address entry, RelocationHolder const& rspec); - void call_literal(address entry, RelocationHolder const& rspec); - - public: - enum Condition { // The amd64 condition codes used for conditional jumps/moves. - zero = 0x4, - notZero = 0x5, - equal = 0x4, - notEqual = 0x5, - less = 0xc, - lessEqual = 0xe, - greater = 0xf, - greaterEqual = 0xd, - below = 0x2, - belowEqual = 0x6, - above = 0x7, - aboveEqual = 0x3, - overflow = 0x0, - noOverflow = 0x1, - carrySet = 0x2, - carryClear = 0x3, - negative = 0x8, - positive = 0x9, - parity = 0xa, - noParity = 0xb - }; - - enum Prefix { - // segment overrides - // XXX remove segment prefixes - CS_segment = 0x2e, - SS_segment = 0x36, - DS_segment = 0x3e, - ES_segment = 0x26, - FS_segment = 0x64, - GS_segment = 0x65, - - REX = 0x40, - - REX_B = 0x41, - REX_X = 0x42, - REX_XB = 0x43, - REX_R = 0x44, - REX_RB = 0x45, - REX_RX = 0x46, - REX_RXB = 0x47, - - REX_W = 0x48, - - REX_WB = 0x49, - REX_WX = 0x4A, - REX_WXB = 0x4B, - REX_WR = 0x4C, - REX_WRB = 0x4D, - REX_WRX = 0x4E, - REX_WRXB = 0x4F - }; - - enum WhichOperand { - // input to locate_operand, and format code for relocations - imm64_operand = 0, // embedded 64-bit immediate operand - disp32_operand = 1, // embedded 32-bit displacement - call32_operand = 2, // embedded 32-bit self-relative displacement -#ifndef AMD64 - _WhichOperand_limit = 3 -#else - narrow_oop_operand = 3, // embedded 32-bit immediate narrow oop - _WhichOperand_limit = 4 -#endif - }; - - public: - - // Creation - Assembler(CodeBuffer* code) - : AbstractAssembler(code) { - } - - // Decoding - static address locate_operand(address inst, WhichOperand which); - static address locate_next_instruction(address inst); - - // Utilities - - static bool is_simm(int64_t x, int nbits) { return -( CONST64(1) << (nbits-1) ) <= x && x < ( CONST64(1) << (nbits-1) ); } - static bool is_simm32 (int64_t x) { return x == (int64_t)(int32_t)x; } - - - // Stack - void pushaq(); - void popaq(); - - void pushfq(); - void popfq(); - - void pushq(int imm32); - - void pushq(Register src); - void pushq(Address src); - - void popq(Register dst); - void popq(Address dst); - - // Instruction prefixes - void prefix(Prefix p); - - int prefix_and_encode(int reg_enc, bool byteinst = false); - int prefixq_and_encode(int reg_enc); - - int prefix_and_encode(int dst_enc, int src_enc, bool byteinst = false); - int prefixq_and_encode(int dst_enc, int src_enc); - - void prefix(Register reg); - void prefix(Address adr); - void prefixq(Address adr); - - void prefix(Address adr, Register reg, bool byteinst = false); - void prefixq(Address adr, Register reg); - - void prefix(Address adr, XMMRegister reg); - - // Moves - void movb(Register dst, Address src); - void movb(Address dst, int imm8); - void movb(Address dst, Register src); - - void movw(Address dst, int imm16); - void movw(Register dst, Address src); - void movw(Address dst, Register src); - - void movl(Register dst, int imm32); - void movl(Register dst, Register src); - void movl(Register dst, Address src); - void movl(Address dst, int imm32); - void movl(Address dst, Register src); - - void movq(Register dst, Register src); - void movq(Register dst, Address src); - void movq(Address dst, Register src); - // These prevent using movq from converting a zero (like NULL) into Register - // by giving the compiler two choices it can't resolve - void movq(Address dst, void* dummy); - void movq(Register dst, void* dummy); - - void mov64(Register dst, intptr_t imm64); - void mov64(Address dst, intptr_t imm64); - - void movsbl(Register dst, Address src); - void movsbl(Register dst, Register src); - void movswl(Register dst, Address src); - void movswl(Register dst, Register src); - void movslq(Register dst, Address src); - void movslq(Register dst, Register src); - - void movzbl(Register dst, Address src); - void movzbl(Register dst, Register src); - void movzwl(Register dst, Address src); - void movzwl(Register dst, Register src); - - protected: // Avoid using the next instructions directly. - // New cpus require use of movsd and movss to avoid partial register stall - // when loading from memory. But for old Opteron use movlpd instead of movsd. - // The selection is done in MacroAssembler::movdbl() and movflt(). - void movss(XMMRegister dst, XMMRegister src); - void movss(XMMRegister dst, Address src); - void movss(Address dst, XMMRegister src); - void movsd(XMMRegister dst, XMMRegister src); - void movsd(Address dst, XMMRegister src); - void movsd(XMMRegister dst, Address src); - void movlpd(XMMRegister dst, Address src); - // New cpus require use of movaps and movapd to avoid partial register stall - // when moving between registers. - void movapd(XMMRegister dst, XMMRegister src); - void movaps(XMMRegister dst, XMMRegister src); - public: - - void movdl(XMMRegister dst, Register src); - void movdl(Register dst, XMMRegister src); - void movdq(XMMRegister dst, Register src); - void movdq(Register dst, XMMRegister src); - - void cmovl(Condition cc, Register dst, Register src); - void cmovl(Condition cc, Register dst, Address src); - void cmovq(Condition cc, Register dst, Register src); - void cmovq(Condition cc, Register dst, Address src); - - // Prefetches - private: - void prefetch_prefix(Address src); - public: - void prefetcht0(Address src); - void prefetcht1(Address src); - void prefetcht2(Address src); - void prefetchnta(Address src); - void prefetchw(Address src); - - // Arithmetics - void adcl(Register dst, int imm32); - void adcl(Register dst, Address src); - void adcl(Register dst, Register src); - void adcq(Register dst, int imm32); - void adcq(Register dst, Address src); - void adcq(Register dst, Register src); - - void addl(Address dst, int imm32); - void addl(Address dst, Register src); - void addl(Register dst, int imm32); - void addl(Register dst, Address src); - void addl(Register dst, Register src); - void addq(Address dst, int imm32); - void addq(Address dst, Register src); - void addq(Register dst, int imm32); - void addq(Register dst, Address src); - void addq(Register dst, Register src); - - void andl(Register dst, int imm32); - void andl(Register dst, Address src); - void andl(Register dst, Register src); - void andq(Register dst, int imm32); - void andq(Register dst, Address src); - void andq(Register dst, Register src); - - void cmpb(Address dst, int imm8); - void cmpl(Address dst, int imm32); - void cmpl(Register dst, int imm32); - void cmpl(Register dst, Register src); - void cmpl(Register dst, Address src); - void cmpq(Address dst, int imm32); - void cmpq(Address dst, Register src); - void cmpq(Register dst, int imm32); - void cmpq(Register dst, Register src); - void cmpq(Register dst, Address src); - - void ucomiss(XMMRegister dst, XMMRegister src); - void ucomisd(XMMRegister dst, XMMRegister src); - - protected: - // Don't use next inc() and dec() methods directly. INC & DEC instructions - // could cause a partial flag stall since they don't set CF flag. - // Use MacroAssembler::decrement() & MacroAssembler::increment() methods - // which call inc() & dec() or add() & sub() in accordance with - // the product flag UseIncDec value. - - void decl(Register dst); - void decl(Address dst); - void decq(Register dst); - void decq(Address dst); - - void incl(Register dst); - void incl(Address dst); - void incq(Register dst); - void incq(Address dst); - - public: - void idivl(Register src); - void idivq(Register src); - void cdql(); - void cdqq(); - - void imull(Register dst, Register src); - void imull(Register dst, Register src, int value); - void imulq(Register dst, Register src); - void imulq(Register dst, Register src, int value); - - void leal(Register dst, Address src); - void leaq(Register dst, Address src); - - void mull(Address src); - void mull(Register src); - - void negl(Register dst); - void negq(Register dst); - - void notl(Register dst); - void notq(Register dst); - - void orl(Address dst, int imm32); - void orl(Register dst, int imm32); - void orl(Register dst, Address src); - void orl(Register dst, Register src); - void orq(Address dst, int imm32); - void orq(Register dst, int imm32); - void orq(Register dst, Address src); - void orq(Register dst, Register src); - - void rcll(Register dst, int imm8); - void rclq(Register dst, int imm8); - - void sarl(Register dst, int imm8); - void sarl(Register dst); - void sarq(Register dst, int imm8); - void sarq(Register dst); - - void sbbl(Address dst, int imm32); - void sbbl(Register dst, int imm32); - void sbbl(Register dst, Address src); - void sbbl(Register dst, Register src); - void sbbq(Address dst, int imm32); - void sbbq(Register dst, int imm32); - void sbbq(Register dst, Address src); - void sbbq(Register dst, Register src); - - void shll(Register dst, int imm8); - void shll(Register dst); - void shlq(Register dst, int imm8); - void shlq(Register dst); - - void shrl(Register dst, int imm8); - void shrl(Register dst); - void shrq(Register dst, int imm8); - void shrq(Register dst); - - void subl(Address dst, int imm32); - void subl(Address dst, Register src); - void subl(Register dst, int imm32); - void subl(Register dst, Address src); - void subl(Register dst, Register src); - void subq(Address dst, int imm32); - void subq(Address dst, Register src); - void subq(Register dst, int imm32); - void subq(Register dst, Address src); - void subq(Register dst, Register src); - - void testb(Register dst, int imm8); - void testl(Register dst, int imm32); - void testl(Register dst, Register src); - void testq(Register dst, int imm32); - void testq(Register dst, Register src); - - void xaddl(Address dst, Register src); - void xaddq(Address dst, Register src); - - void xorl(Register dst, int imm32); - void xorl(Register dst, Address src); - void xorl(Register dst, Register src); - void xorq(Register dst, int imm32); - void xorq(Register dst, Address src); - void xorq(Register dst, Register src); - - // Miscellaneous - void bswapl(Register reg); - void bswapq(Register reg); - void lock(); - - void xchgl(Register reg, Address adr); - void xchgl(Register dst, Register src); - void xchgq(Register reg, Address adr); - void xchgq(Register dst, Register src); - - void cmpxchgl(Register reg, Address adr); - void cmpxchgq(Register reg, Address adr); - - void nop(int i = 1); - void addr_nop_4(); - void addr_nop_5(); - void addr_nop_7(); - void addr_nop_8(); - - void hlt(); - void ret(int imm16); - void smovl(); - void rep_movl(); - void rep_movq(); - void rep_set(); - void repne_scanl(); - void repne_scanq(); - void setb(Condition cc, Register dst); - - void clflush(Address adr); - - enum Membar_mask_bits { - StoreStore = 1 << 3, - LoadStore = 1 << 2, - StoreLoad = 1 << 1, - LoadLoad = 1 << 0 - }; - - // Serializes memory. - void membar(Membar_mask_bits order_constraint) { - // We only have to handle StoreLoad and LoadLoad - if (order_constraint & StoreLoad) { - // MFENCE subsumes LFENCE - mfence(); - } /* [jk] not needed currently: else if (order_constraint & LoadLoad) { - lfence(); - } */ - } - - void lfence() { - emit_byte(0x0F); - emit_byte(0xAE); - emit_byte(0xE8); - } - - void mfence() { - emit_byte(0x0F); - emit_byte(0xAE); - emit_byte(0xF0); - } - - // Identify processor type and features - void cpuid() { - emit_byte(0x0F); - emit_byte(0xA2); - } - - void cld() { emit_byte(0xfc); - } - - void std() { emit_byte(0xfd); - } - - - // Calls - - void call(Label& L, relocInfo::relocType rtype); - void call(Register reg); - void call(Address adr); - - // Jumps - - void jmp(Register reg); - void jmp(Address adr); - - // Label operations & relative jumps (PPUM Appendix D) - // unconditional jump to L - void jmp(Label& L, relocInfo::relocType rtype = relocInfo::none); - - - // Unconditional 8-bit offset jump to L. - // WARNING: be very careful using this for forward jumps. If the label is - // not bound within an 8-bit offset of this instruction, a run-time error - // will occur. - void jmpb(Label& L); - - // jcc is the generic conditional branch generator to run- time - // routines, jcc is used for branches to labels. jcc takes a branch - // opcode (cc) and a label (L) and generates either a backward - // branch or a forward branch and links it to the label fixup - // chain. Usage: - // - // Label L; // unbound label - // jcc(cc, L); // forward branch to unbound label - // bind(L); // bind label to the current pc - // jcc(cc, L); // backward branch to bound label - // bind(L); // illegal: a label may be bound only once - // - // Note: The same Label can be used for forward and backward branches - // but it may be bound only once. - - void jcc(Condition cc, Label& L, - relocInfo::relocType rtype = relocInfo::none); - - // Conditional jump to a 8-bit offset to L. - // WARNING: be very careful using this for forward jumps. If the label is - // not bound within an 8-bit offset of this instruction, a run-time error - // will occur. - void jccb(Condition cc, Label& L); - - // Floating-point operations - - void fxsave(Address dst); - void fxrstor(Address src); - void ldmxcsr(Address src); - void stmxcsr(Address dst); - - void addss(XMMRegister dst, XMMRegister src); - void addss(XMMRegister dst, Address src); - void subss(XMMRegister dst, XMMRegister src); - void subss(XMMRegister dst, Address src); - void mulss(XMMRegister dst, XMMRegister src); - void mulss(XMMRegister dst, Address src); - void divss(XMMRegister dst, XMMRegister src); - void divss(XMMRegister dst, Address src); - void addsd(XMMRegister dst, XMMRegister src); - void addsd(XMMRegister dst, Address src); - void subsd(XMMRegister dst, XMMRegister src); - void subsd(XMMRegister dst, Address src); - void mulsd(XMMRegister dst, XMMRegister src); - void mulsd(XMMRegister dst, Address src); - void divsd(XMMRegister dst, XMMRegister src); - void divsd(XMMRegister dst, Address src); - - // We only need the double form - void sqrtsd(XMMRegister dst, XMMRegister src); - void sqrtsd(XMMRegister dst, Address src); - - void xorps(XMMRegister dst, XMMRegister src); - void xorps(XMMRegister dst, Address src); - void xorpd(XMMRegister dst, XMMRegister src); - void xorpd(XMMRegister dst, Address src); - - void cvtsi2ssl(XMMRegister dst, Register src); - void cvtsi2ssq(XMMRegister dst, Register src); - void cvtsi2sdl(XMMRegister dst, Register src); - void cvtsi2sdq(XMMRegister dst, Register src); - void cvttss2sil(Register dst, XMMRegister src); // truncates - void cvttss2siq(Register dst, XMMRegister src); // truncates - void cvttsd2sil(Register dst, XMMRegister src); // truncates - void cvttsd2siq(Register dst, XMMRegister src); // truncates - void cvtss2sd(XMMRegister dst, XMMRegister src); - void cvtsd2ss(XMMRegister dst, XMMRegister src); - void cvtdq2pd(XMMRegister dst, XMMRegister src); - void cvtdq2ps(XMMRegister dst, XMMRegister src); - - void pxor(XMMRegister dst, Address src); // Xor Packed Byte Integer Values - void pxor(XMMRegister dst, XMMRegister src); // Xor Packed Byte Integer Values - - void movdqa(XMMRegister dst, Address src); // Move Aligned Double Quadword - void movdqa(XMMRegister dst, XMMRegister src); - void movdqa(Address dst, XMMRegister src); - - void movq(XMMRegister dst, Address src); - void movq(Address dst, XMMRegister src); - - void pshufd(XMMRegister dst, XMMRegister src, int mode); // Shuffle Packed Doublewords - void pshufd(XMMRegister dst, Address src, int mode); - void pshuflw(XMMRegister dst, XMMRegister src, int mode); // Shuffle Packed Low Words - void pshuflw(XMMRegister dst, Address src, int mode); - - void psrlq(XMMRegister dst, int shift); // Shift Right Logical Quadword Immediate - - void punpcklbw(XMMRegister dst, XMMRegister src); // Interleave Low Bytes - void punpcklbw(XMMRegister dst, Address src); -}; - - -// MacroAssembler extends Assembler by frequently used macros. -// -// Instructions for which a 'better' code sequence exists depending -// on arguments should also go in here. - -class MacroAssembler : public Assembler { - friend class LIR_Assembler; - protected: - - Address as_Address(AddressLiteral adr); - Address as_Address(ArrayAddress adr); - - // Support for VM calls - // - // This is the base routine called by the different versions of - // call_VM_leaf. The interpreter may customize this version by - // overriding it for its purposes (e.g., to save/restore additional - // registers when doing a VM call). - - virtual void call_VM_leaf_base( - address entry_point, // the entry point - int number_of_arguments // the number of arguments to - // pop after the call - ); - - // This is the base routine called by the different versions of - // call_VM. The interpreter may customize this version by overriding - // it for its purposes (e.g., to save/restore additional registers - // when doing a VM call). - // - // If no java_thread register is specified (noreg) than rdi will be - // used instead. call_VM_base returns the register which contains - // the thread upon return. If a thread register has been specified, - // the return value will correspond to that register. If no - // last_java_sp is specified (noreg) than rsp will be used instead. - virtual void call_VM_base( // returns the register - // containing the thread upon - // return - Register oop_result, // where an oop-result ends up - // if any; use noreg otherwise - Register java_thread, // the thread if computed - // before ; use noreg otherwise - Register last_java_sp, // to set up last_Java_frame in - // stubs; use noreg otherwise - address entry_point, // the entry point - int number_of_arguments, // the number of arguments (w/o - // thread) to pop after the - // call - bool check_exceptions // whether to check for pending - // exceptions after return - ); - - // This routines should emit JVMTI PopFrame handling and ForceEarlyReturn code. - // The implementation is only non-empty for the InterpreterMacroAssembler, - // as only the interpreter handles PopFrame and ForceEarlyReturn requests. - virtual void check_and_handle_popframe(Register java_thread); - virtual void check_and_handle_earlyret(Register java_thread); - - void call_VM_helper(Register oop_result, - address entry_point, - int number_of_arguments, - bool check_exceptions = true); - - public: - MacroAssembler(CodeBuffer* code) : Assembler(code) {} - - // Support for NULL-checks - // - // Generates code that causes a NULL OS exception if the content of - // reg is NULL. If the accessed location is M[reg + offset] and the - // offset is known, provide the offset. No explicit code generation - // is needed if the offset is within a certain range (0 <= offset <= - // page_size). - void null_check(Register reg, int offset = -1); - static bool needs_explicit_null_check(intptr_t offset); - - // Required platform-specific helpers for Label::patch_instructions. - // They _shadow_ the declarations in AbstractAssembler, which are undefined. - void pd_patch_instruction(address branch, address target); -#ifndef PRODUCT - static void pd_print_patched_instruction(address branch); -#endif - - - // The following 4 methods return the offset of the appropriate move - // instruction. Note: these are 32 bit instructions - - // Support for fast byte/word loading with zero extension (depending - // on particular CPU) - int load_unsigned_byte(Register dst, Address src); - int load_unsigned_word(Register dst, Address src); - - // Support for fast byte/word loading with sign extension (depending - // on particular CPU) - int load_signed_byte(Register dst, Address src); - int load_signed_word(Register dst, Address src); - - // Support for inc/dec with optimal instruction selection depending - // on value - void incrementl(Register reg, int value = 1); - void decrementl(Register reg, int value = 1); - void incrementq(Register reg, int value = 1); - void decrementq(Register reg, int value = 1); - - void incrementl(Address dst, int value = 1); - void decrementl(Address dst, int value = 1); - void incrementq(Address dst, int value = 1); - void decrementq(Address dst, int value = 1); - - // Support optimal SSE move instructions. - void movflt(XMMRegister dst, XMMRegister src) { - if (UseXmmRegToRegMoveAll) { movaps(dst, src); return; } - else { movss (dst, src); return; } - } - - void movflt(XMMRegister dst, Address src) { movss(dst, src); } - - void movflt(XMMRegister dst, AddressLiteral src); - - void movflt(Address dst, XMMRegister src) { movss(dst, src); } - - void movdbl(XMMRegister dst, XMMRegister src) { - if (UseXmmRegToRegMoveAll) { movapd(dst, src); return; } - else { movsd (dst, src); return; } - } - - void movdbl(XMMRegister dst, AddressLiteral src); - - void movdbl(XMMRegister dst, Address src) { - if (UseXmmLoadAndClearUpper) { movsd (dst, src); return; } - else { movlpd(dst, src); return; } - } - - void movdbl(Address dst, XMMRegister src) { movsd(dst, src); } - - void incrementl(AddressLiteral dst); - void incrementl(ArrayAddress dst); - - // Alignment - void align(int modulus); - - // Misc - void fat_nop(); // 5 byte nop - - - // C++ bool manipulation - - void movbool(Register dst, Address src); - void movbool(Address dst, bool boolconst); - void movbool(Address dst, Register src); - void testbool(Register dst); - - // oop manipulations - void load_klass(Register dst, Register src); - void store_klass(Register dst, Register src); - void store_klass_gap(Register dst, Register src); - - void load_prototype_header(Register dst, Register src); - - void load_heap_oop(Register dst, Address src); - void store_heap_oop(Address dst, Register src); - void encode_heap_oop(Register r); - void decode_heap_oop(Register r); - void encode_heap_oop_not_null(Register r); - void decode_heap_oop_not_null(Register r); - void encode_heap_oop_not_null(Register dst, Register src); - void decode_heap_oop_not_null(Register dst, Register src); - - void set_narrow_oop(Register dst, jobject obj); - - // Stack frame creation/removal - void enter(); - void leave(); - - // Support for getting the JavaThread pointer (i.e.; a reference to - // thread-local information) The pointer will be loaded into the - // thread register. - void get_thread(Register thread); - - void int3(); - - // Support for VM calls - // - // It is imperative that all calls into the VM are handled via the - // call_VM macros. They make sure that the stack linkage is setup - // correctly. call_VM's correspond to ENTRY/ENTRY_X entry points - // while call_VM_leaf's correspond to LEAF entry points. - void call_VM(Register oop_result, - address entry_point, - bool check_exceptions = true); - void call_VM(Register oop_result, - address entry_point, - Register arg_1, - bool check_exceptions = true); - void call_VM(Register oop_result, - address entry_point, - Register arg_1, Register arg_2, - bool check_exceptions = true); - void call_VM(Register oop_result, - address entry_point, - Register arg_1, Register arg_2, Register arg_3, - bool check_exceptions = true); - - // Overloadings with last_Java_sp - void call_VM(Register oop_result, - Register last_java_sp, - address entry_point, - int number_of_arguments = 0, - bool check_exceptions = true); - void call_VM(Register oop_result, - Register last_java_sp, - address entry_point, - Register arg_1, bool - check_exceptions = true); - void call_VM(Register oop_result, - Register last_java_sp, - address entry_point, - Register arg_1, Register arg_2, - bool check_exceptions = true); - void call_VM(Register oop_result, - Register last_java_sp, - address entry_point, - Register arg_1, Register arg_2, Register arg_3, - bool check_exceptions = true); - - void call_VM_leaf(address entry_point, - int number_of_arguments = 0); - void call_VM_leaf(address entry_point, - Register arg_1); - void call_VM_leaf(address entry_point, - Register arg_1, Register arg_2); - void call_VM_leaf(address entry_point, - Register arg_1, Register arg_2, Register arg_3); - - // last Java Frame (fills frame anchor) - void set_last_Java_frame(Register last_java_sp, - Register last_java_fp, - address last_java_pc); - void reset_last_Java_frame(bool clear_fp, bool clear_pc); - - // Stores - void store_check(Register obj); // store check for - // obj - register is - // destroyed - // afterwards - void store_check(Register obj, Address dst); // same as above, dst - // is exact store - // location (reg. is - // destroyed) - - // split store_check(Register obj) to enhance instruction interleaving - void store_check_part_1(Register obj); - void store_check_part_2(Register obj); - - // C 'boolean' to Java boolean: x == 0 ? 0 : 1 - void c2bool(Register x); - - // Int division/reminder for Java - // (as idivl, but checks for special case as described in JVM spec.) - // returns idivl instruction offset for implicit exception handling - int corrected_idivl(Register reg); - // Long division/reminder for Java - // (as idivq, but checks for special case as described in JVM spec.) - // returns idivq instruction offset for implicit exception handling - int corrected_idivq(Register reg); - - // Push and pop integer/fpu/cpu state - void push_IU_state(); - void pop_IU_state(); - - void push_FPU_state(); - void pop_FPU_state(); - - void push_CPU_state(); - void pop_CPU_state(); - - // Sign extension - void sign_extend_short(Register reg); - void sign_extend_byte(Register reg); - - // Division by power of 2, rounding towards 0 - void division_with_shift(Register reg, int shift_value); - - // Round up to a power of two - void round_to_l(Register reg, int modulus); - void round_to_q(Register reg, int modulus); - - // allocation - void eden_allocate( - Register obj, // result: pointer to object after - // successful allocation - Register var_size_in_bytes, // object size in bytes if unknown at - // compile time; invalid otherwise - int con_size_in_bytes, // object size in bytes if known at - // compile time - Register t1, // temp register - Label& slow_case // continuation point if fast - // allocation fails - ); - void tlab_allocate( - Register obj, // result: pointer to object after - // successful allocation - Register var_size_in_bytes, // object size in bytes if unknown at - // compile time; invalid otherwise - int con_size_in_bytes, // object size in bytes if known at - // compile time - Register t1, // temp register - Register t2, // temp register - Label& slow_case // continuation point if fast - // allocation fails - ); - void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case); - - //---- - - // Debugging - - // only if +VerifyOops - void verify_oop(Register reg, const char* s = "broken oop"); - void verify_oop_addr(Address addr, const char * s = "broken oop addr"); - - // if heap base register is used - reinit it with the correct value - void reinit_heapbase(); - - // only if +VerifyFPU - void verify_FPU(int stack_depth, const char* s = "illegal FPU state") {} - - // prints msg, dumps registers and stops execution - void stop(const char* msg); - - // prints message and continues - void warn(const char* msg); - - static void debug(char* msg, int64_t pc, int64_t regs[]); - - void os_breakpoint(); - - void untested() - { - stop("untested"); - } - - void unimplemented(const char* what = "") - { - char* b = new char[1024]; - sprintf(b, "unimplemented: %s", what); - stop(b); - } - - void should_not_reach_here() - { - stop("should not reach here"); - } - - // Stack overflow checking - void bang_stack_with_offset(int offset) - { - // stack grows down, caller passes positive offset - assert(offset > 0, "must bang with negative offset"); - movl(Address(rsp, (-offset)), rax); - } - - // Writes to stack successive pages until offset reached to check for - // stack overflow + shadow pages. Also, clobbers tmp - void bang_stack_size(Register offset, Register tmp); - - // Support for serializing memory accesses between threads. - void serialize_memory(Register thread, Register tmp); - - void verify_tlab(); - - // Biased locking support - // lock_reg and obj_reg must be loaded up with the appropriate values. - // swap_reg must be rax and is killed. - // tmp_reg must be supplied and is killed. - // If swap_reg_contains_mark is true then the code assumes that the - // mark word of the object has already been loaded into swap_reg. - // Optional slow case is for implementations (interpreter and C1) which branch to - // slow case directly. Leaves condition codes set for C2's Fast_Lock node. - // Returns offset of first potentially-faulting instruction for null - // check info (currently consumed only by C1). If - // swap_reg_contains_mark is true then returns -1 as it is assumed - // the calling code has already passed any potential faults. - int biased_locking_enter(Register lock_reg, Register obj_reg, Register swap_reg, Register tmp_reg, - bool swap_reg_contains_mark, - Label& done, Label* slow_case = NULL, - BiasedLockingCounters* counters = NULL); - void biased_locking_exit (Register obj_reg, Register temp_reg, Label& done); - - Condition negate_condition(Condition cond); - - // Instructions that use AddressLiteral operands. These instruction can handle 32bit/64bit - // operands. In general the names are modified to avoid hiding the instruction in Assembler - // so that we don't need to implement all the varieties in the Assembler with trivial wrappers - // here in MacroAssembler. The major exception to this rule is call - - // Arithmetics - - void cmp8(AddressLiteral src1, int8_t imm32); - - void cmp32(AddressLiteral src1, int32_t src2); - // compare reg - mem, or reg - &mem - void cmp32(Register src1, AddressLiteral src2); - - void cmp32(Register src1, Address src2); - -#ifndef _LP64 - void cmpoop(Address dst, jobject obj); - void cmpoop(Register dst, jobject obj); -#endif // _LP64 - - // NOTE src2 must be the lval. This is NOT an mem-mem compare - void cmpptr(Address src1, AddressLiteral src2); - - void cmpptr(Register src1, AddressLiteral src); - - // will be cmpreg(?) - void cmp64(Register src1, AddressLiteral src); - - void cmpxchgptr(Register reg, Address adr); - void cmpxchgptr(Register reg, AddressLiteral adr); - - // Helper functions for statistics gathering. - // Conditionally (atomically, on MPs) increments passed counter address, preserving condition codes. - void cond_inc32(Condition cond, AddressLiteral counter_addr); - // Unconditional atomic increment. - void atomic_incl(AddressLiteral counter_addr); - - - void lea(Register dst, AddressLiteral src); - void lea(Register dst, Address src); - - - // Calls - void call(Label& L, relocInfo::relocType rtype); - void call(Register entry); - void call(AddressLiteral entry); - - // Jumps - - // 32bit can do a case table jump in one instruction but we no longer allow the base - // to be installed in the Address class - void jump(ArrayAddress entry); - - void jump(AddressLiteral entry); - void jump_cc(Condition cc, AddressLiteral dst); - - // Floating - - void ldmxcsr(Address src) { Assembler::ldmxcsr(src); } - void ldmxcsr(AddressLiteral src); - -private: - // these are private because users should be doing movflt/movdbl - - void movss(XMMRegister dst, XMMRegister src) { Assembler::movss(dst, src); } - void movss(Address dst, XMMRegister src) { Assembler::movss(dst, src); } - void movss(XMMRegister dst, Address src) { Assembler::movss(dst, src); } - void movss(XMMRegister dst, AddressLiteral src); - - void movlpd(XMMRegister dst, Address src) {Assembler::movlpd(dst, src); } - void movlpd(XMMRegister dst, AddressLiteral src); - -public: - - - void xorpd(XMMRegister dst, XMMRegister src) {Assembler::xorpd(dst, src); } - void xorpd(XMMRegister dst, Address src) {Assembler::xorpd(dst, src); } - void xorpd(XMMRegister dst, AddressLiteral src); - - void xorps(XMMRegister dst, XMMRegister src) {Assembler::xorps(dst, src); } - void xorps(XMMRegister dst, Address src) {Assembler::xorps(dst, src); } - void xorps(XMMRegister dst, AddressLiteral src); - - - // Data - - void movoop(Register dst, jobject obj); - void movoop(Address dst, jobject obj); - - void movptr(ArrayAddress dst, Register src); - void movptr(Register dst, AddressLiteral src); - - void movptr(Register dst, intptr_t src); - void movptr(Address dst, intptr_t src); - - void movptr(Register dst, ArrayAddress src); - - // to avoid hiding movl - void mov32(AddressLiteral dst, Register src); - void mov32(Register dst, AddressLiteral src); - - void pushoop(jobject obj); - - // Can push value or effective address - void pushptr(AddressLiteral src); - -}; - -/** - * class SkipIfEqual: - * - * Instantiating this class will result in assembly code being output that will - * jump around any code emitted between the creation of the instance and it's - * automatic destruction at the end of a scope block, depending on the value of - * the flag passed to the constructor, which will be checked at run-time. - */ -class SkipIfEqual { - private: - MacroAssembler* _masm; - Label _label; - - public: - SkipIfEqual(MacroAssembler*, const bool* flag_addr, bool value); - ~SkipIfEqual(); -}; - - -#ifdef ASSERT -inline bool AbstractAssembler::pd_check_instruction_mark() { return true; } -#endif diff --git a/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp b/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp index 09419c95650..2f394855de0 100644 --- a/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,11 +43,12 @@ void ConversionStub::emit_code(LIR_Assembler* ce) { __ comisd(input()->as_xmm_double_reg(), ExternalAddress((address)&double_zero)); } else { - __ pushl(rax); + LP64_ONLY(ShouldNotReachHere()); + __ push(rax); __ ftst(); __ fnstsw_ax(); __ sahf(); - __ popl(rax); + __ pop(rax); } Label NaN, do_return; @@ -61,7 +62,7 @@ void ConversionStub::emit_code(LIR_Assembler* ce) { // input is NaN -> return 0 __ bind(NaN); - __ xorl(result()->as_register(), result()->as_register()); + __ xorptr(result()->as_register(), result()->as_register()); __ bind(do_return); __ jmp(_continuation); @@ -139,7 +140,7 @@ NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKl void NewInstanceStub::emit_code(LIR_Assembler* ce) { assert(__ rsp_offset() == 0, "frame size should be fixed"); __ bind(_entry); - __ movl(rdx, _klass_reg->as_register()); + __ movptr(rdx, _klass_reg->as_register()); __ call(RuntimeAddress(Runtime1::entry_for(_stub_id))); ce->add_call_info_here(_info); ce->verify_oop_map(_info); @@ -306,10 +307,10 @@ void PatchingStub::emit_code(LIR_Assembler* ce) { assert(_obj != noreg, "must be a valid register"); Register tmp = rax; if (_obj == tmp) tmp = rbx; - __ pushl(tmp); + __ push(tmp); __ get_thread(tmp); - __ cmpl(tmp, Address(_obj, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc))); - __ popl(tmp); + __ cmpptr(tmp, Address(_obj, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc))); + __ pop(tmp); __ jcc(Assembler::notEqual, call_patch); // access_field patches may execute the patched code before it's @@ -434,7 +435,7 @@ void ArrayCopyStub::emit_code(LIR_Assembler* ce) { VMReg r_1 = args[i].first(); if (r_1->is_stack()) { int st_off = r_1->reg2stack() * wordSize; - __ movl (Address(rsp, st_off), r[i]); + __ movptr (Address(rsp, st_off), r[i]); } else { assert(r[i] == args[i].first()->as_Register(), "Wrong register for arg "); } @@ -449,7 +450,7 @@ void ArrayCopyStub::emit_code(LIR_Assembler* ce) { ce->add_call_info_here(info()); #ifndef PRODUCT - __ increment(ExternalAddress((address)&Runtime1::_arraycopy_slowcase_cnt)); + __ incrementl(ExternalAddress((address)&Runtime1::_arraycopy_slowcase_cnt)); #endif __ jmp(_continuation); diff --git a/hotspot/src/cpu/x86/vm/c1_Defs_x86.hpp b/hotspot/src/cpu/x86/vm/c1_Defs_x86.hpp index 8594a834907..633e5393450 100644 --- a/hotspot/src/cpu/x86/vm/c1_Defs_x86.hpp +++ b/hotspot/src/cpu/x86/vm/c1_Defs_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,27 +36,34 @@ enum { // registers enum { - pd_nof_cpu_regs_frame_map = 8, // number of registers used during code emission - pd_nof_fpu_regs_frame_map = 8, // number of registers used during code emission - pd_nof_xmm_regs_frame_map = 8, // number of registers used during code emission - pd_nof_caller_save_cpu_regs_frame_map = 6, // number of registers killed by calls - pd_nof_caller_save_fpu_regs_frame_map = 8, // number of registers killed by calls - pd_nof_caller_save_xmm_regs_frame_map = 8, // number of registers killed by calls + pd_nof_cpu_regs_frame_map = RegisterImpl::number_of_registers, // number of registers used during code emission + pd_nof_fpu_regs_frame_map = FloatRegisterImpl::number_of_registers, // number of registers used during code emission + pd_nof_xmm_regs_frame_map = XMMRegisterImpl::number_of_registers, // number of registers used during code emission - pd_nof_cpu_regs_reg_alloc = 6, // number of registers that are visible to register allocator +#ifdef _LP64 + #define UNALLOCATED 4 // rsp, rbp, r15, r10 +#else + #define UNALLOCATED 2 // rsp, rbp +#endif // LP64 + + pd_nof_caller_save_cpu_regs_frame_map = pd_nof_cpu_regs_frame_map - UNALLOCATED, // number of registers killed by calls + pd_nof_caller_save_fpu_regs_frame_map = pd_nof_fpu_regs_frame_map, // number of registers killed by calls + pd_nof_caller_save_xmm_regs_frame_map = pd_nof_xmm_regs_frame_map, // number of registers killed by calls + + pd_nof_cpu_regs_reg_alloc = pd_nof_caller_save_cpu_regs_frame_map, // number of registers that are visible to register allocator pd_nof_fpu_regs_reg_alloc = 6, // number of registers that are visible to register allocator - pd_nof_cpu_regs_linearscan = 8, // number of registers visible to linear scan - pd_nof_fpu_regs_linearscan = 8, // number of registers visible to linear scan - pd_nof_xmm_regs_linearscan = 8, // number of registers visible to linear scan + pd_nof_cpu_regs_linearscan = pd_nof_cpu_regs_frame_map, // number of registers visible to linear scan + pd_nof_fpu_regs_linearscan = pd_nof_fpu_regs_frame_map, // number of registers visible to linear scan + pd_nof_xmm_regs_linearscan = pd_nof_xmm_regs_frame_map, // number of registers visible to linear scan pd_first_cpu_reg = 0, - pd_last_cpu_reg = 5, + pd_last_cpu_reg = NOT_LP64(5) LP64_ONLY(11), pd_first_byte_reg = 2, pd_last_byte_reg = 5, pd_first_fpu_reg = pd_nof_cpu_regs_frame_map, pd_last_fpu_reg = pd_first_fpu_reg + 7, pd_first_xmm_reg = pd_nof_cpu_regs_frame_map + pd_nof_fpu_regs_frame_map, - pd_last_xmm_reg = pd_first_xmm_reg + 7 + pd_last_xmm_reg = pd_first_xmm_reg + pd_nof_xmm_regs_frame_map - 1 }; diff --git a/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.cpp b/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.cpp index 2118ec4483e..b0f7ec96061 100644 --- a/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,10 +39,15 @@ LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool) { opr = LIR_OprFact::address(new LIR_Address(rsp_opr, st_off, type)); } else if (r_1->is_Register()) { Register reg = r_1->as_Register(); - if (r_2->is_Register()) { + if (r_2->is_Register() && (type == T_LONG || type == T_DOUBLE)) { Register reg2 = r_2->as_Register(); +#ifdef _LP64 + assert(reg2 == reg, "must be same register"); + opr = as_long_opr(reg); +#else opr = as_long_opr(reg2, reg); - } else if (type == T_OBJECT) { +#endif // _LP64 + } else if (type == T_OBJECT || type == T_ARRAY) { opr = as_oop_opr(reg); } else { opr = as_opr(reg); @@ -88,18 +93,39 @@ LIR_Opr FrameMap::rax_oop_opr; LIR_Opr FrameMap::rdx_oop_opr; LIR_Opr FrameMap::rcx_oop_opr; -LIR_Opr FrameMap::rax_rdx_long_opr; -LIR_Opr FrameMap::rbx_rcx_long_opr; +LIR_Opr FrameMap::long0_opr; +LIR_Opr FrameMap::long1_opr; LIR_Opr FrameMap::fpu0_float_opr; LIR_Opr FrameMap::fpu0_double_opr; LIR_Opr FrameMap::xmm0_float_opr; LIR_Opr FrameMap::xmm0_double_opr; +#ifdef _LP64 + +LIR_Opr FrameMap::r8_opr; +LIR_Opr FrameMap::r9_opr; +LIR_Opr FrameMap::r10_opr; +LIR_Opr FrameMap::r11_opr; +LIR_Opr FrameMap::r12_opr; +LIR_Opr FrameMap::r13_opr; +LIR_Opr FrameMap::r14_opr; +LIR_Opr FrameMap::r15_opr; + +// r10 and r15 can never contain oops since they aren't available to +// the allocator +LIR_Opr FrameMap::r8_oop_opr; +LIR_Opr FrameMap::r9_oop_opr; +LIR_Opr FrameMap::r11_oop_opr; +LIR_Opr FrameMap::r12_oop_opr; +LIR_Opr FrameMap::r13_oop_opr; +LIR_Opr FrameMap::r14_oop_opr; +#endif // _LP64 + LIR_Opr FrameMap::_caller_save_cpu_regs[] = { 0, }; LIR_Opr FrameMap::_caller_save_fpu_regs[] = { 0, }; LIR_Opr FrameMap::_caller_save_xmm_regs[] = { 0, }; -XMMRegister FrameMap::_xmm_regs [8] = { 0, }; +XMMRegister FrameMap::_xmm_regs [] = { 0, }; XMMRegister FrameMap::nr2xmmreg(int rnr) { assert(_init_done, "tables not initialized"); @@ -113,18 +139,39 @@ XMMRegister FrameMap::nr2xmmreg(int rnr) { void FrameMap::init() { if (_init_done) return; - assert(nof_cpu_regs == 8, "wrong number of CPU registers"); - map_register(0, rsi); rsi_opr = LIR_OprFact::single_cpu(0); rsi_oop_opr = LIR_OprFact::single_cpu_oop(0); - map_register(1, rdi); rdi_opr = LIR_OprFact::single_cpu(1); rdi_oop_opr = LIR_OprFact::single_cpu_oop(1); - map_register(2, rbx); rbx_opr = LIR_OprFact::single_cpu(2); rbx_oop_opr = LIR_OprFact::single_cpu_oop(2); - map_register(3, rax); rax_opr = LIR_OprFact::single_cpu(3); rax_oop_opr = LIR_OprFact::single_cpu_oop(3); - map_register(4, rdx); rdx_opr = LIR_OprFact::single_cpu(4); rdx_oop_opr = LIR_OprFact::single_cpu_oop(4); - map_register(5, rcx); rcx_opr = LIR_OprFact::single_cpu(5); rcx_oop_opr = LIR_OprFact::single_cpu_oop(5); - map_register(6, rsp); rsp_opr = LIR_OprFact::single_cpu(6); - map_register(7, rbp); rbp_opr = LIR_OprFact::single_cpu(7); + assert(nof_cpu_regs == LP64_ONLY(16) NOT_LP64(8), "wrong number of CPU registers"); + map_register(0, rsi); rsi_opr = LIR_OprFact::single_cpu(0); + map_register(1, rdi); rdi_opr = LIR_OprFact::single_cpu(1); + map_register(2, rbx); rbx_opr = LIR_OprFact::single_cpu(2); + map_register(3, rax); rax_opr = LIR_OprFact::single_cpu(3); + map_register(4, rdx); rdx_opr = LIR_OprFact::single_cpu(4); + map_register(5, rcx); rcx_opr = LIR_OprFact::single_cpu(5); - rax_rdx_long_opr = LIR_OprFact::double_cpu(3 /*eax*/, 4 /*edx*/); - rbx_rcx_long_opr = LIR_OprFact::double_cpu(2 /*ebx*/, 5 /*ecx*/); +#ifndef _LP64 + // The unallocatable registers are at the end + map_register(6, rsp); + map_register(7, rbp); +#else + map_register( 6, r8); r8_opr = LIR_OprFact::single_cpu(6); + map_register( 7, r9); r9_opr = LIR_OprFact::single_cpu(7); + map_register( 8, r11); r11_opr = LIR_OprFact::single_cpu(8); + map_register( 9, r12); r12_opr = LIR_OprFact::single_cpu(9); + map_register(10, r13); r13_opr = LIR_OprFact::single_cpu(10); + map_register(11, r14); r14_opr = LIR_OprFact::single_cpu(11); + // The unallocatable registers are at the end + map_register(12, r10); r10_opr = LIR_OprFact::single_cpu(12); + map_register(13, r15); r15_opr = LIR_OprFact::single_cpu(13); + map_register(14, rsp); + map_register(15, rbp); +#endif // _LP64 + +#ifdef _LP64 + long0_opr = LIR_OprFact::double_cpu(3 /*eax*/, 3 /*eax*/); + long1_opr = LIR_OprFact::double_cpu(2 /*ebx*/, 2 /*ebx*/); +#else + long0_opr = LIR_OprFact::double_cpu(3 /*eax*/, 4 /*edx*/); + long1_opr = LIR_OprFact::double_cpu(2 /*ebx*/, 5 /*ecx*/); +#endif // _LP64 fpu0_float_opr = LIR_OprFact::single_fpu(0); fpu0_double_opr = LIR_OprFact::double_fpu(0); xmm0_float_opr = LIR_OprFact::single_xmm(0); @@ -137,6 +184,15 @@ void FrameMap::init() { _caller_save_cpu_regs[4] = rdx_opr; _caller_save_cpu_regs[5] = rcx_opr; +#ifdef _LP64 + _caller_save_cpu_regs[6] = r8_opr; + _caller_save_cpu_regs[7] = r9_opr; + _caller_save_cpu_regs[8] = r11_opr; + _caller_save_cpu_regs[9] = r12_opr; + _caller_save_cpu_regs[10] = r13_opr; + _caller_save_cpu_regs[11] = r14_opr; +#endif // _LP64 + _xmm_regs[0] = xmm0; _xmm_regs[1] = xmm1; @@ -147,18 +203,51 @@ void FrameMap::init() { _xmm_regs[6] = xmm6; _xmm_regs[7] = xmm7; +#ifdef _LP64 + _xmm_regs[8] = xmm8; + _xmm_regs[9] = xmm9; + _xmm_regs[10] = xmm10; + _xmm_regs[11] = xmm11; + _xmm_regs[12] = xmm12; + _xmm_regs[13] = xmm13; + _xmm_regs[14] = xmm14; + _xmm_regs[15] = xmm15; +#endif // _LP64 + for (int i = 0; i < 8; i++) { _caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i); + } + + for (int i = 0; i < nof_caller_save_xmm_regs ; i++) { _caller_save_xmm_regs[i] = LIR_OprFact::single_xmm(i); } _init_done = true; + rsi_oop_opr = as_oop_opr(rsi); + rdi_oop_opr = as_oop_opr(rdi); + rbx_oop_opr = as_oop_opr(rbx); + rax_oop_opr = as_oop_opr(rax); + rdx_oop_opr = as_oop_opr(rdx); + rcx_oop_opr = as_oop_opr(rcx); + + rsp_opr = as_pointer_opr(rsp); + rbp_opr = as_pointer_opr(rbp); + +#ifdef _LP64 + r8_oop_opr = as_oop_opr(r8); + r9_oop_opr = as_oop_opr(r9); + r11_oop_opr = as_oop_opr(r11); + r12_oop_opr = as_oop_opr(r12); + r13_oop_opr = as_oop_opr(r13); + r14_oop_opr = as_oop_opr(r14); +#endif // _LP64 + VMRegPair regs; BasicType sig_bt = T_OBJECT; SharedRuntime::java_calling_convention(&sig_bt, ®s, 1, true); receiver_opr = as_oop_opr(regs.first()->as_Register()); - assert(receiver_opr == rcx_oop_opr, "rcvr ought to be rcx"); + } diff --git a/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp b/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp index 419b8600a3c..65671c32d4a 100644 --- a/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp +++ b/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,8 +38,13 @@ nof_xmm_regs = pd_nof_xmm_regs_frame_map, nof_caller_save_xmm_regs = pd_nof_caller_save_xmm_regs_frame_map, first_available_sp_in_frame = 0, +#ifndef _LP64 frame_pad_in_bytes = 8, nof_reg_args = 2 +#else + frame_pad_in_bytes = 16, + nof_reg_args = 6 +#endif // _LP64 }; private: @@ -65,17 +70,49 @@ static LIR_Opr rax_oop_opr; static LIR_Opr rdx_oop_opr; static LIR_Opr rcx_oop_opr; +#ifdef _LP64 - static LIR_Opr rax_rdx_long_opr; - static LIR_Opr rbx_rcx_long_opr; + static LIR_Opr r8_opr; + static LIR_Opr r9_opr; + static LIR_Opr r10_opr; + static LIR_Opr r11_opr; + static LIR_Opr r12_opr; + static LIR_Opr r13_opr; + static LIR_Opr r14_opr; + static LIR_Opr r15_opr; + + static LIR_Opr r8_oop_opr; + static LIR_Opr r9_oop_opr; + + static LIR_Opr r11_oop_opr; + static LIR_Opr r12_oop_opr; + static LIR_Opr r13_oop_opr; + static LIR_Opr r14_oop_opr; + +#endif // _LP64 + + static LIR_Opr long0_opr; + static LIR_Opr long1_opr; static LIR_Opr fpu0_float_opr; static LIR_Opr fpu0_double_opr; static LIR_Opr xmm0_float_opr; static LIR_Opr xmm0_double_opr; +#ifdef _LP64 + static LIR_Opr as_long_opr(Register r) { + return LIR_OprFact::double_cpu(cpu_reg2rnr(r), cpu_reg2rnr(r)); + } + static LIR_Opr as_pointer_opr(Register r) { + return LIR_OprFact::double_cpu(cpu_reg2rnr(r), cpu_reg2rnr(r)); + } +#else static LIR_Opr as_long_opr(Register r, Register r2) { return LIR_OprFact::double_cpu(cpu_reg2rnr(r), cpu_reg2rnr(r2)); } + static LIR_Opr as_pointer_opr(Register r) { + return LIR_OprFact::single_cpu(cpu_reg2rnr(r)); + } +#endif // _LP64 // VMReg name for spilled physical FPU stack slot n static VMReg fpu_regname (int n); diff --git a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp index 081f38c3bac..4300d196c28 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @@ -113,7 +113,7 @@ bool LIR_Assembler::is_small_constant(LIR_Opr opr) { LIR_Opr LIR_Assembler::receiverOpr() { - return FrameMap::rcx_oop_opr; + return FrameMap::receiver_opr; } LIR_Opr LIR_Assembler::incomingReceiverOpr() { @@ -121,7 +121,7 @@ LIR_Opr LIR_Assembler::incomingReceiverOpr() { } LIR_Opr LIR_Assembler::osrBufferPointer() { - return FrameMap::rcx_opr; + return FrameMap::as_pointer_opr(receiverOpr()->as_register()); } //--------------fpu register translations----------------------- @@ -181,7 +181,7 @@ void LIR_Assembler::push(LIR_Opr opr) { if (opr->is_single_cpu()) { __ push_reg(opr->as_register()); } else if (opr->is_double_cpu()) { - __ push_reg(opr->as_register_hi()); + NOT_LP64(__ push_reg(opr->as_register_hi())); __ push_reg(opr->as_register_lo()); } else if (opr->is_stack()) { __ push_addr(frame_map()->address_for_slot(opr->single_stack_ix())); @@ -202,31 +202,45 @@ void LIR_Assembler::push(LIR_Opr opr) { void LIR_Assembler::pop(LIR_Opr opr) { if (opr->is_single_cpu()) { - __ pop(opr->as_register()); + __ pop_reg(opr->as_register()); } else { ShouldNotReachHere(); } } +bool LIR_Assembler::is_literal_address(LIR_Address* addr) { + return addr->base()->is_illegal() && addr->index()->is_illegal(); +} + //------------------------------------------- + Address LIR_Assembler::as_Address(LIR_Address* addr) { + return as_Address(addr, rscratch1); +} + +Address LIR_Assembler::as_Address(LIR_Address* addr, Register tmp) { if (addr->base()->is_illegal()) { assert(addr->index()->is_illegal(), "must be illegal too"); - //return Address(addr->disp(), relocInfo::none); - // hack for now since this should really return an AddressLiteral - // which will have to await 64bit c1 changes. - return Address(noreg, addr->disp()); + AddressLiteral laddr((address)addr->disp(), relocInfo::none); + if (! __ reachable(laddr)) { + __ movptr(tmp, laddr.addr()); + Address res(tmp, 0); + return res; + } else { + return __ as_Address(laddr); + } } - Register base = addr->base()->as_register(); + Register base = addr->base()->as_pointer_register(); if (addr->index()->is_illegal()) { return Address( base, addr->disp()); - } else if (addr->index()->is_single_cpu()) { - Register index = addr->index()->as_register(); + } else if (addr->index()->is_cpu_register()) { + Register index = addr->index()->as_pointer_register(); return Address(base, index, (Address::ScaleFactor) addr->scale(), addr->disp()); } else if (addr->index()->is_constant()) { - int addr_offset = (addr->index()->as_constant_ptr()->as_jint() << addr->scale()) + addr->disp(); + intptr_t addr_offset = (addr->index()->as_constant_ptr()->as_jint() << addr->scale()) + addr->disp(); + assert(Assembler::is_simm32(addr_offset), "must be"); return Address(base, addr_offset); } else { @@ -284,7 +298,7 @@ void LIR_Assembler::osr_entry() { // All other registers are dead at this point and the locals will be // copied into place by code emitted in the IR. - Register OSR_buf = osrBufferPointer()->as_register(); + Register OSR_buf = osrBufferPointer()->as_pointer_register(); { assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below"); int monitor_offset = BytesPerWord * method()->max_locals() + (BasicObjectLock::size() * BytesPerWord) * (number_of_locks - 1); @@ -294,16 +308,16 @@ void LIR_Assembler::osr_entry() { // verify the interpreter's monitor has a non-null object { Label L; - __ cmpl(Address(OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes()), NULL_WORD); + __ cmpptr(Address(OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD); __ jcc(Assembler::notZero, L); __ stop("locked object is NULL"); __ bind(L); } #endif - __ movl(rbx, Address(OSR_buf, slot_offset + BasicObjectLock::lock_offset_in_bytes())); - __ movl(frame_map()->address_for_monitor_lock(i), rbx); - __ movl(rbx, Address(OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes())); - __ movl(frame_map()->address_for_monitor_object(i), rbx); + __ movptr(rbx, Address(OSR_buf, slot_offset + BasicObjectLock::lock_offset_in_bytes())); + __ movptr(frame_map()->address_for_monitor_lock(i), rbx); + __ movptr(rbx, Address(OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes())); + __ movptr(frame_map()->address_for_monitor_object(i), rbx); } } } @@ -313,10 +327,11 @@ void LIR_Assembler::osr_entry() { int LIR_Assembler::check_icache() { Register receiver = FrameMap::receiver_opr->as_register(); Register ic_klass = IC_Klass; + const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9); if (!VerifyOops) { // insert some nops so that the verified entry point is aligned on CodeEntryAlignment - while ((__ offset() + 9) % CodeEntryAlignment != 0) { + while ((__ offset() + ic_cmp_size) % CodeEntryAlignment != 0) { __ nop(); } } @@ -347,7 +362,7 @@ void LIR_Assembler::monitorexit(LIR_Opr obj_opr, LIR_Opr lock_opr, Register new_ // and cannot block => no GC can happen // The slow case (MonitorAccessStub) uses the first two stack slots // ([esp+0] and [esp+4]), therefore we store the exception at [esp+8] - __ movl (Address(rsp, 2*wordSize), exception); + __ movptr (Address(rsp, 2*wordSize), exception); } Register obj_reg = obj_opr->as_register(); @@ -360,7 +375,7 @@ void LIR_Assembler::monitorexit(LIR_Opr obj_opr, LIR_Opr lock_opr, Register new_ lock_reg = new_hdr; // compute pointer to BasicLock Address lock_addr = frame_map()->address_for_monitor_lock(monitor_no); - __ leal(lock_reg, lock_addr); + __ lea(lock_reg, lock_addr); // unlock object MonitorAccessStub* slow_case = new MonitorExitStub(lock_opr, true, monitor_no); // _slow_case_stubs->append(slow_case); @@ -385,14 +400,18 @@ void LIR_Assembler::monitorexit(LIR_Opr obj_opr, LIR_Opr lock_opr, Register new_ if (exception->is_valid()) { // restore exception - __ movl (exception, Address(rsp, 2 * wordSize)); + __ movptr (exception, Address(rsp, 2 * wordSize)); } } // This specifies the rsp decrement needed to build the frame int LIR_Assembler::initial_frame_size_in_bytes() { // if rounding, must let FrameMap know! - return (frame_map()->framesize() - 2) * BytesPerWord; // subtract two words to account for return address and link + + // The frame_map records size in slots (32bit word) + + // subtract two words to account for return address and link + return (frame_map()->framesize() - (2*VMRegImpl::slots_per_word)) * VMRegImpl::stack_slot_size; } @@ -495,43 +514,43 @@ void LIR_Assembler::emit_deopt_handler() { // This is the fast version of java.lang.String.compare; it has not // OSR-entry and therefore, we generate a slow version for OSR's void LIR_Assembler::emit_string_compare(LIR_Opr arg0, LIR_Opr arg1, LIR_Opr dst, CodeEmitInfo* info) { - __ movl (rbx, rcx); // receiver is in rcx - __ movl (rax, arg1->as_register()); + __ movptr (rbx, rcx); // receiver is in rcx + __ movptr (rax, arg1->as_register()); // Get addresses of first characters from both Strings - __ movl (rsi, Address(rax, java_lang_String::value_offset_in_bytes())); - __ movl (rcx, Address(rax, java_lang_String::offset_offset_in_bytes())); - __ leal (rsi, Address(rsi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); + __ movptr (rsi, Address(rax, java_lang_String::value_offset_in_bytes())); + __ movptr (rcx, Address(rax, java_lang_String::offset_offset_in_bytes())); + __ lea (rsi, Address(rsi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); // rbx, may be NULL add_debug_info_for_null_check_here(info); - __ movl (rdi, Address(rbx, java_lang_String::value_offset_in_bytes())); - __ movl (rcx, Address(rbx, java_lang_String::offset_offset_in_bytes())); - __ leal (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); + __ movptr (rdi, Address(rbx, java_lang_String::value_offset_in_bytes())); + __ movptr (rcx, Address(rbx, java_lang_String::offset_offset_in_bytes())); + __ lea (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); // compute minimum length (in rax) and difference of lengths (on top of stack) if (VM_Version::supports_cmov()) { - __ movl (rbx, Address(rbx, java_lang_String::count_offset_in_bytes())); - __ movl (rax, Address(rax, java_lang_String::count_offset_in_bytes())); - __ movl (rcx, rbx); - __ subl (rbx, rax); // subtract lengths - __ pushl(rbx); // result - __ cmovl(Assembler::lessEqual, rax, rcx); + __ movl (rbx, Address(rbx, java_lang_String::count_offset_in_bytes())); + __ movl (rax, Address(rax, java_lang_String::count_offset_in_bytes())); + __ mov (rcx, rbx); + __ subptr (rbx, rax); // subtract lengths + __ push (rbx); // result + __ cmov (Assembler::lessEqual, rax, rcx); } else { Label L; - __ movl (rbx, Address(rbx, java_lang_String::count_offset_in_bytes())); - __ movl (rcx, Address(rax, java_lang_String::count_offset_in_bytes())); - __ movl (rax, rbx); - __ subl (rbx, rcx); - __ pushl(rbx); - __ jcc (Assembler::lessEqual, L); - __ movl (rax, rcx); + __ movl (rbx, Address(rbx, java_lang_String::count_offset_in_bytes())); + __ movl (rcx, Address(rax, java_lang_String::count_offset_in_bytes())); + __ mov (rax, rbx); + __ subptr (rbx, rcx); + __ push (rbx); + __ jcc (Assembler::lessEqual, L); + __ mov (rax, rcx); __ bind (L); } // is minimum length 0? Label noLoop, haveResult; - __ testl (rax, rax); + __ testptr (rax, rax); __ jcc (Assembler::zero, noLoop); // compare first characters @@ -546,9 +565,9 @@ void LIR_Assembler::emit_string_compare(LIR_Opr arg0, LIR_Opr arg1, LIR_Opr dst, // set rsi.edi to the end of the arrays (arrays have same length) // negate the index - __ leal(rsi, Address(rsi, rax, Address::times_2, type2aelembytes(T_CHAR))); - __ leal(rdi, Address(rdi, rax, Address::times_2, type2aelembytes(T_CHAR))); - __ negl(rax); + __ lea(rsi, Address(rsi, rax, Address::times_2, type2aelembytes(T_CHAR))); + __ lea(rdi, Address(rdi, rax, Address::times_2, type2aelembytes(T_CHAR))); + __ negptr(rax); // compare the strings in a loop @@ -565,12 +584,12 @@ void LIR_Assembler::emit_string_compare(LIR_Opr arg0, LIR_Opr arg1, LIR_Opr dst, // strings are equal up to min length __ bind(noLoop); - __ popl(rax); + __ pop(rax); return_op(LIR_OprFact::illegalOpr); __ bind(haveResult); // leave instruction is going to discard the TOS value - __ movl (rax, rcx); // result of call is in rax, + __ mov (rax, rcx); // result of call is in rax, } @@ -589,6 +608,11 @@ void LIR_Assembler::return_op(LIR_Opr result) { // the poll sets the condition code, but no data registers AddressLiteral polling_page(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()), relocInfo::poll_return_type); + + // NOTE: the requires that the polling page be reachable else the reloc + // goes to the movq that loads the address and not the faulting instruction + // which breaks the signal handler code + __ test32(rax, polling_page); __ ret(0); @@ -606,17 +630,22 @@ int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) { } int offset = __ offset(); + + // NOTE: the requires that the polling page be reachable else the reloc + // goes to the movq that loads the address and not the faulting instruction + // which breaks the signal handler code + __ test32(rax, polling_page); return offset; } void LIR_Assembler::move_regs(Register from_reg, Register to_reg) { - if (from_reg != to_reg) __ movl(to_reg, from_reg); + if (from_reg != to_reg) __ mov(to_reg, from_reg); } void LIR_Assembler::swap_reg(Register a, Register b) { - __ xchgl(a, b); + __ xchgptr(a, b); } @@ -634,8 +663,12 @@ void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_cod case T_LONG: { assert(patch_code == lir_patch_none, "no patching handled here"); - __ movl(dest->as_register_lo(), c->as_jint_lo()); - __ movl(dest->as_register_hi(), c->as_jint_hi()); +#ifdef _LP64 + __ movptr(dest->as_register_lo(), (intptr_t)c->as_jlong()); +#else + __ movptr(dest->as_register_lo(), c->as_jint_lo()); + __ movptr(dest->as_register_hi(), c->as_jint_hi()); +#endif // _LP64 break; } @@ -714,10 +747,15 @@ void LIR_Assembler::const2stack(LIR_Opr src, LIR_Opr dest) { case T_LONG: // fall through case T_DOUBLE: - __ movl(frame_map()->address_for_slot(dest->double_stack_ix(), - lo_word_offset_in_bytes), c->as_jint_lo_bits()); - __ movl(frame_map()->address_for_slot(dest->double_stack_ix(), - hi_word_offset_in_bytes), c->as_jint_hi_bits()); +#ifdef _LP64 + __ movptr(frame_map()->address_for_slot(dest->double_stack_ix(), + lo_word_offset_in_bytes), (intptr_t)c->as_jlong_bits()); +#else + __ movptr(frame_map()->address_for_slot(dest->double_stack_ix(), + lo_word_offset_in_bytes), c->as_jint_lo_bits()); + __ movptr(frame_map()->address_for_slot(dest->double_stack_ix(), + hi_word_offset_in_bytes), c->as_jint_hi_bits()); +#endif // _LP64 break; default: @@ -731,7 +769,7 @@ void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmi LIR_Const* c = src->as_constant_ptr(); LIR_Address* addr = dest->as_address_ptr(); - if (info != NULL) add_debug_info_for_null_check_here(info); + int null_check_here = code_offset(); switch (type) { case T_INT: // fall through case T_FLOAT: @@ -741,16 +779,33 @@ void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmi case T_OBJECT: // fall through case T_ARRAY: if (c->as_jobject() == NULL) { - __ movl(as_Address(addr), NULL_WORD); + __ movptr(as_Address(addr), (int32_t)NULL_WORD); } else { - __ movoop(as_Address(addr), c->as_jobject()); + if (is_literal_address(addr)) { + ShouldNotReachHere(); + __ movoop(as_Address(addr, noreg), c->as_jobject()); + } else { + __ movoop(as_Address(addr), c->as_jobject()); + } } break; case T_LONG: // fall through case T_DOUBLE: - __ movl(as_Address_hi(addr), c->as_jint_hi_bits()); - __ movl(as_Address_lo(addr), c->as_jint_lo_bits()); +#ifdef _LP64 + if (is_literal_address(addr)) { + ShouldNotReachHere(); + __ movptr(as_Address(addr, r15_thread), (intptr_t)c->as_jlong_bits()); + } else { + __ movptr(r10, (intptr_t)c->as_jlong_bits()); + null_check_here = code_offset(); + __ movptr(as_Address_lo(addr), r10); + } +#else + // Always reachable in 32bit so this doesn't produce useless move literal + __ movptr(as_Address_hi(addr), c->as_jint_hi_bits()); + __ movptr(as_Address_lo(addr), c->as_jint_lo_bits()); +#endif // _LP64 break; case T_BOOLEAN: // fall through @@ -766,6 +821,10 @@ void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmi default: ShouldNotReachHere(); }; + + if (info != NULL) { + add_debug_info_for_null_check(null_check_here, info); + } } @@ -775,6 +834,13 @@ void LIR_Assembler::reg2reg(LIR_Opr src, LIR_Opr dest) { // move between cpu-registers if (dest->is_single_cpu()) { +#ifdef _LP64 + if (src->type() == T_LONG) { + // Can do LONG -> OBJECT + move_regs(src->as_register_lo(), dest->as_register()); + return; + } +#endif assert(src->is_single_cpu(), "must match"); if (src->type() == T_OBJECT) { __ verify_oop(src->as_register()); @@ -782,13 +848,27 @@ void LIR_Assembler::reg2reg(LIR_Opr src, LIR_Opr dest) { move_regs(src->as_register(), dest->as_register()); } else if (dest->is_double_cpu()) { +#ifdef _LP64 + if (src->type() == T_OBJECT || src->type() == T_ARRAY) { + // Surprising to me but we can see move of a long to t_object + __ verify_oop(src->as_register()); + move_regs(src->as_register(), dest->as_register_lo()); + return; + } +#endif assert(src->is_double_cpu(), "must match"); Register f_lo = src->as_register_lo(); Register f_hi = src->as_register_hi(); Register t_lo = dest->as_register_lo(); Register t_hi = dest->as_register_hi(); +#ifdef _LP64 + assert(f_hi == f_lo, "must be same"); + assert(t_hi == t_lo, "must be same"); + move_regs(f_lo, t_lo); +#else assert(f_lo != f_hi && t_lo != t_hi, "invalid register allocation"); + if (f_lo == t_hi && f_hi == t_lo) { swap_reg(f_lo, f_hi); } else if (f_hi == t_lo) { @@ -800,6 +880,7 @@ void LIR_Assembler::reg2reg(LIR_Opr src, LIR_Opr dest) { move_regs(f_lo, t_lo); move_regs(f_hi, t_hi); } +#endif // LP64 // special moves from fpu-register to xmm-register // necessary for method results @@ -841,14 +922,16 @@ void LIR_Assembler::reg2stack(LIR_Opr src, LIR_Opr dest, BasicType type, bool po Address dst = frame_map()->address_for_slot(dest->single_stack_ix()); if (type == T_OBJECT || type == T_ARRAY) { __ verify_oop(src->as_register()); + __ movptr (dst, src->as_register()); + } else { + __ movl (dst, src->as_register()); } - __ movl (dst, src->as_register()); } else if (src->is_double_cpu()) { Address dstLO = frame_map()->address_for_slot(dest->double_stack_ix(), lo_word_offset_in_bytes); Address dstHI = frame_map()->address_for_slot(dest->double_stack_ix(), hi_word_offset_in_bytes); - __ movl (dstLO, src->as_register_lo()); - __ movl (dstHI, src->as_register_hi()); + __ movptr (dstLO, src->as_register_lo()); + NOT_LP64(__ movptr (dstHI, src->as_register_hi())); } else if (src->is_single_xmm()) { Address dst_addr = frame_map()->address_for_slot(dest->single_stack_ix()); @@ -885,6 +968,8 @@ void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch } if (patch_code != lir_patch_none) { patch = new PatchingStub(_masm, PatchingStub::access_field_id); + Address toa = as_Address(to_addr); + assert(toa.disp() != 0, "must have"); } if (info != NULL) { add_debug_info_for_null_check_here(info); @@ -918,6 +1003,10 @@ void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch case T_ADDRESS: // fall through case T_ARRAY: // fall through case T_OBJECT: // fall through +#ifdef _LP64 + __ movptr(as_Address(to_addr), src->as_register()); + break; +#endif // _LP64 case T_INT: __ movl(as_Address(to_addr), src->as_register()); break; @@ -925,6 +1014,9 @@ void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch case T_LONG: { Register from_lo = src->as_register_lo(); Register from_hi = src->as_register_hi(); +#ifdef _LP64 + __ movptr(as_Address_lo(to_addr), from_lo); +#else Register base = to_addr->base()->as_register(); Register index = noreg; if (to_addr->index()->is_register()) { @@ -950,6 +1042,7 @@ void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch } __ movl(as_Address_hi(to_addr), from_hi); } +#endif // _LP64 break; } @@ -982,16 +1075,18 @@ void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) { assert(dest->is_register(), "should not call otherwise"); if (dest->is_single_cpu()) { - __ movl(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); if (type == T_ARRAY || type == T_OBJECT) { + __ movptr(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); __ verify_oop(dest->as_register()); + } else { + __ movl(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); } } else if (dest->is_double_cpu()) { Address src_addr_LO = frame_map()->address_for_slot(src->double_stack_ix(), lo_word_offset_in_bytes); Address src_addr_HI = frame_map()->address_for_slot(src->double_stack_ix(), hi_word_offset_in_bytes); - __ movl(dest->as_register_hi(), src_addr_HI); - __ movl(dest->as_register_lo(), src_addr_LO); + __ movptr(dest->as_register_lo(), src_addr_LO); + NOT_LP64(__ movptr(dest->as_register_hi(), src_addr_HI)); } else if (dest->is_single_xmm()) { Address src_addr = frame_map()->address_for_slot(src->single_stack_ix()); @@ -1019,15 +1114,25 @@ void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) { void LIR_Assembler::stack2stack(LIR_Opr src, LIR_Opr dest, BasicType type) { if (src->is_single_stack()) { - __ pushl(frame_map()->address_for_slot(src ->single_stack_ix())); - __ popl (frame_map()->address_for_slot(dest->single_stack_ix())); + if (type == T_OBJECT || type == T_ARRAY) { + __ pushptr(frame_map()->address_for_slot(src ->single_stack_ix())); + __ popptr (frame_map()->address_for_slot(dest->single_stack_ix())); + } else { + __ pushl(frame_map()->address_for_slot(src ->single_stack_ix())); + __ popl (frame_map()->address_for_slot(dest->single_stack_ix())); + } } else if (src->is_double_stack()) { +#ifdef _LP64 + __ pushptr(frame_map()->address_for_slot(src ->double_stack_ix())); + __ popptr (frame_map()->address_for_slot(dest->double_stack_ix())); +#else __ pushl(frame_map()->address_for_slot(src ->double_stack_ix(), 0)); - // push and pop the part at src + 4, adding 4 for the previous push - __ pushl(frame_map()->address_for_slot(src ->double_stack_ix(), 4 + 4)); - __ popl (frame_map()->address_for_slot(dest->double_stack_ix(), 4 + 4)); + // push and pop the part at src + wordSize, adding wordSize for the previous push + __ pushl(frame_map()->address_for_slot(src ->double_stack_ix(), 2 * wordSize)); + __ popl (frame_map()->address_for_slot(dest->double_stack_ix(), 2 * wordSize)); __ popl (frame_map()->address_for_slot(dest->double_stack_ix(), 0)); +#endif // _LP64 } else { ShouldNotReachHere(); @@ -1052,7 +1157,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch // so blow away the value of to_rinfo before loading a // partial word into it. Do it here so that it precedes // the potential patch point below. - __ xorl(dest->as_register(), dest->as_register()); + __ xorptr(dest->as_register(), dest->as_register()); } break; } @@ -1060,6 +1165,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch PatchingStub* patch = NULL; if (patch_code != lir_patch_none) { patch = new PatchingStub(_masm, PatchingStub::access_field_id); + assert(from_addr.disp() != 0, "must have"); } if (info != NULL) { add_debug_info_for_null_check_here(info); @@ -1091,13 +1197,21 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch case T_ADDRESS: // fall through case T_OBJECT: // fall through case T_ARRAY: // fall through +#ifdef _LP64 + __ movptr(dest->as_register(), from_addr); + break; +#endif // _L64 case T_INT: - __ movl(dest->as_register(), from_addr); + // %%% could this be a movl? this is safer but longer instruction + __ movl2ptr(dest->as_register(), from_addr); break; case T_LONG: { Register to_lo = dest->as_register_lo(); Register to_hi = dest->as_register_hi(); +#ifdef _LP64 + __ movptr(to_lo, as_Address_lo(addr)); +#else Register base = addr->base()->as_register(); Register index = noreg; if (addr->index()->is_register()) { @@ -1109,7 +1223,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch // array access so this code will never have to deal with // patches or null checks. assert(info == NULL && patch == NULL, "must be"); - __ leal(to_hi, as_Address(addr)); + __ lea(to_hi, as_Address(addr)); __ movl(to_lo, Address(to_hi, 0)); __ movl(to_hi, Address(to_hi, BytesPerWord)); } else if (base == to_lo || index == to_lo) { @@ -1132,6 +1246,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch } __ movl(to_hi, as_Address_hi(addr)); } +#endif // _LP64 break; } @@ -1140,12 +1255,13 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch Register dest_reg = dest->as_register(); assert(VM_Version::is_P6() || dest_reg->has_byte_register(), "must use byte registers if not P6"); if (VM_Version::is_P6() || from_addr.uses(dest_reg)) { - __ movsxb(dest_reg, from_addr); + __ movsbl(dest_reg, from_addr); } else { __ movb(dest_reg, from_addr); __ shll(dest_reg, 24); __ sarl(dest_reg, 24); } + // These are unsigned so the zero extension on 64bit is just what we need break; } @@ -1153,22 +1269,26 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch Register dest_reg = dest->as_register(); assert(VM_Version::is_P6() || dest_reg->has_byte_register(), "must use byte registers if not P6"); if (VM_Version::is_P6() || from_addr.uses(dest_reg)) { - __ movzxw(dest_reg, from_addr); + __ movzwl(dest_reg, from_addr); } else { __ movw(dest_reg, from_addr); } + // This is unsigned so the zero extension on 64bit is just what we need + // __ movl2ptr(dest_reg, dest_reg); break; } case T_SHORT: { Register dest_reg = dest->as_register(); if (VM_Version::is_P6() || from_addr.uses(dest_reg)) { - __ movsxw(dest_reg, from_addr); + __ movswl(dest_reg, from_addr); } else { __ movw(dest_reg, from_addr); __ shll(dest_reg, 16); __ sarl(dest_reg, 16); } + // Might not be needed in 64bit but certainly doesn't hurt (except for code size) + __ movl2ptr(dest_reg, dest_reg); break; } @@ -1306,9 +1426,13 @@ void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) { switch (op->bytecode()) { case Bytecodes::_i2l: +#ifdef _LP64 + __ movl2ptr(dest->as_register_lo(), src->as_register()); +#else move_regs(src->as_register(), dest->as_register_lo()); move_regs(src->as_register(), dest->as_register_hi()); __ sarl(dest->as_register_hi(), 31); +#endif // LP64 break; case Bytecodes::_l2i: @@ -1346,9 +1470,9 @@ void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) { case Bytecodes::_i2f: case Bytecodes::_i2d: if (dest->is_single_xmm()) { - __ cvtsi2ss(dest->as_xmm_float_reg(), src->as_register()); + __ cvtsi2ssl(dest->as_xmm_float_reg(), src->as_register()); } else if (dest->is_double_xmm()) { - __ cvtsi2sd(dest->as_xmm_double_reg(), src->as_register()); + __ cvtsi2sdl(dest->as_xmm_double_reg(), src->as_register()); } else { assert(dest->fpu() == 0, "result must be on TOS"); __ movl(Address(rsp, 0), src->as_register()); @@ -1359,9 +1483,9 @@ void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) { case Bytecodes::_f2i: case Bytecodes::_d2i: if (src->is_single_xmm()) { - __ cvttss2si(dest->as_register(), src->as_xmm_float_reg()); + __ cvttss2sil(dest->as_register(), src->as_xmm_float_reg()); } else if (src->is_double_xmm()) { - __ cvttsd2si(dest->as_register(), src->as_xmm_double_reg()); + __ cvttsd2sil(dest->as_register(), src->as_xmm_double_reg()); } else { assert(src->fpu() == 0, "input must be on TOS"); __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_trunc())); @@ -1382,8 +1506,8 @@ void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) { assert(!dest->is_xmm_register(), "result in xmm register not supported (no SSE instruction present)"); assert(dest->fpu() == 0, "result must be on TOS"); - __ movl(Address(rsp, 0), src->as_register_lo()); - __ movl(Address(rsp, BytesPerWord), src->as_register_hi()); + __ movptr(Address(rsp, 0), src->as_register_lo()); + NOT_LP64(__ movl(Address(rsp, BytesPerWord), src->as_register_hi())); __ fild_d(Address(rsp, 0)); // float result is rounded later through spilling break; @@ -1392,7 +1516,7 @@ void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) { case Bytecodes::_d2l: assert(!src->is_xmm_register(), "input in xmm register not supported (no SSE instruction present)"); assert(src->fpu() == 0, "input must be on TOS"); - assert(dest == FrameMap::rax_rdx_long_opr, "runtime stub places result in these registers"); + assert(dest == FrameMap::long0_opr, "runtime stub places result in these registers"); // instruction sequence too long to inline it here { @@ -1439,7 +1563,7 @@ void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) { } else if (len == tmp3) { // everything is ok } else { - __ movl(tmp3, len); + __ mov(tmp3, len); } __ allocate_array(op->obj()->as_register(), len, @@ -1466,31 +1590,32 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { CodeStub* stub = op->stub(); Label done; - __ cmpl(value, 0); + __ cmpptr(value, (int32_t)NULL_WORD); __ jcc(Assembler::equal, done); add_debug_info_for_null_check_here(op->info_for_exception()); - __ movl(k_RInfo, Address(array, oopDesc::klass_offset_in_bytes())); - __ movl(klass_RInfo, Address(value, oopDesc::klass_offset_in_bytes())); + __ movptr(k_RInfo, Address(array, oopDesc::klass_offset_in_bytes())); + __ movptr(klass_RInfo, Address(value, oopDesc::klass_offset_in_bytes())); // get instance klass - __ movl(k_RInfo, Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc))); + __ movptr(k_RInfo, Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc))); // get super_check_offset __ movl(Rtmp1, Address(k_RInfo, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes())); // See if we get an immediate positive hit - __ cmpl(k_RInfo, Address(klass_RInfo, Rtmp1, Address::times_1)); + __ cmpptr(k_RInfo, Address(klass_RInfo, Rtmp1, Address::times_1)); __ jcc(Assembler::equal, done); // check for immediate negative hit __ cmpl(Rtmp1, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()); __ jcc(Assembler::notEqual, *stub->entry()); // check for self - __ cmpl(klass_RInfo, k_RInfo); + __ cmpptr(klass_RInfo, k_RInfo); __ jcc(Assembler::equal, done); - __ pushl(klass_RInfo); - __ pushl(k_RInfo); + __ push(klass_RInfo); + __ push(k_RInfo); __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); - __ popl(klass_RInfo); - __ popl(k_RInfo); + __ pop(klass_RInfo); + __ pop(k_RInfo); + // result is a boolean __ cmpl(k_RInfo, 0); __ jcc(Assembler::equal, *stub->entry()); __ bind(done); @@ -1521,10 +1646,14 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { if (!k->is_loaded()) { jobject2reg_with_patching(k_RInfo, op->info_for_patch()); } else { +#ifdef _LP64 + __ movoop(k_RInfo, k->encoding()); +#else k_RInfo = noreg; +#endif // _LP64 } assert(obj != k_RInfo, "must be different"); - __ cmpl(obj, 0); + __ cmpptr(obj, (int32_t)NULL_WORD); if (op->profiled_method() != NULL) { ciMethod* method = op->profiled_method(); int bci = op->profiled_bci(); @@ -1556,9 +1685,13 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { // get object classo // not a safepoint as obj null check happens earlier if (k->is_loaded()) { +#ifdef _LP64 + __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); +#else __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->encoding()); +#endif // _LP64 } else { - __ cmpl(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); + __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); } __ jcc(Assembler::notEqual, *stub->entry()); @@ -1566,24 +1699,37 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { } else { // get object class // not a safepoint as obj null check happens earlier - __ movl(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); + __ movptr(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); if (k->is_loaded()) { // See if we get an immediate positive hit +#ifdef _LP64 + __ cmpptr(k_RInfo, Address(klass_RInfo, k->super_check_offset())); +#else __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->encoding()); +#endif // _LP64 if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) { __ jcc(Assembler::notEqual, *stub->entry()); } else { // See if we get an immediate positive hit __ jcc(Assembler::equal, done); // check for self +#ifdef _LP64 + __ cmpptr(klass_RInfo, k_RInfo); +#else __ cmpoop(klass_RInfo, k->encoding()); +#endif // _LP64 __ jcc(Assembler::equal, done); - __ pushl(klass_RInfo); + __ push(klass_RInfo); +#ifdef _LP64 + __ push(k_RInfo); +#else __ pushoop(k->encoding()); +#endif // _LP64 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); - __ popl(klass_RInfo); - __ popl(klass_RInfo); + __ pop(klass_RInfo); + __ pop(klass_RInfo); + // result is a boolean __ cmpl(klass_RInfo, 0); __ jcc(Assembler::equal, *stub->entry()); } @@ -1591,20 +1737,21 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { } else { __ movl(Rtmp1, Address(k_RInfo, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes())); // See if we get an immediate positive hit - __ cmpl(k_RInfo, Address(klass_RInfo, Rtmp1, Address::times_1)); + __ cmpptr(k_RInfo, Address(klass_RInfo, Rtmp1, Address::times_1)); __ jcc(Assembler::equal, done); // check for immediate negative hit __ cmpl(Rtmp1, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()); __ jcc(Assembler::notEqual, *stub->entry()); // check for self - __ cmpl(klass_RInfo, k_RInfo); + __ cmpptr(klass_RInfo, k_RInfo); __ jcc(Assembler::equal, done); - __ pushl(klass_RInfo); - __ pushl(k_RInfo); + __ push(klass_RInfo); + __ push(k_RInfo); __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); - __ popl(klass_RInfo); - __ popl(k_RInfo); + __ pop(klass_RInfo); + __ pop(k_RInfo); + // result is a boolean __ cmpl(k_RInfo, 0); __ jcc(Assembler::equal, *stub->entry()); __ bind(done); @@ -1612,7 +1759,7 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { } if (dst != obj) { - __ movl(dst, obj); + __ mov(dst, obj); } } else if (code == lir_instanceof) { Register obj = op->object()->as_register(); @@ -1632,29 +1779,33 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { // so let's do it before loading the class if (!k->is_loaded()) { jobject2reg_with_patching(k_RInfo, op->info_for_patch()); + } else { + LP64_ONLY(__ movoop(k_RInfo, k->encoding())); } assert(obj != k_RInfo, "must be different"); __ verify_oop(obj); if (op->fast_check()) { - __ cmpl(obj, 0); + __ cmpptr(obj, (int32_t)NULL_WORD); __ jcc(Assembler::equal, zero); // get object class // not a safepoint as obj null check happens earlier - if (k->is_loaded()) { - __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->encoding()); + if (LP64_ONLY(false &&) k->is_loaded()) { + NOT_LP64(__ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->encoding())); k_RInfo = noreg; } else { - __ cmpl(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); + __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); } __ jcc(Assembler::equal, one); } else { // get object class // not a safepoint as obj null check happens earlier - __ cmpl(obj, 0); + __ cmpptr(obj, (int32_t)NULL_WORD); __ jcc(Assembler::equal, zero); - __ movl(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); + __ movptr(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); + +#ifndef _LP64 if (k->is_loaded()) { // See if we get an immediate positive hit __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->encoding()); @@ -1663,40 +1814,43 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { // check for self __ cmpoop(klass_RInfo, k->encoding()); __ jcc(Assembler::equal, one); - __ pushl(klass_RInfo); + __ push(klass_RInfo); __ pushoop(k->encoding()); __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); - __ popl(klass_RInfo); - __ popl(dst); + __ pop(klass_RInfo); + __ pop(dst); __ jmp(done); } } else { +#else + { // YUCK +#endif // LP64 assert(dst != klass_RInfo && dst != k_RInfo, "need 3 registers"); __ movl(dst, Address(k_RInfo, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes())); // See if we get an immediate positive hit - __ cmpl(k_RInfo, Address(klass_RInfo, dst, Address::times_1)); + __ cmpptr(k_RInfo, Address(klass_RInfo, dst, Address::times_1)); __ jcc(Assembler::equal, one); // check for immediate negative hit __ cmpl(dst, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()); __ jcc(Assembler::notEqual, zero); // check for self - __ cmpl(klass_RInfo, k_RInfo); + __ cmpptr(klass_RInfo, k_RInfo); __ jcc(Assembler::equal, one); - __ pushl(klass_RInfo); - __ pushl(k_RInfo); + __ push(klass_RInfo); + __ push(k_RInfo); __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); - __ popl(klass_RInfo); - __ popl(dst); + __ pop(klass_RInfo); + __ pop(dst); __ jmp(done); } } __ bind(zero); - __ xorl(dst, dst); + __ xorptr(dst, dst); __ jmp(done); __ bind(one); - __ movl(dst, 1); + __ movptr(dst, 1); __ bind(done); } else { ShouldNotReachHere(); @@ -1706,8 +1860,7 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) { - if (op->code() == lir_cas_long) { - assert(VM_Version::supports_cx8(), "wrong machine"); + if (LP64_ONLY(false &&) op->code() == lir_cas_long && VM_Version::supports_cx8()) { assert(op->cmp_value()->as_register_lo() == rax, "wrong register"); assert(op->cmp_value()->as_register_hi() == rdx, "wrong register"); assert(op->new_value()->as_register_lo() == rbx, "wrong register"); @@ -1716,10 +1869,11 @@ void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) { if (os::is_MP()) { __ lock(); } - __ cmpxchg8(Address(addr, 0)); + NOT_LP64(__ cmpxchg8(Address(addr, 0))); - } else if (op->code() == lir_cas_int || op->code() == lir_cas_obj) { - Register addr = op->addr()->as_register(); + } else if (op->code() == lir_cas_int || op->code() == lir_cas_obj ) { + NOT_LP64(assert(op->addr()->is_single_cpu(), "must be single");) + Register addr = (op->addr()->is_single_cpu() ? op->addr()->as_register() : op->addr()->as_register_lo()); Register newval = op->new_value()->as_register(); Register cmpval = op->cmp_value()->as_register(); assert(cmpval == rax, "wrong register"); @@ -1730,7 +1884,28 @@ void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) { if (os::is_MP()) { __ lock(); } - __ cmpxchg(newval, Address(addr, 0)); + if ( op->code() == lir_cas_obj) { + __ cmpxchgptr(newval, Address(addr, 0)); + } else if (op->code() == lir_cas_int) { + __ cmpxchgl(newval, Address(addr, 0)); + } else { + LP64_ONLY(__ cmpxchgq(newval, Address(addr, 0))); + } +#ifdef _LP64 + } else if (op->code() == lir_cas_long) { + Register addr = (op->addr()->is_single_cpu() ? op->addr()->as_register() : op->addr()->as_register_lo()); + Register newval = op->new_value()->as_register_lo(); + Register cmpval = op->cmp_value()->as_register_lo(); + assert(cmpval == rax, "wrong register"); + assert(newval != NULL, "new val must be register"); + assert(cmpval != newval, "cmp and new values must be in different registers"); + assert(cmpval != addr, "cmp and addr must be in different registers"); + assert(newval != addr, "new value and addr must be in different registers"); + if (os::is_MP()) { + __ lock(); + } + __ cmpxchgq(newval, Address(addr, 0)); +#endif // _LP64 } else { Unimplemented(); } @@ -1765,17 +1940,17 @@ void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, L // optimized version that does not require a branch if (opr2->is_single_cpu()) { assert(opr2->cpu_regnr() != result->cpu_regnr(), "opr2 already overwritten by previous move"); - __ cmovl(ncond, result->as_register(), opr2->as_register()); + __ cmov(ncond, result->as_register(), opr2->as_register()); } else if (opr2->is_double_cpu()) { assert(opr2->cpu_regnrLo() != result->cpu_regnrLo() && opr2->cpu_regnrLo() != result->cpu_regnrHi(), "opr2 already overwritten by previous move"); assert(opr2->cpu_regnrHi() != result->cpu_regnrLo() && opr2->cpu_regnrHi() != result->cpu_regnrHi(), "opr2 already overwritten by previous move"); - __ cmovl(ncond, result->as_register_lo(), opr2->as_register_lo()); - __ cmovl(ncond, result->as_register_hi(), opr2->as_register_hi()); + __ cmovptr(ncond, result->as_register_lo(), opr2->as_register_lo()); + NOT_LP64(__ cmovptr(ncond, result->as_register_hi(), opr2->as_register_hi());) } else if (opr2->is_single_stack()) { __ cmovl(ncond, result->as_register(), frame_map()->address_for_slot(opr2->single_stack_ix())); } else if (opr2->is_double_stack()) { - __ cmovl(ncond, result->as_register_lo(), frame_map()->address_for_slot(opr2->double_stack_ix(), lo_word_offset_in_bytes)); - __ cmovl(ncond, result->as_register_hi(), frame_map()->address_for_slot(opr2->double_stack_ix(), hi_word_offset_in_bytes)); + __ cmovptr(ncond, result->as_register_lo(), frame_map()->address_for_slot(opr2->double_stack_ix(), lo_word_offset_in_bytes)); + NOT_LP64(__ cmovptr(ncond, result->as_register_hi(), frame_map()->address_for_slot(opr2->double_stack_ix(), hi_word_offset_in_bytes));) } else { ShouldNotReachHere(); } @@ -1851,23 +2026,28 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr // cpu register - cpu register Register rreg_lo = right->as_register_lo(); Register rreg_hi = right->as_register_hi(); - assert_different_registers(lreg_lo, lreg_hi, rreg_lo, rreg_hi); + NOT_LP64(assert_different_registers(lreg_lo, lreg_hi, rreg_lo, rreg_hi)); + LP64_ONLY(assert_different_registers(lreg_lo, rreg_lo)); switch (code) { case lir_add: - __ addl(lreg_lo, rreg_lo); - __ adcl(lreg_hi, rreg_hi); + __ addptr(lreg_lo, rreg_lo); + NOT_LP64(__ adcl(lreg_hi, rreg_hi)); break; case lir_sub: - __ subl(lreg_lo, rreg_lo); - __ sbbl(lreg_hi, rreg_hi); + __ subptr(lreg_lo, rreg_lo); + NOT_LP64(__ sbbl(lreg_hi, rreg_hi)); break; case lir_mul: +#ifdef _LP64 + __ imulq(lreg_lo, rreg_lo); +#else assert(lreg_lo == rax && lreg_hi == rdx, "must be"); __ imull(lreg_hi, rreg_lo); __ imull(rreg_hi, lreg_lo); __ addl (rreg_hi, lreg_hi); __ mull (rreg_lo); __ addl (lreg_hi, rreg_hi); +#endif // _LP64 break; default: ShouldNotReachHere(); @@ -1875,20 +2055,35 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr } else if (right->is_constant()) { // cpu register - constant +#ifdef _LP64 + jlong c = right->as_constant_ptr()->as_jlong_bits(); + __ movptr(r10, (intptr_t) c); + switch (code) { + case lir_add: + __ addptr(lreg_lo, r10); + break; + case lir_sub: + __ subptr(lreg_lo, r10); + break; + default: + ShouldNotReachHere(); + } +#else jint c_lo = right->as_constant_ptr()->as_jint_lo(); jint c_hi = right->as_constant_ptr()->as_jint_hi(); switch (code) { case lir_add: - __ addl(lreg_lo, c_lo); + __ addptr(lreg_lo, c_lo); __ adcl(lreg_hi, c_hi); break; case lir_sub: - __ subl(lreg_lo, c_lo); + __ subptr(lreg_lo, c_lo); __ sbbl(lreg_hi, c_hi); break; default: ShouldNotReachHere(); } +#endif // _LP64 } else { ShouldNotReachHere(); @@ -2065,11 +2260,11 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr jint c = right->as_constant_ptr()->as_jint(); switch (code) { case lir_add: { - __ increment(laddr, c); + __ incrementl(laddr, c); break; } case lir_sub: { - __ decrement(laddr, c); + __ decrementl(laddr, c); break; } default: ShouldNotReachHere(); @@ -2211,9 +2406,9 @@ void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr } else { Register rright = right->as_register(); switch (code) { - case lir_logic_and: __ andl (reg, rright); break; - case lir_logic_or : __ orl (reg, rright); break; - case lir_logic_xor: __ xorl (reg, rright); break; + case lir_logic_and: __ andptr (reg, rright); break; + case lir_logic_or : __ orptr (reg, rright); break; + case lir_logic_xor: __ xorptr (reg, rright); break; default: ShouldNotReachHere(); } } @@ -2222,6 +2417,21 @@ void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr Register l_lo = left->as_register_lo(); Register l_hi = left->as_register_hi(); if (right->is_constant()) { +#ifdef _LP64 + __ mov64(rscratch1, right->as_constant_ptr()->as_jlong()); + switch (code) { + case lir_logic_and: + __ andq(l_lo, rscratch1); + break; + case lir_logic_or: + __ orq(l_lo, rscratch1); + break; + case lir_logic_xor: + __ xorq(l_lo, rscratch1); + break; + default: ShouldNotReachHere(); + } +#else int r_lo = right->as_constant_ptr()->as_jint_lo(); int r_hi = right->as_constant_ptr()->as_jint_hi(); switch (code) { @@ -2239,22 +2449,23 @@ void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr break; default: ShouldNotReachHere(); } +#endif // _LP64 } else { Register r_lo = right->as_register_lo(); Register r_hi = right->as_register_hi(); assert(l_lo != r_hi, "overwriting registers"); switch (code) { case lir_logic_and: - __ andl(l_lo, r_lo); - __ andl(l_hi, r_hi); + __ andptr(l_lo, r_lo); + NOT_LP64(__ andptr(l_hi, r_hi);) break; case lir_logic_or: - __ orl(l_lo, r_lo); - __ orl(l_hi, r_hi); + __ orptr(l_lo, r_lo); + NOT_LP64(__ orptr(l_hi, r_hi);) break; case lir_logic_xor: - __ xorl(l_lo, r_lo); - __ xorl(l_hi, r_hi); + __ xorptr(l_lo, r_lo); + NOT_LP64(__ xorptr(l_hi, r_hi);) break; default: ShouldNotReachHere(); } @@ -2263,6 +2474,9 @@ void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr Register dst_lo = dst->as_register_lo(); Register dst_hi = dst->as_register_hi(); +#ifdef _LP64 + move_regs(l_lo, dst_lo); +#else if (dst_lo == l_hi) { assert(dst_hi != l_lo, "overwriting registers"); move_regs(l_hi, dst_hi); @@ -2272,6 +2486,7 @@ void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr move_regs(l_lo, dst_lo); move_regs(l_hi, dst_hi); } +#endif // _LP64 } } @@ -2306,7 +2521,7 @@ void LIR_Assembler::arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right, move_regs(lreg, dreg); } else if (code == lir_irem) { Label done; - __ movl(dreg, lreg); + __ mov(dreg, lreg); __ andl(dreg, 0x80000000 | (divisor - 1)); __ jcc(Assembler::positive, done); __ decrement(dreg); @@ -2340,21 +2555,36 @@ void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, Register reg1 = opr1->as_register(); if (opr2->is_single_cpu()) { // cpu register - cpu register - __ cmpl(reg1, opr2->as_register()); + if (opr1->type() == T_OBJECT || opr1->type() == T_ARRAY) { + __ cmpptr(reg1, opr2->as_register()); + } else { + assert(opr2->type() != T_OBJECT && opr2->type() != T_ARRAY, "cmp int, oop?"); + __ cmpl(reg1, opr2->as_register()); + } } else if (opr2->is_stack()) { // cpu register - stack - __ cmpl(reg1, frame_map()->address_for_slot(opr2->single_stack_ix())); + if (opr1->type() == T_OBJECT || opr1->type() == T_ARRAY) { + __ cmpptr(reg1, frame_map()->address_for_slot(opr2->single_stack_ix())); + } else { + __ cmpl(reg1, frame_map()->address_for_slot(opr2->single_stack_ix())); + } } else if (opr2->is_constant()) { // cpu register - constant LIR_Const* c = opr2->as_constant_ptr(); if (c->type() == T_INT) { __ cmpl(reg1, c->as_jint()); - } else if (c->type() == T_OBJECT) { + } else if (c->type() == T_OBJECT || c->type() == T_ARRAY) { + // In 64bit oops are single register jobject o = c->as_jobject(); if (o == NULL) { - __ cmpl(reg1, NULL_WORD); + __ cmpptr(reg1, (int32_t)NULL_WORD); } else { +#ifdef _LP64 + __ movoop(rscratch1, o); + __ cmpptr(reg1, rscratch1); +#else __ cmpoop(reg1, c->as_jobject()); +#endif // _LP64 } } else { ShouldNotReachHere(); @@ -2373,6 +2603,9 @@ void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, Register xlo = opr1->as_register_lo(); Register xhi = opr1->as_register_hi(); if (opr2->is_double_cpu()) { +#ifdef _LP64 + __ cmpptr(xlo, opr2->as_register_lo()); +#else // cpu register - cpu register Register ylo = opr2->as_register_lo(); Register yhi = opr2->as_register_hi(); @@ -2381,11 +2614,16 @@ void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, if (condition == lir_cond_equal || condition == lir_cond_notEqual) { __ orl(xhi, xlo); } +#endif // _LP64 } else if (opr2->is_constant()) { // cpu register - constant 0 assert(opr2->as_jlong() == (jlong)0, "only handles zero"); +#ifdef _LP64 + __ cmpptr(xlo, (int32_t)opr2->as_jlong()); +#else assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "only handles equals case"); __ orl(xhi, xlo); +#endif // _LP64 } else { ShouldNotReachHere(); } @@ -2438,16 +2676,28 @@ void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, __ fcmp(noreg, opr2->fpu(), op->fpu_pop_count() > 0, op->fpu_pop_count() > 1); } else if (opr1->is_address() && opr2->is_constant()) { + LIR_Const* c = opr2->as_constant_ptr(); +#ifdef _LP64 + if (c->type() == T_OBJECT || c->type() == T_ARRAY) { + assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "need to reverse"); + __ movoop(rscratch1, c->as_jobject()); + } +#endif // LP64 if (op->info() != NULL) { add_debug_info_for_null_check_here(op->info()); } // special case: address - constant LIR_Address* addr = opr1->as_address_ptr(); - LIR_Const* c = opr2->as_constant_ptr(); if (c->type() == T_INT) { __ cmpl(as_Address(addr), c->as_jint()); - } else if (c->type() == T_OBJECT) { + } else if (c->type() == T_OBJECT || c->type() == T_ARRAY) { +#ifdef _LP64 + // %%% Make this explode if addr isn't reachable until we figure out a + // better strategy by giving noreg as the temp for as_Address + __ cmpptr(rscratch1, as_Address(addr, noreg)); +#else __ cmpoop(as_Address(addr), c->as_jobject()); +#endif // _LP64 } else { ShouldNotReachHere(); } @@ -2476,11 +2726,27 @@ void LIR_Assembler::comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Op } } else { assert(code == lir_cmp_l2i, "check"); +#ifdef _LP64 + Register dest = dst->as_register(); + __ xorptr(dest, dest); + Label high, done; + __ cmpptr(left->as_register_lo(), right->as_register_lo()); + __ jcc(Assembler::equal, done); + __ jcc(Assembler::greater, high); + __ decrement(dest); + __ jmp(done); + __ bind(high); + __ increment(dest); + + __ bind(done); + +#else __ lcmp2int(left->as_register_hi(), left->as_register_lo(), right->as_register_hi(), right->as_register_lo()); move_regs(left->as_register_hi(), dst->as_register()); +#endif // _LP64 } } @@ -2551,7 +2817,8 @@ void LIR_Assembler::emit_static_call_stub() { __ movoop(rbx, (jobject)NULL); // must be set to -1 at code generation time assert(!os::is_MP() || ((__ offset() + 1) % BytesPerWord) == 0, "must be aligned on MP"); - __ jump(RuntimeAddress((address)-1)); + // On 64bit this will die since it will take a movq & jmp, must be only a jmp + __ jump(RuntimeAddress(__ pc())); assert(__ offset() - start <= call_stub_size, "stub too big") __ end_a_stub(); @@ -2616,6 +2883,14 @@ void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, LIR_Opr count, LIR_Opr Register lo = left->as_register_lo(); Register hi = left->as_register_hi(); assert(lo != SHIFT_count && hi != SHIFT_count, "left cannot be ECX"); +#ifdef _LP64 + switch (code) { + case lir_shl: __ shlptr(lo); break; + case lir_shr: __ sarptr(lo); break; + case lir_ushr: __ shrptr(lo); break; + default: ShouldNotReachHere(); + } +#else switch (code) { case lir_shl: __ lshl(hi, lo); break; @@ -2623,6 +2898,7 @@ void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, LIR_Opr count, LIR_Opr case lir_ushr: __ lshr(hi, lo, false); break; default: ShouldNotReachHere(); } +#endif // LP64 } else { ShouldNotReachHere(); } @@ -2643,7 +2919,21 @@ void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, jint count, LIR_Opr de default: ShouldNotReachHere(); } } else if (dest->is_double_cpu()) { +#ifndef _LP64 Unimplemented(); +#else + // first move left into dest so that left is not destroyed by the shift + Register value = dest->as_register_lo(); + count = count & 0x1F; // Java spec + + move_regs(left->as_register_lo(), value); + switch (code) { + case lir_shl: __ shlptr(value, count); break; + case lir_shr: __ sarptr(value, count); break; + case lir_ushr: __ shrptr(value, count); break; + default: ShouldNotReachHere(); + } +#endif // _LP64 } else { ShouldNotReachHere(); } @@ -2654,7 +2944,7 @@ void LIR_Assembler::store_parameter(Register r, int offset_from_rsp_in_words) { assert(offset_from_rsp_in_words >= 0, "invalid offset from rsp"); int offset_from_rsp_in_bytes = offset_from_rsp_in_words * BytesPerWord; assert(offset_from_rsp_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset"); - __ movl (Address(rsp, offset_from_rsp_in_bytes), r); + __ movptr (Address(rsp, offset_from_rsp_in_bytes), r); } @@ -2662,7 +2952,7 @@ void LIR_Assembler::store_parameter(jint c, int offset_from_rsp_in_words) { assert(offset_from_rsp_in_words >= 0, "invalid offset from rsp"); int offset_from_rsp_in_bytes = offset_from_rsp_in_words * BytesPerWord; assert(offset_from_rsp_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset"); - __ movl (Address(rsp, offset_from_rsp_in_bytes), c); + __ movptr (Address(rsp, offset_from_rsp_in_bytes), c); } @@ -2710,27 +3000,52 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { // these are just temporary placements until we need to reload store_parameter(src_pos, 3); store_parameter(src, 4); - assert(src == rcx && src_pos == rdx, "mismatch in calling convention"); + NOT_LP64(assert(src == rcx && src_pos == rdx, "mismatch in calling convention");) + + address entry = CAST_FROM_FN_PTR(address, Runtime1::arraycopy); // pass arguments: may push as this is not a safepoint; SP must be fix at each safepoint - __ pushl(length); - __ pushl(dst_pos); - __ pushl(dst); - __ pushl(src_pos); - __ pushl(src); - address entry = CAST_FROM_FN_PTR(address, Runtime1::arraycopy); +#ifdef _LP64 + // The arguments are in java calling convention so we can trivially shift them to C + // convention + assert_different_registers(c_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4); + __ mov(c_rarg0, j_rarg0); + assert_different_registers(c_rarg1, j_rarg2, j_rarg3, j_rarg4); + __ mov(c_rarg1, j_rarg1); + assert_different_registers(c_rarg2, j_rarg3, j_rarg4); + __ mov(c_rarg2, j_rarg2); + assert_different_registers(c_rarg3, j_rarg4); + __ mov(c_rarg3, j_rarg3); +#ifdef _WIN64 + // Allocate abi space for args but be sure to keep stack aligned + __ subptr(rsp, 6*wordSize); + store_parameter(j_rarg4, 4); + __ call(RuntimeAddress(entry)); + __ addptr(rsp, 6*wordSize); +#else + __ mov(c_rarg4, j_rarg4); + __ call(RuntimeAddress(entry)); +#endif // _WIN64 +#else + __ push(length); + __ push(dst_pos); + __ push(dst); + __ push(src_pos); + __ push(src); __ call_VM_leaf(entry, 5); // removes pushed parameter from the stack +#endif // _LP64 + __ cmpl(rax, 0); __ jcc(Assembler::equal, *stub->continuation()); // Reload values from the stack so they are where the stub // expects them. - __ movl (dst, Address(rsp, 0*BytesPerWord)); - __ movl (dst_pos, Address(rsp, 1*BytesPerWord)); - __ movl (length, Address(rsp, 2*BytesPerWord)); - __ movl (src_pos, Address(rsp, 3*BytesPerWord)); - __ movl (src, Address(rsp, 4*BytesPerWord)); + __ movptr (dst, Address(rsp, 0*BytesPerWord)); + __ movptr (dst_pos, Address(rsp, 1*BytesPerWord)); + __ movptr (length, Address(rsp, 2*BytesPerWord)); + __ movptr (src_pos, Address(rsp, 3*BytesPerWord)); + __ movptr (src, Address(rsp, 4*BytesPerWord)); __ jmp(*stub->entry()); __ bind(*stub->continuation()); @@ -2769,13 +3084,15 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { Address src_klass_addr = Address(src, oopDesc::klass_offset_in_bytes()); Address dst_klass_addr = Address(dst, oopDesc::klass_offset_in_bytes()); + // length and pos's are all sign extended at this point on 64bit + // test for NULL if (flags & LIR_OpArrayCopy::src_null_check) { - __ testl(src, src); + __ testptr(src, src); __ jcc(Assembler::zero, *stub->entry()); } if (flags & LIR_OpArrayCopy::dst_null_check) { - __ testl(dst, dst); + __ testptr(dst, dst); __ jcc(Assembler::zero, *stub->entry()); } @@ -2794,19 +3111,19 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { } if (flags & LIR_OpArrayCopy::src_range_check) { - __ leal(tmp, Address(src_pos, length, Address::times_1, 0)); + __ lea(tmp, Address(src_pos, length, Address::times_1, 0)); __ cmpl(tmp, src_length_addr); __ jcc(Assembler::above, *stub->entry()); } if (flags & LIR_OpArrayCopy::dst_range_check) { - __ leal(tmp, Address(dst_pos, length, Address::times_1, 0)); + __ lea(tmp, Address(dst_pos, length, Address::times_1, 0)); __ cmpl(tmp, dst_length_addr); __ jcc(Assembler::above, *stub->entry()); } if (flags & LIR_OpArrayCopy::type_check) { - __ movl(tmp, src_klass_addr); - __ cmpl(tmp, dst_klass_addr); + __ movptr(tmp, src_klass_addr); + __ cmpptr(tmp, dst_klass_addr); __ jcc(Assembler::notEqual, *stub->entry()); } @@ -2822,14 +3139,14 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { Label known_ok, halt; __ movoop(tmp, default_type->encoding()); if (basic_type != T_OBJECT) { - __ cmpl(tmp, dst_klass_addr); + __ cmpptr(tmp, dst_klass_addr); __ jcc(Assembler::notEqual, halt); - __ cmpl(tmp, src_klass_addr); + __ cmpptr(tmp, src_klass_addr); __ jcc(Assembler::equal, known_ok); } else { - __ cmpl(tmp, dst_klass_addr); + __ cmpptr(tmp, dst_klass_addr); __ jcc(Assembler::equal, known_ok); - __ cmpl(src, dst); + __ cmpptr(src, dst); __ jcc(Assembler::equal, known_ok); } __ bind(halt); @@ -2838,14 +3155,24 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { } #endif - __ leal(tmp, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); - store_parameter(tmp, 0); - __ leal(tmp, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); - store_parameter(tmp, 1); if (shift_amount > 0 && basic_type != T_OBJECT) { - __ shll(length, shift_amount); + __ shlptr(length, shift_amount); } + +#ifdef _LP64 + assert_different_registers(c_rarg0, dst, dst_pos, length); + __ lea(c_rarg0, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); + assert_different_registers(c_rarg1, length); + __ lea(c_rarg1, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); + __ mov(c_rarg2, length); + +#else + __ lea(tmp, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); + store_parameter(tmp, 0); + __ lea(tmp, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); + store_parameter(tmp, 1); store_parameter(length, 2); +#endif // _LP64 if (basic_type == T_OBJECT) { __ call_VM_leaf(CAST_FROM_FN_PTR(address, Runtime1::oop_arraycopy), 0); } else { @@ -2945,13 +3272,13 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) { } } } else { - __ movl(recv, Address(recv, oopDesc::klass_offset_in_bytes())); + __ movptr(recv, Address(recv, oopDesc::klass_offset_in_bytes())); Label update_done; uint i; for (i = 0; i < VirtualCallData::row_limit(); i++) { Label next_test; // See if the receiver is receiver[n]. - __ cmpl(recv, Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)))); + __ cmpptr(recv, Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)))); __ jcc(Assembler::notEqual, next_test); Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); __ addl(data_addr, DataLayout::counter_increment); @@ -2963,9 +3290,9 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) { for (i = 0; i < VirtualCallData::row_limit(); i++) { Label next_test; Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i))); - __ cmpl(recv_addr, NULL_WORD); + __ cmpptr(recv_addr, (int32_t)NULL_WORD); __ jcc(Assembler::notEqual, next_test); - __ movl(recv_addr, recv); + __ movptr(recv_addr, recv); __ movl(Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))), DataLayout::counter_increment); if (i < (VirtualCallData::row_limit() - 1)) { __ jmp(update_done); @@ -2985,7 +3312,7 @@ void LIR_Assembler::emit_delay(LIR_OpDelay*) { void LIR_Assembler::monitor_address(int monitor_no, LIR_Opr dst) { - __ leal(dst->as_register(), frame_map()->address_for_monitor_lock(monitor_no)); + __ lea(dst->as_register(), frame_map()->address_for_monitor_lock(monitor_no)); } @@ -3001,6 +3328,11 @@ void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest) { } else if (left->is_double_cpu()) { Register lo = left->as_register_lo(); +#ifdef _LP64 + Register dst = dest->as_register_lo(); + __ movptr(dst, lo); + __ negptr(dst); +#else Register hi = left->as_register_hi(); __ lneg(hi, lo); if (dest->as_register_lo() == hi) { @@ -3011,6 +3343,7 @@ void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest) { move_regs(lo, dest->as_register_lo()); move_regs(hi, dest->as_register_hi()); } +#endif // _LP64 } else if (dest->is_single_xmm()) { if (left->as_xmm_float_reg() != dest->as_xmm_float_reg()) { @@ -3039,8 +3372,9 @@ void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest) { void LIR_Assembler::leal(LIR_Opr addr, LIR_Opr dest) { assert(addr->is_address() && dest->is_register(), "check"); - Register reg = dest->as_register(); - __ leal(dest->as_register(), as_Address(addr->as_address_ptr())); + Register reg; + reg = dest->as_pointer_register(); + __ lea(reg, as_Address(addr->as_address_ptr())); } @@ -3063,9 +3397,13 @@ void LIR_Assembler::volatile_move_op(LIR_Opr src, LIR_Opr dest, BasicType type, if (src->is_double_xmm()) { if (dest->is_double_cpu()) { - __ movd(dest->as_register_lo(), src->as_xmm_double_reg()); +#ifdef _LP64 + __ movdq(dest->as_register_lo(), src->as_xmm_double_reg()); +#else + __ movdl(dest->as_register_lo(), src->as_xmm_double_reg()); __ psrlq(src->as_xmm_double_reg(), 32); - __ movd(dest->as_register_hi(), src->as_xmm_double_reg()); + __ movdl(dest->as_register_hi(), src->as_xmm_double_reg()); +#endif // _LP64 } else if (dest->is_double_stack()) { __ movdbl(frame_map()->address_for_slot(dest->double_stack_ix()), src->as_xmm_double_reg()); } else if (dest->is_address()) { @@ -3109,7 +3447,8 @@ void LIR_Assembler::volatile_move_op(LIR_Opr src, LIR_Opr dest, BasicType type, void LIR_Assembler::membar() { - __ membar(); + // QQQ sparc TSO uses this, + __ membar( Assembler::Membar_mask_bits(Assembler::StoreLoad)); } void LIR_Assembler::membar_acquire() { @@ -3124,7 +3463,12 @@ void LIR_Assembler::membar_release() { void LIR_Assembler::get_thread(LIR_Opr result_reg) { assert(result_reg->is_register(), "check"); +#ifdef _LP64 + // __ get_thread(result_reg->as_register_lo()); + __ mov(result_reg->as_register(), r15_thread); +#else __ get_thread(result_reg->as_register()); +#endif // _LP64 } diff --git a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.hpp b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.hpp index 5621a95a372..d364010aa2c 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.hpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,13 +36,20 @@ address float_constant(float f); address double_constant(double d); + bool is_literal_address(LIR_Address* addr); + + // When we need to use something other than rscratch1 use this + // method. + Address as_Address(LIR_Address* addr, Register tmp); + + public: void store_parameter(Register r, int offset_from_esp_in_words); void store_parameter(jint c, int offset_from_esp_in_words); void store_parameter(jobject c, int offset_from_esp_in_words); - enum { call_stub_size = 15, + enum { call_stub_size = NOT_LP64(15) LP64_ONLY(28), exception_handler_size = DEBUG_ONLY(1*K) NOT_DEBUG(175), - deopt_handler_size = 10 + deopt_handler_size = NOT_LP64(10) LP64_ONLY(17) }; diff --git a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp index d2f9e2d35b7..b8c29fb09a8 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp @@ -77,7 +77,7 @@ LIR_Opr LIRGenerator::result_register_for(ValueType* type, bool callee) { switch (type->tag()) { case intTag: opr = FrameMap::rax_opr; break; case objectTag: opr = FrameMap::rax_oop_opr; break; - case longTag: opr = FrameMap::rax_rdx_long_opr; break; + case longTag: opr = FrameMap::long0_opr; break; case floatTag: opr = UseSSE >= 1 ? FrameMap::xmm0_float_opr : FrameMap::fpu0_float_opr; break; case doubleTag: opr = UseSSE >= 2 ? FrameMap::xmm0_double_opr : FrameMap::fpu0_double_opr; break; @@ -117,12 +117,14 @@ bool LIRGenerator::can_store_as_constant(Value v, BasicType type) const { bool LIRGenerator::can_inline_as_constant(Value v) const { + if (v->type()->tag() == longTag) return false; return v->type()->tag() != objectTag || (v->type()->is_constant() && v->type()->as_ObjectType()->constant_value()->is_null_object()); } bool LIRGenerator::can_inline_as_constant(LIR_Const* c) const { + if (c->type() == T_LONG) return false; return c->type() != T_OBJECT || c->as_jobject() == NULL; } @@ -155,6 +157,13 @@ LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_o addr = new LIR_Address(array_opr, offset_in_bytes + index_opr->as_jint() * elem_size, type); } else { +#ifdef _LP64 + if (index_opr->type() == T_INT) { + LIR_Opr tmp = new_register(T_LONG); + __ convert(Bytecodes::_i2l, index_opr, tmp); + index_opr = tmp; + } +#endif // _LP64 addr = new LIR_Address(array_opr, index_opr, LIR_Address::scale(type), @@ -164,7 +173,7 @@ LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_o // This store will need a precise card mark, so go ahead and // compute the full adddres instead of computing once for the // store and again for the card mark. - LIR_Opr tmp = new_register(T_INT); + LIR_Opr tmp = new_pointer_register(); __ leal(LIR_OprFact::address(addr), tmp); return new LIR_Address(tmp, 0, type); } else { @@ -174,9 +183,8 @@ LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_o void LIRGenerator::increment_counter(address counter, int step) { - LIR_Opr temp = new_register(T_INT); - LIR_Opr pointer = new_register(T_INT); - __ move(LIR_OprFact::intConst((int)counter), pointer); + LIR_Opr pointer = new_pointer_register(); + __ move(LIR_OprFact::intptrConst(counter), pointer); LIR_Address* addr = new LIR_Address(pointer, 0, T_INT); increment_counter(addr, step); } @@ -481,7 +489,7 @@ void LIRGenerator::do_ArithmeticOp_Long(ArithmeticOp* x) { left.load_item(); right.load_item(); - LIR_Opr reg = FrameMap::rax_rdx_long_opr; + LIR_Opr reg = FrameMap::long0_opr; arithmetic_op_long(x->op(), reg, left.result(), right.result(), NULL); LIR_Opr result = rlock_result(x); __ move(reg, result); @@ -690,10 +698,10 @@ void LIRGenerator::do_AttemptUpdate(Intrinsic* x) { LIRItem new_value (x->argument_at(2), this); // replace field with new_value if it matches cmp_value // compare value must be in rdx,eax (hi,lo); may be destroyed by cmpxchg8 instruction - cmp_value.load_item_force(FrameMap::rax_rdx_long_opr); + cmp_value.load_item_force(FrameMap::long0_opr); // new value must be in rcx,ebx (hi,lo) - new_value.load_item_force(FrameMap::rbx_rcx_long_opr); + new_value.load_item_force(FrameMap::long1_opr); // object pointer register is overwritten with field address obj.load_item(); @@ -720,7 +728,10 @@ void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) { LIRItem val (x->argument_at(3), this); // replace field with val if matches cmp assert(obj.type()->tag() == objectTag, "invalid type"); - assert(offset.type()->tag() == intTag, "invalid type"); + + // In 64bit the type can be long, sparc doesn't have this assert + // assert(offset.type()->tag() == intTag, "invalid type"); + assert(cmp.type()->tag() == type->tag(), "invalid type"); assert(val.type()->tag() == type->tag(), "invalid type"); @@ -735,8 +746,8 @@ void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) { cmp.load_item_force(FrameMap::rax_opr); val.load_item(); } else if (type == longType) { - cmp.load_item_force(FrameMap::rax_rdx_long_opr); - val.load_item_force(FrameMap::rbx_rcx_long_opr); + cmp.load_item_force(FrameMap::long0_opr); + val.load_item_force(FrameMap::long1_opr); } else { ShouldNotReachHere(); } @@ -833,12 +844,33 @@ void LIRGenerator::do_ArrayCopy(Intrinsic* x) { // operands for arraycopy must use fixed registers, otherwise // LinearScan will fail allocation (because arraycopy always needs a // call) + +#ifndef _LP64 src.load_item_force (FrameMap::rcx_oop_opr); src_pos.load_item_force (FrameMap::rdx_opr); dst.load_item_force (FrameMap::rax_oop_opr); dst_pos.load_item_force (FrameMap::rbx_opr); length.load_item_force (FrameMap::rdi_opr); LIR_Opr tmp = (FrameMap::rsi_opr); +#else + + // The java calling convention will give us enough registers + // so that on the stub side the args will be perfect already. + // On the other slow/special case side we call C and the arg + // positions are not similar enough to pick one as the best. + // Also because the java calling convention is a "shifted" version + // of the C convention we can process the java args trivially into C + // args without worry of overwriting during the xfer + + src.load_item_force (FrameMap::as_oop_opr(j_rarg0)); + src_pos.load_item_force (FrameMap::as_opr(j_rarg1)); + dst.load_item_force (FrameMap::as_oop_opr(j_rarg2)); + dst_pos.load_item_force (FrameMap::as_opr(j_rarg3)); + length.load_item_force (FrameMap::as_opr(j_rarg4)); + + LIR_Opr tmp = FrameMap::as_opr(j_rarg5); +#endif // LP64 + set_no_result(x); int flags; @@ -857,7 +889,7 @@ LIR_Opr fixed_register_for(BasicType type) { case T_FLOAT: return FrameMap::fpu0_float_opr; case T_DOUBLE: return FrameMap::fpu0_double_opr; case T_INT: return FrameMap::rax_opr; - case T_LONG: return FrameMap::rax_rdx_long_opr; + case T_LONG: return FrameMap::long0_opr; default: ShouldNotReachHere(); return LIR_OprFact::illegalOpr; } } @@ -1161,9 +1193,13 @@ void LIRGenerator::do_If(If* x) { LIR_Opr LIRGenerator::getThreadPointer() { +#ifdef _LP64 + return FrameMap::as_pointer_opr(r15_thread); +#else LIR_Opr result = new_register(T_INT); __ get_thread(result); return result; +#endif // } void LIRGenerator::trace_block_entry(BlockBegin* block) { diff --git a/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.hpp b/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.hpp index cdfa446daa2..ee23a875728 100644 --- a/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.hpp +++ b/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,18 +23,29 @@ */ inline bool LinearScan::is_processed_reg_num(int reg_num) { +#ifndef _LP64 // rsp and rbp (numbers 6 ancd 7) are ignored assert(FrameMap::rsp_opr->cpu_regnr() == 6, "wrong assumption below"); assert(FrameMap::rbp_opr->cpu_regnr() == 7, "wrong assumption below"); assert(reg_num >= 0, "invalid reg_num"); return reg_num < 6 || reg_num > 7; +#else + // rsp and rbp, r10, r15 (numbers 6 ancd 7) are ignored + assert(FrameMap::r10_opr->cpu_regnr() == 12, "wrong assumption below"); + assert(FrameMap::r15_opr->cpu_regnr() == 13, "wrong assumption below"); + assert(FrameMap::rsp_opr->cpu_regnrLo() == 14, "wrong assumption below"); + assert(FrameMap::rbp_opr->cpu_regnrLo() == 15, "wrong assumption below"); + assert(reg_num >= 0, "invalid reg_num"); + + return reg_num < 12 || reg_num > 15; +#endif // _LP64 } inline int LinearScan::num_physical_regs(BasicType type) { // Intel requires two cpu registers for long, // but requires only one fpu register for double - if (type == T_LONG) { + if (LP64_ONLY(false &&) type == T_LONG) { return 2; } return 1; diff --git a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp index 27024aa8a4b..8af0ceeb89a 100644 --- a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp @@ -26,18 +26,17 @@ #include "incls/_c1_MacroAssembler_x86.cpp.incl" int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Register scratch, Label& slow_case) { - const int aligned_mask = 3; + const int aligned_mask = BytesPerWord -1; const int hdr_offset = oopDesc::mark_offset_in_bytes(); assert(hdr == rax, "hdr must be rax, for the cmpxchg instruction"); assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different"); - assert(BytesPerWord == 4, "adjust aligned_mask and code"); Label done; int null_check_offset = -1; verify_oop(obj); // save object being locked into the BasicObjectLock - movl(Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()), obj); + movptr(Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()), obj); if (UseBiasedLocking) { assert(scratch != noreg, "should have scratch register at this point"); @@ -47,16 +46,16 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr } // Load object header - movl(hdr, Address(obj, hdr_offset)); + movptr(hdr, Address(obj, hdr_offset)); // and mark it as unlocked - orl(hdr, markOopDesc::unlocked_value); + orptr(hdr, markOopDesc::unlocked_value); // save unlocked object header into the displaced header location on the stack - movl(Address(disp_hdr, 0), hdr); + movptr(Address(disp_hdr, 0), hdr); // test if object header is still the same (i.e. unlocked), and if so, store the // displaced header address in the object header - if it is not the same, get the // object header instead if (os::is_MP()) MacroAssembler::lock(); // must be immediately before cmpxchg! - cmpxchg(disp_hdr, Address(obj, hdr_offset)); + cmpxchgptr(disp_hdr, Address(obj, hdr_offset)); // if the object header was the same, we're done if (PrintBiasedLockingStatistics) { cond_inc32(Assembler::equal, @@ -76,11 +75,11 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr // // assuming both the stack pointer and page_size have their least // significant 2 bits cleared and page_size is a power of 2 - subl(hdr, rsp); - andl(hdr, aligned_mask - os::vm_page_size()); + subptr(hdr, rsp); + andptr(hdr, aligned_mask - os::vm_page_size()); // for recursive locking, the result is zero => save it in the displaced header // location (NULL in the displaced hdr location indicates recursive locking) - movl(Address(disp_hdr, 0), hdr); + movptr(Address(disp_hdr, 0), hdr); // otherwise we don't care about the result and handle locking via runtime call jcc(Assembler::notZero, slow_case); // done @@ -90,35 +89,34 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) { - const int aligned_mask = 3; + const int aligned_mask = BytesPerWord -1; const int hdr_offset = oopDesc::mark_offset_in_bytes(); assert(disp_hdr == rax, "disp_hdr must be rax, for the cmpxchg instruction"); assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different"); - assert(BytesPerWord == 4, "adjust aligned_mask and code"); Label done; if (UseBiasedLocking) { // load object - movl(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes())); + movptr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes())); biased_locking_exit(obj, hdr, done); } // load displaced header - movl(hdr, Address(disp_hdr, 0)); + movptr(hdr, Address(disp_hdr, 0)); // if the loaded hdr is NULL we had recursive locking - testl(hdr, hdr); + testptr(hdr, hdr); // if we had recursive locking, we are done jcc(Assembler::zero, done); if (!UseBiasedLocking) { // load object - movl(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes())); + movptr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes())); } verify_oop(obj); // test if object header is pointing to the displaced header, and if so, restore // the displaced header in the object - if the object header is not pointing to // the displaced header, get the object header instead if (os::is_MP()) MacroAssembler::lock(); // must be immediately before cmpxchg! - cmpxchg(hdr, Address(obj, hdr_offset)); + cmpxchgptr(hdr, Address(obj, hdr_offset)); // if the object header was not pointing to the displaced header, // we do unlocking via runtime call jcc(Assembler::notEqual, slow_case); @@ -141,13 +139,14 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register assert_different_registers(obj, klass, len); if (UseBiasedLocking && !len->is_valid()) { assert_different_registers(obj, klass, len, t1, t2); - movl(t1, Address(klass, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); - movl(Address(obj, oopDesc::mark_offset_in_bytes()), t1); + movptr(t1, Address(klass, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + movptr(Address(obj, oopDesc::mark_offset_in_bytes()), t1); } else { - movl(Address(obj, oopDesc::mark_offset_in_bytes ()), (int)markOopDesc::prototype()); + // This assumes that all prototype bits fit in an int32_t + movptr(Address(obj, oopDesc::mark_offset_in_bytes ()), (int32_t)(intptr_t)markOopDesc::prototype()); } - movl(Address(obj, oopDesc::klass_offset_in_bytes()), klass); + movptr(Address(obj, oopDesc::klass_offset_in_bytes()), klass); if (len->is_valid()) { movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len); } @@ -160,25 +159,27 @@ void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int assert(obj != len_in_bytes && obj != t1 && t1 != len_in_bytes, "registers must be different"); assert((hdr_size_in_bytes & (BytesPerWord - 1)) == 0, "header size is not a multiple of BytesPerWord"); Register index = len_in_bytes; - subl(index, hdr_size_in_bytes); + // index is positive and ptr sized + subptr(index, hdr_size_in_bytes); jcc(Assembler::zero, done); // initialize topmost word, divide index by 2, check if odd and test if zero // note: for the remaining code to work, index must be a multiple of BytesPerWord #ifdef ASSERT { Label L; - testl(index, BytesPerWord - 1); + testptr(index, BytesPerWord - 1); jcc(Assembler::zero, L); stop("index is not a multiple of BytesPerWord"); bind(L); } #endif - xorl(t1, t1); // use _zero reg to clear memory (shorter code) + xorptr(t1, t1); // use _zero reg to clear memory (shorter code) if (UseIncDec) { - shrl(index, 3); // divide by 8 and set carry flag if bit 2 was set + shrptr(index, 3); // divide by 8/16 and set carry flag if bit 2 was set } else { - shrl(index, 2); // use 2 instructions to avoid partial flag stall - shrl(index, 1); + shrptr(index, 2); // use 2 instructions to avoid partial flag stall + shrptr(index, 1); } +#ifndef _LP64 // index could have been not a multiple of 8 (i.e., bit 2 was set) { Label even; // note: if index was a multiple of 8, than it cannot @@ -186,16 +187,17 @@ void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int // => if it is even, we don't need to check for 0 again jcc(Assembler::carryClear, even); // clear topmost word (no jump needed if conditional assignment would work here) - movl(Address(obj, index, Address::times_8, hdr_size_in_bytes - 0*BytesPerWord), t1); + movptr(Address(obj, index, Address::times_8, hdr_size_in_bytes - 0*BytesPerWord), t1); // index could be 0 now, need to check again jcc(Assembler::zero, done); bind(even); } +#endif // !_LP64 // initialize remaining object fields: rdx is a multiple of 2 now { Label loop; bind(loop); - movl(Address(obj, index, Address::times_8, hdr_size_in_bytes - 1*BytesPerWord), t1); - movl(Address(obj, index, Address::times_8, hdr_size_in_bytes - 2*BytesPerWord), t1); + movptr(Address(obj, index, Address::times_8, hdr_size_in_bytes - 1*BytesPerWord), t1); + NOT_LP64(movptr(Address(obj, index, Address::times_8, hdr_size_in_bytes - 2*BytesPerWord), t1);) decrement(index); jcc(Assembler::notZero, loop); } @@ -227,30 +229,30 @@ void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register const Register index = t2; const int threshold = 6 * BytesPerWord; // approximate break even point for code size (see comments below) if (var_size_in_bytes != noreg) { - movl(index, var_size_in_bytes); + mov(index, var_size_in_bytes); initialize_body(obj, index, hdr_size_in_bytes, t1_zero); } else if (con_size_in_bytes <= threshold) { // use explicit null stores // code size = 2 + 3*n bytes (n = number of fields to clear) - xorl(t1_zero, t1_zero); // use t1_zero reg to clear memory (shorter code) + xorptr(t1_zero, t1_zero); // use t1_zero reg to clear memory (shorter code) for (int i = hdr_size_in_bytes; i < con_size_in_bytes; i += BytesPerWord) - movl(Address(obj, i), t1_zero); + movptr(Address(obj, i), t1_zero); } else if (con_size_in_bytes > hdr_size_in_bytes) { // use loop to null out the fields // code size = 16 bytes for even n (n = number of fields to clear) // initialize last object field first if odd number of fields - xorl(t1_zero, t1_zero); // use t1_zero reg to clear memory (shorter code) - movl(index, (con_size_in_bytes - hdr_size_in_bytes) >> 3); + xorptr(t1_zero, t1_zero); // use t1_zero reg to clear memory (shorter code) + movptr(index, (con_size_in_bytes - hdr_size_in_bytes) >> 3); // initialize last object field if constant size is odd if (((con_size_in_bytes - hdr_size_in_bytes) & 4) != 0) - movl(Address(obj, con_size_in_bytes - (1*BytesPerWord)), t1_zero); + movptr(Address(obj, con_size_in_bytes - (1*BytesPerWord)), t1_zero); // initialize remaining object fields: rdx is a multiple of 2 { Label loop; bind(loop); - movl(Address(obj, index, Address::times_8, - hdr_size_in_bytes - (1*BytesPerWord)), t1_zero); - movl(Address(obj, index, Address::times_8, - hdr_size_in_bytes - (2*BytesPerWord)), t1_zero); + movptr(Address(obj, index, Address::times_8, hdr_size_in_bytes - (1*BytesPerWord)), + t1_zero); + NOT_LP64(movptr(Address(obj, index, Address::times_8, hdr_size_in_bytes - (2*BytesPerWord)), + t1_zero);) decrement(index); jcc(Assembler::notZero, loop); } @@ -269,17 +271,17 @@ void C1_MacroAssembler::allocate_array(Register obj, Register len, Register t1, assert_different_registers(obj, len, t1, t2, klass); // determine alignment mask - assert(BytesPerWord == 4, "must be a multiple of 2 for masking code to work"); + assert(!(BytesPerWord & 1), "must be a multiple of 2 for masking code to work"); // check for negative or excessive length - cmpl(len, max_array_allocation_length); + cmpptr(len, (int32_t)max_array_allocation_length); jcc(Assembler::above, slow_case); const Register arr_size = t2; // okay to be the same // align object end - movl(arr_size, header_size * BytesPerWord + MinObjAlignmentInBytesMask); - leal(arr_size, Address(arr_size, len, f)); - andl(arr_size, ~MinObjAlignmentInBytesMask); + movptr(arr_size, (int32_t)header_size * BytesPerWord + MinObjAlignmentInBytesMask); + lea(arr_size, Address(arr_size, len, f)); + andptr(arr_size, ~MinObjAlignmentInBytesMask); try_allocate(obj, arr_size, 0, t1, t2, slow_case); @@ -305,12 +307,13 @@ void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) { // check against inline cache assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check"); int start_offset = offset(); - cmpl(iCache, Address(receiver, oopDesc::klass_offset_in_bytes())); + cmpptr(iCache, Address(receiver, oopDesc::klass_offset_in_bytes())); // if icache check fails, then jump to runtime routine // Note: RECEIVER must still contain the receiver! jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); - assert(offset() - start_offset == 9, "check alignment in emit_method_entry"); + const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9); + assert(offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry"); } @@ -364,7 +367,7 @@ void C1_MacroAssembler::verify_stack_oop(int stack_offset) { void C1_MacroAssembler::verify_not_null_oop(Register r) { if (!VerifyOops) return; Label not_null; - testl(r, r); + testptr(r, r); jcc(Assembler::notZero, not_null); stop("non-null oop required"); bind(not_null); @@ -373,12 +376,12 @@ void C1_MacroAssembler::verify_not_null_oop(Register r) { void C1_MacroAssembler::invalidate_registers(bool inv_rax, bool inv_rbx, bool inv_rcx, bool inv_rdx, bool inv_rsi, bool inv_rdi) { #ifdef ASSERT - if (inv_rax) movl(rax, 0xDEAD); - if (inv_rbx) movl(rbx, 0xDEAD); - if (inv_rcx) movl(rcx, 0xDEAD); - if (inv_rdx) movl(rdx, 0xDEAD); - if (inv_rsi) movl(rsi, 0xDEAD); - if (inv_rdi) movl(rdi, 0xDEAD); + if (inv_rax) movptr(rax, 0xDEAD); + if (inv_rbx) movptr(rbx, 0xDEAD); + if (inv_rcx) movptr(rcx, 0xDEAD); + if (inv_rdx) movptr(rdx, 0xDEAD); + if (inv_rsi) movptr(rsi, 0xDEAD); + if (inv_rdi) movptr(rdi, 0xDEAD); #endif } diff --git a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.hpp b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.hpp index 62f6d4c14a8..bbd5aaddf57 100644 --- a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.hpp +++ b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -94,16 +94,17 @@ // Note: NEVER push values directly, but only through following push_xxx functions; // This helps us to track the rsp changes compared to the entry rsp (->_rsp_offset) - void push_jint (jint i) { _rsp_offset++; pushl(i); } + void push_jint (jint i) { _rsp_offset++; push(i); } void push_oop (jobject o) { _rsp_offset++; pushoop(o); } - void push_addr (Address a) { _rsp_offset++; pushl(a); } - void push_reg (Register r) { _rsp_offset++; pushl(r); } - void pop (Register r) { _rsp_offset--; popl (r); assert(_rsp_offset >= 0, "stack offset underflow"); } + // Seems to always be in wordSize + void push_addr (Address a) { _rsp_offset++; pushptr(a); } + void push_reg (Register r) { _rsp_offset++; push(r); } + void pop_reg (Register r) { _rsp_offset--; pop(r); assert(_rsp_offset >= 0, "stack offset underflow"); } void dec_stack (int nof_words) { _rsp_offset -= nof_words; assert(_rsp_offset >= 0, "stack offset underflow"); - addl(rsp, wordSize * nof_words); + addptr(rsp, wordSize * nof_words); } void dec_stack_after_call (int nof_words) { diff --git a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp index be73c79365b..9f36305a35b 100644 --- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,52 +30,58 @@ int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, int args_size) { // setup registers - const Register thread = rdi; // is callee-saved register (Visual C++ calling conventions) + const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); // is callee-saved register (Visual C++ calling conventions) assert(!(oop_result1->is_valid() || oop_result2->is_valid()) || oop_result1 != oop_result2, "registers must be different"); assert(oop_result1 != thread && oop_result2 != thread, "registers must be different"); assert(args_size >= 0, "illegal args_size"); +#ifdef _LP64 + mov(c_rarg0, thread); + set_num_rt_args(0); // Nothing on stack +#else set_num_rt_args(1 + args_size); // push java thread (becomes first argument of C function) get_thread(thread); - pushl(thread); + push(thread); +#endif // _LP64 set_last_Java_frame(thread, noreg, rbp, NULL); + // do the call call(RuntimeAddress(entry)); int call_offset = offset(); // verify callee-saved register #ifdef ASSERT guarantee(thread != rax, "change this code"); - pushl(rax); + push(rax); { Label L; get_thread(rax); - cmpl(thread, rax); + cmpptr(thread, rax); jcc(Assembler::equal, L); int3(); stop("StubAssembler::call_RT: rdi not callee saved?"); bind(L); } - popl(rax); + pop(rax); #endif reset_last_Java_frame(thread, true, false); // discard thread and arguments - addl(rsp, (1 + args_size)*BytesPerWord); + NOT_LP64(addptr(rsp, num_rt_args()*BytesPerWord)); // check for pending exceptions { Label L; - cmpl(Address(thread, Thread::pending_exception_offset()), NULL_WORD); + cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); jcc(Assembler::equal, L); // exception pending => remove activation and forward to exception handler - movl(rax, Address(thread, Thread::pending_exception_offset())); + movptr(rax, Address(thread, Thread::pending_exception_offset())); // make sure that the vm_results are cleared if (oop_result1->is_valid()) { - movl(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); + movptr(Address(thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD); } if (oop_result2->is_valid()) { - movl(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD); + movptr(Address(thread, JavaThread::vm_result_2_offset()), (int32_t)NULL_WORD); } if (frame_size() == no_frame_size) { leave(); @@ -89,13 +95,13 @@ int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address e } // get oop results if there are any and reset the values in the thread if (oop_result1->is_valid()) { - movl(oop_result1, Address(thread, JavaThread::vm_result_offset())); - movl(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); + movptr(oop_result1, Address(thread, JavaThread::vm_result_offset())); + movptr(Address(thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD); verify_oop(oop_result1); } if (oop_result2->is_valid()) { - movl(oop_result2, Address(thread, JavaThread::vm_result_2_offset())); - movl(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD); + movptr(oop_result2, Address(thread, JavaThread::vm_result_2_offset())); + movptr(Address(thread, JavaThread::vm_result_2_offset()), (int32_t)NULL_WORD); verify_oop(oop_result2); } return call_offset; @@ -103,22 +109,58 @@ int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address e int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1) { - pushl(arg1); +#ifdef _LP64 + mov(c_rarg1, arg1); +#else + push(arg1); +#endif // _LP64 return call_RT(oop_result1, oop_result2, entry, 1); } int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1, Register arg2) { - pushl(arg2); - pushl(arg1); +#ifdef _LP64 + if (c_rarg1 == arg2) { + if (c_rarg2 == arg1) { + xchgq(arg1, arg2); + } else { + mov(c_rarg2, arg2); + mov(c_rarg1, arg1); + } + } else { + mov(c_rarg1, arg1); + mov(c_rarg2, arg2); + } +#else + push(arg2); + push(arg1); +#endif // _LP64 return call_RT(oop_result1, oop_result2, entry, 2); } int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1, Register arg2, Register arg3) { - pushl(arg3); - pushl(arg2); - pushl(arg1); +#ifdef _LP64 + // if there is any conflict use the stack + if (arg1 == c_rarg2 || arg1 == c_rarg3 || + arg2 == c_rarg1 || arg1 == c_rarg3 || + arg3 == c_rarg1 || arg1 == c_rarg2) { + push(arg3); + push(arg2); + push(arg1); + pop(c_rarg1); + pop(c_rarg2); + pop(c_rarg3); + } else { + mov(c_rarg1, arg1); + mov(c_rarg2, arg2); + mov(c_rarg3, arg3); + } +#else + push(arg3); + push(arg2); + push(arg1); +#endif // _LP64 return call_RT(oop_result1, oop_result2, entry, 3); } @@ -154,7 +196,7 @@ void StubFrame::load_argument(int offset_in_words, Register reg) { // + 3: argument with offset 1 // + 4: ... - __ movl(reg, Address(rbp, (offset_in_words + 2) * BytesPerWord)); + __ movptr(reg, Address(rbp, (offset_in_words + 2) * BytesPerWord)); } @@ -170,8 +212,8 @@ StubFrame::~StubFrame() { #define __ sasm-> -const int float_regs_as_doubles_size_in_words = 16; -const int xmm_regs_as_doubles_size_in_words = 16; +const int float_regs_as_doubles_size_in_slots = pd_nof_fpu_regs_frame_map * 2; +const int xmm_regs_as_doubles_size_in_slots = FrameMap::nof_xmm_regs * 2; // Stack layout for saving/restoring all the registers needed during a runtime // call (this includes deoptimization) @@ -180,29 +222,61 @@ const int xmm_regs_as_doubles_size_in_words = 16; // but the code in save_live_registers will take the argument count into // account. // +#ifdef _LP64 + #define SLOT2(x) x, + #define SLOT_PER_WORD 2 +#else + #define SLOT2(x) + #define SLOT_PER_WORD 1 +#endif // _LP64 + enum reg_save_layout { - dummy1, - dummy2, + // 64bit needs to keep stack 16 byte aligned. So we add some alignment dummies to make that + // happen and will assert if the stack size we create is misaligned +#ifdef _LP64 + align_dummy_0, align_dummy_1, +#endif // _LP64 + dummy1, SLOT2(dummy1H) // 0, 4 + dummy2, SLOT2(dummy2H) // 8, 12 // Two temps to be used as needed by users of save/restore callee registers - temp_2_off, - temp_1_off, - xmm_regs_as_doubles_off, - float_regs_as_doubles_off = xmm_regs_as_doubles_off + xmm_regs_as_doubles_size_in_words, - fpu_state_off = float_regs_as_doubles_off + float_regs_as_doubles_size_in_words, - fpu_state_end_off = fpu_state_off + FPUStateSizeInWords, - marker = fpu_state_end_off, - extra_space_offset, + temp_2_off, SLOT2(temp_2H_off) // 16, 20 + temp_1_off, SLOT2(temp_1H_off) // 24, 28 + xmm_regs_as_doubles_off, // 32 + float_regs_as_doubles_off = xmm_regs_as_doubles_off + xmm_regs_as_doubles_size_in_slots, // 160 + fpu_state_off = float_regs_as_doubles_off + float_regs_as_doubles_size_in_slots, // 224 + // fpu_state_end_off is exclusive + fpu_state_end_off = fpu_state_off + (FPUStateSizeInWords / SLOT_PER_WORD), // 352 + marker = fpu_state_end_off, SLOT2(markerH) // 352, 356 + extra_space_offset, // 360 +#ifdef _LP64 + r15_off = extra_space_offset, r15H_off, // 360, 364 + r14_off, r14H_off, // 368, 372 + r13_off, r13H_off, // 376, 380 + r12_off, r12H_off, // 384, 388 + r11_off, r11H_off, // 392, 396 + r10_off, r10H_off, // 400, 404 + r9_off, r9H_off, // 408, 412 + r8_off, r8H_off, // 416, 420 + rdi_off, rdiH_off, // 424, 428 +#else rdi_off = extra_space_offset, - rsi_off, - rbp_off, - rsp_off, - rbx_off, - rdx_off, - rcx_off, - rax_off, - saved_rbp_off, - return_off, - reg_save_frame_size, // As noted: neglects any parameters to runtime +#endif // _LP64 + rsi_off, SLOT2(rsiH_off) // 432, 436 + rbp_off, SLOT2(rbpH_off) // 440, 444 + rsp_off, SLOT2(rspH_off) // 448, 452 + rbx_off, SLOT2(rbxH_off) // 456, 460 + rdx_off, SLOT2(rdxH_off) // 464, 468 + rcx_off, SLOT2(rcxH_off) // 472, 476 + rax_off, SLOT2(raxH_off) // 480, 484 + saved_rbp_off, SLOT2(saved_rbpH_off) // 488, 492 + return_off, SLOT2(returnH_off) // 496, 500 + reg_save_frame_size, // As noted: neglects any parameters to runtime // 504 + +#ifdef _WIN64 + c_rarg0_off = rcx_off, +#else + c_rarg0_off = rdi_off, +#endif // WIN64 // equates @@ -229,18 +303,49 @@ enum reg_save_layout { static OopMap* generate_oop_map(StubAssembler* sasm, int num_rt_args, bool save_fpu_registers = true) { - int frame_size = reg_save_frame_size + num_rt_args; // args + thread - sasm->set_frame_size(frame_size); + + // In 64bit all the args are in regs so there are no additional stack slots + LP64_ONLY(num_rt_args = 0); + LP64_ONLY(assert((reg_save_frame_size * VMRegImpl::stack_slot_size) % 16 == 0, "must be 16 byte aligned");) + int frame_size_in_slots = reg_save_frame_size + num_rt_args; // args + thread + sasm->set_frame_size(frame_size_in_slots / VMRegImpl::slots_per_word ); // record saved value locations in an OopMap // locations are offsets from sp after runtime call; num_rt_args is number of arguments in call, including thread - OopMap* map = new OopMap(frame_size, 0); + OopMap* map = new OopMap(frame_size_in_slots, 0); map->set_callee_saved(VMRegImpl::stack2reg(rax_off + num_rt_args), rax->as_VMReg()); map->set_callee_saved(VMRegImpl::stack2reg(rcx_off + num_rt_args), rcx->as_VMReg()); map->set_callee_saved(VMRegImpl::stack2reg(rdx_off + num_rt_args), rdx->as_VMReg()); map->set_callee_saved(VMRegImpl::stack2reg(rbx_off + num_rt_args), rbx->as_VMReg()); map->set_callee_saved(VMRegImpl::stack2reg(rsi_off + num_rt_args), rsi->as_VMReg()); map->set_callee_saved(VMRegImpl::stack2reg(rdi_off + num_rt_args), rdi->as_VMReg()); +#ifdef _LP64 + map->set_callee_saved(VMRegImpl::stack2reg(r8_off + num_rt_args), r8->as_VMReg()); + map->set_callee_saved(VMRegImpl::stack2reg(r9_off + num_rt_args), r9->as_VMReg()); + map->set_callee_saved(VMRegImpl::stack2reg(r10_off + num_rt_args), r10->as_VMReg()); + map->set_callee_saved(VMRegImpl::stack2reg(r11_off + num_rt_args), r11->as_VMReg()); + map->set_callee_saved(VMRegImpl::stack2reg(r12_off + num_rt_args), r12->as_VMReg()); + map->set_callee_saved(VMRegImpl::stack2reg(r13_off + num_rt_args), r13->as_VMReg()); + map->set_callee_saved(VMRegImpl::stack2reg(r14_off + num_rt_args), r14->as_VMReg()); + map->set_callee_saved(VMRegImpl::stack2reg(r15_off + num_rt_args), r15->as_VMReg()); + + // This is stupid but needed. + map->set_callee_saved(VMRegImpl::stack2reg(raxH_off + num_rt_args), rax->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(rcxH_off + num_rt_args), rcx->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(rdxH_off + num_rt_args), rdx->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(rbxH_off + num_rt_args), rbx->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(rsiH_off + num_rt_args), rsi->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(rdiH_off + num_rt_args), rdi->as_VMReg()->next()); + + map->set_callee_saved(VMRegImpl::stack2reg(r8H_off + num_rt_args), r8->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(r9H_off + num_rt_args), r9->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(r10H_off + num_rt_args), r10->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(r11H_off + num_rt_args), r11->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(r12H_off + num_rt_args), r12->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(r13H_off + num_rt_args), r13->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(r14H_off + num_rt_args), r14->as_VMReg()->next()); + map->set_callee_saved(VMRegImpl::stack2reg(r15H_off + num_rt_args), r15->as_VMReg()->next()); +#endif // _LP64 if (save_fpu_registers) { if (UseSSE < 2) { @@ -288,30 +393,31 @@ static OopMap* save_live_registers(StubAssembler* sasm, int num_rt_args, bool save_fpu_registers = true) { __ block_comment("save_live_registers"); - int frame_size = reg_save_frame_size + num_rt_args; // args + thread + // 64bit passes the args in regs to the c++ runtime + int frame_size_in_slots = reg_save_frame_size NOT_LP64(+ num_rt_args); // args + thread // frame_size = round_to(frame_size, 4); - sasm->set_frame_size(frame_size); + sasm->set_frame_size(frame_size_in_slots / VMRegImpl::slots_per_word ); - __ pushad(); // integer registers + __ pusha(); // integer registers // assert(float_regs_as_doubles_off % 2 == 0, "misaligned offset"); // assert(xmm_regs_as_doubles_off % 2 == 0, "misaligned offset"); - __ subl(rsp, extra_space_offset * wordSize); + __ subptr(rsp, extra_space_offset * VMRegImpl::stack_slot_size); #ifdef ASSERT - __ movl(Address(rsp, marker * wordSize), 0xfeedbeef); + __ movptr(Address(rsp, marker * VMRegImpl::stack_slot_size), (int32_t)0xfeedbeef); #endif if (save_fpu_registers) { if (UseSSE < 2) { // save FPU stack - __ fnsave(Address(rsp, fpu_state_off * wordSize)); + __ fnsave(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size)); __ fwait(); #ifdef ASSERT Label ok; - __ cmpw(Address(rsp, fpu_state_off * wordSize), StubRoutines::fpu_cntrl_wrd_std()); + __ cmpw(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size), StubRoutines::fpu_cntrl_wrd_std()); __ jccb(Assembler::equal, ok); __ stop("corrupted control word detected"); __ bind(ok); @@ -321,18 +427,18 @@ static OopMap* save_live_registers(StubAssembler* sasm, int num_rt_args, // since fstp_d can cause FPU stack underflow exceptions. Write it // into the on stack copy and then reload that to make sure that the // current and future values are correct. - __ movw(Address(rsp, fpu_state_off * wordSize), StubRoutines::fpu_cntrl_wrd_std()); - __ frstor(Address(rsp, fpu_state_off * wordSize)); + __ movw(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size), StubRoutines::fpu_cntrl_wrd_std()); + __ frstor(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size)); // Save the FPU registers in de-opt-able form - __ fstp_d(Address(rsp, float_regs_as_doubles_off * BytesPerWord + 0)); - __ fstp_d(Address(rsp, float_regs_as_doubles_off * BytesPerWord + 8)); - __ fstp_d(Address(rsp, float_regs_as_doubles_off * BytesPerWord + 16)); - __ fstp_d(Address(rsp, float_regs_as_doubles_off * BytesPerWord + 24)); - __ fstp_d(Address(rsp, float_regs_as_doubles_off * BytesPerWord + 32)); - __ fstp_d(Address(rsp, float_regs_as_doubles_off * BytesPerWord + 40)); - __ fstp_d(Address(rsp, float_regs_as_doubles_off * BytesPerWord + 48)); - __ fstp_d(Address(rsp, float_regs_as_doubles_off * BytesPerWord + 56)); + __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 0)); + __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 8)); + __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 16)); + __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 24)); + __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 32)); + __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 40)); + __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 48)); + __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 56)); } if (UseSSE >= 2) { @@ -341,24 +447,34 @@ static OopMap* save_live_registers(StubAssembler* sasm, int num_rt_args, // so always save them as doubles. // note that float values are _not_ converted automatically, so for float values // the second word contains only garbage data. - __ movdbl(Address(rsp, xmm_regs_as_doubles_off * wordSize + 0), xmm0); - __ movdbl(Address(rsp, xmm_regs_as_doubles_off * wordSize + 8), xmm1); - __ movdbl(Address(rsp, xmm_regs_as_doubles_off * wordSize + 16), xmm2); - __ movdbl(Address(rsp, xmm_regs_as_doubles_off * wordSize + 24), xmm3); - __ movdbl(Address(rsp, xmm_regs_as_doubles_off * wordSize + 32), xmm4); - __ movdbl(Address(rsp, xmm_regs_as_doubles_off * wordSize + 40), xmm5); - __ movdbl(Address(rsp, xmm_regs_as_doubles_off * wordSize + 48), xmm6); - __ movdbl(Address(rsp, xmm_regs_as_doubles_off * wordSize + 56), xmm7); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 0), xmm0); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 8), xmm1); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 16), xmm2); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 24), xmm3); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 32), xmm4); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 40), xmm5); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 48), xmm6); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 56), xmm7); +#ifdef _LP64 + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 64), xmm8); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 72), xmm9); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 80), xmm10); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 88), xmm11); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 96), xmm12); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 104), xmm13); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 112), xmm14); + __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 120), xmm15); +#endif // _LP64 } else if (UseSSE == 1) { // save XMM registers as float because double not supported without SSE2 - __ movflt(Address(rsp, xmm_regs_as_doubles_off * wordSize + 0), xmm0); - __ movflt(Address(rsp, xmm_regs_as_doubles_off * wordSize + 8), xmm1); - __ movflt(Address(rsp, xmm_regs_as_doubles_off * wordSize + 16), xmm2); - __ movflt(Address(rsp, xmm_regs_as_doubles_off * wordSize + 24), xmm3); - __ movflt(Address(rsp, xmm_regs_as_doubles_off * wordSize + 32), xmm4); - __ movflt(Address(rsp, xmm_regs_as_doubles_off * wordSize + 40), xmm5); - __ movflt(Address(rsp, xmm_regs_as_doubles_off * wordSize + 48), xmm6); - __ movflt(Address(rsp, xmm_regs_as_doubles_off * wordSize + 56), xmm7); + __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 0), xmm0); + __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 8), xmm1); + __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 16), xmm2); + __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 24), xmm3); + __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 32), xmm4); + __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 40), xmm5); + __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 48), xmm6); + __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 56), xmm7); } } @@ -373,28 +489,38 @@ static void restore_fpu(StubAssembler* sasm, bool restore_fpu_registers = true) if (restore_fpu_registers) { if (UseSSE >= 2) { // restore XMM registers - __ movdbl(xmm0, Address(rsp, xmm_regs_as_doubles_off * wordSize + 0)); - __ movdbl(xmm1, Address(rsp, xmm_regs_as_doubles_off * wordSize + 8)); - __ movdbl(xmm2, Address(rsp, xmm_regs_as_doubles_off * wordSize + 16)); - __ movdbl(xmm3, Address(rsp, xmm_regs_as_doubles_off * wordSize + 24)); - __ movdbl(xmm4, Address(rsp, xmm_regs_as_doubles_off * wordSize + 32)); - __ movdbl(xmm5, Address(rsp, xmm_regs_as_doubles_off * wordSize + 40)); - __ movdbl(xmm6, Address(rsp, xmm_regs_as_doubles_off * wordSize + 48)); - __ movdbl(xmm7, Address(rsp, xmm_regs_as_doubles_off * wordSize + 56)); + __ movdbl(xmm0, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 0)); + __ movdbl(xmm1, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 8)); + __ movdbl(xmm2, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 16)); + __ movdbl(xmm3, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 24)); + __ movdbl(xmm4, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 32)); + __ movdbl(xmm5, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 40)); + __ movdbl(xmm6, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 48)); + __ movdbl(xmm7, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 56)); +#ifdef _LP64 + __ movdbl(xmm8, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 64)); + __ movdbl(xmm9, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 72)); + __ movdbl(xmm10, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 80)); + __ movdbl(xmm11, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 88)); + __ movdbl(xmm12, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 96)); + __ movdbl(xmm13, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 104)); + __ movdbl(xmm14, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 112)); + __ movdbl(xmm15, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 120)); +#endif // _LP64 } else if (UseSSE == 1) { // restore XMM registers - __ movflt(xmm0, Address(rsp, xmm_regs_as_doubles_off * wordSize + 0)); - __ movflt(xmm1, Address(rsp, xmm_regs_as_doubles_off * wordSize + 8)); - __ movflt(xmm2, Address(rsp, xmm_regs_as_doubles_off * wordSize + 16)); - __ movflt(xmm3, Address(rsp, xmm_regs_as_doubles_off * wordSize + 24)); - __ movflt(xmm4, Address(rsp, xmm_regs_as_doubles_off * wordSize + 32)); - __ movflt(xmm5, Address(rsp, xmm_regs_as_doubles_off * wordSize + 40)); - __ movflt(xmm6, Address(rsp, xmm_regs_as_doubles_off * wordSize + 48)); - __ movflt(xmm7, Address(rsp, xmm_regs_as_doubles_off * wordSize + 56)); + __ movflt(xmm0, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 0)); + __ movflt(xmm1, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 8)); + __ movflt(xmm2, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 16)); + __ movflt(xmm3, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 24)); + __ movflt(xmm4, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 32)); + __ movflt(xmm5, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 40)); + __ movflt(xmm6, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 48)); + __ movflt(xmm7, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 56)); } if (UseSSE < 2) { - __ frstor(Address(rsp, fpu_state_off * wordSize)); + __ frstor(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size)); } else { // check that FPU stack is really empty __ verify_FPU(0, "restore_live_registers"); @@ -408,14 +534,14 @@ static void restore_fpu(StubAssembler* sasm, bool restore_fpu_registers = true) #ifdef ASSERT { Label ok; - __ cmpl(Address(rsp, marker * wordSize), 0xfeedbeef); + __ cmpptr(Address(rsp, marker * VMRegImpl::stack_slot_size), (int32_t)0xfeedbeef); __ jcc(Assembler::equal, ok); __ stop("bad offsets in frame"); __ bind(ok); } -#endif +#endif // ASSERT - __ addl(rsp, extra_space_offset * wordSize); + __ addptr(rsp, extra_space_offset * VMRegImpl::stack_slot_size); } @@ -423,7 +549,7 @@ static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registe __ block_comment("restore_live_registers"); restore_fpu(sasm, restore_fpu_registers); - __ popad(); + __ popa(); } @@ -432,14 +558,35 @@ static void restore_live_registers_except_rax(StubAssembler* sasm, bool restore_ restore_fpu(sasm, restore_fpu_registers); - __ popl(rdi); - __ popl(rsi); - __ popl(rbp); - __ popl(rbx); // skip this value - __ popl(rbx); - __ popl(rdx); - __ popl(rcx); - __ addl(rsp, 4); +#ifdef _LP64 + __ movptr(r15, Address(rsp, 0)); + __ movptr(r14, Address(rsp, wordSize)); + __ movptr(r13, Address(rsp, 2 * wordSize)); + __ movptr(r12, Address(rsp, 3 * wordSize)); + __ movptr(r11, Address(rsp, 4 * wordSize)); + __ movptr(r10, Address(rsp, 5 * wordSize)); + __ movptr(r9, Address(rsp, 6 * wordSize)); + __ movptr(r8, Address(rsp, 7 * wordSize)); + __ movptr(rdi, Address(rsp, 8 * wordSize)); + __ movptr(rsi, Address(rsp, 9 * wordSize)); + __ movptr(rbp, Address(rsp, 10 * wordSize)); + // skip rsp + __ movptr(rbx, Address(rsp, 12 * wordSize)); + __ movptr(rdx, Address(rsp, 13 * wordSize)); + __ movptr(rcx, Address(rsp, 14 * wordSize)); + + __ addptr(rsp, 16 * wordSize); +#else + + __ pop(rdi); + __ pop(rsi); + __ pop(rbp); + __ pop(rbx); // skip this value + __ pop(rbx); + __ pop(rdx); + __ pop(rcx); + __ addptr(rsp, BytesPerWord); +#endif // _LP64 } @@ -465,10 +612,13 @@ OopMapSet* Runtime1::generate_exception_throw(StubAssembler* sasm, address targe // load argument for exception that is passed as an argument into the stub if (has_argument) { - __ movl(temp_reg, Address(rbp, 2*BytesPerWord)); - __ pushl(temp_reg); +#ifdef _LP64 + __ movptr(c_rarg1, Address(rbp, 2*BytesPerWord)); +#else + __ movptr(temp_reg, Address(rbp, 2*BytesPerWord)); + __ push(temp_reg); +#endif // _LP64 } - int call_offset = __ call_RT(noreg, noreg, target, num_rt_args - 1); OopMapSet* oop_maps = new OopMapSet(); @@ -486,7 +636,7 @@ void Runtime1::generate_handle_exception(StubAssembler *sasm, OopMapSet* oop_map const Register exception_pc = rdx; // other registers used in this stub const Register real_return_addr = rbx; - const Register thread = rdi; + const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); __ block_comment("generate_handle_exception"); @@ -503,19 +653,19 @@ void Runtime1::generate_handle_exception(StubAssembler *sasm, OopMapSet* oop_map __ verify_not_null_oop(exception_oop); // load address of JavaThread object for thread-local data - __ get_thread(thread); + NOT_LP64(__ get_thread(thread);) #ifdef ASSERT // check that fields in JavaThread for exception oop and issuing pc are // empty before writing to them Label oop_empty; - __ cmpl(Address(thread, JavaThread::exception_oop_offset()), 0); + __ cmpptr(Address(thread, JavaThread::exception_oop_offset()), (int32_t) NULL_WORD); __ jcc(Assembler::equal, oop_empty); __ stop("exception oop already set"); __ bind(oop_empty); Label pc_empty; - __ cmpl(Address(thread, JavaThread::exception_pc_offset()), 0); + __ cmpptr(Address(thread, JavaThread::exception_pc_offset()), 0); __ jcc(Assembler::equal, pc_empty); __ stop("exception pc already set"); __ bind(pc_empty); @@ -523,15 +673,15 @@ void Runtime1::generate_handle_exception(StubAssembler *sasm, OopMapSet* oop_map // save exception oop and issuing pc into JavaThread // (exception handler will load it from here) - __ movl(Address(thread, JavaThread::exception_oop_offset()), exception_oop); - __ movl(Address(thread, JavaThread::exception_pc_offset()), exception_pc); + __ movptr(Address(thread, JavaThread::exception_oop_offset()), exception_oop); + __ movptr(Address(thread, JavaThread::exception_pc_offset()), exception_pc); // save real return address (pc that called this stub) - __ movl(real_return_addr, Address(rbp, 1*BytesPerWord)); - __ movl(Address(rsp, temp_1_off * BytesPerWord), real_return_addr); + __ movptr(real_return_addr, Address(rbp, 1*BytesPerWord)); + __ movptr(Address(rsp, temp_1_off * VMRegImpl::stack_slot_size), real_return_addr); // patch throwing pc into return address (has bci & oop map) - __ movl(Address(rbp, 1*BytesPerWord), exception_pc); + __ movptr(Address(rbp, 1*BytesPerWord), exception_pc); // compute the exception handler. // the exception oop and the throwing pc are read from the fields in JavaThread @@ -548,12 +698,12 @@ void Runtime1::generate_handle_exception(StubAssembler *sasm, OopMapSet* oop_map // Do we have an exception handler in the nmethod? Label no_handler; Label done; - __ testl(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, no_handler); // exception handler found // patch the return address -> the stub will directly return to the exception handler - __ movl(Address(rbp, 1*BytesPerWord), rax); + __ movptr(Address(rbp, 1*BytesPerWord), rax); // restore registers restore_live_registers(sasm, save_fpu_registers); @@ -568,18 +718,18 @@ void Runtime1::generate_handle_exception(StubAssembler *sasm, OopMapSet* oop_map // there is no need to restore the registers // restore the real return address that was saved before the RT-call - __ movl(real_return_addr, Address(rsp, temp_1_off * BytesPerWord)); - __ movl(Address(rbp, 1*BytesPerWord), real_return_addr); + __ movptr(real_return_addr, Address(rsp, temp_1_off * VMRegImpl::stack_slot_size)); + __ movptr(Address(rbp, 1*BytesPerWord), real_return_addr); // load address of JavaThread object for thread-local data - __ get_thread(thread); + NOT_LP64(__ get_thread(thread);) // restore exception oop into rax, (convention for unwind code) - __ movl(exception_oop, Address(thread, JavaThread::exception_oop_offset())); + __ movptr(exception_oop, Address(thread, JavaThread::exception_oop_offset())); // clear exception fields in JavaThread because they are no longer needed // (fields must be cleared because they are processed by GC otherwise) - __ movl(Address(thread, JavaThread::exception_oop_offset()), NULL_WORD); - __ movl(Address(thread, JavaThread::exception_pc_offset()), NULL_WORD); + __ movptr(Address(thread, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD); + __ movptr(Address(thread, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); // pop the stub frame off __ leave(); @@ -595,22 +745,22 @@ void Runtime1::generate_unwind_exception(StubAssembler *sasm) { // other registers used in this stub const Register exception_pc = rdx; const Register handler_addr = rbx; - const Register thread = rdi; + const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); // verify that only rax, is valid at this time __ invalidate_registers(false, true, true, true, true, true); #ifdef ASSERT // check that fields in JavaThread for exception oop and issuing pc are empty - __ get_thread(thread); + NOT_LP64(__ get_thread(thread);) Label oop_empty; - __ cmpl(Address(thread, JavaThread::exception_oop_offset()), 0); + __ cmpptr(Address(thread, JavaThread::exception_oop_offset()), 0); __ jcc(Assembler::equal, oop_empty); __ stop("exception oop must be empty"); __ bind(oop_empty); Label pc_empty; - __ cmpl(Address(thread, JavaThread::exception_pc_offset()), 0); + __ cmpptr(Address(thread, JavaThread::exception_pc_offset()), 0); __ jcc(Assembler::equal, pc_empty); __ stop("exception pc must be empty"); __ bind(pc_empty); @@ -622,12 +772,12 @@ void Runtime1::generate_unwind_exception(StubAssembler *sasm) { // leave activation of nmethod __ leave(); // store return address (is on top of stack after leave) - __ movl(exception_pc, Address(rsp, 0)); + __ movptr(exception_pc, Address(rsp, 0)); __ verify_oop(exception_oop); // save exception oop from rax, to stack before call - __ pushl(exception_oop); + __ push(exception_oop); // search the exception handler address of the caller (using the return address) __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), exception_pc); @@ -637,17 +787,17 @@ void Runtime1::generate_unwind_exception(StubAssembler *sasm) { __ invalidate_registers(false, true, true, true, true, true); // move result of call into correct register - __ movl(handler_addr, rax); + __ movptr(handler_addr, rax); // restore exception oop in rax, (required convention of exception handler) - __ popl(exception_oop); + __ pop(exception_oop); __ verify_oop(exception_oop); // get throwing pc (= return address). // rdx has been destroyed by the call, so it must be set again // the pop is also necessary to simulate the effect of a ret(0) - __ popl(exception_pc); + __ pop(exception_pc); // verify that that there is really a valid exception in rax, __ verify_not_null_oop(exception_oop); @@ -677,12 +827,18 @@ OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) { OopMap* oop_map = save_live_registers(sasm, num_rt_args); - __ pushl(rax); // push dummy +#ifdef _LP64 + const Register thread = r15_thread; + // No need to worry about dummy + __ mov(c_rarg0, thread); +#else + __ push(rax); // push dummy const Register thread = rdi; // is callee-saved register (Visual C++ calling conventions) // push java thread (becomes first argument of C function) __ get_thread(thread); - __ pushl(thread); + __ push(thread); +#endif // _LP64 __ set_last_Java_frame(thread, noreg, rbp, NULL); // do the call __ call(RuntimeAddress(target)); @@ -691,27 +847,29 @@ OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) { // verify callee-saved register #ifdef ASSERT guarantee(thread != rax, "change this code"); - __ pushl(rax); + __ push(rax); { Label L; __ get_thread(rax); - __ cmpl(thread, rax); + __ cmpptr(thread, rax); __ jcc(Assembler::equal, L); - __ stop("StubAssembler::call_RT: rdi not callee saved?"); + __ stop("StubAssembler::call_RT: rdi/r15 not callee saved?"); __ bind(L); } - __ popl(rax); + __ pop(rax); #endif __ reset_last_Java_frame(thread, true, false); - __ popl(rcx); // discard thread arg - __ popl(rcx); // discard dummy +#ifndef _LP64 + __ pop(rcx); // discard thread arg + __ pop(rcx); // discard dummy +#endif // _LP64 // check for pending exceptions { Label L; - __ cmpl(Address(thread, Thread::pending_exception_offset()), NULL_WORD); + __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::equal, L); // exception pending => remove activation and forward to exception handler - __ testl(rax, rax); // have we deoptimized? + __ testptr(rax, rax); // have we deoptimized? __ jump_cc(Assembler::equal, RuntimeAddress(Runtime1::entry_for(Runtime1::forward_exception_id))); @@ -719,38 +877,38 @@ OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) { // JavaThread, so copy and clear pending exception. // load and clear pending exception - __ movl(rax, Address(thread, Thread::pending_exception_offset())); - __ movl(Address(thread, Thread::pending_exception_offset()), NULL_WORD); + __ movptr(rax, Address(thread, Thread::pending_exception_offset())); + __ movptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); // check that there is really a valid exception __ verify_not_null_oop(rax); // load throwing pc: this is the return address of the stub - __ movl(rdx, Address(rsp, return_off * BytesPerWord)); + __ movptr(rdx, Address(rsp, return_off * VMRegImpl::stack_slot_size)); #ifdef ASSERT // check that fields in JavaThread for exception oop and issuing pc are empty Label oop_empty; - __ cmpoop(Address(thread, JavaThread::exception_oop_offset()), 0); + __ cmpptr(Address(thread, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::equal, oop_empty); __ stop("exception oop must be empty"); __ bind(oop_empty); Label pc_empty; - __ cmpl(Address(thread, JavaThread::exception_pc_offset()), 0); + __ cmpptr(Address(thread, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::equal, pc_empty); __ stop("exception pc must be empty"); __ bind(pc_empty); #endif // store exception oop and throwing pc to JavaThread - __ movl(Address(thread, JavaThread::exception_oop_offset()), rax); - __ movl(Address(thread, JavaThread::exception_pc_offset()), rdx); + __ movptr(Address(thread, JavaThread::exception_oop_offset()), rax); + __ movptr(Address(thread, JavaThread::exception_pc_offset()), rdx); restore_live_registers(sasm); __ leave(); - __ addl(rsp, 4); // remove return address from stack + __ addptr(rsp, BytesPerWord); // remove return address from stack // Forward the exception directly to deopt blob. We can blow no // registers and must leave throwing pc on the stack. A patch may @@ -767,7 +925,7 @@ OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) { Label reexecuteEntry, cont; - __ testl(rax, rax); // have we deoptimized? + __ testptr(rax, rax); // have we deoptimized? __ jcc(Assembler::equal, cont); // no // Will reexecute. Proper return address is already on the stack we just restore @@ -806,21 +964,21 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { // dispatch to the handler if found. Otherwise unwind and // dispatch to the callers exception handler. - const Register thread = rdi; + const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); const Register exception_oop = rax; const Register exception_pc = rdx; // load pending exception oop into rax, - __ movl(exception_oop, Address(thread, Thread::pending_exception_offset())); + __ movptr(exception_oop, Address(thread, Thread::pending_exception_offset())); // clear pending exception - __ movl(Address(thread, Thread::pending_exception_offset()), NULL_WORD); + __ movptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); // load issuing PC (the return address for this stub) into rdx - __ movl(exception_pc, Address(rbp, 1*BytesPerWord)); + __ movptr(exception_pc, Address(rbp, 1*BytesPerWord)); // make sure that the vm_results are cleared (may be unnecessary) - __ movl(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); - __ movl(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD); + __ movptr(Address(thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD); + __ movptr(Address(thread, JavaThread::vm_result_2_offset()), (int32_t)NULL_WORD); // verify that that there is really a valid exception in rax, __ verify_not_null_oop(exception_oop); @@ -857,8 +1015,8 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { Register t2 = rsi; assert_different_registers(klass, obj, obj_size, t1, t2); - __ pushl(rdi); - __ pushl(rbx); + __ push(rdi); + __ push(rbx); if (id == fast_new_instance_init_check_id) { // make sure the klass is initialized @@ -889,28 +1047,28 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ bind(retry_tlab); - // get the instance size + // get the instance size (size is postive so movl is fine for 64bit) __ movl(obj_size, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes())); __ tlab_allocate(obj, obj_size, 0, t1, t2, slow_path); __ initialize_object(obj, klass, obj_size, 0, t1, t2); __ verify_oop(obj); - __ popl(rbx); - __ popl(rdi); + __ pop(rbx); + __ pop(rdi); __ ret(0); __ bind(try_eden); - // get the instance size + // get the instance size (size is postive so movl is fine for 64bit) __ movl(obj_size, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes())); __ eden_allocate(obj, obj_size, 0, t1, slow_path); __ initialize_object(obj, klass, obj_size, 0, t1, t2); __ verify_oop(obj); - __ popl(rbx); - __ popl(rdi); + __ pop(rbx); + __ pop(rdi); __ ret(0); __ bind(slow_path); - __ popl(rbx); - __ popl(rdi); + __ pop(rbx); + __ pop(rdi); } __ enter(); @@ -996,15 +1154,17 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ bind(retry_tlab); // get the allocation size: round_up(hdr + length << (layout_helper & 0x1F)) + // since size is postive movl does right thing on 64bit __ movl(t1, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes())); + // since size is postive movl does right thing on 64bit __ movl(arr_size, length); assert(t1 == rcx, "fixed register usage"); - __ shll(arr_size /* by t1=rcx, mod 32 */); - __ shrl(t1, Klass::_lh_header_size_shift); - __ andl(t1, Klass::_lh_header_size_mask); - __ addl(arr_size, t1); - __ addl(arr_size, MinObjAlignmentInBytesMask); // align up - __ andl(arr_size, ~MinObjAlignmentInBytesMask); + __ shlptr(arr_size /* by t1=rcx, mod 32 */); + __ shrptr(t1, Klass::_lh_header_size_shift); + __ andptr(t1, Klass::_lh_header_size_mask); + __ addptr(arr_size, t1); + __ addptr(arr_size, MinObjAlignmentInBytesMask); // align up + __ andptr(arr_size, ~MinObjAlignmentInBytesMask); __ tlab_allocate(obj, arr_size, 0, t1, t2, slow_path); // preserves arr_size @@ -1012,24 +1172,26 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ movb(t1, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes() + (Klass::_lh_header_size_shift / BitsPerByte))); assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise"); assert(Klass::_lh_header_size_mask <= 0xFF, "bytewise"); - __ andl(t1, Klass::_lh_header_size_mask); - __ subl(arr_size, t1); // body length - __ addl(t1, obj); // body start + __ andptr(t1, Klass::_lh_header_size_mask); + __ subptr(arr_size, t1); // body length + __ addptr(t1, obj); // body start __ initialize_body(t1, arr_size, 0, t2); __ verify_oop(obj); __ ret(0); __ bind(try_eden); // get the allocation size: round_up(hdr + length << (layout_helper & 0x1F)) + // since size is postive movl does right thing on 64bit __ movl(t1, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes())); + // since size is postive movl does right thing on 64bit __ movl(arr_size, length); assert(t1 == rcx, "fixed register usage"); - __ shll(arr_size /* by t1=rcx, mod 32 */); - __ shrl(t1, Klass::_lh_header_size_shift); - __ andl(t1, Klass::_lh_header_size_mask); - __ addl(arr_size, t1); - __ addl(arr_size, MinObjAlignmentInBytesMask); // align up - __ andl(arr_size, ~MinObjAlignmentInBytesMask); + __ shlptr(arr_size /* by t1=rcx, mod 32 */); + __ shrptr(t1, Klass::_lh_header_size_shift); + __ andptr(t1, Klass::_lh_header_size_mask); + __ addptr(arr_size, t1); + __ addptr(arr_size, MinObjAlignmentInBytesMask); // align up + __ andptr(arr_size, ~MinObjAlignmentInBytesMask); __ eden_allocate(obj, arr_size, 0, t1, slow_path); // preserves arr_size @@ -1037,9 +1199,9 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ movb(t1, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes() + (Klass::_lh_header_size_shift / BitsPerByte))); assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise"); assert(Klass::_lh_header_size_mask <= 0xFF, "bytewise"); - __ andl(t1, Klass::_lh_header_size_mask); - __ subl(arr_size, t1); // body length - __ addl(t1, obj); // body start + __ andptr(t1, Klass::_lh_header_size_mask); + __ subptr(arr_size, t1); // body length + __ addptr(t1, obj); // body start __ initialize_body(t1, arr_size, 0, t2); __ verify_oop(obj); __ ret(0); @@ -1089,15 +1251,23 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { { __ set_info("register_finalizer", dont_gc_arguments); + // This is called via call_runtime so the arguments + // will be place in C abi locations + +#ifdef _LP64 + __ verify_oop(c_rarg0); + __ mov(rax, c_rarg0); +#else // The object is passed on the stack and we haven't pushed a // frame yet so it's one work away from top of stack. - __ movl(rax, Address(rsp, 1 * BytesPerWord)); + __ movptr(rax, Address(rsp, 1 * BytesPerWord)); __ verify_oop(rax); +#endif // _LP64 // load the klass and check the has finalizer flag Label register_finalizer; Register t = rsi; - __ movl(t, Address(rax, oopDesc::klass_offset_in_bytes())); + __ movptr(t, Address(rax, oopDesc::klass_offset_in_bytes())); __ movl(t, Address(t, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc))); __ testl(t, JVM_ACC_HAS_FINALIZER); __ jcc(Assembler::notZero, register_finalizer); @@ -1185,46 +1355,49 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { case slow_subtype_check_id: { enum layout { - rax_off, - rcx_off, - rsi_off, - rdi_off, - saved_rbp_off, - return_off, - sub_off, - super_off, + rax_off, SLOT2(raxH_off) + rcx_off, SLOT2(rcxH_off) + rsi_off, SLOT2(rsiH_off) + rdi_off, SLOT2(rdiH_off) + // saved_rbp_off, SLOT2(saved_rbpH_off) + return_off, SLOT2(returnH_off) + sub_off, SLOT2(subH_off) + super_off, SLOT2(superH_off) framesize }; __ set_info("slow_subtype_check", dont_gc_arguments); - __ pushl(rdi); - __ pushl(rsi); - __ pushl(rcx); - __ pushl(rax); - __ movl(rsi, Address(rsp, (super_off - 1) * BytesPerWord)); // super - __ movl(rax, Address(rsp, (sub_off - 1) * BytesPerWord)); // sub + __ push(rdi); + __ push(rsi); + __ push(rcx); + __ push(rax); - __ movl(rdi,Address(rsi,sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())); - __ movl(rcx,Address(rdi,arrayOopDesc::length_offset_in_bytes())); - __ addl(rdi,arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + // This is called by pushing args and not with C abi + __ movptr(rsi, Address(rsp, (super_off) * VMRegImpl::stack_slot_size)); // super + __ movptr(rax, Address(rsp, (sub_off ) * VMRegImpl::stack_slot_size)); // sub + + __ movptr(rdi,Address(rsi,sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())); + // since size is postive movl does right thing on 64bit + __ movl(rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes())); + __ addptr(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); Label miss; __ repne_scan(); __ jcc(Assembler::notEqual, miss); - __ movl(Address(rsi,sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()), rax); - __ movl(Address(rsp, (super_off - 1) * BytesPerWord), 1); // result - __ popl(rax); - __ popl(rcx); - __ popl(rsi); - __ popl(rdi); + __ movptr(Address(rsi,sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()), rax); + __ movptr(Address(rsp, (super_off) * VMRegImpl::stack_slot_size), 1); // result + __ pop(rax); + __ pop(rcx); + __ pop(rsi); + __ pop(rdi); __ ret(0); __ bind(miss); - __ movl(Address(rsp, (super_off - 1) * BytesPerWord), 0); // result - __ popl(rax); - __ popl(rcx); - __ popl(rsi); - __ popl(rdi); + __ movptr(Address(rsp, (super_off) * VMRegImpl::stack_slot_size), 0); // result + __ pop(rax); + __ pop(rcx); + __ pop(rsi); + __ pop(rdi); __ ret(0); } break; @@ -1237,6 +1410,8 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { StubFrame f(sasm, "monitorenter", dont_gc_arguments); OopMap* map = save_live_registers(sasm, 3, save_fpu_registers); + // Called with store_parameter and not C abi + f.load_argument(1, rax); // rax,: object f.load_argument(0, rbx); // rbx,: lock address @@ -1256,6 +1431,8 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { StubFrame f(sasm, "monitorexit", dont_gc_arguments); OopMap* map = save_live_registers(sasm, 2, save_fpu_registers); + // Called with store_parameter and not C abi + f.load_argument(0, rax); // rax,: lock address // note: really a leaf routine but must setup last java sp @@ -1304,9 +1481,9 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { // the live registers get saved. save_live_registers(sasm, 1); - __ pushl(rax); + __ NOT_LP64(push(rax)) LP64_ONLY(mov(c_rarg0, rax)); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc))); - __ popl(rax); + NOT_LP64(__ pop(rax)); restore_live_registers(sasm); } @@ -1316,18 +1493,19 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { { // rax, and rdx are destroyed, but should be free since the result is returned there // preserve rsi,ecx - __ pushl(rsi); - __ pushl(rcx); + __ push(rsi); + __ push(rcx); + LP64_ONLY(__ push(rdx);) // check for NaN Label return0, do_return, return_min_jlong, do_convert; - Address value_high_word(rsp, 8); - Address value_low_word(rsp, 4); - Address result_high_word(rsp, 16); - Address result_low_word(rsp, 12); + Address value_high_word(rsp, wordSize + 4); + Address value_low_word(rsp, wordSize); + Address result_high_word(rsp, 3*wordSize + 4); + Address result_low_word(rsp, 3*wordSize); - __ subl(rsp, 20); + __ subptr(rsp, 32); // more than enough on 32bit __ fst_d(value_low_word); __ movl(rax, value_high_word); __ andl(rax, 0x7ff00000); @@ -1340,7 +1518,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ bind(do_convert); __ fnstcw(Address(rsp, 0)); - __ movzxw(rax, Address(rsp, 0)); + __ movzwl(rax, Address(rsp, 0)); __ orl(rax, 0xc00); __ movw(Address(rsp, 2), rax); __ fldcw(Address(rsp, 2)); @@ -1348,9 +1526,11 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ fistp_d(result_low_word); __ fldcw(Address(rsp, 0)); __ fwait(); - __ movl(rax, result_low_word); + // This gets the entire long in rax on 64bit + __ movptr(rax, result_low_word); + // testing of high bits __ movl(rdx, result_high_word); - __ movl(rcx, rax); + __ mov(rcx, rax); // What the heck is the point of the next instruction??? __ xorl(rcx, 0x0); __ movl(rsi, 0x80000000); @@ -1360,34 +1540,52 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ fldz(); __ fcomp_d(value_low_word); __ fnstsw_ax(); +#ifdef _LP64 + __ testl(rax, 0x4100); // ZF & CF == 0 + __ jcc(Assembler::equal, return_min_jlong); +#else __ sahf(); __ jcc(Assembler::above, return_min_jlong); +#endif // _LP64 // return max_jlong +#ifndef _LP64 __ movl(rdx, 0x7fffffff); __ movl(rax, 0xffffffff); +#else + __ mov64(rax, CONST64(0x7fffffffffffffff)); +#endif // _LP64 __ jmp(do_return); __ bind(return_min_jlong); +#ifndef _LP64 __ movl(rdx, 0x80000000); __ xorl(rax, rax); +#else + __ mov64(rax, CONST64(0x8000000000000000)); +#endif // _LP64 __ jmp(do_return); __ bind(return0); __ fpop(); - __ xorl(rdx,rdx); - __ xorl(rax,rax); +#ifndef _LP64 + __ xorptr(rdx,rdx); + __ xorptr(rax,rax); +#else + __ xorptr(rax, rax); +#endif // _LP64 __ bind(do_return); - __ addl(rsp, 20); - __ popl(rcx); - __ popl(rsi); + __ addptr(rsp, 32); + LP64_ONLY(__ pop(rdx);) + __ pop(rcx); + __ pop(rsi); __ ret(0); } break; default: { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments); - __ movl(rax, (int)id); + __ movptr(rax, (int)id); __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), rax); __ should_not_reach_here(); } diff --git a/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp b/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp index 89c497de7a4..ecaa3ec21af 100644 --- a/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp +++ b/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,6 +44,14 @@ extern "C" void RecursiveInterpreterActivation(interpreterState istate ) Label fast_accessor_slow_entry_path; // fast accessor methods need to be able to jmp to unsynchronized // c++ interpreter entry point this holds that entry point label. +// default registers for state and sender_sp +// state and sender_sp are the same on 32bit because we have no choice. +// state could be rsi on 64bit but it is an arg reg and not callee save +// so r13 is better choice. + +const Register state = NOT_LP64(rsi) LP64_ONLY(r13); +const Register sender_sp_on_entry = NOT_LP64(rsi) LP64_ONLY(r13); + // NEEDED for JVMTI? // address AbstractInterpreter::_remove_activation_preserving_args_entry; @@ -88,7 +96,6 @@ bool CppInterpreter::contains(address pc) { address CppInterpreterGenerator::generate_result_handler_for(BasicType type) { - const Register state = rsi; // current activation object, valid on entry address entry = __ pc(); switch (type) { case T_BOOLEAN: __ c2bool(rax); break; @@ -98,19 +105,22 @@ address CppInterpreterGenerator::generate_result_handler_for(BasicType type) { case T_VOID : // fall thru case T_LONG : // fall thru case T_INT : /* nothing to do */ break; + case T_DOUBLE : case T_FLOAT : - { const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp(); - __ popl(t); // remove return address first - __ pop_dtos_to_rsp(); + { + const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp(); + __ pop(t); // remove return address first // Must return a result for interpreter or compiler. In SSE // mode, results are returned in xmm0 and the FPU stack must // be empty. if (type == T_FLOAT && UseSSE >= 1) { +#ifndef _LP64 // Load ST0 __ fld_d(Address(rsp, 0)); // Store as float and empty fpu stack __ fstp_s(Address(rsp, 0)); +#endif // !_LP64 // and reload __ movflt(xmm0, Address(rsp, 0)); } else if (type == T_DOUBLE && UseSSE >= 2 ) { @@ -120,13 +130,13 @@ address CppInterpreterGenerator::generate_result_handler_for(BasicType type) { __ fld_d(Address(rsp, 0)); } // and pop the temp - __ addl(rsp, 2 * wordSize); - __ pushl(t); // restore return address + __ addptr(rsp, 2 * wordSize); + __ push(t); // restore return address } break; case T_OBJECT : // retrieve result from frame - __ movl(rax, STATE(_oop_temp)); + __ movptr(rax, STATE(_oop_temp)); // and verify it __ verify_oop(rax); break; @@ -146,7 +156,7 @@ address CppInterpreterGenerator::generate_tosca_to_stack_converter(BasicType typ address entry = __ pc(); const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp(); - __ popl(t); // remove return address first + __ pop(t); // remove return address first switch (type) { case T_VOID: break; @@ -154,53 +164,53 @@ address CppInterpreterGenerator::generate_tosca_to_stack_converter(BasicType typ #ifdef EXTEND __ c2bool(rax); #endif - __ pushl(rax); + __ push(rax); break; case T_CHAR : #ifdef EXTEND __ andl(rax, 0xFFFF); #endif - __ pushl(rax); + __ push(rax); break; case T_BYTE : #ifdef EXTEND __ sign_extend_byte (rax); #endif - __ pushl(rax); + __ push(rax); break; case T_SHORT : #ifdef EXTEND __ sign_extend_short(rax); #endif - __ pushl(rax); + __ push(rax); break; case T_LONG : - __ pushl(rdx); - __ pushl(rax); + __ push(rdx); // pushes useless junk on 64bit + __ push(rax); break; case T_INT : - __ pushl(rax); + __ push(rax); break; case T_FLOAT : - // Result is in ST(0) + // Result is in ST(0)/xmm0 + __ subptr(rsp, wordSize); if ( UseSSE < 1) { - __ push(ftos); // and save it + __ fstp_s(Address(rsp, 0)); } else { - __ subl(rsp, wordSize); __ movflt(Address(rsp, 0), xmm0); } break; case T_DOUBLE : + __ subptr(rsp, 2*wordSize); if ( UseSSE < 2 ) { - __ push(dtos); // put ST0 on java stack + __ fstp_d(Address(rsp, 0)); } else { - __ subl(rsp, 2*wordSize); __ movdbl(Address(rsp, 0), xmm0); } break; case T_OBJECT : __ verify_oop(rax); // verify it - __ pushl(rax); + __ push(rax); break; default : ShouldNotReachHere(); } @@ -212,7 +222,7 @@ address CppInterpreterGenerator::generate_stack_to_stack_converter(BasicType typ // A result is in the java expression stack of the interpreted method that has just // returned. Place this result on the java expression stack of the caller. // - // The current interpreter activation in rsi is for the method just returning its + // The current interpreter activation in rsi/r13 is for the method just returning its // result. So we know that the result of this method is on the top of the current // execution stack (which is pre-pushed) and will be return to the top of the caller // stack. The top of the callers stack is the bottom of the locals of the current @@ -222,20 +232,19 @@ address CppInterpreterGenerator::generate_stack_to_stack_converter(BasicType typ // of the calling activation. This enable this routine to leave the return address // to the frame manager on the stack and do a vanilla return. // - // On entry: rsi - interpreter state of activation returning a (potential) result - // On Return: rsi - unchanged + // On entry: rsi/r13 - interpreter state of activation returning a (potential) result + // On Return: rsi/r13 - unchanged // rax - new stack top for caller activation (i.e. activation in _prev_link) // // Can destroy rdx, rcx. // address entry = __ pc(); - const Register state = rsi; // current activation object, valid on entry const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp(); switch (type) { case T_VOID: - __ movl(rax, STATE(_locals)); // pop parameters get new stack value - __ addl(rax, wordSize); // account for prepush before we return + __ movptr(rax, STATE(_locals)); // pop parameters get new stack value + __ addptr(rax, wordSize); // account for prepush before we return break; case T_FLOAT : case T_BOOLEAN: @@ -244,10 +253,10 @@ address CppInterpreterGenerator::generate_stack_to_stack_converter(BasicType typ case T_SHORT : case T_INT : // 1 word result - __ movl(rdx, STATE(_stack)); - __ movl(rax, STATE(_locals)); // address for result + __ movptr(rdx, STATE(_stack)); + __ movptr(rax, STATE(_locals)); // address for result __ movl(rdx, Address(rdx, wordSize)); // get result - __ movl(Address(rax, 0), rdx); // and store it + __ movptr(Address(rax, 0), rdx); // and store it break; case T_LONG : case T_DOUBLE : @@ -256,20 +265,20 @@ address CppInterpreterGenerator::generate_stack_to_stack_converter(BasicType typ // except we allocated one extra word for this intepretState so we won't overwrite it // when we return a two word result. - __ movl(rax, STATE(_locals)); // address for result - __ movl(rcx, STATE(_stack)); - __ subl(rax, wordSize); // need addition word besides locals[0] - __ movl(rdx, Address(rcx, 2*wordSize)); // get result word - __ movl(Address(rax, wordSize), rdx); // and store it - __ movl(rdx, Address(rcx, wordSize)); // get result word - __ movl(Address(rax, 0), rdx); // and store it + __ movptr(rax, STATE(_locals)); // address for result + __ movptr(rcx, STATE(_stack)); + __ subptr(rax, wordSize); // need addition word besides locals[0] + __ movptr(rdx, Address(rcx, 2*wordSize)); // get result word (junk in 64bit) + __ movptr(Address(rax, wordSize), rdx); // and store it + __ movptr(rdx, Address(rcx, wordSize)); // get result word + __ movptr(Address(rax, 0), rdx); // and store it break; case T_OBJECT : - __ movl(rdx, STATE(_stack)); - __ movl(rax, STATE(_locals)); // address for result - __ movl(rdx, Address(rdx, wordSize)); // get result + __ movptr(rdx, STATE(_stack)); + __ movptr(rax, STATE(_locals)); // address for result + __ movptr(rdx, Address(rdx, wordSize)); // get result __ verify_oop(rdx); // verify it - __ movl(Address(rax, 0), rdx); // and store it + __ movptr(Address(rax, 0), rdx); // and store it break; default : ShouldNotReachHere(); } @@ -285,12 +294,11 @@ address CppInterpreterGenerator::generate_stack_to_native_abi_converter(BasicTyp // frame manager execept in this situation the caller is native code (c1/c2/call_stub) // and so rather than return result onto caller's java expression stack we return the // result in the expected location based on the native abi. - // On entry: rsi - interpreter state of activation returning a (potential) result - // On Return: rsi - unchanged + // On entry: rsi/r13 - interpreter state of activation returning a (potential) result + // On Return: rsi/r13 - unchanged // Other registers changed [rax/rdx/ST(0) as needed for the result returned] address entry = __ pc(); - const Register state = rsi; // current activation object, valid on entry switch (type) { case T_VOID: break; @@ -299,17 +307,16 @@ address CppInterpreterGenerator::generate_stack_to_native_abi_converter(BasicTyp case T_BYTE : case T_SHORT : case T_INT : - __ movl(rdx, STATE(_stack)); // get top of stack + __ movptr(rdx, STATE(_stack)); // get top of stack __ movl(rax, Address(rdx, wordSize)); // get result word 1 break; case T_LONG : - __ movl(rdx, STATE(_stack)); // get top of stack - __ movl(rax, Address(rdx, wordSize)); // get result low word - __ movl(rdx, Address(rdx, 2*wordSize)); // get result high word - break; + __ movptr(rdx, STATE(_stack)); // get top of stack + __ movptr(rax, Address(rdx, wordSize)); // get result low word + NOT_LP64(__ movl(rdx, Address(rdx, 2*wordSize));) // get result high word break; case T_FLOAT : - __ movl(rdx, STATE(_stack)); // get top of stack + __ movptr(rdx, STATE(_stack)); // get top of stack if ( UseSSE >= 1) { __ movflt(xmm0, Address(rdx, wordSize)); } else { @@ -317,7 +324,7 @@ address CppInterpreterGenerator::generate_stack_to_native_abi_converter(BasicTyp } break; case T_DOUBLE : - __ movl(rdx, STATE(_stack)); // get top of stack + __ movptr(rdx, STATE(_stack)); // get top of stack if ( UseSSE > 1) { __ movdbl(xmm0, Address(rdx, wordSize)); } else { @@ -325,8 +332,8 @@ address CppInterpreterGenerator::generate_stack_to_native_abi_converter(BasicTyp } break; case T_OBJECT : - __ movl(rdx, STATE(_stack)); // get top of stack - __ movl(rax, Address(rdx, wordSize)); // get result word 1 + __ movptr(rdx, STATE(_stack)); // get top of stack + __ movptr(rax, Address(rdx, wordSize)); // get result word 1 __ verify_oop(rax); // verify it break; default : ShouldNotReachHere(); @@ -408,54 +415,58 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register if (!native) { #ifdef PRODUCT - __ subl(rsp, 2*wordSize); + __ subptr(rsp, 2*wordSize); #else /* PRODUCT */ - __ pushl((int)NULL); - __ pushl(state); // make it look like a real argument + __ push((int32_t)NULL_WORD); + __ push(state); // make it look like a real argument #endif /* PRODUCT */ } // Now that we are assure of space for stack result, setup typical linkage - __ pushl(rax); + __ push(rax); __ enter(); - __ movl(rax, state); // save current state + __ mov(rax, state); // save current state - __ leal(rsp, Address(rsp, -(int)sizeof(BytecodeInterpreter))); - __ movl(state, rsp); + __ lea(rsp, Address(rsp, -(int)sizeof(BytecodeInterpreter))); + __ mov(state, rsp); - // rsi == state/locals rax == prevstate + // rsi/r13 == state/locals rax == prevstate // initialize the "shadow" frame so that use since C++ interpreter not directly // recursive. Simpler to recurse but we can't trim expression stack as we call // new methods. - __ movl(STATE(_locals), locals); // state->_locals = locals() - __ movl(STATE(_self_link), state); // point to self - __ movl(STATE(_prev_link), rax); // state->_link = state on entry (NULL or previous state) - __ movl(STATE(_sender_sp), sender_sp); // state->_sender_sp = sender_sp + __ movptr(STATE(_locals), locals); // state->_locals = locals() + __ movptr(STATE(_self_link), state); // point to self + __ movptr(STATE(_prev_link), rax); // state->_link = state on entry (NULL or previous state) + __ movptr(STATE(_sender_sp), sender_sp); // state->_sender_sp = sender_sp +#ifdef _LP64 + __ movptr(STATE(_thread), r15_thread); // state->_bcp = codes() +#else __ get_thread(rax); // get vm's javathread* - __ movl(STATE(_thread), rax); // state->_bcp = codes() - __ movl(rdx, Address(rbx, methodOopDesc::const_offset())); // get constantMethodOop - __ leal(rdx, Address(rdx, constMethodOopDesc::codes_offset())); // get code base + __ movptr(STATE(_thread), rax); // state->_bcp = codes() +#endif // _LP64 + __ movptr(rdx, Address(rbx, methodOopDesc::const_offset())); // get constantMethodOop + __ lea(rdx, Address(rdx, constMethodOopDesc::codes_offset())); // get code base if (native) { - __ movl(STATE(_bcp), (intptr_t)NULL); // state->_bcp = NULL + __ movptr(STATE(_bcp), (int32_t)NULL_WORD); // state->_bcp = NULL } else { - __ movl(STATE(_bcp), rdx); // state->_bcp = codes() + __ movptr(STATE(_bcp), rdx); // state->_bcp = codes() } - __ xorl(rdx, rdx); - __ movl(STATE(_oop_temp), rdx); // state->_oop_temp = NULL (only really needed for native) - __ movl(STATE(_mdx), rdx); // state->_mdx = NULL - __ movl(rdx, Address(rbx, methodOopDesc::constants_offset())); - __ movl(rdx, Address(rdx, constantPoolOopDesc::cache_offset_in_bytes())); - __ movl(STATE(_constants), rdx); // state->_constants = constants() + __ xorptr(rdx, rdx); + __ movptr(STATE(_oop_temp), rdx); // state->_oop_temp = NULL (only really needed for native) + __ movptr(STATE(_mdx), rdx); // state->_mdx = NULL + __ movptr(rdx, Address(rbx, methodOopDesc::constants_offset())); + __ movptr(rdx, Address(rdx, constantPoolOopDesc::cache_offset_in_bytes())); + __ movptr(STATE(_constants), rdx); // state->_constants = constants() - __ movl(STATE(_method), rbx); // state->_method = method() - __ movl(STATE(_msg), (int) BytecodeInterpreter::method_entry); // state->_msg = initial method entry - __ movl(STATE(_result._to_call._callee), (int) NULL); // state->_result._to_call._callee_callee = NULL + __ movptr(STATE(_method), rbx); // state->_method = method() + __ movl(STATE(_msg), (int32_t) BytecodeInterpreter::method_entry); // state->_msg = initial method entry + __ movptr(STATE(_result._to_call._callee), (int32_t) NULL_WORD); // state->_result._to_call._callee_callee = NULL - __ movl(STATE(_monitor_base), rsp); // set monitor block bottom (grows down) this would point to entry [0] + __ movptr(STATE(_monitor_base), rsp); // set monitor block bottom (grows down) this would point to entry [0] // entries run from -1..x where &monitor[x] == { @@ -479,36 +490,44 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register const int mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes(); __ movl(rax, access_flags); __ testl(rax, JVM_ACC_STATIC); - __ movl(rax, Address(locals, 0)); // get receiver (assume this is frequent case) + __ movptr(rax, Address(locals, 0)); // get receiver (assume this is frequent case) __ jcc(Assembler::zero, done); - __ movl(rax, Address(rbx, methodOopDesc::constants_offset())); - __ movl(rax, Address(rax, constantPoolOopDesc::pool_holder_offset_in_bytes())); - __ movl(rax, Address(rax, mirror_offset)); + __ movptr(rax, Address(rbx, methodOopDesc::constants_offset())); + __ movptr(rax, Address(rax, constantPoolOopDesc::pool_holder_offset_in_bytes())); + __ movptr(rax, Address(rax, mirror_offset)); __ bind(done); // add space for monitor & lock - __ subl(rsp, entry_size); // add space for a monitor entry - __ movl(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax); // store object + __ subptr(rsp, entry_size); // add space for a monitor entry + __ movptr(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax); // store object __ bind(not_synced); } - __ movl(STATE(_stack_base), rsp); // set expression stack base ( == &monitors[-count]) + __ movptr(STATE(_stack_base), rsp); // set expression stack base ( == &monitors[-count]) if (native) { - __ movl(STATE(_stack), rsp); // set current expression stack tos - __ movl(STATE(_stack_limit), rsp); + __ movptr(STATE(_stack), rsp); // set current expression stack tos + __ movptr(STATE(_stack_limit), rsp); } else { - __ subl(rsp, wordSize); // pre-push stack - __ movl(STATE(_stack), rsp); // set current expression stack tos + __ subptr(rsp, wordSize); // pre-push stack + __ movptr(STATE(_stack), rsp); // set current expression stack tos // compute full expression stack limit const Address size_of_stack (rbx, methodOopDesc::max_stack_offset()); __ load_unsigned_word(rdx, size_of_stack); // get size of expression stack in words - __ negl(rdx); // so we can subtract in next step + __ negptr(rdx); // so we can subtract in next step // Allocate expression stack - __ leal(rsp, Address(rsp, rdx, Address::times_4)); - __ movl(STATE(_stack_limit), rsp); + __ lea(rsp, Address(rsp, rdx, Address::times_ptr)); + __ movptr(STATE(_stack_limit), rsp); } +#ifdef _LP64 + // Make sure stack is properly aligned and sized for the abi + __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows + __ andptr(rsp, -16); // must be 16 byte boundry (see amd64 ABI) +#endif // _LP64 + + + } // Helpers for commoning out cases in the various type of method entries. @@ -528,7 +547,7 @@ void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile const Address backedge_counter (rbx, methodOopDesc::backedge_counter_offset() + InvocationCounter::counter_offset()); if (ProfileInterpreter) { // %%% Merge this into methodDataOop - __ increment(Address(rbx,methodOopDesc::interpreter_invocation_counter_offset())); + __ incrementl(Address(rbx,methodOopDesc::interpreter_invocation_counter_offset())); } // Update standard invocation counters __ movl(rax, backedge_counter); // load backedge counter @@ -552,7 +571,7 @@ void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile void InterpreterGenerator::generate_counter_overflow(Label* do_continue) { // C++ interpreter on entry - // rsi - new interpreter state pointer + // rsi/r13 - new interpreter state pointer // rbp - interpreter frame pointer // rbx - method @@ -563,7 +582,7 @@ void InterpreterGenerator::generate_counter_overflow(Label* do_continue) { // rsp - sender_sp // C++ interpreter only - // rsi - previous interpreter state pointer + // rsi/r13 - previous interpreter state pointer const Address size_of_parameters(rbx, methodOopDesc::size_of_parameters_offset()); @@ -571,16 +590,14 @@ void InterpreterGenerator::generate_counter_overflow(Label* do_continue) { // indicating if the counter overflow occurs at a backwards branch (non-NULL bcp). // The call returns the address of the verified entry point for the method or NULL // if the compilation did not complete (either went background or bailed out). - __ movl(rax, (int)false); + __ movptr(rax, (int32_t)false); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), rax); // for c++ interpreter can rsi really be munged? - __ leal(rsi, Address(rbp, -sizeof(BytecodeInterpreter))); // restore state - __ movl(rbx, Address(rsi, byte_offset_of(BytecodeInterpreter, _method))); // restore method - __ movl(rdi, Address(rsi, byte_offset_of(BytecodeInterpreter, _locals))); // get locals pointer + __ lea(state, Address(rbp, -sizeof(BytecodeInterpreter))); // restore state + __ movptr(rbx, Address(state, byte_offset_of(BytecodeInterpreter, _method))); // restore method + __ movptr(rdi, Address(state, byte_offset_of(BytecodeInterpreter, _locals))); // get locals pointer - // Preserve invariant that rsi/rdi contain bcp/locals of sender frame - // and jump to the interpreted entry. __ jmp(*do_continue, relocInfo::none); } @@ -597,7 +614,7 @@ void InterpreterGenerator::generate_stack_overflow_check(void) { // rbx,: methodOop // C++ Interpreter - // rsi: previous interpreter frame state object + // rsi/r13: previous interpreter frame state object // rdi: &locals[0] // rcx: # of locals // rdx: number of additional locals this frame needs (what we must check) @@ -628,11 +645,11 @@ void InterpreterGenerator::generate_stack_overflow_check(void) { // save rsi == caller's bytecode ptr (c++ previous interp. state) // QQQ problem here?? rsi overload???? - __ pushl(rsi); + __ push(state); - const Register thread = rsi; + const Register thread = LP64_ONLY(r15_thread) NOT_LP64(rsi); - __ get_thread(thread); + NOT_LP64(__ get_thread(thread)); const Address stack_base(thread, Thread::stack_base_offset()); const Address stack_size(thread, Thread::stack_size_offset()); @@ -643,26 +660,26 @@ void InterpreterGenerator::generate_stack_overflow_check(void) { // Any additional monitors need a check when moving the expression stack const one_monitor = frame::interpreter_frame_monitor_size() * wordSize; __ load_unsigned_word(rax, size_of_stack); // get size of expression stack in words - __ leal(rax, Address(noreg, rax, Interpreter::stackElementScale(), one_monitor)); - __ leal(rax, Address(rax, rdx, Interpreter::stackElementScale(), overhead_size)); + __ lea(rax, Address(noreg, rax, Interpreter::stackElementScale(), one_monitor)); + __ lea(rax, Address(rax, rdx, Interpreter::stackElementScale(), overhead_size)); #ifdef ASSERT Label stack_base_okay, stack_size_okay; // verify that thread stack base is non-zero - __ cmpl(stack_base, 0); + __ cmpptr(stack_base, (int32_t)0); __ jcc(Assembler::notEqual, stack_base_okay); __ stop("stack base is zero"); __ bind(stack_base_okay); // verify that thread stack size is non-zero - __ cmpl(stack_size, 0); + __ cmpptr(stack_size, (int32_t)0); __ jcc(Assembler::notEqual, stack_size_okay); __ stop("stack size is zero"); __ bind(stack_size_okay); #endif // Add stack base to locals and subtract stack size - __ addl(rax, stack_base); - __ subl(rax, stack_size); + __ addptr(rax, stack_base); + __ subptr(rax, stack_size); // We should have a magic number here for the size of the c++ interpreter frame. // We can't actually tell this ahead of time. The debug version size is around 3k @@ -674,20 +691,20 @@ void InterpreterGenerator::generate_stack_overflow_check(void) { (StackRedPages+StackYellowPages); // Only need this if we are stack banging which is temporary while // we're debugging. - __ addl(rax, slop + 2*max_pages * page_size); + __ addptr(rax, slop + 2*max_pages * page_size); // check against the current stack bottom - __ cmpl(rsp, rax); + __ cmpptr(rsp, rax); __ jcc(Assembler::above, after_frame_check_pop); - __ popl(rsi); // get saved bcp / (c++ prev state ). + __ pop(state); // get c++ prev state. // throw exception return address becomes throwing pc __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_StackOverflowError)); // all done with frame size check __ bind(after_frame_check_pop); - __ popl(rsi); + __ pop(state); __ bind(after_frame_check); } @@ -696,17 +713,18 @@ void InterpreterGenerator::generate_stack_overflow_check(void) { // rbx - methodOop // void InterpreterGenerator::lock_method(void) { - // assumes state == rsi == pointer to current interpreterState - // minimally destroys rax, rdx, rdi + // assumes state == rsi/r13 == pointer to current interpreterState + // minimally destroys rax, rdx|c_rarg1, rdi // // synchronize method - const Register state = rsi; const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; const Address access_flags (rbx, methodOopDesc::access_flags_offset()); + const Register monitor = NOT_LP64(rdx) LP64_ONLY(c_rarg1); + // find initial monitor i.e. monitors[-1] - __ movl(rdx, STATE(_monitor_base)); // get monitor bottom limit - __ subl(rdx, entry_size); // point to initial monitor + __ movptr(monitor, STATE(_monitor_base)); // get monitor bottom limit + __ subptr(monitor, entry_size); // point to initial monitor #ifdef ASSERT { Label L; @@ -721,35 +739,34 @@ void InterpreterGenerator::lock_method(void) { { Label done; const int mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes(); __ movl(rax, access_flags); - __ movl(rdi, STATE(_locals)); // prepare to get receiver (assume common case) + __ movptr(rdi, STATE(_locals)); // prepare to get receiver (assume common case) __ testl(rax, JVM_ACC_STATIC); - __ movl(rax, Address(rdi, 0)); // get receiver (assume this is frequent case) + __ movptr(rax, Address(rdi, 0)); // get receiver (assume this is frequent case) __ jcc(Assembler::zero, done); - __ movl(rax, Address(rbx, methodOopDesc::constants_offset())); - __ movl(rax, Address(rax, constantPoolOopDesc::pool_holder_offset_in_bytes())); - __ movl(rax, Address(rax, mirror_offset)); + __ movptr(rax, Address(rbx, methodOopDesc::constants_offset())); + __ movptr(rax, Address(rax, constantPoolOopDesc::pool_holder_offset_in_bytes())); + __ movptr(rax, Address(rax, mirror_offset)); __ bind(done); } #ifdef ASSERT { Label L; - __ cmpl(rax, Address(rdx, BasicObjectLock::obj_offset_in_bytes())); // correct object? + __ cmpptr(rax, Address(monitor, BasicObjectLock::obj_offset_in_bytes())); // correct object? __ jcc(Assembler::equal, L); __ stop("wrong synchronization lobject"); __ bind(L); } #endif // ASSERT - // can destroy rax, rdx, rcx, and (via call_VM) rdi! - __ lock_object(rdx); + // can destroy rax, rdx|c_rarg1, rcx, and (via call_VM) rdi! + __ lock_object(monitor); } // Call an accessor method (assuming it is resolved, otherwise drop into vanilla (slow path) entry address InterpreterGenerator::generate_accessor_entry(void) { - // rbx,: methodOop - // rcx: receiver (preserve for slow entry into asm interpreter) + // rbx: methodOop - // rsi: senderSP must preserved for slow path, set SP to it on fast path + // rsi/r13: senderSP must preserved for slow path, set SP to it on fast path Label xreturn_path; @@ -772,21 +789,21 @@ address InterpreterGenerator::generate_accessor_entry(void) { // these conditions first and use slow path if necessary. // rbx,: method // rcx: receiver - __ movl(rax, Address(rsp, wordSize)); + __ movptr(rax, Address(rsp, wordSize)); // check if local 0 != NULL and read field - __ testl(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, slow_path); - __ movl(rdi, Address(rbx, methodOopDesc::constants_offset())); + __ movptr(rdi, Address(rbx, methodOopDesc::constants_offset())); // read first instruction word and extract bytecode @ 1 and index @ 2 - __ movl(rdx, Address(rbx, methodOopDesc::const_offset())); + __ movptr(rdx, Address(rbx, methodOopDesc::const_offset())); __ movl(rdx, Address(rdx, constMethodOopDesc::codes_offset())); // Shift codes right to get the index on the right. // The bytecode fetched looks like <0xb4><0x2a> __ shrl(rdx, 2*BitsPerByte); __ shll(rdx, exact_log2(in_words(ConstantPoolCacheEntry::size()))); - __ movl(rdi, Address(rdi, constantPoolOopDesc::cache_offset_in_bytes())); + __ movptr(rdi, Address(rdi, constantPoolOopDesc::cache_offset_in_bytes())); // rax,: local 0 // rbx,: method @@ -794,7 +811,7 @@ address InterpreterGenerator::generate_accessor_entry(void) { // rcx: scratch // rdx: constant pool cache index // rdi: constant pool cache - // rsi: sender sp + // rsi/r13: sender sp // check if getfield has been resolved and read constant pool cache entry // check the validity of the cache entry by testing whether _indices field @@ -803,21 +820,21 @@ address InterpreterGenerator::generate_accessor_entry(void) { __ movl(rcx, Address(rdi, rdx, - Address::times_4, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); + Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); __ shrl(rcx, 2*BitsPerByte); __ andl(rcx, 0xFF); __ cmpl(rcx, Bytecodes::_getfield); __ jcc(Assembler::notEqual, slow_path); // Note: constant pool entry is not valid before bytecode is resolved - __ movl(rcx, + __ movptr(rcx, Address(rdi, rdx, - Address::times_4, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f2_offset())); + Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f2_offset())); __ movl(rdx, Address(rdi, rdx, - Address::times_4, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::flags_offset())); + Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::flags_offset())); Label notByte, notShort, notChar; const Address field_address (rax, rcx, Address::times_1); @@ -828,6 +845,16 @@ address InterpreterGenerator::generate_accessor_entry(void) { __ shrl(rdx, ConstantPoolCacheEntry::tosBits); // Make sure we don't need to mask rdx for tosBits after the above shift ConstantPoolCacheEntry::verify_tosBits(); +#ifdef _LP64 + Label notObj; + __ cmpl(rdx, atos); + __ jcc(Assembler::notEqual, notObj); + // atos + __ movptr(rax, field_address); + __ jmp(xreturn_path); + + __ bind(notObj); +#endif // _LP64 __ cmpl(rdx, btos); __ jcc(Assembler::notEqual, notByte); __ load_signed_byte(rax, field_address); @@ -848,8 +875,10 @@ address InterpreterGenerator::generate_accessor_entry(void) { __ bind(notChar); #ifdef ASSERT Label okay; +#ifndef _LP64 __ cmpl(rdx, atos); __ jcc(Assembler::equal, okay); +#endif // _LP64 __ cmpl(rdx, itos); __ jcc(Assembler::equal, okay); __ stop("what type is this?"); @@ -861,8 +890,8 @@ address InterpreterGenerator::generate_accessor_entry(void) { __ bind(xreturn_path); // _ireturn/_areturn - __ popl(rdi); // get return address - __ movl(rsp, rsi); // set sp to sender sp + __ pop(rdi); // get return address + __ mov(rsp, sender_sp_on_entry); // set sp to sender sp __ jmp(rdi); // generate a vanilla interpreter entry as the slow path @@ -894,8 +923,8 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // rbx: methodOop // rcx: receiver (unused) - // rsi: previous interpreter state (if called from C++ interpreter) must preserve - // in any case. If called via c1/c2/call_stub rsi is junk (to use) but harmless + // rsi/r13: previous interpreter state (if called from C++ interpreter) must preserve + // in any case. If called via c1/c2/call_stub rsi/r13 is junk (to use) but harmless // to save/restore. address entry_point = __ pc(); @@ -904,8 +933,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { const Address invocation_counter(rbx, methodOopDesc::invocation_counter_offset() + InvocationCounter::counter_offset()); const Address access_flags (rbx, methodOopDesc::access_flags_offset()); - // rsi == state/locals rdi == prevstate - const Register state = rsi; + // rsi/r13 == state/locals rdi == prevstate const Register locals = rdi; // get parameter size (always needed) @@ -913,11 +941,11 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // rbx: methodOop // rcx: size of parameters - __ popl(rax); // get return address + __ pop(rax); // get return address // for natives the size of locals is zero // compute beginning of parameters /locals - __ leal(locals, Address(rsp, rcx, Address::times_4, -wordSize)); + __ lea(locals, Address(rsp, rcx, Address::times_ptr, -wordSize)); // initialize fixed part of activation frame @@ -931,15 +959,20 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // OUT(rsp) -> bottom of methods expression stack // save sender_sp - __ movl(rcx, rsi); + __ mov(rcx, sender_sp_on_entry); // start with NULL previous state - __ movl(state, 0); + __ movptr(state, (int32_t)NULL_WORD); generate_compute_interpreter_state(state, locals, rcx, true); #ifdef ASSERT { Label L; - __ movl(rax, STATE(_stack_base)); - __ cmpl(rax, rsp); + __ movptr(rax, STATE(_stack_base)); +#ifdef _LP64 + // duplicate the alignment rsp got after setting stack_base + __ subptr(rax, frame::arg_reg_save_area_bytes); // windows + __ andptr(rax, -16); // must be 16 byte boundry (see amd64 ABI) +#endif // _LP64 + __ cmpptr(rax, rsp); __ jcc(Assembler::equal, L); __ stop("broken stack frame setup in interpreter"); __ bind(L); @@ -948,14 +981,15 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { if (inc_counter) __ movl(rcx, invocation_counter); // (pre-)fetch invocation count - __ movl(rax, STATE(_thread)); // get thread + const Register unlock_thread = LP64_ONLY(r15_thread) NOT_LP64(rax); + NOT_LP64(__ movptr(unlock_thread, STATE(_thread));) // get thread // Since at this point in the method invocation the exception handler // would try to exit the monitor of synchronized methods which hasn't // been entered yet, we set the thread local variable // _do_not_unlock_if_synchronized to true. The remove_activation will // check this flag. - const Address do_not_unlock_if_synchronized(rax, + const Address do_not_unlock_if_synchronized(unlock_thread, in_bytes(JavaThread::do_not_unlock_if_synchronized_offset())); __ movbool(do_not_unlock_if_synchronized, true); @@ -991,7 +1025,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { bang_stack_shadow_pages(true); // reset the _do_not_unlock_if_synchronized flag - __ movl(rax, STATE(_thread)); // get thread + NOT_LP64(__ movl(rax, STATE(_thread));) // get thread __ movbool(do_not_unlock_if_synchronized, false); @@ -1022,62 +1056,81 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // work registers const Register method = rbx; - const Register thread = rdi; - const Register t = rcx; + const Register thread = LP64_ONLY(r15_thread) NOT_LP64(rdi); + const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp(); // rcx|rscratch1 // allocate space for parameters - __ movl(method, STATE(_method)); + __ movptr(method, STATE(_method)); __ verify_oop(method); __ load_unsigned_word(t, Address(method, methodOopDesc::size_of_parameters_offset())); __ shll(t, 2); - __ addl(t, 2*wordSize); // allocate two more slots for JNIEnv and possible mirror - __ subl(rsp, t); - __ andl(rsp, -(StackAlignmentInBytes)); // gcc needs 16 byte aligned stacks to do XMM intrinsics +#ifdef _LP64 + __ subptr(rsp, t); + __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows + __ andptr(rsp, -16); // must be 16 byte boundry (see amd64 ABI) +#else + __ addptr(t, 2*wordSize); // allocate two more slots for JNIEnv and possible mirror + __ subptr(rsp, t); + __ andptr(rsp, -(StackAlignmentInBytes)); // gcc needs 16 byte aligned stacks to do XMM intrinsics +#endif // _LP64 // get signature handler Label pending_exception_present; { Label L; - __ movl(t, Address(method, methodOopDesc::signature_handler_offset())); - __ testl(t, t); + __ movptr(t, Address(method, methodOopDesc::signature_handler_offset())); + __ testptr(t, t); __ jcc(Assembler::notZero, L); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), method, false); - __ movl(method, STATE(_method)); - __ cmpl(Address(thread, Thread::pending_exception_offset()), NULL_WORD); + __ movptr(method, STATE(_method)); + __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::notEqual, pending_exception_present); __ verify_oop(method); - __ movl(t, Address(method, methodOopDesc::signature_handler_offset())); + __ movptr(t, Address(method, methodOopDesc::signature_handler_offset())); __ bind(L); } #ifdef ASSERT { Label L; - __ pushl(t); + __ push(t); __ get_thread(t); // get vm's javathread* - __ cmpl(t, STATE(_thread)); + __ cmpptr(t, STATE(_thread)); __ jcc(Assembler::equal, L); __ int3(); __ bind(L); - __ popl(t); + __ pop(t); } #endif // + const Register from_ptr = InterpreterRuntime::SignatureHandlerGenerator::from(); // call signature handler - assert(InterpreterRuntime::SignatureHandlerGenerator::from() == rdi, "adjust this code"); assert(InterpreterRuntime::SignatureHandlerGenerator::to () == rsp, "adjust this code"); - assert(InterpreterRuntime::SignatureHandlerGenerator::temp() == t , "adjust this code"); + // The generated handlers do not touch RBX (the method oop). // However, large signatures cannot be cached and are generated // each time here. The slow-path generator will blow RBX // sometime, so we must reload it after the call. - __ movl(rdi, STATE(_locals)); // get the from pointer + __ movptr(from_ptr, STATE(_locals)); // get the from pointer __ call(t); - __ movl(method, STATE(_method)); + __ movptr(method, STATE(_method)); __ verify_oop(method); // result handler is in rax // set result handler - __ movl(STATE(_result_handler), rax); + __ movptr(STATE(_result_handler), rax); + + + // get native function entry point + { Label L; + __ movptr(rax, Address(method, methodOopDesc::native_function_offset())); + __ testptr(rax, rax); + __ jcc(Assembler::notZero, L); + __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), method); + __ movptr(method, STATE(_method)); + __ verify_oop(method); + __ movptr(rax, Address(method, methodOopDesc::native_function_offset())); + __ bind(L); + } // pass mirror handle if static call { Label L; @@ -1086,55 +1139,53 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ testl(t, JVM_ACC_STATIC); __ jcc(Assembler::zero, L); // get mirror - __ movl(t, Address(method, methodOopDesc:: constants_offset())); - __ movl(t, Address(t, constantPoolOopDesc::pool_holder_offset_in_bytes())); - __ movl(t, Address(t, mirror_offset)); + __ movptr(t, Address(method, methodOopDesc:: constants_offset())); + __ movptr(t, Address(t, constantPoolOopDesc::pool_holder_offset_in_bytes())); + __ movptr(t, Address(t, mirror_offset)); // copy mirror into activation object - __ movl(STATE(_oop_temp), t); + __ movptr(STATE(_oop_temp), t); // pass handle to mirror - __ leal(t, STATE(_oop_temp)); - __ movl(Address(rsp, wordSize), t); +#ifdef _LP64 + __ lea(c_rarg1, STATE(_oop_temp)); +#else + __ lea(t, STATE(_oop_temp)); + __ movptr(Address(rsp, wordSize), t); +#endif // _LP64 __ bind(L); } #ifdef ASSERT { Label L; - __ pushl(t); + __ push(t); __ get_thread(t); // get vm's javathread* - __ cmpl(t, STATE(_thread)); + __ cmpptr(t, STATE(_thread)); __ jcc(Assembler::equal, L); __ int3(); __ bind(L); - __ popl(t); + __ pop(t); } #endif // - // get native function entry point - { Label L; - __ movl(rax, Address(method, methodOopDesc::native_function_offset())); - __ testl(rax, rax); - __ jcc(Assembler::notZero, L); - __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), method); - __ movl(method, STATE(_method)); - __ verify_oop(method); - __ movl(rax, Address(method, methodOopDesc::native_function_offset())); - __ bind(L); - } - // pass JNIEnv - __ movl(thread, STATE(_thread)); // get thread - __ leal(t, Address(thread, JavaThread::jni_environment_offset())); - __ movl(Address(rsp, 0), t); +#ifdef _LP64 + __ lea(c_rarg0, Address(thread, JavaThread::jni_environment_offset())); +#else + __ movptr(thread, STATE(_thread)); // get thread + __ lea(t, Address(thread, JavaThread::jni_environment_offset())); + + __ movptr(Address(rsp, 0), t); +#endif // _LP64 + #ifdef ASSERT { Label L; - __ pushl(t); + __ push(t); __ get_thread(t); // get vm's javathread* - __ cmpl(t, STATE(_thread)); + __ cmpptr(t, STATE(_thread)); __ jcc(Assembler::equal, L); __ int3(); __ bind(L); - __ popl(t); + __ pop(t); } #endif // @@ -1159,8 +1210,8 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ call(rax); // result potentially in rdx:rax or ST0 - __ movl(method, STATE(_method)); - __ movl(thread, STATE(_thread)); // get thread + __ movptr(method, STATE(_method)); + NOT_LP64(__ movptr(thread, STATE(_thread));) // get thread // The potential result is in ST(0) & rdx:rax // With C++ interpreter we leave any possible result in ST(0) until we are in result handler and then @@ -1170,7 +1221,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // It is safe to do these pushes because state is _thread_in_native and return address will be found // via _last_native_pc and not via _last_jave_sp - // Must save the value of ST(0) since it could be destroyed before we get to result handler + // Must save the value of ST(0)/xmm0 since it could be destroyed before we get to result handler { Label Lpush, Lskip; ExternalAddress float_handler(AbstractInterpreter::result_handler(T_FLOAT)); ExternalAddress double_handler(AbstractInterpreter::result_handler(T_DOUBLE)); @@ -1179,11 +1230,20 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ cmpptr(STATE(_result_handler), double_handler.addr()); __ jcc(Assembler::notEqual, Lskip); __ bind(Lpush); - __ push(dtos); + __ subptr(rsp, 2*wordSize); + if ( UseSSE < 2 ) { + __ fstp_d(Address(rsp, 0)); + } else { + __ movdbl(Address(rsp, 0), xmm0); + } __ bind(Lskip); } - __ push(ltos); // save rax:rdx for potential use by result handler. + // save rax:rdx for potential use by result handler. + __ push(rax); +#ifndef _LP64 + __ push(rdx); +#endif // _LP64 // Either restore the MXCSR register after returning from the JNI Call // or verify that it wasn't changed. @@ -1192,15 +1252,17 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ ldmxcsr(ExternalAddress(StubRoutines::addr_mxcsr_std())); } else if (CheckJNICalls ) { - __ call(RuntimeAddress(StubRoutines::i486::verify_mxcsr_entry())); + __ call(RuntimeAddress(StubRoutines::x86::verify_mxcsr_entry())); } } +#ifndef _LP64 // Either restore the x87 floating pointer control word after returning // from the JNI call or verify that it wasn't changed. if (CheckJNICalls) { - __ call(RuntimeAddress(StubRoutines::i486::verify_fpu_cntrl_wrd_entry())); + __ call(RuntimeAddress(StubRoutines::x86::verify_fpu_cntrl_wrd_entry())); } +#endif // _LP64 // change thread state @@ -1231,17 +1293,16 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // Don't use call_VM as it will see a possible pending exception and forward it // and never return here preventing us from clearing _last_native_pc down below. // Also can't use call_VM_leaf either as it will check to see if rsi & rdi are - // preserved and correspond to the bcp/locals pointers. So we do a runtime call - // by hand. + // preserved and correspond to the bcp/locals pointers. // - __ pushl(thread); - __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, - JavaThread::check_special_condition_for_native_trans))); + + ((MacroAssembler*)_masm)->call_VM_leaf(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans), + thread); __ increment(rsp, wordSize); - __ movl(method, STATE(_method)); + __ movptr(method, STATE(_method)); __ verify_oop(method); - __ movl(thread, STATE(_thread)); // get thread + __ movptr(thread, STATE(_thread)); // get thread __ bind(Continue); } @@ -1252,8 +1313,8 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ reset_last_Java_frame(thread, true, true); // reset handle block - __ movl(t, Address(thread, JavaThread::active_handles_offset())); - __ movl(Address(t, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD); + __ movptr(t, Address(thread, JavaThread::active_handles_offset())); + __ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); // If result was an oop then unbox and save it in the frame { Label L; @@ -1261,15 +1322,21 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { ExternalAddress oop_handler(AbstractInterpreter::result_handler(T_OBJECT)); __ cmpptr(STATE(_result_handler), oop_handler.addr()); __ jcc(Assembler::notEqual, no_oop); - __ pop(ltos); - __ testl(rax, rax); +#ifndef _LP64 + __ pop(rdx); +#endif // _LP64 + __ pop(rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, store_result); // unbox - __ movl(rax, Address(rax, 0)); + __ movptr(rax, Address(rax, 0)); __ bind(store_result); - __ movl(STATE(_oop_temp), rax); + __ movptr(STATE(_oop_temp), rax); // keep stack depth as expected by pushing oop which will eventually be discarded - __ push(ltos); + __ push(rax); +#ifndef _LP64 + __ push(rdx); +#endif // _LP64 __ bind(no_oop); } @@ -1278,9 +1345,9 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ cmpl(Address(thread, JavaThread::stack_guard_state_offset()), JavaThread::stack_guard_yellow_disabled); __ jcc(Assembler::notEqual, no_reguard); - __ pushad(); + __ pusha(); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages))); - __ popad(); + __ popa(); __ bind(no_reguard); } @@ -1295,7 +1362,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // handle exceptions (exception handling will handle unlocking!) { Label L; - __ cmpl(Address(thread, Thread::pending_exception_offset()), NULL_WORD); + __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::zero, L); __ bind(pending_exception_present); @@ -1307,12 +1374,12 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // remove activation - __ movl(t, STATE(_sender_sp)); + __ movptr(t, STATE(_sender_sp)); __ leave(); // remove frame anchor - __ popl(rdi); // get return address - __ movl(state, STATE(_prev_link)); // get previous state for return - __ movl(rsp, t); // set sp to sender sp - __ pushl(rdi); // [ush throwing pc + __ pop(rdi); // get return address + __ movptr(state, STATE(_prev_link)); // get previous state for return + __ mov(rsp, t); // set sp to sender sp + __ push(rdi); // push throwing pc // The skips unlocking!! This seems to be what asm interpreter does but seems // very wrong. Not clear if this violates the spec. __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); @@ -1326,13 +1393,14 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ jcc(Assembler::zero, L); // the code below should be shared with interpreter macro assembler implementation { Label unlock; + const Register monitor = NOT_LP64(rdx) LP64_ONLY(c_rarg1); // BasicObjectLock will be first in list, since this is a synchronized method. However, need // to check that the object has not been unlocked by an explicit monitorexit bytecode. - __ movl(rdx, STATE(_monitor_base)); - __ subl(rdx, frame::interpreter_frame_monitor_size() * wordSize); // address of initial monitor + __ movptr(monitor, STATE(_monitor_base)); + __ subptr(monitor, frame::interpreter_frame_monitor_size() * wordSize); // address of initial monitor - __ movl(t, Address(rdx, BasicObjectLock::obj_offset_in_bytes())); - __ testl(t, t); + __ movptr(t, Address(monitor, BasicObjectLock::obj_offset_in_bytes())); + __ testptr(t, t); __ jcc(Assembler::notZero, unlock); // Entry already unlocked, need to throw exception @@ -1340,9 +1408,9 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ should_not_reach_here(); __ bind(unlock); - __ unlock_object(rdx); + __ unlock_object(monitor); // unlock can blow rbx so restore it for path that needs it below - __ movl(method, STATE(_method)); + __ movptr(method, STATE(_method)); } __ bind(L); } @@ -1355,18 +1423,21 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ notify_method_exit(vtos, InterpreterMacroAssembler::NotifyJVMTI); // restore potential result in rdx:rax, call result handler to restore potential result in ST0 & handle result - __ pop(ltos); // restore rax/rdx floating result if present still on stack - __ movl(t, STATE(_result_handler)); // get result handler +#ifndef _LP64 + __ pop(rdx); +#endif // _LP64 + __ pop(rax); + __ movptr(t, STATE(_result_handler)); // get result handler __ call(t); // call result handler to convert to tosca form // remove activation - __ movl(t, STATE(_sender_sp)); + __ movptr(t, STATE(_sender_sp)); __ leave(); // remove frame anchor - __ popl(rdi); // get return address - __ movl(state, STATE(_prev_link)); // get previous state for return (if c++ interpreter was caller) - __ movl(rsp, t); // set sp to sender sp + __ pop(rdi); // get return address + __ movptr(state, STATE(_prev_link)); // get previous state for return (if c++ interpreter was caller) + __ mov(rsp, t); // set sp to sender sp __ jmp(rdi); // invocation counter overflow @@ -1382,7 +1453,6 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // Generate entries that will put a result type index into rcx void CppInterpreterGenerator::generate_deopt_handling() { - const Register state = rsi; Label return_from_deopt_common; // Generate entries that will put a result type index into rcx @@ -1449,51 +1519,50 @@ void CppInterpreterGenerator::generate_deopt_handling() { // __ bind(return_from_deopt_common); - __ leal(state, Address(rbp, -(int)sizeof(BytecodeInterpreter))); + __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter))); // setup rsp so we can push the "result" as needed. - __ movl(rsp, STATE(_stack)); // trim stack (is prepushed) - __ addl(rsp, wordSize); // undo prepush + __ movptr(rsp, STATE(_stack)); // trim stack (is prepushed) + __ addptr(rsp, wordSize); // undo prepush ExternalAddress tosca_to_stack((address)CppInterpreter::_tosca_to_stack); - // Address index(noreg, rcx, Address::times_4); - __ movptr(rcx, ArrayAddress(tosca_to_stack, Address(noreg, rcx, Address::times_4))); - // __ movl(rcx, Address(noreg, rcx, Address::times_4, int(AbstractInterpreter::_tosca_to_stack))); + // Address index(noreg, rcx, Address::times_ptr); + __ movptr(rcx, ArrayAddress(tosca_to_stack, Address(noreg, rcx, Address::times_ptr))); + // __ movl(rcx, Address(noreg, rcx, Address::times_ptr, int(AbstractInterpreter::_tosca_to_stack))); __ call(rcx); // call result converter __ movl(STATE(_msg), (int)BytecodeInterpreter::deopt_resume); - __ leal(rsp, Address(rsp, -wordSize)); // prepush stack (result if any already present) - __ movl(STATE(_stack), rsp); // inform interpreter of new stack depth (parameters removed, + __ lea(rsp, Address(rsp, -wordSize)); // prepush stack (result if any already present) + __ movptr(STATE(_stack), rsp); // inform interpreter of new stack depth (parameters removed, // result if any on stack already ) - __ movl(rsp, STATE(_stack_limit)); // restore expression stack to full depth + __ movptr(rsp, STATE(_stack_limit)); // restore expression stack to full depth } // Generate the code to handle a more_monitors message from the c++ interpreter void CppInterpreterGenerator::generate_more_monitors() { - const Register state = rsi; Label entry, loop; const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; - // 1. compute new pointers // rsp: old expression stack top - __ movl(rdx, STATE(_stack_base)); // rdx: old expression stack bottom - __ subl(rsp, entry_size); // move expression stack top limit - __ subl(STATE(_stack), entry_size); // update interpreter stack top - __ movl(STATE(_stack_limit), rsp); // inform interpreter - __ subl(rdx, entry_size); // move expression stack bottom - __ movl(STATE(_stack_base), rdx); // inform interpreter - __ movl(rcx, STATE(_stack)); // set start value for copy loop + // 1. compute new pointers // rsp: old expression stack top + __ movptr(rdx, STATE(_stack_base)); // rdx: old expression stack bottom + __ subptr(rsp, entry_size); // move expression stack top limit + __ subptr(STATE(_stack), entry_size); // update interpreter stack top + __ subptr(STATE(_stack_limit), entry_size); // inform interpreter + __ subptr(rdx, entry_size); // move expression stack bottom + __ movptr(STATE(_stack_base), rdx); // inform interpreter + __ movptr(rcx, STATE(_stack)); // set start value for copy loop __ jmp(entry); // 2. move expression stack contents __ bind(loop); - __ movl(rbx, Address(rcx, entry_size)); // load expression stack word from old location - __ movl(Address(rcx, 0), rbx); // and store it at new location - __ addl(rcx, wordSize); // advance to next word + __ movptr(rbx, Address(rcx, entry_size)); // load expression stack word from old location + __ movptr(Address(rcx, 0), rbx); // and store it at new location + __ addptr(rcx, wordSize); // advance to next word __ bind(entry); - __ cmpl(rcx, rdx); // check if bottom reached - __ jcc(Assembler::notEqual, loop); // if not at bottom then copy next word + __ cmpptr(rcx, rdx); // check if bottom reached + __ jcc(Assembler::notEqual, loop); // if not at bottom then copy next word // now zero the slot so we can find it. - __ movl(Address(rdx, BasicObjectLock::obj_offset_in_bytes()), (int) NULL); + __ movptr(Address(rdx, BasicObjectLock::obj_offset_in_bytes()), (int32_t) NULL_WORD); __ movl(STATE(_msg), (int)BytecodeInterpreter::got_monitors); } @@ -1517,7 +1586,7 @@ void CppInterpreterGenerator::generate_more_monitors() { // // rbx: methodOop // rcx: receiver - unused (retrieved from stack as needed) -// rsi: previous frame manager state (NULL from the call_stub/c1/c2) +// rsi/r13: previous frame manager state (NULL from the call_stub/c1/c2) // // // Stack layout at entry @@ -1539,7 +1608,7 @@ static address interpreter_frame_manager = NULL; address InterpreterGenerator::generate_normal_entry(bool synchronized) { // rbx: methodOop - // rsi: sender sp + // rsi/r13: sender sp // Because we redispatch "recursive" interpreter entries thru this same entry point // the "input" register usage is a little strange and not what you expect coming @@ -1562,12 +1631,11 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { if (UseFastAccessorMethods && !synchronized) __ bind(fast_accessor_slow_entry_path); Label dispatch_entry_2; - __ movl(rcx, rsi); - __ movl(rsi, 0); // no current activation + __ movptr(rcx, sender_sp_on_entry); + __ movptr(state, (int32_t)NULL_WORD); // no current activation __ jmp(dispatch_entry_2); - const Register state = rsi; // current activation object, valid on entry const Register locals = rdi; Label re_dispatch; @@ -1575,12 +1643,12 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { __ bind(re_dispatch); // save sender sp (doesn't include return address - __ leal(rcx, Address(rsp, wordSize)); + __ lea(rcx, Address(rsp, wordSize)); __ bind(dispatch_entry_2); // save sender sp - __ pushl(rcx); + __ push(rcx); const Address size_of_parameters(rbx, methodOopDesc::size_of_parameters_offset()); const Address size_of_locals (rbx, methodOopDesc::size_of_locals_offset()); @@ -1597,7 +1665,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { // rcx: size of parameters __ load_unsigned_word(rdx, size_of_locals); // get size of locals in words - __ subl(rdx, rcx); // rdx = no. of additional locals + __ subptr(rdx, rcx); // rdx = no. of additional locals // see if we've got enough room on the stack for locals plus overhead. generate_stack_overflow_check(); // C++ @@ -1609,26 +1677,26 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { // compute beginning of parameters (rdi) - __ leal(locals, Address(rsp, rcx, Address::times_4, wordSize)); + __ lea(locals, Address(rsp, rcx, Address::times_ptr, wordSize)); // save sender's sp // __ movl(rcx, rsp); // get sender's sp - __ popl(rcx); + __ pop(rcx); // get return address - __ popl(rax); + __ pop(rax); // rdx - # of additional locals // allocate space for locals // explicitly initialize locals { Label exit, loop; - __ testl(rdx, rdx); + __ testl(rdx, rdx); // (32bit ok) __ jcc(Assembler::lessEqual, exit); // do nothing if rdx <= 0 __ bind(loop); - __ pushl((int)NULL); // initialize local variables + __ push((int32_t)NULL_WORD); // initialize local variables __ decrement(rdx); // until everything initialized __ jcc(Assembler::greater, loop); __ bind(exit); @@ -1664,17 +1732,21 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { __ bind(call_interpreter_2); { - const Register thread = rcx; + const Register thread = NOT_LP64(rcx) LP64_ONLY(r15_thread); - __ pushl(state); // push arg to interpreter - __ movl(thread, STATE(_thread)); +#ifdef _LP64 + __ mov(c_rarg0, state); +#else + __ push(state); // push arg to interpreter + __ movptr(thread, STATE(_thread)); +#endif // _LP64 // We can setup the frame anchor with everything we want at this point // as we are thread_in_Java and no safepoints can occur until we go to // vm mode. We do have to clear flags on return from vm but that is it // - __ movl(Address(thread, JavaThread::last_Java_fp_offset()), rbp); - __ movl(Address(thread, JavaThread::last_Java_sp_offset()), rsp); + __ movptr(Address(thread, JavaThread::last_Java_fp_offset()), rbp); + __ movptr(Address(thread, JavaThread::last_Java_sp_offset()), rsp); // Call the interpreter @@ -1682,14 +1754,14 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { RuntimeAddress checking(CAST_FROM_FN_PTR(address, BytecodeInterpreter::runWithChecks)); __ call(JvmtiExport::can_post_interpreter_events() ? checking : normal); - __ popl(rax); // discard parameter to run + NOT_LP64(__ pop(rax);) // discard parameter to run // // state is preserved since it is callee saved // // reset_last_Java_frame - __ movl(thread, STATE(_thread)); + NOT_LP64(__ movl(thread, STATE(_thread));) __ reset_last_Java_frame(thread, true, true); } @@ -1703,15 +1775,15 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { Label bad_msg; Label do_OSR; - __ cmpl(rdx, (int)BytecodeInterpreter::call_method); + __ cmpl(rdx, (int32_t)BytecodeInterpreter::call_method); __ jcc(Assembler::equal, call_method); - __ cmpl(rdx, (int)BytecodeInterpreter::return_from_method); + __ cmpl(rdx, (int32_t)BytecodeInterpreter::return_from_method); __ jcc(Assembler::equal, return_from_interpreted_method); - __ cmpl(rdx, (int)BytecodeInterpreter::do_osr); + __ cmpl(rdx, (int32_t)BytecodeInterpreter::do_osr); __ jcc(Assembler::equal, do_OSR); - __ cmpl(rdx, (int)BytecodeInterpreter::throwing_exception); + __ cmpl(rdx, (int32_t)BytecodeInterpreter::throwing_exception); __ jcc(Assembler::equal, throw_exception); - __ cmpl(rdx, (int)BytecodeInterpreter::more_monitors); + __ cmpl(rdx, (int32_t)BytecodeInterpreter::more_monitors); __ jcc(Assembler::notEqual, bad_msg); // Allocate more monitor space, shuffle expression stack.... @@ -1724,8 +1796,8 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { unctrap_frame_manager_entry = __ pc(); // // Load the registers we need. - __ leal(state, Address(rbp, -(int)sizeof(BytecodeInterpreter))); - __ movl(rsp, STATE(_stack_limit)); // restore expression stack to full depth + __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter))); + __ movptr(rsp, STATE(_stack_limit)); // restore expression stack to full depth __ jmp(call_interpreter_2); @@ -1757,13 +1829,17 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { Label unwind_and_forward; // restore state pointer. - __ leal(state, Address(rbp, -sizeof(BytecodeInterpreter))); + __ lea(state, Address(rbp, -sizeof(BytecodeInterpreter))); - __ movl(rbx, STATE(_method)); // get method + __ movptr(rbx, STATE(_method)); // get method +#ifdef _LP64 + __ movptr(Address(r15_thread, Thread::pending_exception_offset()), rax); +#else __ movl(rcx, STATE(_thread)); // get thread // Store exception with interpreter will expect it - __ movl(Address(rcx, Thread::pending_exception_offset()), rax); + __ movptr(Address(rcx, Thread::pending_exception_offset()), rax); +#endif // _LP64 // is current frame vanilla or native? @@ -1779,11 +1855,11 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { // unwind rbp, return stack to unextended value and re-push return address - __ movl(rcx, STATE(_sender_sp)); + __ movptr(rcx, STATE(_sender_sp)); __ leave(); - __ popl(rdx); - __ movl(rsp, rcx); - __ pushl(rdx); + __ pop(rdx); + __ mov(rsp, rcx); + __ push(rdx); __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); // Return point from a call which returns a result in the native abi @@ -1801,8 +1877,8 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { // The FPU stack is clean if UseSSE >= 2 but must be cleaned in other cases if (UseSSE < 2) { - __ leal(state, Address(rbp, -sizeof(BytecodeInterpreter))); - __ movl(rbx, STATE(_result._to_call._callee)); // get method just executed + __ lea(state, Address(rbp, -sizeof(BytecodeInterpreter))); + __ movptr(rbx, STATE(_result._to_call._callee)); // get method just executed __ movl(rcx, Address(rbx, methodOopDesc::result_index_offset())); __ cmpl(rcx, AbstractInterpreter::BasicType_as_index(T_FLOAT)); // Result stub address array index __ jcc(Assembler::equal, do_float); @@ -1832,10 +1908,12 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { __ jmp(done_conv); } +#if 0 // emit a sentinel we can test for when converting an interpreter // entry point to a compiled entry point. __ a_long(Interpreter::return_sentinel); __ a_long((int)compiled_entry); +#endif // Return point to interpreter from compiled/native method @@ -1848,33 +1926,37 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { // calling convention left it (i.e. params may or may not be present) // Copy the result from tosca and place it on java expression stack. - // Restore rsi as compiled code may not preserve it + // Restore rsi/r13 as compiled code may not preserve it - __ leal(state, Address(rbp, -sizeof(BytecodeInterpreter))); + __ lea(state, Address(rbp, -sizeof(BytecodeInterpreter))); // restore stack to what we had when we left (in case i2c extended it) - __ movl(rsp, STATE(_stack)); - __ leal(rsp, Address(rsp, wordSize)); + __ movptr(rsp, STATE(_stack)); + __ lea(rsp, Address(rsp, wordSize)); // If there is a pending exception then we don't really have a result to process - __ movl(rcx, STATE(_thread)); // get thread - __ cmpl(Address(rcx, Thread::pending_exception_offset()), (int)NULL); +#ifdef _LP64 + __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); +#else + __ movptr(rcx, STATE(_thread)); // get thread + __ cmpptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD); +#endif / __LP64 __ jcc(Assembler::notZero, return_with_exception); // get method just executed - __ movl(rbx, STATE(_result._to_call._callee)); + __ movptr(rbx, STATE(_result._to_call._callee)); // callee left args on top of expression stack, remove them __ load_unsigned_word(rcx, Address(rbx, methodOopDesc::size_of_parameters_offset())); - __ leal(rsp, Address(rsp, rcx, Address::times_4)); + __ lea(rsp, Address(rsp, rcx, Address::times_ptr)); __ movl(rcx, Address(rbx, methodOopDesc::result_index_offset())); ExternalAddress tosca_to_stack((address)CppInterpreter::_tosca_to_stack); - // Address index(noreg, rax, Address::times_4); - __ movptr(rcx, ArrayAddress(tosca_to_stack, Address(noreg, rcx, Address::times_4))); - // __ movl(rcx, Address(noreg, rcx, Address::times_4, int(AbstractInterpreter::_tosca_to_stack))); + // Address index(noreg, rax, Address::times_ptr); + __ movptr(rcx, ArrayAddress(tosca_to_stack, Address(noreg, rcx, Address::times_ptr))); + // __ movl(rcx, Address(noreg, rcx, Address::times_ptr, int(AbstractInterpreter::_tosca_to_stack))); __ call(rcx); // call result converter __ jmp(resume_interpreter); @@ -1884,7 +1966,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { __ bind(return_with_exception); // Exception present, empty stack - __ movl(rsp, STATE(_stack_base)); + __ movptr(rsp, STATE(_stack_base)); __ jmp(resume_interpreter); // Return from interpreted method we return result appropriate to the caller (i.e. "recursive" @@ -1895,17 +1977,17 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { Label return_to_initial_caller; - __ movl(rbx, STATE(_method)); // get method just executed - __ cmpl(STATE(_prev_link), (int)NULL); // returning from "recursive" interpreter call? + __ movptr(rbx, STATE(_method)); // get method just executed + __ cmpptr(STATE(_prev_link), (int32_t)NULL_WORD); // returning from "recursive" interpreter call? __ movl(rax, Address(rbx, methodOopDesc::result_index_offset())); // get result type index __ jcc(Assembler::equal, return_to_initial_caller); // back to native code (call_stub/c1/c2) // Copy result to callers java stack ExternalAddress stack_to_stack((address)CppInterpreter::_stack_to_stack); - // Address index(noreg, rax, Address::times_4); + // Address index(noreg, rax, Address::times_ptr); - __ movptr(rax, ArrayAddress(stack_to_stack, Address(noreg, rax, Address::times_4))); - // __ movl(rax, Address(noreg, rax, Address::times_4, int(AbstractInterpreter::_stack_to_stack))); + __ movptr(rax, ArrayAddress(stack_to_stack, Address(noreg, rax, Address::times_ptr))); + // __ movl(rax, Address(noreg, rax, Address::times_ptr, int(AbstractInterpreter::_stack_to_stack))); __ call(rax); // call result converter Label unwind_recursive_activation; @@ -1915,9 +1997,9 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { // result converter left rax pointing to top of the java stack for method we are returning // to. Now all we must do is unwind the state from the completed call - __ movl(state, STATE(_prev_link)); // unwind state + __ movptr(state, STATE(_prev_link)); // unwind state __ leave(); // pop the frame - __ movl(rsp, rax); // unwind stack to remove args + __ mov(rsp, rax); // unwind stack to remove args // Resume the interpreter. The current frame contains the current interpreter // state object. @@ -1928,10 +2010,10 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { // state == interpreterState object for method we are resuming __ movl(STATE(_msg), (int)BytecodeInterpreter::method_resume); - __ leal(rsp, Address(rsp, -wordSize)); // prepush stack (result if any already present) - __ movl(STATE(_stack), rsp); // inform interpreter of new stack depth (parameters removed, + __ lea(rsp, Address(rsp, -wordSize)); // prepush stack (result if any already present) + __ movptr(STATE(_stack), rsp); // inform interpreter of new stack depth (parameters removed, // result if any on stack already ) - __ movl(rsp, STATE(_stack_limit)); // restore expression stack to full depth + __ movptr(rsp, STATE(_stack_limit)); // restore expression stack to full depth __ jmp(call_interpreter_2); // No need to bang // interpreter returning to native code (call_stub/c1/c2) @@ -1940,9 +2022,9 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { __ bind(return_to_initial_caller); ExternalAddress stack_to_native((address)CppInterpreter::_stack_to_native_abi); - // Address index(noreg, rax, Address::times_4); + // Address index(noreg, rax, Address::times_ptr); - __ movptr(rax, ArrayAddress(stack_to_native, Address(noreg, rax, Address::times_4))); + __ movptr(rax, ArrayAddress(stack_to_native, Address(noreg, rax, Address::times_ptr))); __ call(rax); // call result converter Label unwind_initial_activation; @@ -1964,11 +2046,11 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { // return restoring the stack to the original sender_sp value - __ movl(rcx, STATE(_sender_sp)); + __ movptr(rcx, STATE(_sender_sp)); __ leave(); - __ popl(rdi); // get return address + __ pop(rdi); // get return address // set stack to sender's sp - __ movl(rsp, rcx); + __ mov(rsp, rcx); __ jmp(rdi); // return to call_stub // OSR request, adjust return address to make current frame into adapter frame @@ -1982,17 +2064,16 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { // it or is it callstub/compiled? // Move buffer to the expected parameter location - __ movl(rcx, STATE(_result._osr._osr_buf)); + __ movptr(rcx, STATE(_result._osr._osr_buf)); - __ movl(rax, STATE(_result._osr._osr_entry)); + __ movptr(rax, STATE(_result._osr._osr_entry)); - __ cmpl(STATE(_prev_link), (int)NULL); // returning from "recursive" interpreter call? + __ cmpptr(STATE(_prev_link), (int32_t)NULL_WORD); // returning from "recursive" interpreter call? __ jcc(Assembler::equal, remove_initial_frame); // back to native code (call_stub/c1/c2) - // __ movl(state, STATE(_prev_link)); // unwind state - __ movl(rsi, STATE(_sender_sp)); // get sender's sp in expected register + __ movptr(sender_sp_on_entry, STATE(_sender_sp)); // get sender's sp in expected register __ leave(); // pop the frame - __ movl(rsp, rsi); // trim any stack expansion + __ mov(rsp, sender_sp_on_entry); // trim any stack expansion // We know we are calling compiled so push specialized return @@ -2006,14 +2087,14 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { __ bind(remove_initial_frame); - __ movl(rdx, STATE(_sender_sp)); + __ movptr(rdx, STATE(_sender_sp)); __ leave(); // get real return - __ popl(rsi); + __ pop(rsi); // set stack to sender's sp - __ movl(rsp, rdx); + __ mov(rsp, rdx); // repush real return - __ pushl(rsi); + __ push(rsi); // Enter OSR nmethod __ jmp(rax); @@ -2028,10 +2109,10 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { // stack points to next free location and not top element on expression stack // method expects sp to be pointing to topmost element - __ movl(rsp, STATE(_stack)); // pop args to c++ interpreter, set sp to java stack top - __ leal(rsp, Address(rsp, wordSize)); + __ movptr(rsp, STATE(_stack)); // pop args to c++ interpreter, set sp to java stack top + __ lea(rsp, Address(rsp, wordSize)); - __ movl(rbx, STATE(_result._to_call._callee)); // get method to execute + __ movptr(rbx, STATE(_result._to_call._callee)); // get method to execute // don't need a return address if reinvoking interpreter @@ -2047,13 +2128,13 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { __ cmpptr(STATE(_result._to_call._callee_entry_point), entry.addr()); // returning to interpreter? __ jcc(Assembler::equal, re_dispatch); // yes - __ popl(rax); // pop dummy address + __ pop(rax); // pop dummy address // get specialized entry - __ movl(rax, STATE(_result._to_call._callee_entry_point)); + __ movptr(rax, STATE(_result._to_call._callee_entry_point)); // set sender SP - __ movl(rsi, rsp); + __ mov(sender_sp_on_entry, rsp); // method uses specialized entry, push a return so we look like call stub setup // this path will handle fact that result is returned in registers and not @@ -2073,10 +2154,10 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { Label unwind_initial_with_pending_exception; __ bind(throw_exception); - __ cmpl(STATE(_prev_link), (int)NULL); // returning from recursive interpreter call? + __ cmpptr(STATE(_prev_link), (int32_t)NULL_WORD); // returning from recursive interpreter call? __ jcc(Assembler::equal, unwind_initial_with_pending_exception); // no, back to native code (call_stub/c1/c2) - __ movl(rax, STATE(_locals)); // pop parameters get new stack value - __ addl(rax, wordSize); // account for prepush before we return + __ movptr(rax, STATE(_locals)); // pop parameters get new stack value + __ addptr(rax, wordSize); // account for prepush before we return __ jmp(unwind_recursive_activation); __ bind(unwind_initial_with_pending_exception); diff --git a/hotspot/src/cpu/x86/vm/dump_x86_32.cpp b/hotspot/src/cpu/x86/vm/dump_x86_32.cpp index db80c6367f7..a31f9153837 100644 --- a/hotspot/src/cpu/x86/vm/dump_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/dump_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -98,24 +98,24 @@ void CompactingPermGenGen::generate_vtable_methods(void** vtbl_list, // table. #ifdef WIN32 - __ pushl(rcx); // save "this" + __ push(rcx); // save "this" #endif - __ movl(rcx, rax); - __ shrl(rcx, 8); // isolate vtable identifier. - __ shll(rcx, LogBytesPerWord); + __ mov(rcx, rax); + __ shrptr(rcx, 8); // isolate vtable identifier. + __ shlptr(rcx, LogBytesPerWord); Address index(noreg, rcx, Address::times_1); ExternalAddress vtbl((address)vtbl_list); __ movptr(rdx, ArrayAddress(vtbl, index)); // get correct vtable address. #ifdef WIN32 - __ popl(rcx); // restore "this" + __ pop(rcx); // restore "this" #else - __ movl(rcx, Address(rsp, 4)); // fetch "this" + __ movptr(rcx, Address(rsp, BytesPerWord)); // fetch "this" #endif - __ movl(Address(rcx, 0), rdx); // update vtable pointer. + __ movptr(Address(rcx, 0), rdx); // update vtable pointer. - __ andl(rax, 0x00ff); // isolate vtable method index - __ shll(rax, LogBytesPerWord); - __ addl(rax, rdx); // address of real method pointer. + __ andptr(rax, 0x00ff); // isolate vtable method index + __ shlptr(rax, LogBytesPerWord); + __ addptr(rax, rdx); // address of real method pointer. __ jmp(Address(rax, 0)); // get real method pointer. __ flush(); diff --git a/hotspot/src/cpu/x86/vm/dump_x86_64.cpp b/hotspot/src/cpu/x86/vm/dump_x86_64.cpp index 7e80bbeacf2..ef64f7dcdc7 100644 --- a/hotspot/src/cpu/x86/vm/dump_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/dump_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -90,22 +90,22 @@ void CompactingPermGenGen::generate_vtable_methods(void** vtbl_list, // are on the stack and the "this" pointer is in c_rarg0. In addition, rax // was set (above) to the offset of the method in the table. - __ pushq(c_rarg1); // save & free register - __ pushq(c_rarg0); // save "this" - __ movq(c_rarg0, rax); - __ shrq(c_rarg0, 8); // isolate vtable identifier. - __ shlq(c_rarg0, LogBytesPerWord); + __ push(c_rarg1); // save & free register + __ push(c_rarg0); // save "this" + __ mov(c_rarg0, rax); + __ shrptr(c_rarg0, 8); // isolate vtable identifier. + __ shlptr(c_rarg0, LogBytesPerWord); __ lea(c_rarg1, ExternalAddress((address)vtbl_list)); // ptr to correct vtable list. - __ addq(c_rarg1, c_rarg0); // ptr to list entry. - __ movq(c_rarg1, Address(c_rarg1, 0)); // get correct vtable address. - __ popq(c_rarg0); // restore "this" - __ movq(Address(c_rarg0, 0), c_rarg1); // update vtable pointer. + __ addptr(c_rarg1, c_rarg0); // ptr to list entry. + __ movptr(c_rarg1, Address(c_rarg1, 0)); // get correct vtable address. + __ pop(c_rarg0); // restore "this" + __ movptr(Address(c_rarg0, 0), c_rarg1); // update vtable pointer. - __ andq(rax, 0x00ff); // isolate vtable method index - __ shlq(rax, LogBytesPerWord); - __ addq(rax, c_rarg1); // address of real method pointer. - __ popq(c_rarg1); // restore register. - __ movq(rax, Address(rax, 0)); // get real method pointer. + __ andptr(rax, 0x00ff); // isolate vtable method index + __ shlptr(rax, LogBytesPerWord); + __ addptr(rax, c_rarg1); // address of real method pointer. + __ pop(c_rarg1); // restore register. + __ movptr(rax, Address(rax, 0)); // get real method pointer. __ jmp(rax); // jump to the real method. __ flush(); diff --git a/hotspot/src/cpu/x86/vm/frame_x86.cpp b/hotspot/src/cpu/x86/vm/frame_x86.cpp index 9fe370e85de..4df2c039dc1 100644 --- a/hotspot/src/cpu/x86/vm/frame_x86.cpp +++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp @@ -217,7 +217,8 @@ bool frame::safe_for_sender(JavaThread *thread) { void frame::patch_pc(Thread* thread, address pc) { if (TracePcPatching) { - tty->print_cr("patch_pc at address 0x%x [0x%x -> 0x%x] ", &((address *)sp())[-1], ((address *)sp())[-1], pc); + tty->print_cr("patch_pc at address" INTPTR_FORMAT " [" INTPTR_FORMAT " -> " INTPTR_FORMAT "] ", + &((address *)sp())[-1], ((address *)sp())[-1], pc); } ((address *)sp())[-1] = pc; _cb = CodeCache::find_blob(pc); diff --git a/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp b/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp index 85a1944bd44..f06b40de350 100644 --- a/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp +++ b/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp @@ -159,7 +159,7 @@ inline intptr_t** frame::interpreter_frame_locals_addr() const { inline intptr_t* frame::interpreter_frame_bcx_addr() const { assert(is_interpreted_frame(), "must be interpreted"); - return (jint*) &(get_interpreterState()->_bcp); + return (intptr_t*) &(get_interpreterState()->_bcp); } @@ -179,7 +179,7 @@ inline methodOop* frame::interpreter_frame_method_addr() const { inline intptr_t* frame::interpreter_frame_mdx_addr() const { assert(is_interpreted_frame(), "must be interpreted"); - return (jint*) &(get_interpreterState()->_mdx); + return (intptr_t*) &(get_interpreterState()->_mdx); } // top of expression stack diff --git a/hotspot/src/cpu/x86/vm/icache_x86.cpp b/hotspot/src/cpu/x86/vm/icache_x86.cpp index 6a031f07413..58b8f2f1507 100644 --- a/hotspot/src/cpu/x86/vm/icache_x86.cpp +++ b/hotspot/src/cpu/x86/vm/icache_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,7 @@ void ICacheStubGenerator::generate_icache_flush(ICache::flush_icache_stub_t* flu __ bind(flush_line); __ clflush(Address(addr, 0)); - __ addq(addr, ICache::line_size); + __ addptr(addr, ICache::line_size); __ decrementl(lines); __ jcc(Assembler::notZero, flush_line); @@ -60,7 +60,7 @@ void ICacheStubGenerator::generate_icache_flush(ICache::flush_icache_stub_t* flu const Address magic(rsp, 3*wordSize); __ lock(); __ addl(Address(rsp, 0), 0); #endif // AMD64 - __ movl(rax, magic); // Handshake with caller to make sure it happened! + __ movptr(rax, magic); // Handshake with caller to make sure it happened! __ ret(0); // Must be set here so StubCodeMark destructor can call the flush stub. diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp index 4b174357a2f..78f0f123833 100644 --- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,8 +29,8 @@ // Implementation of InterpreterMacroAssembler #ifdef CC_INTERP void InterpreterMacroAssembler::get_method(Register reg) { - movl(reg, Address(rbp, -(sizeof(BytecodeInterpreter) + 2 * wordSize))); - movl(reg, Address(reg, byte_offset_of(BytecodeInterpreter, _method))); + movptr(reg, Address(rbp, -(sizeof(BytecodeInterpreter) + 2 * wordSize))); + movptr(reg, Address(reg, byte_offset_of(BytecodeInterpreter, _method))); } #endif // CC_INTERP @@ -53,7 +53,7 @@ void InterpreterMacroAssembler::call_VM_leaf_base( // when jvm built with ASSERTs. #ifdef ASSERT { Label L; - cmpl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + cmpptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); jcc(Assembler::equal, L); stop("InterpreterMacroAssembler::call_VM_leaf_base: last_sp != NULL"); bind(L); @@ -79,7 +79,7 @@ void InterpreterMacroAssembler::call_VM_base( ) { #ifdef ASSERT { Label L; - cmpl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + cmpptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); jcc(Assembler::equal, L); stop("InterpreterMacroAssembler::call_VM_base: last_sp != NULL"); bind(L); @@ -132,10 +132,11 @@ void InterpreterMacroAssembler::load_earlyret_value(TosState state) { const Address val_addr1(rcx, JvmtiThreadState::earlyret_value_offset() + in_ByteSize(wordSize)); switch (state) { - case atos: movl(rax, oop_addr); - movl(oop_addr, NULL_WORD); + case atos: movptr(rax, oop_addr); + movptr(oop_addr, (int32_t)NULL_WORD); verify_oop(rax, state); break; - case ltos: movl(rdx, val_addr1); // fall through + case ltos: + movl(rdx, val_addr1); // fall through case btos: // fall through case ctos: // fall through case stos: // fall through @@ -146,9 +147,9 @@ void InterpreterMacroAssembler::load_earlyret_value(TosState state) { default : ShouldNotReachHere(); } // Clean up tos value in the thread object - movl(tos_addr, (int) ilgl); - movl(val_addr, NULL_WORD); - movl(val_addr1, NULL_WORD); + movl(tos_addr, (int32_t) ilgl); + movptr(val_addr, (int32_t)NULL_WORD); + NOT_LP64(movl(val_addr1, (int32_t)NULL_WORD)); } @@ -156,8 +157,8 @@ void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread) if (JvmtiExport::can_force_early_return()) { Label L; Register tmp = java_thread; - movl(tmp, Address(tmp, JavaThread::jvmti_thread_state_offset())); - testl(tmp, tmp); + movptr(tmp, Address(tmp, JavaThread::jvmti_thread_state_offset())); + testptr(tmp, tmp); jcc(Assembler::zero, L); // if (thread->jvmti_thread_state() == NULL) exit; // Initiate earlyret handling only if it is not already being processed. @@ -170,7 +171,7 @@ void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread) // Call Interpreter::remove_activation_early_entry() to get the address of the // same-named entrypoint in the generated interpreter code. get_thread(java_thread); - movl(tmp, Address(java_thread, JavaThread::jvmti_thread_state_offset())); + movptr(tmp, Address(java_thread, JavaThread::jvmti_thread_state_offset())); pushl(Address(tmp, JvmtiThreadState::earlyret_tos_offset())); call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_early_entry), 1); jmp(rax); @@ -183,7 +184,7 @@ void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread) void InterpreterMacroAssembler::get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset) { assert(bcp_offset >= 0, "bcp is still pointing to start of bytecode"); movl(reg, Address(rsi, bcp_offset)); - bswap(reg); + bswapl(reg); shrl(reg, 16); } @@ -192,9 +193,9 @@ void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, Regis assert(bcp_offset > 0, "bcp is still pointing to start of bytecode"); assert(cache != index, "must use different registers"); load_unsigned_word(index, Address(rsi, bcp_offset)); - movl(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); + movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below"); - shll(index, 2); // convert from field index to ConstantPoolCacheEntry index + shlptr(index, 2); // convert from field index to ConstantPoolCacheEntry index } @@ -206,10 +207,10 @@ void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, R // convert from field index to ConstantPoolCacheEntry index // and from word offset to byte offset shll(tmp, 2 + LogBytesPerWord); - movl(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); + movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); // skip past the header - addl(cache, in_bytes(constantPoolCacheOopDesc::base_offset())); - addl(cache, tmp); // construct pointer to cache entry + addptr(cache, in_bytes(constantPoolCacheOopDesc::base_offset())); + addptr(cache, tmp); // construct pointer to cache entry } @@ -232,22 +233,22 @@ void InterpreterMacroAssembler::gen_subtype_check( Register Rsub_klass, Label &o // if the super-klass is an interface or exceptionally deep in the Java // hierarchy and we have to scan the secondary superclass list the hard way. // See if we get an immediate positive hit - cmpl( rax, Address(Rsub_klass,rcx,Address::times_1) ); + cmpptr( rax, Address(Rsub_klass,rcx,Address::times_1) ); jcc( Assembler::equal,ok_is_subtype ); // Check for immediate negative hit cmpl( rcx, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() ); jcc( Assembler::notEqual, not_subtype ); // Check for self - cmpl( Rsub_klass, rax ); + cmpptr( Rsub_klass, rax ); jcc( Assembler::equal, ok_is_subtype ); // Now do a linear scan of the secondary super-klass chain. - movl( rdi, Address(Rsub_klass, sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes()) ); + movptr( rdi, Address(Rsub_klass, sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes()) ); // EDI holds the objArrayOop of secondary supers. movl( rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes()));// Load the array length // Skip to start of data; also clear Z flag incase ECX is zero - addl( rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT) ); + addptr( rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT) ); // Scan ECX words at [EDI] for occurance of EAX // Set NZ/Z based on last compare repne_scan(); @@ -255,7 +256,7 @@ void InterpreterMacroAssembler::gen_subtype_check( Register Rsub_klass, Label &o // Not equal? jcc( Assembler::notEqual, not_subtype ); // Must be equal but missed in cache. Update cache. - movl( Address(Rsub_klass, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()), rax ); + movptr( Address(Rsub_klass, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()), rax ); jmp( ok_is_subtype ); bind(not_subtype); @@ -276,7 +277,6 @@ void InterpreterMacroAssembler::d2ieee() { fld_d(Address(rsp, 0)); } } -#endif // CC_INTERP // Java Expression Stack @@ -284,11 +284,11 @@ void InterpreterMacroAssembler::d2ieee() { void InterpreterMacroAssembler::verify_stack_tag(frame::Tag t) { if (TaggedStackInterpreter) { Label okay; - cmpl(Address(rsp, wordSize), (int)t); + cmpptr(Address(rsp, wordSize), (int32_t)t); jcc(Assembler::equal, okay); // Also compare if the stack value is zero, then the tag might // not have been set coming from deopt. - cmpl(Address(rsp, 0), 0); + cmpptr(Address(rsp, 0), 0); jcc(Assembler::equal, okay); stop("Java Expression stack tag value is bad"); bind(okay); @@ -298,43 +298,43 @@ void InterpreterMacroAssembler::verify_stack_tag(frame::Tag t) { void InterpreterMacroAssembler::pop_ptr(Register r) { debug_only(verify_stack_tag(frame::TagReference)); - popl(r); - if (TaggedStackInterpreter) addl(rsp, 1 * wordSize); + pop(r); + if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); } void InterpreterMacroAssembler::pop_ptr(Register r, Register tag) { - popl(r); + pop(r); // Tag may not be reference for jsr, can be returnAddress - if (TaggedStackInterpreter) popl(tag); + if (TaggedStackInterpreter) pop(tag); } void InterpreterMacroAssembler::pop_i(Register r) { debug_only(verify_stack_tag(frame::TagValue)); - popl(r); - if (TaggedStackInterpreter) addl(rsp, 1 * wordSize); + pop(r); + if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); } void InterpreterMacroAssembler::pop_l(Register lo, Register hi) { debug_only(verify_stack_tag(frame::TagValue)); - popl(lo); - if (TaggedStackInterpreter) addl(rsp, 1 * wordSize); + pop(lo); + if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); debug_only(verify_stack_tag(frame::TagValue)); - popl(hi); - if (TaggedStackInterpreter) addl(rsp, 1 * wordSize); + pop(hi); + if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); } void InterpreterMacroAssembler::pop_f() { debug_only(verify_stack_tag(frame::TagValue)); fld_s(Address(rsp, 0)); - addl(rsp, 1 * wordSize); - if (TaggedStackInterpreter) addl(rsp, 1 * wordSize); + addptr(rsp, 1 * wordSize); + if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); } void InterpreterMacroAssembler::pop_d() { // Write double to stack contiguously and load into ST0 pop_dtos_to_rsp(); fld_d(Address(rsp, 0)); - addl(rsp, 2 * wordSize); + addptr(rsp, 2 * wordSize); } @@ -344,22 +344,22 @@ void InterpreterMacroAssembler::pop_dtos_to_rsp() { if (TaggedStackInterpreter) { // Pop double value into scratch registers debug_only(verify_stack_tag(frame::TagValue)); - popl(rax); - addl(rsp, 1* wordSize); + pop(rax); + addptr(rsp, 1* wordSize); debug_only(verify_stack_tag(frame::TagValue)); - popl(rdx); - addl(rsp, 1* wordSize); - pushl(rdx); - pushl(rax); + pop(rdx); + addptr(rsp, 1* wordSize); + push(rdx); + push(rax); } } void InterpreterMacroAssembler::pop_ftos_to_rsp() { if (TaggedStackInterpreter) { debug_only(verify_stack_tag(frame::TagValue)); - popl(rax); - addl(rsp, 1 * wordSize); - pushl(rax); // ftos is at rsp + pop(rax); + addptr(rsp, 1 * wordSize); + push(rax); // ftos is at rsp } } @@ -380,31 +380,31 @@ void InterpreterMacroAssembler::pop(TosState state) { } void InterpreterMacroAssembler::push_ptr(Register r) { - if (TaggedStackInterpreter) pushl(frame::TagReference); - pushl(r); + if (TaggedStackInterpreter) push(frame::TagReference); + push(r); } void InterpreterMacroAssembler::push_ptr(Register r, Register tag) { - if (TaggedStackInterpreter) pushl(tag); // tag first - pushl(r); + if (TaggedStackInterpreter) push(tag); // tag first + push(r); } void InterpreterMacroAssembler::push_i(Register r) { - if (TaggedStackInterpreter) pushl(frame::TagValue); - pushl(r); + if (TaggedStackInterpreter) push(frame::TagValue); + push(r); } void InterpreterMacroAssembler::push_l(Register lo, Register hi) { - if (TaggedStackInterpreter) pushl(frame::TagValue); - pushl(hi); - if (TaggedStackInterpreter) pushl(frame::TagValue); - pushl(lo); + if (TaggedStackInterpreter) push(frame::TagValue); + push(hi); + if (TaggedStackInterpreter) push(frame::TagValue); + push(lo); } void InterpreterMacroAssembler::push_f() { - if (TaggedStackInterpreter) pushl(frame::TagValue); + if (TaggedStackInterpreter) push(frame::TagValue); // Do not schedule for no AGI! Never write beyond rsp! - subl(rsp, 1 * wordSize); + subptr(rsp, 1 * wordSize); fstp_s(Address(rsp, 0)); } @@ -415,8 +415,8 @@ void InterpreterMacroAssembler::push_d(Register r) { // high // tag // low - pushl(frame::TagValue); - subl(rsp, 3 * wordSize); + push(frame::TagValue); + subptr(rsp, 3 * wordSize); fstp_d(Address(rsp, 0)); // move high word up to slot n-1 movl(r, Address(rsp, 1*wordSize)); @@ -425,7 +425,7 @@ void InterpreterMacroAssembler::push_d(Register r) { movl(Address(rsp, 1*wordSize), frame::TagValue); } else { // Do not schedule for no AGI! Never write beyond rsp! - subl(rsp, 2 * wordSize); + subptr(rsp, 2 * wordSize); fstp_d(Address(rsp, 0)); } } @@ -447,22 +447,21 @@ void InterpreterMacroAssembler::push(TosState state) { } } -#ifndef CC_INTERP // Tagged stack helpers for swap and dup void InterpreterMacroAssembler::load_ptr_and_tag(int n, Register val, Register tag) { - movl(val, Address(rsp, Interpreter::expr_offset_in_bytes(n))); + movptr(val, Address(rsp, Interpreter::expr_offset_in_bytes(n))); if (TaggedStackInterpreter) { - movl(tag, Address(rsp, Interpreter::expr_tag_offset_in_bytes(n))); + movptr(tag, Address(rsp, Interpreter::expr_tag_offset_in_bytes(n))); } } void InterpreterMacroAssembler::store_ptr_and_tag(int n, Register val, Register tag) { - movl(Address(rsp, Interpreter::expr_offset_in_bytes(n)), val); + movptr(Address(rsp, Interpreter::expr_offset_in_bytes(n)), val); if (TaggedStackInterpreter) { - movl(Address(rsp, Interpreter::expr_tag_offset_in_bytes(n)), tag); + movptr(Address(rsp, Interpreter::expr_tag_offset_in_bytes(n)), tag); } } @@ -471,10 +470,10 @@ void InterpreterMacroAssembler::store_ptr_and_tag(int n, Register val, void InterpreterMacroAssembler::tag_local(frame::Tag tag, int n) { if (TaggedStackInterpreter) { if (tag == frame::TagCategory2) { - movl(Address(rdi, Interpreter::local_tag_offset_in_bytes(n+1)), (int)frame::TagValue); - movl(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int)frame::TagValue); + movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n+1)), (int32_t)frame::TagValue); + movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)frame::TagValue); } else { - movl(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int)tag); + movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)tag); } } } @@ -482,13 +481,13 @@ void InterpreterMacroAssembler::tag_local(frame::Tag tag, int n) { void InterpreterMacroAssembler::tag_local(frame::Tag tag, Register idx) { if (TaggedStackInterpreter) { if (tag == frame::TagCategory2) { - movl(Address(rdi, idx, Interpreter::stackElementScale(), - Interpreter::local_tag_offset_in_bytes(1)), (int)frame::TagValue); - movl(Address(rdi, idx, Interpreter::stackElementScale(), - Interpreter::local_tag_offset_in_bytes(0)), (int)frame::TagValue); + movptr(Address(rdi, idx, Interpreter::stackElementScale(), + Interpreter::local_tag_offset_in_bytes(1)), (int32_t)frame::TagValue); + movptr(Address(rdi, idx, Interpreter::stackElementScale(), + Interpreter::local_tag_offset_in_bytes(0)), (int32_t)frame::TagValue); } else { - movl(Address(rdi, idx, Interpreter::stackElementScale(), - Interpreter::local_tag_offset_in_bytes(0)), (int)tag); + movptr(Address(rdi, idx, Interpreter::stackElementScale(), + Interpreter::local_tag_offset_in_bytes(0)), (int32_t)tag); } } } @@ -496,7 +495,7 @@ void InterpreterMacroAssembler::tag_local(frame::Tag tag, Register idx) { void InterpreterMacroAssembler::tag_local(Register tag, Register idx) { if (TaggedStackInterpreter) { // can only be TagValue or TagReference - movl(Address(rdi, idx, Interpreter::stackElementScale(), + movptr(Address(rdi, idx, Interpreter::stackElementScale(), Interpreter::local_tag_offset_in_bytes(0)), tag); } } @@ -505,7 +504,7 @@ void InterpreterMacroAssembler::tag_local(Register tag, Register idx) { void InterpreterMacroAssembler::tag_local(Register tag, int n) { if (TaggedStackInterpreter) { // can only be TagValue or TagReference - movl(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), tag); + movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), tag); } } @@ -516,17 +515,17 @@ void InterpreterMacroAssembler::verify_local_tag(frame::Tag tag, int n) { if (tag == frame::TagCategory2) { Label nbl; t = frame::TagValue; // change to what is stored in locals - cmpl(Address(rdi, Interpreter::local_tag_offset_in_bytes(n+1)), (int)t); + cmpptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n+1)), (int32_t)t); jcc(Assembler::equal, nbl); stop("Local tag is bad for long/double"); bind(nbl); } Label notBad; - cmpl(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int)t); + cmpptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)t); jcc(Assembler::equal, notBad); // Also compare if the local value is zero, then the tag might // not have been set coming from deopt. - cmpl(Address(rdi, Interpreter::local_offset_in_bytes(n)), 0); + cmpptr(Address(rdi, Interpreter::local_offset_in_bytes(n)), 0); jcc(Assembler::equal, notBad); stop("Local tag is bad"); bind(notBad); @@ -539,19 +538,19 @@ void InterpreterMacroAssembler::verify_local_tag(frame::Tag tag, Register idx) { if (tag == frame::TagCategory2) { Label nbl; t = frame::TagValue; // change to what is stored in locals - cmpl(Address(rdi, idx, Interpreter::stackElementScale(), - Interpreter::local_tag_offset_in_bytes(1)), (int)t); + cmpptr(Address(rdi, idx, Interpreter::stackElementScale(), + Interpreter::local_tag_offset_in_bytes(1)), (int32_t)t); jcc(Assembler::equal, nbl); stop("Local tag is bad for long/double"); bind(nbl); } Label notBad; cmpl(Address(rdi, idx, Interpreter::stackElementScale(), - Interpreter::local_tag_offset_in_bytes(0)), (int)t); + Interpreter::local_tag_offset_in_bytes(0)), (int32_t)t); jcc(Assembler::equal, notBad); // Also compare if the local value is zero, then the tag might // not have been set coming from deopt. - cmpl(Address(rdi, idx, Interpreter::stackElementScale(), + cmpptr(Address(rdi, idx, Interpreter::stackElementScale(), Interpreter::local_offset_in_bytes(0)), 0); jcc(Assembler::equal, notBad); stop("Local tag is bad"); @@ -567,22 +566,22 @@ void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point) { void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, Register arg_1) { - pushl(arg_1); + push(arg_1); MacroAssembler::call_VM_leaf_base(entry_point, 1); } void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, Register arg_1, Register arg_2) { - pushl(arg_2); - pushl(arg_1); + push(arg_2); + push(arg_1); MacroAssembler::call_VM_leaf_base(entry_point, 2); } void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, Register arg_1, Register arg_2, Register arg_3) { - pushl(arg_3); - pushl(arg_2); - pushl(arg_1); + push(arg_3); + push(arg_2); + push(arg_1); MacroAssembler::call_VM_leaf_base(entry_point, 3); } @@ -591,9 +590,9 @@ void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, Register // in this thread in which case we must call the i2i entry void InterpreterMacroAssembler::jump_from_interpreted(Register method, Register temp) { // set sender sp - leal(rsi, Address(rsp, wordSize)); + lea(rsi, Address(rsp, wordSize)); // record last_sp - movl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), rsi); + movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), rsi); if (JvmtiExport::can_post_interpreter_events()) { Label run_compiled_code; @@ -629,16 +628,16 @@ void InterpreterMacroAssembler::dispatch_base(TosState state, address* table, verify_FPU(1, state); if (VerifyActivationFrameSize) { Label L; - movl(rcx, rbp); - subl(rcx, rsp); + mov(rcx, rbp); + subptr(rcx, rsp); int min_frame_size = (frame::link_offset - frame::interpreter_frame_initial_sp_offset) * wordSize; - cmpl(rcx, min_frame_size); + cmpptr(rcx, min_frame_size); jcc(Assembler::greaterEqual, L); stop("broken stack frame"); bind(L); } if (verifyoop) verify_oop(rax, state); - Address index(noreg, rbx, Address::times_4); + Address index(noreg, rbx, Address::times_ptr); ExternalAddress tbl((address)table); ArrayAddress dispatch(tbl, index); jump(dispatch); @@ -700,10 +699,10 @@ void InterpreterMacroAssembler::remove_activation(TosState state, Register ret_a in_bytes(JavaThread::do_not_unlock_if_synchronized_offset())); movbool(rbx, do_not_unlock_if_synchronized); - movl(rdi,rbx); + mov(rdi,rbx); movbool(do_not_unlock_if_synchronized, false); // reset the flag - movl(rbx, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); // get method access flags + movptr(rbx, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); // get method access flags movl(rcx, Address(rbx, methodOopDesc::access_flags_offset())); testl(rcx, JVM_ACC_SYNCHRONIZED); @@ -711,7 +710,7 @@ void InterpreterMacroAssembler::remove_activation(TosState state, Register ret_a // Don't unlock anything if the _do_not_unlock_if_synchronized flag // is set. - movl(rcx,rdi); + mov(rcx,rdi); testbool(rcx); jcc(Assembler::notZero, no_unlock); @@ -721,11 +720,11 @@ void InterpreterMacroAssembler::remove_activation(TosState state, Register ret_a // BasicObjectLock will be first in list, since this is a synchronized method. However, need // to check that the object has not been unlocked by an explicit monitorexit bytecode. const Address monitor(rbp, frame::interpreter_frame_initial_sp_offset * wordSize - (int)sizeof(BasicObjectLock)); - leal (rdx, monitor); // address of first monitor + lea (rdx, monitor); // address of first monitor - movl (rax, Address(rdx, BasicObjectLock::obj_offset_in_bytes())); - testl (rax, rax); - jcc (Assembler::notZero, unlock); + movptr (rax, Address(rdx, BasicObjectLock::obj_offset_in_bytes())); + testptr(rax, rax); + jcc (Assembler::notZero, unlock); pop(state); if (throw_monitor_exception) { @@ -762,8 +761,8 @@ void InterpreterMacroAssembler::remove_activation(TosState state, Register ret_a const Address monitor_block_bot(rbp, frame::interpreter_frame_initial_sp_offset * wordSize); bind(restart); - movl(rcx, monitor_block_top); // points to current entry, starting with top-most entry - leal(rbx, monitor_block_bot); // points to word before bottom of monitor block + movptr(rcx, monitor_block_top); // points to current entry, starting with top-most entry + lea(rbx, monitor_block_bot); // points to word before bottom of monitor block jmp(entry); // Entry already locked, need to throw exception @@ -780,7 +779,7 @@ void InterpreterMacroAssembler::remove_activation(TosState state, Register ret_a // Unlock does not block, so don't have to worry about the frame push(state); - movl(rdx, rcx); + mov(rdx, rcx); unlock_object(rdx); pop(state); @@ -793,12 +792,12 @@ void InterpreterMacroAssembler::remove_activation(TosState state, Register ret_a } bind(loop); - cmpl(Address(rcx, BasicObjectLock::obj_offset_in_bytes()), NULL_WORD); // check if current entry is used + cmpptr(Address(rcx, BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD); // check if current entry is used jcc(Assembler::notEqual, exception); - addl(rcx, entry_size); // otherwise advance to next entry + addptr(rcx, entry_size); // otherwise advance to next entry bind(entry); - cmpl(rcx, rbx); // check if bottom reached + cmpptr(rcx, rbx); // check if bottom reached jcc(Assembler::notEqual, loop); // if not at bottom then check this entry } @@ -812,22 +811,22 @@ void InterpreterMacroAssembler::remove_activation(TosState state, Register ret_a } // remove activation - movl(rbx, Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp + movptr(rbx, Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp leave(); // remove frame anchor - popl(ret_addr); // get return address - movl(rsp, rbx); // set sp to sender sp + pop(ret_addr); // get return address + mov(rsp, rbx); // set sp to sender sp if (UseSSE) { // float and double are returned in xmm register in SSE-mode if (state == ftos && UseSSE >= 1) { - subl(rsp, wordSize); + subptr(rsp, wordSize); fstp_s(Address(rsp, 0)); movflt(xmm0, Address(rsp, 0)); - addl(rsp, wordSize); + addptr(rsp, wordSize); } else if (state == dtos && UseSSE >= 2) { - subl(rsp, 2*wordSize); + subptr(rsp, 2*wordSize); fstp_d(Address(rsp, 0)); movdbl(xmm0, Address(rsp, 0)); - addl(rsp, 2*wordSize); + addptr(rsp, 2*wordSize); } } } @@ -858,7 +857,7 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg) { Label slow_case; // Load object pointer into obj_reg %rcx - movl(obj_reg, Address(lock_reg, obj_offset)); + movptr(obj_reg, Address(lock_reg, obj_offset)); if (UseBiasedLocking) { // Note: we use noreg for the temporary register since it's hard @@ -867,19 +866,19 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg) { } // Load immediate 1 into swap_reg %rax, - movl(swap_reg, 1); + movptr(swap_reg, (int32_t)1); // Load (object->mark() | 1) into swap_reg %rax, - orl(swap_reg, Address(obj_reg, 0)); + orptr(swap_reg, Address(obj_reg, 0)); // Save (object->mark() | 1) into BasicLock's displaced header - movl(Address(lock_reg, mark_offset), swap_reg); + movptr(Address(lock_reg, mark_offset), swap_reg); assert(lock_offset == 0, "displached header must be first word in BasicObjectLock"); if (os::is_MP()) { lock(); } - cmpxchg(lock_reg, Address(obj_reg, 0)); + cmpxchgptr(lock_reg, Address(obj_reg, 0)); if (PrintBiasedLockingStatistics) { cond_inc32(Assembler::zero, ExternalAddress((address) BiasedLocking::fast_path_entry_count_addr())); @@ -895,11 +894,11 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg) { // assuming both stack pointer and pagesize have their // least significant 2 bits clear. // NOTE: the oopMark is in swap_reg %rax, as the result of cmpxchg - subl(swap_reg, rsp); - andl(swap_reg, 3 - os::vm_page_size()); + subptr(swap_reg, rsp); + andptr(swap_reg, 3 - os::vm_page_size()); // Save the test result, for recursive case, the result is zero - movl(Address(lock_reg, mark_offset), swap_reg); + movptr(Address(lock_reg, mark_offset), swap_reg); if (PrintBiasedLockingStatistics) { cond_inc32(Assembler::zero, @@ -939,36 +938,36 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg) { // Convert from BasicObjectLock structure to object and BasicLock structure // Store the BasicLock address into %rax, - leal(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes())); + lea(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes())); // Load oop into obj_reg(%rcx) - movl(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes ())); + movptr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes ())); // Free entry - movl(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), NULL_WORD); + movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD); if (UseBiasedLocking) { biased_locking_exit(obj_reg, header_reg, done); } // Load the old header from BasicLock structure - movl(header_reg, Address(swap_reg, BasicLock::displaced_header_offset_in_bytes())); + movptr(header_reg, Address(swap_reg, BasicLock::displaced_header_offset_in_bytes())); // Test for recursion - testl(header_reg, header_reg); + testptr(header_reg, header_reg); // zero for recursive case jcc(Assembler::zero, done); // Atomic swap back the old header if (os::is_MP()) lock(); - cmpxchg(header_reg, Address(obj_reg, 0)); + cmpxchgptr(header_reg, Address(obj_reg, 0)); // zero for recursive case jcc(Assembler::zero, done); // Call the runtime routine for slow case. - movl(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), obj_reg); // restore obj + movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), obj_reg); // restore obj call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg); bind(done); @@ -983,8 +982,8 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg) { // Test ImethodDataPtr. If it is null, continue at the specified label void InterpreterMacroAssembler::test_method_data_pointer(Register mdp, Label& zero_continue) { assert(ProfileInterpreter, "must be profiling interpreter"); - movl(mdp, Address(rbp, frame::interpreter_frame_mdx_offset * wordSize)); - testl(mdp, mdp); + movptr(mdp, Address(rbp, frame::interpreter_frame_mdx_offset * wordSize)); + testptr(mdp, mdp); jcc(Assembler::zero, zero_continue); } @@ -993,13 +992,13 @@ void InterpreterMacroAssembler::test_method_data_pointer(Register mdp, Label& ze void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() { assert(ProfileInterpreter, "must be profiling interpreter"); Label zero_continue; - pushl(rax); - pushl(rbx); + push(rax); + push(rbx); get_method(rbx); // Test MDO to avoid the call if it is NULL. - movl(rax, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); - testl(rax, rax); + movptr(rax, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); + testptr(rax, rax); jcc(Assembler::zero, zero_continue); // rbx,: method @@ -1007,53 +1006,55 @@ void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() { call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::bcp_to_di), rbx, rsi); // rax,: mdi - movl(rbx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); - testl(rbx, rbx); + movptr(rbx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); + testptr(rbx, rbx); jcc(Assembler::zero, zero_continue); - addl(rbx, in_bytes(methodDataOopDesc::data_offset())); - addl(rbx, rax); - movl(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rbx); + addptr(rbx, in_bytes(methodDataOopDesc::data_offset())); + addptr(rbx, rax); + movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rbx); bind(zero_continue); - popl(rbx); - popl(rax); + pop(rbx); + pop(rax); } void InterpreterMacroAssembler::verify_method_data_pointer() { assert(ProfileInterpreter, "must be profiling interpreter"); #ifdef ASSERT Label verify_continue; - pushl(rax); - pushl(rbx); - pushl(rcx); - pushl(rdx); + push(rax); + push(rbx); + push(rcx); + push(rdx); test_method_data_pointer(rcx, verify_continue); // If mdp is zero, continue get_method(rbx); // If the mdp is valid, it will point to a DataLayout header which is // consistent with the bcp. The converse is highly probable also. load_unsigned_word(rdx, Address(rcx, in_bytes(DataLayout::bci_offset()))); - addl(rdx, Address(rbx, methodOopDesc::const_offset())); - leal(rdx, Address(rdx, constMethodOopDesc::codes_offset())); - cmpl(rdx, rsi); + addptr(rdx, Address(rbx, methodOopDesc::const_offset())); + lea(rdx, Address(rdx, constMethodOopDesc::codes_offset())); + cmpptr(rdx, rsi); jcc(Assembler::equal, verify_continue); // rbx,: method // rsi: bcp // rcx: mdp call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::verify_mdp), rbx, rsi, rcx); bind(verify_continue); - popl(rdx); - popl(rcx); - popl(rbx); - popl(rax); + pop(rdx); + pop(rcx); + pop(rbx); + pop(rax); #endif // ASSERT } void InterpreterMacroAssembler::set_mdp_data_at(Register mdp_in, int constant, Register value) { + // %%% this seems to be used to store counter data which is surely 32bits + // however 64bit side stores 64 bits which seems wrong assert(ProfileInterpreter, "must be profiling interpreter"); Address data(mdp_in, constant); - movl(data, value); + movptr(data, value); } @@ -1073,6 +1074,7 @@ void InterpreterMacroAssembler::increment_mdp_data_at(Address data, assert( DataLayout::counter_increment==1, "flow-free idiom only works with 1" ); assert(ProfileInterpreter, "must be profiling interpreter"); + // %%% 64bit treats this as 64 bit which seems unlikely if (decrement) { // Decrement the register. Set condition codes. addl(data, -DataLayout::counter_increment); @@ -1119,11 +1121,11 @@ void InterpreterMacroAssembler::test_mdp_data_at(Register mdp_in, Label& not_equal_continue) { assert(ProfileInterpreter, "must be profiling interpreter"); if (test_value_out == noreg) { - cmpl(value, Address(mdp_in, offset)); + cmpptr(value, Address(mdp_in, offset)); } else { // Put the test value into a register, so caller can use it: - movl(test_value_out, Address(mdp_in, offset)); - cmpl(test_value_out, value); + movptr(test_value_out, Address(mdp_in, offset)); + cmpptr(test_value_out, value); } jcc(Assembler::notEqual, not_equal_continue); } @@ -1132,31 +1134,31 @@ void InterpreterMacroAssembler::test_mdp_data_at(Register mdp_in, void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in, int offset_of_disp) { assert(ProfileInterpreter, "must be profiling interpreter"); Address disp_address(mdp_in, offset_of_disp); - addl(mdp_in,disp_address); - movl(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); + addptr(mdp_in,disp_address); + movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); } void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in, Register reg, int offset_of_disp) { assert(ProfileInterpreter, "must be profiling interpreter"); Address disp_address(mdp_in, reg, Address::times_1, offset_of_disp); - addl(mdp_in, disp_address); - movl(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); + addptr(mdp_in, disp_address); + movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); } void InterpreterMacroAssembler::update_mdp_by_constant(Register mdp_in, int constant) { assert(ProfileInterpreter, "must be profiling interpreter"); - addl(mdp_in, constant); - movl(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); + addptr(mdp_in, constant); + movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); } void InterpreterMacroAssembler::update_mdp_for_ret(Register return_bci) { assert(ProfileInterpreter, "must be profiling interpreter"); - pushl(return_bci); // save/restore across call_VM + push(return_bci); // save/restore across call_VM call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::update_mdp_for_ret), return_bci); - popl(return_bci); + pop(return_bci); } @@ -1172,6 +1174,8 @@ void InterpreterMacroAssembler::profile_taken_branch(Register mdp, Register bump // We inline increment_mdp_data_at to return bumped_count in a register //increment_mdp_data_at(mdp, in_bytes(JumpData::taken_offset())); Address data(mdp, in_bytes(JumpData::taken_offset())); + + // %%% 64bit treats these cells as 64 bit but they seem to be 32 bit movl(bumped_count,data); assert( DataLayout::counter_increment==1, "flow-free idiom only works with 1" ); addl(bumped_count, DataLayout::counter_increment); @@ -1289,7 +1293,7 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper( if (row == start_row) { // Failed the equality check on receiver[n]... Test for null. - testl(reg2, reg2); + testptr(reg2, reg2); if (start_row == last_row) { // The only thing left to do is handle the null case. jcc(Assembler::notZero, done); @@ -1315,7 +1319,7 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper( int recvr_offset = in_bytes(VirtualCallData::receiver_offset(start_row)); set_mdp_data_at(mdp, recvr_offset, receiver); int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row)); - movl(reg2, DataLayout::counter_increment); + movptr(reg2, (int32_t)DataLayout::counter_increment); set_mdp_data_at(mdp, count_offset, reg2); jmp(done); } @@ -1454,9 +1458,11 @@ void InterpreterMacroAssembler::profile_switch_case(Register index, Register mdp test_method_data_pointer(mdp, profile_continue); // Build the base (index * per_case_size_in_bytes()) + case_array_offset_in_bytes() - movl(reg2, in_bytes(MultiBranchData::per_case_size())); - imull(index, reg2); - addl(index, in_bytes(MultiBranchData::case_array_offset())); + movptr(reg2, (int32_t)in_bytes(MultiBranchData::per_case_size())); + // index is positive and so should have correct value if this code were + // used on 64bits + imulptr(index, reg2); + addptr(index, in_bytes(MultiBranchData::case_array_offset())); // Update the case count increment_mdp_data_at(mdp, index, in_bytes(MultiBranchData::relative_count_offset())); @@ -1535,12 +1541,12 @@ void InterpreterMacroAssembler::notify_method_exit( { SkipIfEqual skip_if(this, &DTraceMethodProbes, 0); - push(state); + NOT_CC_INTERP(push(state)); get_thread(rbx); get_method(rcx); call_VM_leaf( CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), rbx, rcx); - pop(state); + NOT_CC_INTERP(pop(state)); } } diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp index 10cf8140a22..247f4ec3b47 100644 --- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,15 +65,15 @@ class InterpreterMacroAssembler: public MacroAssembler { #else - void save_bcp() { movl(Address(rbp, frame::interpreter_frame_bcx_offset * wordSize), rsi); } - void restore_bcp() { movl(rsi, Address(rbp, frame::interpreter_frame_bcx_offset * wordSize)); } - void restore_locals() { movl(rdi, Address(rbp, frame::interpreter_frame_locals_offset * wordSize)); } + void save_bcp() { movptr(Address(rbp, frame::interpreter_frame_bcx_offset * wordSize), rsi); } + void restore_bcp() { movptr(rsi, Address(rbp, frame::interpreter_frame_bcx_offset * wordSize)); } + void restore_locals() { movptr(rdi, Address(rbp, frame::interpreter_frame_locals_offset * wordSize)); } // Helpers for runtime call arguments/results - void get_method(Register reg) { movl(reg, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); } - void get_constant_pool(Register reg) { get_method(reg); movl(reg, Address(reg, methodOopDesc::constants_offset())); } - void get_constant_pool_cache(Register reg) { get_constant_pool(reg); movl(reg, Address(reg, constantPoolOopDesc::cache_offset_in_bytes())); } - void get_cpool_and_tags(Register cpool, Register tags) { get_constant_pool(cpool); movl(tags, Address(cpool, constantPoolOopDesc::tags_offset_in_bytes())); + void get_method(Register reg) { movptr(reg, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); } + void get_constant_pool(Register reg) { get_method(reg); movptr(reg, Address(reg, methodOopDesc::constants_offset())); } + void get_constant_pool_cache(Register reg) { get_constant_pool(reg); movptr(reg, Address(reg, constantPoolOopDesc::cache_offset_in_bytes())); } + void get_cpool_and_tags(Register cpool, Register tags) { get_constant_pool(cpool); movptr(tags, Address(cpool, constantPoolOopDesc::tags_offset_in_bytes())); } void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset); void get_cache_and_index_at_bcp(Register cache, Register index, int bcp_offset); @@ -82,8 +82,6 @@ class InterpreterMacroAssembler: public MacroAssembler { // Expression stack void f2ieee(); // truncate ftos to 32bits void d2ieee(); // truncate dtos to 64bits -#endif // CC_INTERP - void pop_ptr(Register r = rax); void pop_ptr(Register r, Register tag); @@ -104,14 +102,25 @@ class InterpreterMacroAssembler: public MacroAssembler { void pop(TosState state); // transition vtos -> state void push(TosState state); // transition state -> vtos + void pop(Register r ) { ((MacroAssembler*)this)->pop(r); } + + void push(Register r ) { ((MacroAssembler*)this)->push(r); } + void push(int32_t imm ) { ((MacroAssembler*)this)->push(imm); } + + // These are dummies to prevent surprise implicit conversions to Register + void pop(void* v ); // Add unimplemented ambiguous method + void push(void* v ); // Add unimplemented ambiguous method + DEBUG_ONLY(void verify_stack_tag(frame::Tag t);) +#endif // CC_INTERP + #ifndef CC_INTERP void empty_expression_stack() { - movl(rsp, Address(rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize)); + movptr(rsp, Address(rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize)); // NULL last_sp until next java call - movl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); } // Tagged stack helpers for swap and dup diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp index 4756a2587be..75ca463ace0 100644 --- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp @@ -28,6 +28,15 @@ // Implementation of InterpreterMacroAssembler +#ifdef CC_INTERP +void InterpreterMacroAssembler::get_method(Register reg) { + movptr(reg, Address(rbp, -(sizeof(BytecodeInterpreter) + 2 * wordSize))); + movptr(reg, Address(reg, byte_offset_of(BytecodeInterpreter, _method))); +} +#endif // CC_INTERP + +#ifndef CC_INTERP + void InterpreterMacroAssembler::call_VM_leaf_base(address entry_point, int number_of_arguments) { // interpreter specific @@ -39,7 +48,7 @@ void InterpreterMacroAssembler::call_VM_leaf_base(address entry_point, save_bcp(); { Label L; - cmpq(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int)NULL_WORD); + cmpptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); jcc(Assembler::equal, L); stop("InterpreterMacroAssembler::call_VM_leaf_base:" " last_sp != NULL"); @@ -52,7 +61,7 @@ void InterpreterMacroAssembler::call_VM_leaf_base(address entry_point, #ifdef ASSERT { Label L; - cmpq(r13, Address(rbp, frame::interpreter_frame_bcx_offset * wordSize)); + cmpptr(r13, Address(rbp, frame::interpreter_frame_bcx_offset * wordSize)); jcc(Assembler::equal, L); stop("InterpreterMacroAssembler::call_VM_leaf_base:" " r13 not callee saved?"); @@ -60,7 +69,7 @@ void InterpreterMacroAssembler::call_VM_leaf_base(address entry_point, } { Label L; - cmpq(r14, Address(rbp, frame::interpreter_frame_locals_offset * wordSize)); + cmpptr(r14, Address(rbp, frame::interpreter_frame_locals_offset * wordSize)); jcc(Assembler::equal, L); stop("InterpreterMacroAssembler::call_VM_leaf_base:" " r14 not callee saved?"); @@ -86,7 +95,7 @@ void InterpreterMacroAssembler::call_VM_base(Register oop_result, #ifdef ASSERT { Label L; - cmpq(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int)NULL_WORD); + cmpptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); jcc(Assembler::equal, L); stop("InterpreterMacroAssembler::call_VM_leaf_base:" " last_sp != NULL"); @@ -127,15 +136,15 @@ void InterpreterMacroAssembler::check_and_handle_popframe(Register java_thread) void InterpreterMacroAssembler::load_earlyret_value(TosState state) { - movq(rcx, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); + movptr(rcx, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); const Address tos_addr(rcx, JvmtiThreadState::earlyret_tos_offset()); const Address oop_addr(rcx, JvmtiThreadState::earlyret_oop_offset()); const Address val_addr(rcx, JvmtiThreadState::earlyret_value_offset()); switch (state) { - case atos: movq(rax, oop_addr); - movptr(oop_addr, NULL_WORD); + case atos: movptr(rax, oop_addr); + movptr(oop_addr, (int32_t)NULL_WORD); verify_oop(rax, state); break; - case ltos: movq(rax, val_addr); break; + case ltos: movptr(rax, val_addr); break; case btos: // fall through case ctos: // fall through case stos: // fall through @@ -147,15 +156,15 @@ void InterpreterMacroAssembler::load_earlyret_value(TosState state) { } // Clean up tos value in the thread object movl(tos_addr, (int) ilgl); - movl(val_addr, (int) NULL_WORD); + movl(val_addr, (int32_t) NULL_WORD); } void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread) { if (JvmtiExport::can_force_early_return()) { Label L; - movq(c_rarg0, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); - testq(c_rarg0, c_rarg0); + movptr(c_rarg0, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); + testptr(c_rarg0, c_rarg0); jcc(Assembler::zero, L); // if (thread->jvmti_thread_state() == NULL) exit; // Initiate earlyret handling only if it is not already being processed. @@ -167,7 +176,7 @@ void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread) // Call Interpreter::remove_activation_early_entry() to get the address of the // same-named entrypoint in the generated interpreter code. - movq(c_rarg0, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); + movptr(c_rarg0, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); movl(c_rarg0, Address(c_rarg0, JvmtiThreadState::earlyret_tos_offset())); call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_early_entry), c_rarg0); jmp(rax); @@ -192,7 +201,7 @@ void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, assert(bcp_offset > 0, "bcp is still pointing to start of bytecode"); assert(cache != index, "must use different registers"); load_unsigned_word(index, Address(r13, bcp_offset)); - movq(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); + movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below"); // convert from field index to ConstantPoolCacheEntry index shll(index, 2); @@ -209,10 +218,10 @@ void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, // convert from field index to ConstantPoolCacheEntry index // and from word offset to byte offset shll(tmp, 2 + LogBytesPerWord); - movq(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); + movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); // skip past the header - addq(cache, in_bytes(constantPoolCacheOopDesc::base_offset())); - addq(cache, tmp); // construct pointer to cache entry + addptr(cache, in_bytes(constantPoolCacheOopDesc::base_offset())); + addptr(cache, tmp); // construct pointer to cache entry } @@ -247,24 +256,24 @@ void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass, // exceptionally deep in the Java hierarchy and we have to scan the // secondary superclass list the hard way. See if we get an // immediate positive hit - cmpq(rax, Address(Rsub_klass, rcx, Address::times_1)); + cmpptr(rax, Address(Rsub_klass, rcx, Address::times_1)); jcc(Assembler::equal,ok_is_subtype); // Check for immediate negative hit cmpl(rcx, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()); jcc( Assembler::notEqual, not_subtype ); // Check for self - cmpq(Rsub_klass, rax); + cmpptr(Rsub_klass, rax); jcc(Assembler::equal, ok_is_subtype); // Now do a linear scan of the secondary super-klass chain. - movq(rdi, Address(Rsub_klass, sizeof(oopDesc) + - Klass::secondary_supers_offset_in_bytes())); + movptr(rdi, Address(Rsub_klass, sizeof(oopDesc) + + Klass::secondary_supers_offset_in_bytes())); // rdi holds the objArrayOop of secondary supers. // Load the array length movl(rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes())); // Skip to start of data; also clear Z flag incase rcx is zero - addq(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + addptr(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); // Scan rcx words at [rdi] for occurance of rax // Set NZ/Z based on last compare @@ -272,30 +281,31 @@ void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass, // and we store values in objArrays always encoded, thus we need to encode value // before repne if (UseCompressedOops) { - pushq(rax); + push(rax); encode_heap_oop(rax); repne_scanl(); // Not equal? jcc(Assembler::notEqual, not_subtype_pop); // restore heap oop here for movq - popq(rax); + pop(rax); } else { - repne_scanq(); + repne_scan(); jcc(Assembler::notEqual, not_subtype); } // Must be equal but missed in cache. Update cache. - movq(Address(Rsub_klass, sizeof(oopDesc) + + movptr(Address(Rsub_klass, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()), rax); jmp(ok_is_subtype); bind(not_subtype_pop); // restore heap oop here for miss - if (UseCompressedOops) popq(rax); + if (UseCompressedOops) pop(rax); bind(not_subtype); profile_typecheck_failed(rcx); // blows rcx } + // Java Expression Stack #ifdef ASSERT @@ -307,17 +317,17 @@ void InterpreterMacroAssembler::verify_stack_tag(frame::Tag t) { if (t == frame::TagCategory2) { tag = frame::TagValue; Label hokay; - cmpq(Address(rsp, 3*wordSize), (int)tag); + cmpptr(Address(rsp, 3*wordSize), (int32_t)tag); jcc(Assembler::equal, hokay); stop("Java Expression stack tag high value is bad"); bind(hokay); } Label okay; - cmpq(Address(rsp, wordSize), (int)tag); + cmpptr(Address(rsp, wordSize), (int32_t)tag); jcc(Assembler::equal, okay); // Also compare if the stack value is zero, then the tag might // not have been set coming from deopt. - cmpq(Address(rsp, 0), 0); + cmpptr(Address(rsp, 0), 0); jcc(Assembler::equal, okay); stop("Java Expression stack tag value is bad"); bind(okay); @@ -327,83 +337,83 @@ void InterpreterMacroAssembler::verify_stack_tag(frame::Tag t) { void InterpreterMacroAssembler::pop_ptr(Register r) { debug_only(verify_stack_tag(frame::TagReference)); - popq(r); - if (TaggedStackInterpreter) addq(rsp, 1 * wordSize); + pop(r); + if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); } void InterpreterMacroAssembler::pop_ptr(Register r, Register tag) { - popq(r); - if (TaggedStackInterpreter) popq(tag); + pop(r); + if (TaggedStackInterpreter) pop(tag); } void InterpreterMacroAssembler::pop_i(Register r) { - // XXX can't use popq currently, upper half non clean + // XXX can't use pop currently, upper half non clean debug_only(verify_stack_tag(frame::TagValue)); movl(r, Address(rsp, 0)); - addq(rsp, wordSize); - if (TaggedStackInterpreter) addq(rsp, 1 * wordSize); + addptr(rsp, wordSize); + if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); } void InterpreterMacroAssembler::pop_l(Register r) { debug_only(verify_stack_tag(frame::TagCategory2)); movq(r, Address(rsp, 0)); - addq(rsp, 2 * Interpreter::stackElementSize()); + addptr(rsp, 2 * Interpreter::stackElementSize()); } void InterpreterMacroAssembler::pop_f(XMMRegister r) { debug_only(verify_stack_tag(frame::TagValue)); movflt(r, Address(rsp, 0)); - addq(rsp, wordSize); - if (TaggedStackInterpreter) addq(rsp, 1 * wordSize); + addptr(rsp, wordSize); + if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); } void InterpreterMacroAssembler::pop_d(XMMRegister r) { debug_only(verify_stack_tag(frame::TagCategory2)); movdbl(r, Address(rsp, 0)); - addq(rsp, 2 * Interpreter::stackElementSize()); + addptr(rsp, 2 * Interpreter::stackElementSize()); } void InterpreterMacroAssembler::push_ptr(Register r) { - if (TaggedStackInterpreter) pushq(frame::TagReference); - pushq(r); + if (TaggedStackInterpreter) push(frame::TagReference); + push(r); } void InterpreterMacroAssembler::push_ptr(Register r, Register tag) { - if (TaggedStackInterpreter) pushq(tag); - pushq(r); + if (TaggedStackInterpreter) push(tag); + push(r); } void InterpreterMacroAssembler::push_i(Register r) { - if (TaggedStackInterpreter) pushq(frame::TagValue); - pushq(r); + if (TaggedStackInterpreter) push(frame::TagValue); + push(r); } void InterpreterMacroAssembler::push_l(Register r) { if (TaggedStackInterpreter) { - pushq(frame::TagValue); - subq(rsp, 1 * wordSize); - pushq(frame::TagValue); - subq(rsp, 1 * wordSize); + push(frame::TagValue); + subptr(rsp, 1 * wordSize); + push(frame::TagValue); + subptr(rsp, 1 * wordSize); } else { - subq(rsp, 2 * wordSize); + subptr(rsp, 2 * wordSize); } movq(Address(rsp, 0), r); } void InterpreterMacroAssembler::push_f(XMMRegister r) { - if (TaggedStackInterpreter) pushq(frame::TagValue); - subq(rsp, wordSize); + if (TaggedStackInterpreter) push(frame::TagValue); + subptr(rsp, wordSize); movflt(Address(rsp, 0), r); } void InterpreterMacroAssembler::push_d(XMMRegister r) { if (TaggedStackInterpreter) { - pushq(frame::TagValue); - subq(rsp, 1 * wordSize); - pushq(frame::TagValue); - subq(rsp, 1 * wordSize); + push(frame::TagValue); + subptr(rsp, 1 * wordSize); + push(frame::TagValue); + subptr(rsp, 1 * wordSize); } else { - subq(rsp, 2 * wordSize); + subptr(rsp, 2 * wordSize); } movdbl(Address(rsp, 0), r); } @@ -441,20 +451,22 @@ void InterpreterMacroAssembler::push(TosState state) { } + + // Tagged stack helpers for swap and dup void InterpreterMacroAssembler::load_ptr_and_tag(int n, Register val, Register tag) { - movq(val, Address(rsp, Interpreter::expr_offset_in_bytes(n))); + movptr(val, Address(rsp, Interpreter::expr_offset_in_bytes(n))); if (TaggedStackInterpreter) { - movq(tag, Address(rsp, Interpreter::expr_tag_offset_in_bytes(n))); + movptr(tag, Address(rsp, Interpreter::expr_tag_offset_in_bytes(n))); } } void InterpreterMacroAssembler::store_ptr_and_tag(int n, Register val, Register tag) { - movq(Address(rsp, Interpreter::expr_offset_in_bytes(n)), val); + movptr(Address(rsp, Interpreter::expr_offset_in_bytes(n)), val); if (TaggedStackInterpreter) { - movq(Address(rsp, Interpreter::expr_tag_offset_in_bytes(n)), tag); + movptr(Address(rsp, Interpreter::expr_tag_offset_in_bytes(n)), tag); } } @@ -463,12 +475,12 @@ void InterpreterMacroAssembler::store_ptr_and_tag(int n, Register val, void InterpreterMacroAssembler::tag_local(frame::Tag tag, int n) { if (TaggedStackInterpreter) { if (tag == frame::TagCategory2) { - mov64(Address(r14, Interpreter::local_tag_offset_in_bytes(n+1)), - (intptr_t)frame::TagValue); - mov64(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), - (intptr_t)frame::TagValue); + movptr(Address(r14, Interpreter::local_tag_offset_in_bytes(n+1)), + (int32_t)frame::TagValue); + movptr(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), + (int32_t)frame::TagValue); } else { - mov64(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), (intptr_t)tag); + movptr(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)tag); } } } @@ -476,13 +488,13 @@ void InterpreterMacroAssembler::tag_local(frame::Tag tag, int n) { void InterpreterMacroAssembler::tag_local(frame::Tag tag, Register idx) { if (TaggedStackInterpreter) { if (tag == frame::TagCategory2) { - mov64(Address(r14, idx, Address::times_8, - Interpreter::local_tag_offset_in_bytes(1)), (intptr_t)frame::TagValue); - mov64(Address(r14, idx, Address::times_8, - Interpreter::local_tag_offset_in_bytes(0)), (intptr_t)frame::TagValue); + movptr(Address(r14, idx, Address::times_8, + Interpreter::local_tag_offset_in_bytes(1)), (int32_t)frame::TagValue); + movptr(Address(r14, idx, Address::times_8, + Interpreter::local_tag_offset_in_bytes(0)), (int32_t)frame::TagValue); } else { - mov64(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(0)), - (intptr_t)tag); + movptr(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(0)), + (int32_t)tag); } } } @@ -490,7 +502,7 @@ void InterpreterMacroAssembler::tag_local(frame::Tag tag, Register idx) { void InterpreterMacroAssembler::tag_local(Register tag, Register idx) { if (TaggedStackInterpreter) { // can only be TagValue or TagReference - movq(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(0)), tag); + movptr(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(0)), tag); } } @@ -498,7 +510,7 @@ void InterpreterMacroAssembler::tag_local(Register tag, Register idx) { void InterpreterMacroAssembler::tag_local(Register tag, int n) { if (TaggedStackInterpreter) { // can only be TagValue or TagReference - movq(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), tag); + movptr(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), tag); } } @@ -509,17 +521,17 @@ void InterpreterMacroAssembler::verify_local_tag(frame::Tag tag, int n) { if (tag == frame::TagCategory2) { Label nbl; t = frame::TagValue; // change to what is stored in locals - cmpq(Address(r14, Interpreter::local_tag_offset_in_bytes(n+1)), (int)t); + cmpptr(Address(r14, Interpreter::local_tag_offset_in_bytes(n+1)), (int32_t)t); jcc(Assembler::equal, nbl); stop("Local tag is bad for long/double"); bind(nbl); } Label notBad; - cmpq(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), (int)t); + cmpq(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)t); jcc(Assembler::equal, notBad); // Also compare if the local value is zero, then the tag might // not have been set coming from deopt. - cmpq(Address(r14, Interpreter::local_offset_in_bytes(n)), 0); + cmpptr(Address(r14, Interpreter::local_offset_in_bytes(n)), 0); jcc(Assembler::equal, notBad); stop("Local tag is bad"); bind(notBad); @@ -532,17 +544,17 @@ void InterpreterMacroAssembler::verify_local_tag(frame::Tag tag, Register idx) { if (tag == frame::TagCategory2) { Label nbl; t = frame::TagValue; // change to what is stored in locals - cmpq(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(1)), (int)t); + cmpptr(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(1)), (int32_t)t); jcc(Assembler::equal, nbl); stop("Local tag is bad for long/double"); bind(nbl); } Label notBad; - cmpq(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(0)), (int)t); + cmpptr(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(0)), (int32_t)t); jcc(Assembler::equal, notBad); // Also compare if the local value is zero, then the tag might // not have been set coming from deopt. - cmpq(Address(r14, idx, Address::times_8, Interpreter::local_offset_in_bytes(0)), 0); + cmpptr(Address(r14, idx, Address::times_8, Interpreter::local_offset_in_bytes(0)), 0); jcc(Assembler::equal, notBad); stop("Local tag is bad"); bind(notBad); @@ -559,7 +571,7 @@ void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point) { void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, Register arg_1) { if (c_rarg0 != arg_1) { - movq(c_rarg0, arg_1); + mov(c_rarg0, arg_1); } MacroAssembler::call_VM_leaf_base(entry_point, 1); } @@ -571,10 +583,10 @@ void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, assert(c_rarg0 != arg_2, "smashed argument"); assert(c_rarg1 != arg_1, "smashed argument"); if (c_rarg0 != arg_1) { - movq(c_rarg0, arg_1); + mov(c_rarg0, arg_1); } if (c_rarg1 != arg_2) { - movq(c_rarg1, arg_2); + mov(c_rarg1, arg_2); } MacroAssembler::call_VM_leaf_base(entry_point, 2); } @@ -590,13 +602,13 @@ void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, assert(c_rarg2 != arg_1, "smashed argument"); assert(c_rarg2 != arg_2, "smashed argument"); if (c_rarg0 != arg_1) { - movq(c_rarg0, arg_1); + mov(c_rarg0, arg_1); } if (c_rarg1 != arg_2) { - movq(c_rarg1, arg_2); + mov(c_rarg1, arg_2); } if (c_rarg2 != arg_3) { - movq(c_rarg2, arg_3); + mov(c_rarg2, arg_3); } MacroAssembler::call_VM_leaf_base(entry_point, 3); } @@ -605,9 +617,9 @@ void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, // in this thread in which case we must call the i2i entry void InterpreterMacroAssembler::jump_from_interpreted(Register method, Register temp) { // set sender sp - leaq(r13, Address(rsp, wordSize)); + lea(r13, Address(rsp, wordSize)); // record last_sp - movq(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), r13); + movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), r13); if (JvmtiExport::can_post_interpreter_events()) { Label run_compiled_code; @@ -644,12 +656,12 @@ void InterpreterMacroAssembler::dispatch_base(TosState state, verify_FPU(1, state); if (VerifyActivationFrameSize) { Label L; - movq(rcx, rbp); - subq(rcx, rsp); - int min_frame_size = + mov(rcx, rbp); + subptr(rcx, rsp); + int32_t min_frame_size = (frame::link_offset - frame::interpreter_frame_initial_sp_offset) * wordSize; - cmpq(rcx, min_frame_size); + cmpptr(rcx, (int32_t)min_frame_size); jcc(Assembler::greaterEqual, L); stop("broken stack frame"); bind(L); @@ -678,7 +690,7 @@ void InterpreterMacroAssembler::dispatch_next(TosState state, int step) { // load next bytecode (load before advancing r13 to prevent AGI) load_unsigned_byte(rbx, Address(r13, step)); // advance r13 - incrementq(r13, step); + increment(r13, step); dispatch_base(state, Interpreter::dispatch_table(state)); } @@ -718,7 +730,7 @@ void InterpreterMacroAssembler::remove_activation( movbool(do_not_unlock_if_synchronized, false); // reset the flag // get method access flags - movq(rbx, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); + movptr(rbx, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); movl(rcx, Address(rbx, methodOopDesc::access_flags_offset())); testl(rcx, JVM_ACC_SYNCHRONIZED); jcc(Assembler::zero, unlocked); @@ -738,10 +750,10 @@ void InterpreterMacroAssembler::remove_activation( wordSize - (int) sizeof(BasicObjectLock)); // We use c_rarg1 so that if we go slow path it will be the correct // register for unlock_object to pass to VM directly - leaq(c_rarg1, monitor); // address of first monitor + lea(c_rarg1, monitor); // address of first monitor - movq(rax, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes())); - testq(rax, rax); + movptr(rax, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes())); + testptr(rax, rax); jcc(Assembler::notZero, unlock); pop(state); @@ -783,9 +795,9 @@ void InterpreterMacroAssembler::remove_activation( bind(restart); // We use c_rarg1 so that if we go slow path it will be the correct // register for unlock_object to pass to VM directly - movq(c_rarg1, monitor_block_top); // points to current entry, starting + movptr(c_rarg1, monitor_block_top); // points to current entry, starting // with top-most entry - leaq(rbx, monitor_block_bot); // points to word before bottom of + lea(rbx, monitor_block_bot); // points to word before bottom of // monitor block jmp(entry); @@ -818,12 +830,12 @@ void InterpreterMacroAssembler::remove_activation( bind(loop); // check if current entry is used - cmpq(Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes()), (int) NULL); + cmpptr(Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes()), (int32_t) NULL); jcc(Assembler::notEqual, exception); - addq(c_rarg1, entry_size); // otherwise advance to next entry + addptr(c_rarg1, entry_size); // otherwise advance to next entry bind(entry); - cmpq(c_rarg1, rbx); // check if bottom reached + cmpptr(c_rarg1, rbx); // check if bottom reached jcc(Assembler::notEqual, loop); // if not at bottom then check this entry } @@ -838,13 +850,15 @@ void InterpreterMacroAssembler::remove_activation( // remove activation // get sender sp - movq(rbx, - Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); + movptr(rbx, + Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); leave(); // remove frame anchor - popq(ret_addr); // get return address - movq(rsp, rbx); // set sp to sender sp + pop(ret_addr); // get return address + mov(rsp, rbx); // set sp to sender sp } +#endif // C_INTERP + // Lock object // // Args: @@ -875,7 +889,7 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg) { Label slow_case; // Load object pointer into obj_reg %c_rarg3 - movq(obj_reg, Address(lock_reg, obj_offset)); + movptr(obj_reg, Address(lock_reg, obj_offset)); if (UseBiasedLocking) { biased_locking_enter(lock_reg, obj_reg, swap_reg, rscratch1, false, done, &slow_case); @@ -885,16 +899,16 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg) { movl(swap_reg, 1); // Load (object->mark() | 1) into swap_reg %rax - orq(swap_reg, Address(obj_reg, 0)); + orptr(swap_reg, Address(obj_reg, 0)); // Save (object->mark() | 1) into BasicLock's displaced header - movq(Address(lock_reg, mark_offset), swap_reg); + movptr(Address(lock_reg, mark_offset), swap_reg); assert(lock_offset == 0, "displached header must be first word in BasicObjectLock"); if (os::is_MP()) lock(); - cmpxchgq(lock_reg, Address(obj_reg, 0)); + cmpxchgptr(lock_reg, Address(obj_reg, 0)); if (PrintBiasedLockingStatistics) { cond_inc32(Assembler::zero, ExternalAddress((address) BiasedLocking::fast_path_entry_count_addr())); @@ -910,11 +924,11 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg) { // assuming both stack pointer and pagesize have their // least significant 3 bits clear. // NOTE: the oopMark is in swap_reg %rax as the result of cmpxchg - subq(swap_reg, rsp); - andq(swap_reg, 7 - os::vm_page_size()); + subptr(swap_reg, rsp); + andptr(swap_reg, 7 - os::vm_page_size()); // Save the test result, for recursive case, the result is zero - movq(Address(lock_reg, mark_offset), swap_reg); + movptr(Address(lock_reg, mark_offset), swap_reg); if (PrintBiasedLockingStatistics) { cond_inc32(Assembler::zero, @@ -963,37 +977,37 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg) { // Convert from BasicObjectLock structure to object and BasicLock // structure Store the BasicLock address into %rax - leaq(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes())); + lea(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes())); // Load oop into obj_reg(%c_rarg3) - movq(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes())); + movptr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes())); // Free entry - movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), NULL_WORD); + movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD); if (UseBiasedLocking) { biased_locking_exit(obj_reg, header_reg, done); } // Load the old header from BasicLock structure - movq(header_reg, Address(swap_reg, - BasicLock::displaced_header_offset_in_bytes())); + movptr(header_reg, Address(swap_reg, + BasicLock::displaced_header_offset_in_bytes())); // Test for recursion - testq(header_reg, header_reg); + testptr(header_reg, header_reg); // zero for recursive case jcc(Assembler::zero, done); // Atomic swap back the old header if (os::is_MP()) lock(); - cmpxchgq(header_reg, Address(obj_reg, 0)); + cmpxchgptr(header_reg, Address(obj_reg, 0)); // zero for recursive case jcc(Assembler::zero, done); // Call the runtime routine for slow case. - movq(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), + movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), obj_reg); // restore obj call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), @@ -1005,12 +1019,13 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg) { } } +#ifndef CC_INTERP void InterpreterMacroAssembler::test_method_data_pointer(Register mdp, Label& zero_continue) { assert(ProfileInterpreter, "must be profiling interpreter"); - movq(mdp, Address(rbp, frame::interpreter_frame_mdx_offset * wordSize)); - testq(mdp, mdp); + movptr(mdp, Address(rbp, frame::interpreter_frame_mdx_offset * wordSize)); + testptr(mdp, mdp); jcc(Assembler::zero, zero_continue); } @@ -1019,13 +1034,13 @@ void InterpreterMacroAssembler::test_method_data_pointer(Register mdp, void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() { assert(ProfileInterpreter, "must be profiling interpreter"); Label zero_continue; - pushq(rax); - pushq(rbx); + push(rax); + push(rbx); get_method(rbx); // Test MDO to avoid the call if it is NULL. - movq(rax, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); - testq(rax, rax); + movptr(rax, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); + testptr(rax, rax); jcc(Assembler::zero, zero_continue); // rbx: method @@ -1033,26 +1048,26 @@ void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() { call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::bcp_to_di), rbx, r13); // rax: mdi - movq(rbx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); - testq(rbx, rbx); + movptr(rbx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); + testptr(rbx, rbx); jcc(Assembler::zero, zero_continue); - addq(rbx, in_bytes(methodDataOopDesc::data_offset())); - addq(rbx, rax); - movq(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rbx); + addptr(rbx, in_bytes(methodDataOopDesc::data_offset())); + addptr(rbx, rax); + movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rbx); bind(zero_continue); - popq(rbx); - popq(rax); + pop(rbx); + pop(rax); } void InterpreterMacroAssembler::verify_method_data_pointer() { assert(ProfileInterpreter, "must be profiling interpreter"); #ifdef ASSERT Label verify_continue; - pushq(rax); - pushq(rbx); - pushq(c_rarg3); - pushq(c_rarg2); + push(rax); + push(rbx); + push(c_rarg3); + push(c_rarg2); test_method_data_pointer(c_rarg3, verify_continue); // If mdp is zero, continue get_method(rbx); @@ -1060,9 +1075,9 @@ void InterpreterMacroAssembler::verify_method_data_pointer() { // consistent with the bcp. The converse is highly probable also. load_unsigned_word(c_rarg2, Address(c_rarg3, in_bytes(DataLayout::bci_offset()))); - addq(c_rarg2, Address(rbx, methodOopDesc::const_offset())); - leaq(c_rarg2, Address(c_rarg2, constMethodOopDesc::codes_offset())); - cmpq(c_rarg2, r13); + addptr(c_rarg2, Address(rbx, methodOopDesc::const_offset())); + lea(c_rarg2, Address(c_rarg2, constMethodOopDesc::codes_offset())); + cmpptr(c_rarg2, r13); jcc(Assembler::equal, verify_continue); // rbx: method // r13: bcp @@ -1070,10 +1085,10 @@ void InterpreterMacroAssembler::verify_method_data_pointer() { call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::verify_mdp), rbx, r13, c_rarg3); bind(verify_continue); - popq(c_rarg2); - popq(c_rarg3); - popq(rbx); - popq(rax); + pop(c_rarg2); + pop(c_rarg3); + pop(rbx); + pop(rax); #endif // ASSERT } @@ -1083,7 +1098,7 @@ void InterpreterMacroAssembler::set_mdp_data_at(Register mdp_in, Register value) { assert(ProfileInterpreter, "must be profiling interpreter"); Address data(mdp_in, constant); - movq(data, value); + movptr(data, value); } @@ -1099,22 +1114,24 @@ void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in, void InterpreterMacroAssembler::increment_mdp_data_at(Address data, bool decrement) { assert(ProfileInterpreter, "must be profiling interpreter"); + // %%% this does 64bit counters at best it is wasting space + // at worst it is a rare bug when counters overflow if (decrement) { // Decrement the register. Set condition codes. - addq(data, -DataLayout::counter_increment); + addptr(data, (int32_t) -DataLayout::counter_increment); // If the decrement causes the counter to overflow, stay negative Label L; jcc(Assembler::negative, L); - addq(data, DataLayout::counter_increment); + addptr(data, (int32_t) DataLayout::counter_increment); bind(L); } else { assert(DataLayout::counter_increment == 1, "flow-free idiom only works with 1"); // Increment the register. Set carry flag. - addq(data, DataLayout::counter_increment); + addptr(data, DataLayout::counter_increment); // If the increment causes the counter to overflow, pull back by 1. - sbbq(data, 0); + sbbptr(data, (int32_t)0); } } @@ -1146,11 +1163,11 @@ void InterpreterMacroAssembler::test_mdp_data_at(Register mdp_in, Label& not_equal_continue) { assert(ProfileInterpreter, "must be profiling interpreter"); if (test_value_out == noreg) { - cmpq(value, Address(mdp_in, offset)); + cmpptr(value, Address(mdp_in, offset)); } else { // Put the test value into a register, so caller can use it: - movq(test_value_out, Address(mdp_in, offset)); - cmpq(test_value_out, value); + movptr(test_value_out, Address(mdp_in, offset)); + cmpptr(test_value_out, value); } jcc(Assembler::notEqual, not_equal_continue); } @@ -1160,8 +1177,8 @@ void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in, int offset_of_disp) { assert(ProfileInterpreter, "must be profiling interpreter"); Address disp_address(mdp_in, offset_of_disp); - addq(mdp_in, disp_address); - movq(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); + addptr(mdp_in, disp_address); + movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); } @@ -1170,26 +1187,26 @@ void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in, int offset_of_disp) { assert(ProfileInterpreter, "must be profiling interpreter"); Address disp_address(mdp_in, reg, Address::times_1, offset_of_disp); - addq(mdp_in, disp_address); - movq(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); + addptr(mdp_in, disp_address); + movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); } void InterpreterMacroAssembler::update_mdp_by_constant(Register mdp_in, int constant) { assert(ProfileInterpreter, "must be profiling interpreter"); - addq(mdp_in, constant); - movq(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); + addptr(mdp_in, constant); + movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); } void InterpreterMacroAssembler::update_mdp_for_ret(Register return_bci) { assert(ProfileInterpreter, "must be profiling interpreter"); - pushq(return_bci); // save/restore across call_VM + push(return_bci); // save/restore across call_VM call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::update_mdp_for_ret), return_bci); - popq(return_bci); + pop(return_bci); } @@ -1206,12 +1223,12 @@ void InterpreterMacroAssembler::profile_taken_branch(Register mdp, // We inline increment_mdp_data_at to return bumped_count in a register //increment_mdp_data_at(mdp, in_bytes(JumpData::taken_offset())); Address data(mdp, in_bytes(JumpData::taken_offset())); - movq(bumped_count, data); + movptr(bumped_count, data); assert(DataLayout::counter_increment == 1, "flow-free idiom only works with 1"); - addq(bumped_count, DataLayout::counter_increment); - sbbq(bumped_count, 0); - movq(data, bumped_count); // Store back out + addptr(bumped_count, DataLayout::counter_increment); + sbbptr(bumped_count, 0); + movptr(data, bumped_count); // Store back out // The method data pointer needs to be updated to reflect the new target. update_mdp_by_offset(mdp, in_bytes(JumpData::displacement_offset())); @@ -1339,7 +1356,7 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper( if (test_for_null_also) { // Failed the equality check on receiver[n]... Test for null. - testq(reg2, reg2); + testptr(reg2, reg2); if (start_row == last_row) { // The only thing left to do is handle the null case. jcc(Assembler::notZero, done); @@ -1535,8 +1552,8 @@ void InterpreterMacroAssembler::profile_switch_case(Register index, // Build the base (index * per_case_size_in_bytes()) + // case_array_offset_in_bytes() movl(reg2, in_bytes(MultiBranchData::per_case_size())); - imulq(index, reg2); // XXX l ? - addq(index, in_bytes(MultiBranchData::case_array_offset())); // XXX l ? + imulptr(index, reg2); // XXX l ? + addptr(index, in_bytes(MultiBranchData::case_array_offset())); // XXX l ? // Update the case count increment_mdp_data_at(mdp, @@ -1554,6 +1571,7 @@ void InterpreterMacroAssembler::profile_switch_case(Register index, } + void InterpreterMacroAssembler::verify_oop(Register reg, TosState state) { if (state == atos) { MacroAssembler::verify_oop(reg); @@ -1562,6 +1580,7 @@ void InterpreterMacroAssembler::verify_oop(Register reg, TosState state) { void InterpreterMacroAssembler::verify_FPU(int stack_depth, TosState state) { } +#endif // !CC_INTERP void InterpreterMacroAssembler::notify_method_entry() { @@ -1598,22 +1617,25 @@ void InterpreterMacroAssembler::notify_method_exit( // method result is saved across the call to post_method_exit. If this // is changed then the interpreter_frame_result implementation will // need to be updated too. - push(state); + + // For c++ interpreter the result is always stored at a known location in the frame + // template interpreter will leave it on the top of the stack. + NOT_CC_INTERP(push(state);) movl(rdx, Address(r15_thread, JavaThread::interp_only_mode_offset())); testl(rdx, rdx); jcc(Assembler::zero, L); call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_exit)); bind(L); - pop(state); + NOT_CC_INTERP(pop(state)); } { SkipIfEqual skip(this, &DTraceMethodProbes, false); - push(state); + NOT_CC_INTERP(push(state)); get_method(c_rarg1); call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), r15_thread, c_rarg1); - pop(state); + NOT_CC_INTERP(pop(state)); } } diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp index 3b1baa258cf..62396c94ba6 100644 --- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,8 @@ // This file specializes the assember with interpreter-specific macros -class InterpreterMacroAssembler - : public MacroAssembler { +class InterpreterMacroAssembler: public MacroAssembler { +#ifndef CC_INTERP protected: // Interpreter specific version of call_VM_base virtual void call_VM_leaf_base(address entry_point, @@ -44,52 +44,53 @@ class InterpreterMacroAssembler // base routine for all dispatches void dispatch_base(TosState state, address* table, bool verifyoop = true); +#endif // CC_INTERP public: - InterpreterMacroAssembler(CodeBuffer* code) - : MacroAssembler(code) - {} + InterpreterMacroAssembler(CodeBuffer* code) : MacroAssembler(code) {} void load_earlyret_value(TosState state); +#ifdef CC_INTERP + void save_bcp() { /* not needed in c++ interpreter and harmless */ } + void restore_bcp() { /* not needed in c++ interpreter and harmless */ } + + // Helpers for runtime call arguments/results + void get_method(Register reg); + +#else + // Interpreter-specific registers - void save_bcp() - { - movq(Address(rbp, frame::interpreter_frame_bcx_offset * wordSize), r13); + void save_bcp() { + movptr(Address(rbp, frame::interpreter_frame_bcx_offset * wordSize), r13); } - void restore_bcp() - { - movq(r13, Address(rbp, frame::interpreter_frame_bcx_offset * wordSize)); + void restore_bcp() { + movptr(r13, Address(rbp, frame::interpreter_frame_bcx_offset * wordSize)); } - void restore_locals() - { - movq(r14, Address(rbp, frame::interpreter_frame_locals_offset * wordSize)); + void restore_locals() { + movptr(r14, Address(rbp, frame::interpreter_frame_locals_offset * wordSize)); } // Helpers for runtime call arguments/results - void get_method(Register reg) - { - movq(reg, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); + void get_method(Register reg) { + movptr(reg, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); } - void get_constant_pool(Register reg) - { + void get_constant_pool(Register reg) { get_method(reg); - movq(reg, Address(reg, methodOopDesc::constants_offset())); + movptr(reg, Address(reg, methodOopDesc::constants_offset())); } - void get_constant_pool_cache(Register reg) - { + void get_constant_pool_cache(Register reg) { get_constant_pool(reg); - movq(reg, Address(reg, constantPoolOopDesc::cache_offset_in_bytes())); + movptr(reg, Address(reg, constantPoolOopDesc::cache_offset_in_bytes())); } - void get_cpool_and_tags(Register cpool, Register tags) - { + void get_cpool_and_tags(Register cpool, Register tags) { get_constant_pool(cpool); - movq(tags, Address(cpool, constantPoolOopDesc::tags_offset_in_bytes())); + movptr(tags, Address(cpool, constantPoolOopDesc::tags_offset_in_bytes())); } void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset); @@ -98,6 +99,7 @@ class InterpreterMacroAssembler void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset); + void pop_ptr(Register r = rax); void pop_i(Register r = rax); void pop_l(Register r = rax); @@ -109,15 +111,23 @@ class InterpreterMacroAssembler void push_f(XMMRegister r = xmm0); void push_d(XMMRegister r = xmm0); + void pop(Register r ) { ((MacroAssembler*)this)->pop(r); } + + void push(Register r ) { ((MacroAssembler*)this)->push(r); } + void push(int32_t imm ) { ((MacroAssembler*)this)->push(imm); } + void pop(TosState state); // transition vtos -> state void push(TosState state); // transition state -> vtos // Tagged stack support, pop and push both tag and value. void pop_ptr(Register r, Register tag); void push_ptr(Register r, Register tag); +#endif // CC_INTERP DEBUG_ONLY(void verify_stack_tag(frame::Tag t);) +#ifndef CC_INTERP + // Tagged stack helpers for swap and dup void load_ptr_and_tag(int n, Register val, Register tag); void store_ptr_and_tag(int n, Register val, Register tag); @@ -133,12 +143,12 @@ class InterpreterMacroAssembler void verify_local_tag(frame::Tag tag, Register idx); #endif // ASSERT + void empty_expression_stack() { - movq(rsp, Address(rbp, frame::interpreter_frame_monitor_block_top_offset * - wordSize)); + movptr(rsp, Address(rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize)); // NULL last_sp until next java call - movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); } // Super call_VM calls - correspond to MacroAssembler::call_VM(_leaf) calls @@ -185,11 +195,14 @@ class InterpreterMacroAssembler bool throw_monitor_exception = true, bool install_monitor_exception = true, bool notify_jvmdi = true); +#endif // CC_INTERP // Object locking void lock_object (Register lock_reg); void unlock_object(Register lock_reg); +#ifndef CC_INTERP + // Interpreter profiling operations void set_method_data_pointer_for_bcp(); void test_method_data_pointer(Register mdp, Label& zero_continue); @@ -237,6 +250,8 @@ class InterpreterMacroAssembler // only if +VerifyFPU && (state == ftos || state == dtos) void verify_FPU(int stack_depth, TosState state = ftos); +#endif // !CC_INTERP + typedef enum { NotifyJVMTI, SkipNotifyJVMTI } NotifyMethodExitMode; // support for jvmti/dtrace diff --git a/hotspot/src/cpu/x86/vm/interpreterRT_x86_32.cpp b/hotspot/src/cpu/x86/vm/interpreterRT_x86_32.cpp index 73f11d64ccd..96a1c3073d4 100644 --- a/hotspot/src/cpu/x86/vm/interpreterRT_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/interpreterRT_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,13 +50,13 @@ void InterpreterRuntime::SignatureHandlerGenerator::move(int from_offset, int to void InterpreterRuntime::SignatureHandlerGenerator::box(int from_offset, int to_offset) { - __ leal(temp(), Address(from(), Interpreter::local_offset_in_bytes(from_offset))); - __ cmpl(Address(from(), Interpreter::local_offset_in_bytes(from_offset)), 0); // do not use temp() to avoid AGI + __ lea(temp(), Address(from(), Interpreter::local_offset_in_bytes(from_offset))); + __ cmpptr(Address(from(), Interpreter::local_offset_in_bytes(from_offset)), (int32_t)NULL_WORD); // do not use temp() to avoid AGI Label L; __ jcc(Assembler::notZero, L); - __ movl(temp(), 0); + __ movptr(temp(), ((int32_t)NULL_WORD)); __ bind(L); - __ movl(Address(to(), to_offset * wordSize), temp()); + __ movptr(Address(to(), to_offset * wordSize), temp()); } diff --git a/hotspot/src/cpu/x86/vm/interpreterRT_x86_64.cpp b/hotspot/src/cpu/x86/vm/interpreterRT_x86_64.cpp index 90d0ad9d8d0..e3c8c6be94b 100644 --- a/hotspot/src/cpu/x86/vm/interpreterRT_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/interpreterRT_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -93,49 +93,49 @@ void InterpreterRuntime::SignatureHandlerGenerator::pass_long() { #ifdef _WIN64 switch (_num_args) { case 0: - __ movq(c_rarg1, src); + __ movptr(c_rarg1, src); _num_args++; break; case 1: - __ movq(c_rarg2, src); + __ movptr(c_rarg2, src); _num_args++; break; case 2: - __ movq(c_rarg3, src); + __ movptr(c_rarg3, src); _num_args++; break; case 3: default: - __ movq(rax, src); - __ movq(Address(to(), _stack_offset), rax); + __ movptr(rax, src); + __ movptr(Address(to(), _stack_offset), rax); _stack_offset += wordSize; break; } #else switch (_num_int_args) { case 0: - __ movq(c_rarg1, src); + __ movptr(c_rarg1, src); _num_int_args++; break; case 1: - __ movq(c_rarg2, src); + __ movptr(c_rarg2, src); _num_int_args++; break; case 2: - __ movq(c_rarg3, src); + __ movptr(c_rarg3, src); _num_int_args++; break; case 3: - __ movq(c_rarg4, src); + __ movptr(c_rarg4, src); _num_int_args++; break; case 4: - __ movq(c_rarg5, src); + __ movptr(c_rarg5, src); _num_int_args++; break; default: - __ movq(rax, src); - __ movq(Address(to(), _stack_offset), rax); + __ movptr(rax, src); + __ movptr(Address(to(), _stack_offset), rax); _stack_offset += wordSize; break; } @@ -171,16 +171,16 @@ void InterpreterRuntime::SignatureHandlerGenerator::pass_double() { if (_num_args < Argument::n_float_register_parameters_c-1) { __ movdbl(as_XMMRegister(++_num_args), src); } else { - __ movq(rax, src); - __ movq(Address(to(), _stack_offset), rax); + __ movptr(rax, src); + __ movptr(Address(to(), _stack_offset), rax); _stack_offset += wordSize; } #else if (_num_fp_args < Argument::n_float_register_parameters_c) { __ movdbl(as_XMMRegister(_num_fp_args++), src); } else { - __ movq(rax, src); - __ movq(Address(to(), _stack_offset), rax); + __ movptr(rax, src); + __ movptr(Address(to(), _stack_offset), rax); _stack_offset += wordSize; } #endif @@ -193,29 +193,29 @@ void InterpreterRuntime::SignatureHandlerGenerator::pass_object() { switch (_num_args) { case 0: assert(offset() == 0, "argument register 1 can only be (non-null) receiver"); - __ leaq(c_rarg1, src); + __ lea(c_rarg1, src); _num_args++; break; case 1: - __ leaq(rax, src); + __ lea(rax, src); __ xorl(c_rarg2, c_rarg2); - __ cmpq(src, 0); - __ cmovq(Assembler::notEqual, c_rarg2, rax); + __ cmpptr(src, 0); + __ cmov(Assembler::notEqual, c_rarg2, rax); _num_args++; break; case 2: - __ leaq(rax, src); + __ lea(rax, src); __ xorl(c_rarg3, c_rarg3); - __ cmpq(src, 0); - __ cmovq(Assembler::notEqual, c_rarg3, rax); + __ cmpptr(src, 0); + __ cmov(Assembler::notEqual, c_rarg3, rax); _num_args++; break; default: - __ leaq(rax, src); + __ lea(rax, src); __ xorl(temp(), temp()); - __ cmpq(src, 0); - __ cmovq(Assembler::notEqual, temp(), rax); - __ movq(Address(to(), _stack_offset), temp()); + __ cmpptr(src, 0); + __ cmov(Assembler::notEqual, temp(), rax); + __ movptr(Address(to(), _stack_offset), temp()); _stack_offset += wordSize; break; } @@ -223,43 +223,43 @@ void InterpreterRuntime::SignatureHandlerGenerator::pass_object() { switch (_num_int_args) { case 0: assert(offset() == 0, "argument register 1 can only be (non-null) receiver"); - __ leaq(c_rarg1, src); + __ lea(c_rarg1, src); _num_int_args++; break; case 1: - __ leaq(rax, src); + __ lea(rax, src); __ xorl(c_rarg2, c_rarg2); - __ cmpq(src, 0); - __ cmovq(Assembler::notEqual, c_rarg2, rax); + __ cmpptr(src, 0); + __ cmov(Assembler::notEqual, c_rarg2, rax); _num_int_args++; break; case 2: - __ leaq(rax, src); + __ lea(rax, src); __ xorl(c_rarg3, c_rarg3); - __ cmpq(src, 0); - __ cmovq(Assembler::notEqual, c_rarg3, rax); + __ cmpptr(src, 0); + __ cmov(Assembler::notEqual, c_rarg3, rax); _num_int_args++; break; case 3: - __ leaq(rax, src); + __ lea(rax, src); __ xorl(c_rarg4, c_rarg4); - __ cmpq(src, 0); - __ cmovq(Assembler::notEqual, c_rarg4, rax); + __ cmpptr(src, 0); + __ cmov(Assembler::notEqual, c_rarg4, rax); _num_int_args++; break; case 4: - __ leaq(rax, src); + __ lea(rax, src); __ xorl(c_rarg5, c_rarg5); - __ cmpq(src, 0); - __ cmovq(Assembler::notEqual, c_rarg5, rax); + __ cmpptr(src, 0); + __ cmov(Assembler::notEqual, c_rarg5, rax); _num_int_args++; break; default: - __ leaq(rax, src); + __ lea(rax, src); __ xorl(temp(), temp()); - __ cmpq(src, 0); - __ cmovq(Assembler::notEqual, temp(), rax); - __ movq(Address(to(), _stack_offset), temp()); + __ cmpptr(src, 0); + __ cmov(Assembler::notEqual, temp(), rax); + __ movptr(Address(to(), _stack_offset), temp()); _stack_offset += wordSize; break; } diff --git a/hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp b/hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp index fbdf398bc80..221cd8561b0 100644 --- a/hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ address AbstractInterpreterGenerator::generate_slow_signature_handler() { // rcx: temporary // rdi: pointer to locals // rsp: end of copied parameters area - __ movl(rcx, rsp); + __ mov(rcx, rsp); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::slow_signature_handler), rbx, rdi, rcx); __ ret(0); return entry; @@ -75,8 +75,8 @@ address InterpreterGenerator::generate_empty_entry(void) { // Code: _return // _return // return w/o popping parameters - __ popl(rax); - __ movl(rsp, rsi); + __ pop(rax); + __ mov(rsp, rsi); __ jmp(rax); __ bind(slow_path); @@ -135,7 +135,7 @@ address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKin __ pushl(Address(rsp, 3*wordSize)); // push hi (and note rsp -= wordSize) __ pushl(Address(rsp, 2*wordSize)); // push lo __ fld_d(Address(rsp, 0)); // get double in ST0 - __ addl(rsp, 2*wordSize); + __ addptr(rsp, 2*wordSize); } else { __ fld_d(Address(rsp, 1*wordSize)); } @@ -173,15 +173,15 @@ address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKin // return double result in xmm0 for interpreter and compilers. if (UseSSE >= 2) { - __ subl(rsp, 2*wordSize); + __ subptr(rsp, 2*wordSize); __ fstp_d(Address(rsp, 0)); __ movdbl(xmm0, Address(rsp, 0)); - __ addl(rsp, 2*wordSize); + __ addptr(rsp, 2*wordSize); } // done, result in FPU ST(0) or XMM0 - __ popl(rdi); // get return address - __ movl(rsp, rsi); // set sp to sender sp + __ pop(rdi); // get return address + __ mov(rsp, rsi); // set sp to sender sp __ jmp(rdi); return entry_point; @@ -202,10 +202,10 @@ address InterpreterGenerator::generate_abstract_entry(void) { // abstract method entry // remove return address. Not really needed, since exception handling throws away expression stack - __ popl(rbx); + __ pop(rbx); // adjust stack to what a normal return would do - __ movl(rsp, rsi); + __ mov(rsp, rsi); // throw exception __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError)); // the call_VM checks for exception, so we should never return here. diff --git a/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp b/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp index 9636c5739e5..34e5b56b8d6 100644 --- a/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp @@ -35,9 +35,9 @@ address AbstractInterpreterGenerator::generate_slow_signature_handler() { // rbx: method // r14: pointer to locals // c_rarg3: first stack arg - wordSize - __ movq(c_rarg3, rsp); + __ mov(c_rarg3, rsp); // adjust rsp - __ subq(rsp, 4 * wordSize); + __ subptr(rsp, 4 * wordSize); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::slow_signature_handler), @@ -70,13 +70,13 @@ address AbstractInterpreterGenerator::generate_slow_signature_handler() { case 0: __ movl(rscratch1, Address(rbx, methodOopDesc::access_flags_offset())); __ testl(rscratch1, JVM_ACC_STATIC); - __ cmovq(Assembler::zero, c_rarg1, Address(rsp, 0)); + __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0)); break; case 1: - __ movq(c_rarg2, Address(rsp, wordSize)); + __ movptr(c_rarg2, Address(rsp, wordSize)); break; case 2: - __ movq(c_rarg3, Address(rsp, 2 * wordSize)); + __ movptr(c_rarg3, Address(rsp, 2 * wordSize)); break; default: break; @@ -101,7 +101,7 @@ address AbstractInterpreterGenerator::generate_slow_signature_handler() { // restore rsp - __ addq(rsp, 4 * wordSize); + __ addptr(rsp, 4 * wordSize); __ ret(0); @@ -114,9 +114,9 @@ address AbstractInterpreterGenerator::generate_slow_signature_handler() { // rbx: method // r14: pointer to locals // c_rarg3: first stack arg - wordSize - __ movq(c_rarg3, rsp); + __ mov(c_rarg3, rsp); // adjust rsp - __ subq(rsp, 14 * wordSize); + __ subptr(rsp, 14 * wordSize); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::slow_signature_handler), @@ -155,15 +155,15 @@ address AbstractInterpreterGenerator::generate_slow_signature_handler() { // Now handle integrals. Only do c_rarg1 if not static. __ movl(c_rarg3, Address(rbx, methodOopDesc::access_flags_offset())); __ testl(c_rarg3, JVM_ACC_STATIC); - __ cmovq(Assembler::zero, c_rarg1, Address(rsp, 0)); + __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0)); - __ movq(c_rarg2, Address(rsp, wordSize)); - __ movq(c_rarg3, Address(rsp, 2 * wordSize)); - __ movq(c_rarg4, Address(rsp, 3 * wordSize)); - __ movq(c_rarg5, Address(rsp, 4 * wordSize)); + __ movptr(c_rarg2, Address(rsp, wordSize)); + __ movptr(c_rarg3, Address(rsp, 2 * wordSize)); + __ movptr(c_rarg4, Address(rsp, 3 * wordSize)); + __ movptr(c_rarg5, Address(rsp, 4 * wordSize)); // restore rsp - __ addq(rsp, 14 * wordSize); + __ addptr(rsp, 14 * wordSize); __ ret(0); @@ -176,15 +176,14 @@ address AbstractInterpreterGenerator::generate_slow_signature_handler() { // Various method entries // -address InterpreterGenerator::generate_math_entry( - AbstractInterpreter::MethodKind kind) { - // rbx: methodOop +address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) { + + // rbx,: methodOop + // rcx: scratrch + // r13: sender sp if (!InlineIntrinsics) return NULL; // Generate a vanilla entry - assert(kind == Interpreter::java_lang_math_sqrt, - "Other intrinsics are not special"); - address entry_point = __ pc(); // These don't need a safepoint check because they aren't virtually @@ -197,6 +196,11 @@ address InterpreterGenerator::generate_math_entry( // in order to avoid monotonicity bugs when switching // from interpreter to compiler in the middle of some // computation) + // + // stack: [ ret adr ] <-- rsp + // [ lo(arg) ] + // [ hi(arg) ] + // // Note: For JDK 1.2 StrictMath doesn't exist and Math.sin/cos/sqrt are // native methods. Interpreter::method_kind(...) does a check for @@ -218,10 +222,46 @@ address InterpreterGenerator::generate_math_entry( // Note: For JDK 1.3 StrictMath exists and Math.sin/cos/sqrt are // java methods. Interpreter::method_kind(...) will select // this entry point for the corresponding methods in JDK 1.3. - __ sqrtsd(xmm0, Address(rsp, wordSize)); + // get argument - __ popq(rax); - __ movq(rsp, r13); + if (kind == Interpreter::java_lang_math_sqrt) { + __ sqrtsd(xmm0, Address(rsp, wordSize)); + } else { + __ fld_d(Address(rsp, wordSize)); + switch (kind) { + case Interpreter::java_lang_math_sin : + __ trigfunc('s'); + break; + case Interpreter::java_lang_math_cos : + __ trigfunc('c'); + break; + case Interpreter::java_lang_math_tan : + __ trigfunc('t'); + break; + case Interpreter::java_lang_math_abs: + __ fabs(); + break; + case Interpreter::java_lang_math_log: + __ flog(); + break; + case Interpreter::java_lang_math_log10: + __ flog10(); + break; + default : + ShouldNotReachHere(); + } + + // return double result in xmm0 for interpreter and compilers. + __ subptr(rsp, 2*wordSize); + // Round to 64bit precision + __ fstp_d(Address(rsp, 0)); + __ movdbl(xmm0, Address(rsp, 0)); + __ addptr(rsp, 2*wordSize); + } + + + __ pop(rax); + __ mov(rsp, r13); __ jmp(rax); return entry_point; @@ -239,10 +279,10 @@ address InterpreterGenerator::generate_abstract_entry(void) { // abstract method entry // remove return address. Not really needed, since exception // handling throws away expression stack - __ popq(rbx); + __ pop(rbx); // adjust stack to what a normal return would do - __ movq(rsp, r13); + __ mov(rsp, r13); // throw exception __ call_VM(noreg, CAST_FROM_FN_PTR(address, @@ -276,8 +316,8 @@ address InterpreterGenerator::generate_empty_entry(void) { // Code: _return // _return // return w/o popping parameters - __ popq(rax); - __ movq(rsp, r13); + __ pop(rax); + __ mov(rsp, r13); __ jmp(rax); __ bind(slow_path); @@ -286,148 +326,6 @@ address InterpreterGenerator::generate_empty_entry(void) { } -// Call an accessor method (assuming it is resolved, otherwise drop -// into vanilla (slow path) entry -address InterpreterGenerator::generate_accessor_entry(void) { - // rbx: methodOop - - // r13: senderSP must preserver for slow path, set SP to it on fast path - - address entry_point = __ pc(); - Label xreturn_path; - - // do fastpath for resolved accessor methods - if (UseFastAccessorMethods) { - // Code: _aload_0, _(i|a)getfield, _(i|a)return or any rewrites - // thereof; parameter size = 1 - // Note: We can only use this code if the getfield has been resolved - // and if we don't have a null-pointer exception => check for - // these conditions first and use slow path if necessary. - Label slow_path; - // If we need a safepoint check, generate full interpreter entry. - __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), - SafepointSynchronize::_not_synchronized); - - __ jcc(Assembler::notEqual, slow_path); - // rbx: method - __ movq(rax, Address(rsp, wordSize)); - - // check if local 0 != NULL and read field - __ testq(rax, rax); - __ jcc(Assembler::zero, slow_path); - - __ movq(rdi, Address(rbx, methodOopDesc::constants_offset())); - // read first instruction word and extract bytecode @ 1 and index @ 2 - __ movq(rdx, Address(rbx, methodOopDesc::const_offset())); - __ movl(rdx, Address(rdx, constMethodOopDesc::codes_offset())); - // Shift codes right to get the index on the right. - // The bytecode fetched looks like <0xb4><0x2a> - __ shrl(rdx, 2 * BitsPerByte); - __ shll(rdx, exact_log2(in_words(ConstantPoolCacheEntry::size()))); - __ movq(rdi, Address(rdi, constantPoolOopDesc::cache_offset_in_bytes())); - - // rax: local 0 - // rbx: method - // rdx: constant pool cache index - // rdi: constant pool cache - - // check if getfield has been resolved and read constant pool cache entry - // check the validity of the cache entry by testing whether _indices field - // contains Bytecode::_getfield in b1 byte. - assert(in_words(ConstantPoolCacheEntry::size()) == 4, - "adjust shift below"); - __ movl(rcx, - Address(rdi, - rdx, - Address::times_8, - constantPoolCacheOopDesc::base_offset() + - ConstantPoolCacheEntry::indices_offset())); - __ shrl(rcx, 2 * BitsPerByte); - __ andl(rcx, 0xFF); - __ cmpl(rcx, Bytecodes::_getfield); - __ jcc(Assembler::notEqual, slow_path); - - // Note: constant pool entry is not valid before bytecode is resolved - __ movq(rcx, - Address(rdi, - rdx, - Address::times_8, - constantPoolCacheOopDesc::base_offset() + - ConstantPoolCacheEntry::f2_offset())); - // edx: flags - __ movl(rdx, - Address(rdi, - rdx, - Address::times_8, - constantPoolCacheOopDesc::base_offset() + - ConstantPoolCacheEntry::flags_offset())); - - Label notObj, notInt, notByte, notShort; - const Address field_address(rax, rcx, Address::times_1); - - // Need to differentiate between igetfield, agetfield, bgetfield etc. - // because they are different sizes. - // Use the type from the constant pool cache - __ shrl(rdx, ConstantPoolCacheEntry::tosBits); - // Make sure we don't need to mask edx for tosBits after the above shift - ConstantPoolCacheEntry::verify_tosBits(); - - __ cmpl(rdx, atos); - __ jcc(Assembler::notEqual, notObj); - // atos - __ load_heap_oop(rax, field_address); - __ jmp(xreturn_path); - - __ bind(notObj); - __ cmpl(rdx, itos); - __ jcc(Assembler::notEqual, notInt); - // itos - __ movl(rax, field_address); - __ jmp(xreturn_path); - - __ bind(notInt); - __ cmpl(rdx, btos); - __ jcc(Assembler::notEqual, notByte); - // btos - __ load_signed_byte(rax, field_address); - __ jmp(xreturn_path); - - __ bind(notByte); - __ cmpl(rdx, stos); - __ jcc(Assembler::notEqual, notShort); - // stos - __ load_signed_word(rax, field_address); - __ jmp(xreturn_path); - - __ bind(notShort); -#ifdef ASSERT - Label okay; - __ cmpl(rdx, ctos); - __ jcc(Assembler::equal, okay); - __ stop("what type is this?"); - __ bind(okay); -#endif - // ctos - __ load_unsigned_word(rax, field_address); - - __ bind(xreturn_path); - - // _ireturn/_areturn - __ popq(rdi); - __ movq(rsp, r13); - __ jmp(rdi); - __ ret(0); - - // generate a vanilla interpreter entry as the slow path - __ bind(slow_path); - (void) generate_normal_entry(false); - } else { - (void) generate_normal_entry(false); - } - - return entry_point; -} - // This method tells the deoptimizer how big an interpreted frame must be: int AbstractInterpreter::size_activation(methodOop method, int tempcount, diff --git a/hotspot/src/cpu/x86/vm/jniFastGetField_x86_32.cpp b/hotspot/src/cpu/x86/vm/jniFastGetField_x86_32.cpp index 9643c843d0d..f9637589f76 100644 --- a/hotspot/src/cpu/x86/vm/jniFastGetField_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/jniFastGetField_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -72,25 +72,25 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { __ testb (rcx, 1); __ jcc (Assembler::notZero, slow); if (os::is_MP()) { - __ movl (rax, rcx); - __ andl (rax, 1); // rax, must end up 0 - __ movl (rdx, Address(rsp, rax, Address::times_1, 2*wordSize)); + __ mov(rax, rcx); + __ andptr(rax, 1); // rax, must end up 0 + __ movptr(rdx, Address(rsp, rax, Address::times_1, 2*wordSize)); // obj, notice rax, is 0. // rdx is data dependent on rcx. } else { - __ movl (rdx, Address(rsp, 2*wordSize)); // obj + __ movptr (rdx, Address(rsp, 2*wordSize)); // obj } - __ movl (rax, Address(rsp, 3*wordSize)); // jfieldID - __ movl (rdx, Address(rdx, 0)); // *obj - __ shrl (rax, 2); // offset + __ movptr(rax, Address(rsp, 3*wordSize)); // jfieldID + __ movptr(rdx, Address(rdx, 0)); // *obj + __ shrptr (rax, 2); // offset assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); speculative_load_pclist[count] = __ pc(); switch (type) { - case T_BOOLEAN: __ movzxb (rax, Address(rdx, rax, Address::times_1)); break; - case T_BYTE: __ movsxb (rax, Address(rdx, rax, Address::times_1)); break; - case T_CHAR: __ movzxw (rax, Address(rdx, rax, Address::times_1)); break; - case T_SHORT: __ movsxw (rax, Address(rdx, rax, Address::times_1)); break; + case T_BOOLEAN: __ movzbl (rax, Address(rdx, rax, Address::times_1)); break; + case T_BYTE: __ movsbl (rax, Address(rdx, rax, Address::times_1)); break; + case T_CHAR: __ movzwl (rax, Address(rdx, rax, Address::times_1)); break; + case T_SHORT: __ movswl (rax, Address(rdx, rax, Address::times_1)); break; case T_INT: __ movl (rax, Address(rdx, rax, Address::times_1)); break; default: ShouldNotReachHere(); } @@ -98,8 +98,8 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { Address ca1; if (os::is_MP()) { __ lea(rdx, counter); - __ xorl(rdx, rax); - __ xorl(rdx, rax); + __ xorptr(rdx, rax); + __ xorptr(rdx, rax); __ cmp32(rcx, Address(rdx, 0)); // ca1 is the same as ca because // rax, ^ counter_addr ^ rax, = address @@ -184,35 +184,37 @@ address JNI_FastGetField::generate_fast_get_long_field() { ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr()); - __ pushl (rsi); + __ push (rsi); __ mov32 (rcx, counter); __ testb (rcx, 1); __ jcc (Assembler::notZero, slow); if (os::is_MP()) { - __ movl (rax, rcx); - __ andl (rax, 1); // rax, must end up 0 - __ movl (rdx, Address(rsp, rax, Address::times_1, 3*wordSize)); + __ mov(rax, rcx); + __ andptr(rax, 1); // rax, must end up 0 + __ movptr(rdx, Address(rsp, rax, Address::times_1, 3*wordSize)); // obj, notice rax, is 0. // rdx is data dependent on rcx. } else { - __ movl (rdx, Address(rsp, 3*wordSize)); // obj + __ movptr(rdx, Address(rsp, 3*wordSize)); // obj } - __ movl (rsi, Address(rsp, 4*wordSize)); // jfieldID - __ movl (rdx, Address(rdx, 0)); // *obj - __ shrl (rsi, 2); // offset + __ movptr(rsi, Address(rsp, 4*wordSize)); // jfieldID + __ movptr(rdx, Address(rdx, 0)); // *obj + __ shrptr(rsi, 2); // offset assert(count < LIST_CAPACITY-1, "LIST_CAPACITY too small"); speculative_load_pclist[count++] = __ pc(); - __ movl (rax, Address(rdx, rsi, Address::times_1)); + __ movptr(rax, Address(rdx, rsi, Address::times_1)); +#ifndef _LP64 speculative_load_pclist[count] = __ pc(); - __ movl (rdx, Address(rdx, rsi, Address::times_1, 4)); + __ movl(rdx, Address(rdx, rsi, Address::times_1, 4)); +#endif // _LP64 if (os::is_MP()) { - __ lea (rsi, counter); - __ xorl (rsi, rdx); - __ xorl (rsi, rax); - __ xorl (rsi, rdx); - __ xorl (rsi, rax); + __ lea(rsi, counter); + __ xorptr(rsi, rdx); + __ xorptr(rsi, rax); + __ xorptr(rsi, rdx); + __ xorptr(rsi, rax); __ cmp32(rcx, Address(rsi, 0)); // ca1 is the same as ca because // rax, ^ rdx ^ counter_addr ^ rax, ^ rdx = address @@ -222,7 +224,7 @@ address JNI_FastGetField::generate_fast_get_long_field() { } __ jcc (Assembler::notEqual, slow); - __ popl (rsi); + __ pop (rsi); #ifndef _WINDOWS __ ret (0); @@ -234,7 +236,7 @@ address JNI_FastGetField::generate_fast_get_long_field() { slowcase_entry_pclist[count-1] = __ pc(); slowcase_entry_pclist[count++] = __ pc(); __ bind (slow); - __ popl (rsi); + __ pop (rsi); address slow_case_addr = jni_GetLongField_addr();; // tail call __ jump (ExternalAddress(slow_case_addr)); @@ -276,23 +278,28 @@ address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) { __ testb (rcx, 1); __ jcc (Assembler::notZero, slow); if (os::is_MP()) { - __ movl (rax, rcx); - __ andl (rax, 1); // rax, must end up 0 - __ movl (rdx, Address(rsp, rax, Address::times_1, 2*wordSize)); + __ mov(rax, rcx); + __ andptr(rax, 1); // rax, must end up 0 + __ movptr(rdx, Address(rsp, rax, Address::times_1, 2*wordSize)); // obj, notice rax, is 0. // rdx is data dependent on rcx. } else { - __ movl (rdx, Address(rsp, 2*wordSize)); // obj + __ movptr(rdx, Address(rsp, 2*wordSize)); // obj } - __ movl (rax, Address(rsp, 3*wordSize)); // jfieldID - __ movl (rdx, Address(rdx, 0)); // *obj - __ shrl (rax, 2); // offset + __ movptr(rax, Address(rsp, 3*wordSize)); // jfieldID + __ movptr(rdx, Address(rdx, 0)); // *obj + __ shrptr(rax, 2); // offset assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); speculative_load_pclist[count] = __ pc(); switch (type) { +#ifndef _LP64 case T_FLOAT: __ fld_s (Address(rdx, rax, Address::times_1)); break; case T_DOUBLE: __ fld_d (Address(rdx, rax, Address::times_1)); break; +#else + case T_FLOAT: __ movflt (xmm0, Address(robj, roffset, Address::times_1)); break; + case T_DOUBLE: __ movdbl (xmm0, Address(robj, roffset, Address::times_1)); break; +#endif // _LP64 default: ShouldNotReachHere(); } @@ -301,8 +308,9 @@ address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) { __ fst_s (Address(rsp, -4)); __ lea(rdx, counter); __ movl (rax, Address(rsp, -4)); - __ xorl(rdx, rax); - __ xorl(rdx, rax); + // garbage hi-order bits on 64bit are harmless. + __ xorptr(rdx, rax); + __ xorptr(rdx, rax); __ cmp32(rcx, Address(rdx, 0)); // rax, ^ counter_addr ^ rax, = address // ca1 is data dependent on the field diff --git a/hotspot/src/cpu/x86/vm/jniFastGetField_x86_64.cpp b/hotspot/src/cpu/x86/vm/jniFastGetField_x86_64.cpp index 31160b66f56..b18a2c3efbf 100644 --- a/hotspot/src/cpu/x86/vm/jniFastGetField_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/jniFastGetField_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,18 +67,18 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr()); __ mov32 (rcounter, counter); - __ movq (robj, c_rarg1); + __ mov (robj, c_rarg1); __ testb (rcounter, 1); __ jcc (Assembler::notZero, slow); if (os::is_MP()) { - __ xorq (robj, rcounter); - __ xorq (robj, rcounter); // obj, since + __ xorptr(robj, rcounter); + __ xorptr(robj, rcounter); // obj, since // robj ^ rcounter ^ rcounter == robj // robj is data dependent on rcounter. } - __ movq (robj, Address(robj, 0)); // *obj - __ movq (roffset, c_rarg2); - __ shrq (roffset, 2); // offset + __ movptr(robj, Address(robj, 0)); // *obj + __ mov (roffset, c_rarg2); + __ shrptr(roffset, 2); // offset assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); speculative_load_pclist[count] = __ pc(); @@ -95,8 +95,8 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { if (os::is_MP()) { __ lea(rcounter_addr, counter); // ca is data dependent on rax. - __ xorq (rcounter_addr, rax); - __ xorq (rcounter_addr, rax); + __ xorptr(rcounter_addr, rax); + __ xorptr(rcounter_addr, rax); __ cmpl (rcounter, Address(rcounter_addr, 0)); } else { __ cmp32 (rcounter, counter); @@ -165,18 +165,18 @@ address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) { ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr()); __ mov32 (rcounter, counter); - __ movq (robj, c_rarg1); + __ mov (robj, c_rarg1); __ testb (rcounter, 1); __ jcc (Assembler::notZero, slow); if (os::is_MP()) { - __ xorq (robj, rcounter); - __ xorq (robj, rcounter); // obj, since + __ xorptr(robj, rcounter); + __ xorptr(robj, rcounter); // obj, since // robj ^ rcounter ^ rcounter == robj // robj is data dependent on rcounter. } - __ movq (robj, Address(robj, 0)); // *obj - __ movq (roffset, c_rarg2); - __ shrq (roffset, 2); // offset + __ movptr(robj, Address(robj, 0)); // *obj + __ mov (roffset, c_rarg2); + __ shrptr(roffset, 2); // offset assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); speculative_load_pclist[count] = __ pc(); @@ -190,8 +190,8 @@ address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) { __ lea(rcounter_addr, counter); __ movdq (rax, xmm0); // counter address is data dependent on xmm0. - __ xorq (rcounter_addr, rax); - __ xorq (rcounter_addr, rax); + __ xorptr(rcounter_addr, rax); + __ xorptr(rcounter_addr, rax); __ cmpl (rcounter, Address(rcounter_addr, 0)); } else { __ cmp32 (rcounter, counter); diff --git a/hotspot/src/cpu/x86/vm/nativeInst_x86.cpp b/hotspot/src/cpu/x86/vm/nativeInst_x86.cpp index f8147a4cc64..b4a3ccea503 100644 --- a/hotspot/src/cpu/x86/vm/nativeInst_x86.cpp +++ b/hotspot/src/cpu/x86/vm/nativeInst_x86.cpp @@ -223,49 +223,150 @@ void NativeMovConstReg::print() { //------------------------------------------------------------------- -#ifndef AMD64 +int NativeMovRegMem::instruction_start() const { + int off = 0; + u_char instr_0 = ubyte_at(off); -void NativeMovRegMem::copy_instruction_to(address new_instruction_address) { - int inst_size = instruction_size; - - // See if there's an instruction size prefix override. - if ( *(address(this)) == instruction_operandsize_prefix && - *(address(this)+1) != instruction_code_xmm_code ) { // Not SSE instr - inst_size += 1; + // First check to see if we have a (prefixed or not) xor + if ( instr_0 >= instruction_prefix_wide_lo && // 0x40 + instr_0 <= instruction_prefix_wide_hi) { // 0x4f + off++; + instr_0 = ubyte_at(off); } - if ( *(address(this)) == instruction_extended_prefix ) inst_size += 1; - for (int i = 0; i < instruction_size; i++) { - *(new_instruction_address + i) = *(address(this) + i); + if (instr_0 == instruction_code_xor) { + off += 2; + instr_0 = ubyte_at(off); } + + // Now look for the real instruction and the many prefix/size specifiers. + + if (instr_0 == instruction_operandsize_prefix ) { // 0x66 + off++; // Not SSE instructions + instr_0 = ubyte_at(off); + } + + if ( instr_0 == instruction_code_xmm_ss_prefix || // 0xf3 + instr_0 == instruction_code_xmm_sd_prefix) { // 0xf2 + off++; + instr_0 = ubyte_at(off); + } + + if ( instr_0 >= instruction_prefix_wide_lo && // 0x40 + instr_0 <= instruction_prefix_wide_hi) { // 0x4f + off++; + instr_0 = ubyte_at(off); + } + + + if (instr_0 == instruction_extended_prefix ) { // 0x0f + off++; + } + + return off; +} + +address NativeMovRegMem::instruction_address() const { + return addr_at(instruction_start()); +} + +address NativeMovRegMem::next_instruction_address() const { + address ret = instruction_address() + instruction_size; + u_char instr_0 = *(u_char*) instruction_address(); + switch (instr_0) { + case instruction_operandsize_prefix: + + fatal("should have skipped instruction_operandsize_prefix"); + break; + + case instruction_extended_prefix: + fatal("should have skipped instruction_extended_prefix"); + break; + + case instruction_code_mem2reg_movslq: // 0x63 + case instruction_code_mem2reg_movzxb: // 0xB6 + case instruction_code_mem2reg_movsxb: // 0xBE + case instruction_code_mem2reg_movzxw: // 0xB7 + case instruction_code_mem2reg_movsxw: // 0xBF + case instruction_code_reg2mem: // 0x89 (q/l) + case instruction_code_mem2reg: // 0x8B (q/l) + case instruction_code_reg2memb: // 0x88 + case instruction_code_mem2regb: // 0x8a + + case instruction_code_float_s: // 0xd9 fld_s a + case instruction_code_float_d: // 0xdd fld_d a + + case instruction_code_xmm_load: // 0x10 + case instruction_code_xmm_store: // 0x11 + case instruction_code_xmm_lpd: // 0x12 + { + // If there is an SIB then instruction is longer than expected + u_char mod_rm = *(u_char*)(instruction_address() + 1); + if ((mod_rm & 7) == 0x4) { + ret++; + } + } + case instruction_code_xor: + fatal("should have skipped xor lead in"); + break; + + default: + fatal("not a NativeMovRegMem"); + } + return ret; + +} + +int NativeMovRegMem::offset() const{ + int off = data_offset + instruction_start(); + u_char mod_rm = *(u_char*)(instruction_address() + 1); + // nnnn(r12|rsp) isn't coded as simple mod/rm since that is + // the encoding to use an SIB byte. Which will have the nnnn + // field off by one byte + if ((mod_rm & 7) == 0x4) { + off++; + } + return int_at(off); +} + +void NativeMovRegMem::set_offset(int x) { + int off = data_offset + instruction_start(); + u_char mod_rm = *(u_char*)(instruction_address() + 1); + // nnnn(r12|rsp) isn't coded as simple mod/rm since that is + // the encoding to use an SIB byte. Which will have the nnnn + // field off by one byte + if ((mod_rm & 7) == 0x4) { + off++; + } + set_int_at(off, x); } void NativeMovRegMem::verify() { // make sure code pattern is actually a mov [reg+offset], reg instruction u_char test_byte = *(u_char*)instruction_address(); - if ( ! ( (test_byte == instruction_code_reg2memb) - || (test_byte == instruction_code_mem2regb) - || (test_byte == instruction_code_mem2regl) - || (test_byte == instruction_code_reg2meml) - || (test_byte == instruction_code_mem2reg_movzxb ) - || (test_byte == instruction_code_mem2reg_movzxw ) - || (test_byte == instruction_code_mem2reg_movsxb ) - || (test_byte == instruction_code_mem2reg_movsxw ) - || (test_byte == instruction_code_float_s) - || (test_byte == instruction_code_float_d) - || (test_byte == instruction_code_long_volatile) ) ) - { - u_char byte1 = ((u_char*)instruction_address())[1]; - u_char byte2 = ((u_char*)instruction_address())[2]; - if ((test_byte != instruction_code_xmm_ss_prefix && - test_byte != instruction_code_xmm_sd_prefix && - test_byte != instruction_operandsize_prefix) || - byte1 != instruction_code_xmm_code || - (byte2 != instruction_code_xmm_load && - byte2 != instruction_code_xmm_lpd && - byte2 != instruction_code_xmm_store)) { + switch (test_byte) { + case instruction_code_reg2memb: // 0x88 movb a, r + case instruction_code_reg2mem: // 0x89 movl a, r (can be movq in 64bit) + case instruction_code_mem2regb: // 0x8a movb r, a + case instruction_code_mem2reg: // 0x8b movl r, a (can be movq in 64bit) + break; + + case instruction_code_mem2reg_movslq: // 0x63 movsql r, a + case instruction_code_mem2reg_movzxb: // 0xb6 movzbl r, a (movzxb) + case instruction_code_mem2reg_movzxw: // 0xb7 movzwl r, a (movzxw) + case instruction_code_mem2reg_movsxb: // 0xbe movsbl r, a (movsxb) + case instruction_code_mem2reg_movsxw: // 0xbf movswl r, a (movsxw) + break; + + case instruction_code_float_s: // 0xd9 fld_s a + case instruction_code_float_d: // 0xdd fld_d a + case instruction_code_xmm_load: // 0x10 movsd xmm, a + case instruction_code_xmm_store: // 0x11 movsd a, xmm + case instruction_code_xmm_lpd: // 0x12 movlpd xmm, a + break; + + default: fatal ("not a mov [reg+offs], reg instruction"); - } } } @@ -279,7 +380,14 @@ void NativeMovRegMem::print() { void NativeLoadAddress::verify() { // make sure code pattern is actually a mov [reg+offset], reg instruction u_char test_byte = *(u_char*)instruction_address(); - if ( ! (test_byte == instruction_code) ) { +#ifdef _LP64 + if ( (test_byte == instruction_prefix_wide || + test_byte == instruction_prefix_wide_extended) ) { + test_byte = *(u_char*)(instruction_address() + 1); + } +#endif // _LP64 + if ( ! ((test_byte == lea_instruction_code) + LP64_ONLY(|| (test_byte == mov64_instruction_code) ))) { fatal ("not a lea reg, [reg+offs] instruction"); } } @@ -289,8 +397,6 @@ void NativeLoadAddress::print() { tty->print_cr("0x%x: lea [reg + %x], reg", instruction_address(), offset()); } -#endif // !AMD64 - //-------------------------------------------------------------------------------- void NativeJump::verify() { diff --git a/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp b/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp index 255e8210f99..bd15cbb7b7b 100644 --- a/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp +++ b/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp @@ -235,16 +235,15 @@ class NativeMovConstRegPatching: public NativeMovConstReg { } }; -#ifndef AMD64 - // An interface for accessing/manipulating native moves of the form: -// mov[b/w/l] [reg + offset], reg (instruction_code_reg2mem) -// mov[b/w/l] reg, [reg+offset] (instruction_code_mem2reg -// mov[s/z]x[w/b] [reg + offset], reg +// mov[b/w/l/q] [reg + offset], reg (instruction_code_reg2mem) +// mov[b/w/l/q] reg, [reg+offset] (instruction_code_mem2reg +// mov[s/z]x[w/b/q] [reg + offset], reg // fld_s [reg+offset] // fld_d [reg+offset] // fstp_s [reg + offset] // fstp_d [reg + offset] +// mov_literal64 scratch, ; mov[b/w/l/q] 0(scratch),reg | mov[b/w/l/q] reg,0(scratch) // // Warning: These routines must be able to handle any instruction sequences // that are generated as a result of the load/store byte,word,long @@ -255,15 +254,18 @@ class NativeMovConstRegPatching: public NativeMovConstReg { class NativeMovRegMem: public NativeInstruction { public: enum Intel_specific_constants { + instruction_prefix_wide_lo = Assembler::REX, + instruction_prefix_wide_hi = Assembler::REX_WRXB, instruction_code_xor = 0x33, instruction_extended_prefix = 0x0F, + instruction_code_mem2reg_movslq = 0x63, instruction_code_mem2reg_movzxb = 0xB6, instruction_code_mem2reg_movsxb = 0xBE, instruction_code_mem2reg_movzxw = 0xB7, instruction_code_mem2reg_movsxw = 0xBF, instruction_operandsize_prefix = 0x66, - instruction_code_reg2meml = 0x89, - instruction_code_mem2regl = 0x8b, + instruction_code_reg2mem = 0x89, + instruction_code_mem2reg = 0x8b, instruction_code_reg2memb = 0x88, instruction_code_mem2regb = 0x8a, instruction_code_float_s = 0xd9, @@ -282,73 +284,18 @@ class NativeMovRegMem: public NativeInstruction { next_instruction_offset = 4 }; - address instruction_address() const { - if (*addr_at(instruction_offset) == instruction_operandsize_prefix && - *addr_at(instruction_offset+1) != instruction_code_xmm_code) { - return addr_at(instruction_offset+1); // Not SSE instructions - } - else if (*addr_at(instruction_offset) == instruction_extended_prefix) { - return addr_at(instruction_offset+1); - } - else if (*addr_at(instruction_offset) == instruction_code_xor) { - return addr_at(instruction_offset+2); - } - else return addr_at(instruction_offset); - } + // helper + int instruction_start() const; - address next_instruction_address() const { - switch (*addr_at(instruction_offset)) { - case instruction_operandsize_prefix: - if (*addr_at(instruction_offset+1) == instruction_code_xmm_code) - return instruction_address() + instruction_size; // SSE instructions - case instruction_extended_prefix: - return instruction_address() + instruction_size + 1; - case instruction_code_reg2meml: - case instruction_code_mem2regl: - case instruction_code_reg2memb: - case instruction_code_mem2regb: - case instruction_code_xor: - return instruction_address() + instruction_size + 2; - default: - return instruction_address() + instruction_size; - } - } - int offset() const{ - if (*addr_at(instruction_offset) == instruction_operandsize_prefix && - *addr_at(instruction_offset+1) != instruction_code_xmm_code) { - return int_at(data_offset+1); // Not SSE instructions - } - else if (*addr_at(instruction_offset) == instruction_extended_prefix) { - return int_at(data_offset+1); - } - else if (*addr_at(instruction_offset) == instruction_code_xor || - *addr_at(instruction_offset) == instruction_code_xmm_ss_prefix || - *addr_at(instruction_offset) == instruction_code_xmm_sd_prefix || - *addr_at(instruction_offset) == instruction_operandsize_prefix) { - return int_at(data_offset+2); - } - else return int_at(data_offset); - } + address instruction_address() const; - void set_offset(int x) { - if (*addr_at(instruction_offset) == instruction_operandsize_prefix && - *addr_at(instruction_offset+1) != instruction_code_xmm_code) { - set_int_at(data_offset+1, x); // Not SSE instructions - } - else if (*addr_at(instruction_offset) == instruction_extended_prefix) { - set_int_at(data_offset+1, x); - } - else if (*addr_at(instruction_offset) == instruction_code_xor || - *addr_at(instruction_offset) == instruction_code_xmm_ss_prefix || - *addr_at(instruction_offset) == instruction_code_xmm_sd_prefix || - *addr_at(instruction_offset) == instruction_operandsize_prefix) { - set_int_at(data_offset+2, x); - } - else set_int_at(data_offset, x); - } + address next_instruction_address() const; + + int offset() const; + + void set_offset(int x); void add_offset_in_bytes(int add_offset) { set_offset ( ( offset() + add_offset ) ); } - void copy_instruction_to(address new_instruction_address); void verify(); void print (); @@ -385,9 +332,19 @@ class NativeMovRegMemPatching: public NativeMovRegMem { // leal reg, [reg + offset] class NativeLoadAddress: public NativeMovRegMem { +#ifdef AMD64 + static const bool has_rex = true; + static const int rex_size = 1; +#else + static const bool has_rex = false; + static const int rex_size = 0; +#endif // AMD64 public: enum Intel_specific_constants { - instruction_code = 0x8D + instruction_prefix_wide = Assembler::REX_W, + instruction_prefix_wide_extended = Assembler::REX_WB, + lea_instruction_code = 0x8D, + mov64_instruction_code = 0xB8 }; void verify(); @@ -406,8 +363,6 @@ class NativeLoadAddress: public NativeMovRegMem { } }; -#endif // AMD64 - // jump rel32off class NativeJump: public NativeInstruction { @@ -424,22 +379,23 @@ class NativeJump: public NativeInstruction { address next_instruction_address() const { return addr_at(next_instruction_offset); } address jump_destination() const { address dest = (int_at(data_offset)+next_instruction_address()); -#ifdef AMD64 // What is this about? + // 32bit used to encode unresolved jmp as jmp -1 + // 64bit can't produce this so it used jump to self. + // Now 32bit and 64bit use jump to self as the unresolved address + // which the inline cache code (and relocs) know about + // return -1 if jump to self dest = (dest == (address) this) ? (address) -1 : dest; -#endif // AMD64 return dest; } void set_jump_destination(address dest) { intptr_t val = dest - next_instruction_address(); -#ifdef AMD64 - if (dest == (address) -1) { // can't encode jump to -1 + if (dest == (address) -1) { val = -5; // jump to self - } else { - assert((labs(val) & 0xFFFFFFFF00000000) == 0, - "must be 32bit offset"); } +#ifdef AMD64 + assert((labs(val) & 0xFFFFFFFF00000000) == 0 || dest == (address)-1, "must be 32bit offset or -1"); #endif // AMD64 set_int_at(data_offset, (jint)val); } @@ -568,11 +524,15 @@ inline bool NativeInstruction::is_cond_jump() { return (int_at(0) & 0xF0FF) = (ubyte_at(0) & 0xF0) == 0x70; /* short jump */ } inline bool NativeInstruction::is_safepoint_poll() { #ifdef AMD64 - return ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl && - ubyte_at(1) == 0x05 && // 00 rax 101 - ((intptr_t) addr_at(6)) + int_at(2) == (intptr_t) os::get_polling_page(); + if ( ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl && + ubyte_at(1) == 0x05 ) { // 00 rax 101 + address fault = addr_at(6) + int_at(2); + return os::is_poll_address(fault); + } else { + return false; + } #else - return ( ubyte_at(0) == NativeMovRegMem::instruction_code_mem2regl || + return ( ubyte_at(0) == NativeMovRegMem::instruction_code_mem2reg || ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl ) && (ubyte_at(1)&0xC7) == 0x05 && /* Mod R/M == disp32 */ (os::is_poll_address((address)int_at(2))); diff --git a/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp b/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp index 055c237149b..4f49d14bb42 100644 --- a/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp +++ b/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp @@ -30,11 +30,11 @@ void Relocation::pd_set_data_value(address x, intptr_t o) { #ifdef AMD64 x += o; typedef Assembler::WhichOperand WhichOperand; - WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm64, call32, narrow oop + WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm, call32, narrow oop assert(which == Assembler::disp32_operand || which == Assembler::narrow_oop_operand || - which == Assembler::imm64_operand, "format unpacks ok"); - if (which == Assembler::imm64_operand) { + which == Assembler::imm_operand, "format unpacks ok"); + if (which == Assembler::imm_operand) { *pd_address_in_code() = x; } else if (which == Assembler::narrow_oop_operand) { address disp = Assembler::locate_operand(addr(), which); @@ -81,11 +81,16 @@ void Relocation::pd_set_call_destination(address x) { nativeCall_at(addr())->set_destination(x); } else if (ni->is_jump()) { NativeJump* nj = nativeJump_at(addr()); -#ifdef AMD64 + + // Unresolved jumps are recognized by a destination of -1 + // However 64bit can't actually produce such an address + // and encodes a jump to self but jump_destination will + // return a -1 as the signal. We must not relocate this + // jmp or the ic code will not see it as unresolved. + if (nj->jump_destination() == (address) -1) { - x = (address) -1; // retain jump to self + x = addr(); // jump to self } -#endif // AMD64 nj->set_jump_destination(x); } else if (ni->is_cond_jump()) { // %%%% kludge this, for now, until we get a jump_destination method @@ -106,19 +111,19 @@ address* Relocation::pd_address_in_code() { // we must parse the instruction a bit to find the embedded word. assert(is_data(), "must be a DataRelocation"); typedef Assembler::WhichOperand WhichOperand; - WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm64/imm32 + WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm/imm32 #ifdef AMD64 assert(which == Assembler::disp32_operand || which == Assembler::call32_operand || - which == Assembler::imm64_operand, "format unpacks ok"); - if (which != Assembler::imm64_operand) { + which == Assembler::imm_operand, "format unpacks ok"); + if (which != Assembler::imm_operand) { // The "address" in the code is a displacement can't return it as // and address* since it is really a jint* ShouldNotReachHere(); return NULL; } #else - assert(which == Assembler::disp32_operand || which == Assembler::imm32_operand, "format unpacks ok"); + assert(which == Assembler::disp32_operand || which == Assembler::imm_operand, "format unpacks ok"); #endif // AMD64 return (address*) Assembler::locate_operand(addr(), which); } @@ -131,11 +136,11 @@ address Relocation::pd_get_address_from_code() { // we must parse the instruction a bit to find the embedded word. assert(is_data(), "must be a DataRelocation"); typedef Assembler::WhichOperand WhichOperand; - WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm64/imm32 + WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm/imm32 assert(which == Assembler::disp32_operand || which == Assembler::call32_operand || - which == Assembler::imm64_operand, "format unpacks ok"); - if (which != Assembler::imm64_operand) { + which == Assembler::imm_operand, "format unpacks ok"); + if (which != Assembler::imm_operand) { address ip = addr(); address disp = Assembler::locate_operand(ip, which); address next_ip = Assembler::locate_next_instruction(ip); @@ -169,3 +174,44 @@ void Relocation::pd_swap_out_breakpoint(address x, short* instrs, int instrlen) NativeInstruction* ni = nativeInstruction_at(x); *(short*)ni->addr_at(0) = instrs[0]; } + +void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { +#ifdef _LP64 + typedef Assembler::WhichOperand WhichOperand; + WhichOperand which = (WhichOperand) format(); + // This format is imm but it is really disp32 + which = Assembler::disp32_operand; + address orig_addr = old_addr_for(addr(), src, dest); + NativeInstruction* oni = nativeInstruction_at(orig_addr); + int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which); + // This poll_addr is incorrect by the size of the instruction it is irrelevant + intptr_t poll_addr = (intptr_t)oni + *orig_disp; + + NativeInstruction* ni = nativeInstruction_at(addr()); + intptr_t new_disp = poll_addr - (intptr_t) ni; + + int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which); + * disp = (int32_t)new_disp; + +#endif // _LP64 +} + +void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { +#ifdef _LP64 + typedef Assembler::WhichOperand WhichOperand; + WhichOperand which = (WhichOperand) format(); + // This format is imm but it is really disp32 + which = Assembler::disp32_operand; + address orig_addr = old_addr_for(addr(), src, dest); + NativeInstruction* oni = nativeInstruction_at(orig_addr); + int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which); + // This poll_addr is incorrect by the size of the instruction it is irrelevant + intptr_t poll_addr = (intptr_t)oni + *orig_disp; + + NativeInstruction* ni = nativeInstruction_at(addr()); + intptr_t new_disp = poll_addr - (intptr_t) ni; + + int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which); + * disp = (int32_t)new_disp; +#endif // _LP64 +} diff --git a/hotspot/src/cpu/x86/vm/runtime_x86_32.cpp b/hotspot/src/cpu/x86/vm/runtime_x86_32.cpp index d8d190936b7..72870e11e07 100644 --- a/hotspot/src/cpu/x86/vm/runtime_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/runtime_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -78,18 +78,18 @@ void OptoRuntime::generate_exception_blob() { address start = __ pc(); - __ pushl(rdx); - __ subl(rsp, return_off * wordSize); // Prolog! + __ push(rdx); + __ subptr(rsp, return_off * wordSize); // Prolog! // rbp, location is implicitly known - __ movl(Address(rsp,rbp_off *wordSize),rbp); + __ movptr(Address(rsp,rbp_off *wordSize), rbp); // Store exception in Thread object. We cannot pass any arguments to the // handle_exception call, since we do not want to make any assumption // about the size of the frame where the exception happened in. __ get_thread(rcx); - __ movl(Address(rcx, JavaThread::exception_oop_offset()), rax); - __ movl(Address(rcx, JavaThread::exception_pc_offset()), rdx); + __ movptr(Address(rcx, JavaThread::exception_oop_offset()), rax); + __ movptr(Address(rcx, JavaThread::exception_pc_offset()), rdx); // This call does all the hard work. It checks if an exception handler // exists in the method. @@ -97,7 +97,7 @@ void OptoRuntime::generate_exception_blob() { // If not, it prepares for stack-unwinding, restoring the callee-save // registers of the frame being removed. // - __ movl(Address(rsp, thread_off * wordSize), rcx); // Thread is first argument + __ movptr(Address(rsp, thread_off * wordSize), rcx); // Thread is first argument __ set_last_Java_frame(rcx, noreg, noreg, NULL); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, OptoRuntime::handle_exception_C))); @@ -108,10 +108,10 @@ void OptoRuntime::generate_exception_blob() { __ reset_last_Java_frame(rcx, false, false); // Restore callee-saved registers - __ movl(rbp, Address(rsp, rbp_off * wordSize)); + __ movptr(rbp, Address(rsp, rbp_off * wordSize)); - __ addl(rsp, return_off * wordSize); // Epilog! - __ popl(rdx); // Exception pc + __ addptr(rsp, return_off * wordSize); // Epilog! + __ pop(rdx); // Exception pc // rax,: exception handler for given @@ -119,23 +119,23 @@ void OptoRuntime::generate_exception_blob() { // We have a handler in rax, (could be deopt blob) // rdx - throwing pc, deopt blob will need it. - __ pushl(rax); + __ push(rax); // rcx contains handler address __ get_thread(rcx); // TLS // Get the exception - __ movl(rax, Address(rcx, JavaThread::exception_oop_offset())); + __ movptr(rax, Address(rcx, JavaThread::exception_oop_offset())); // Get the exception pc in case we are deoptimized - __ movl(rdx, Address(rcx, JavaThread::exception_pc_offset())); + __ movptr(rdx, Address(rcx, JavaThread::exception_pc_offset())); #ifdef ASSERT - __ movl(Address(rcx, JavaThread::exception_handler_pc_offset()), 0); - __ movl(Address(rcx, JavaThread::exception_pc_offset()), 0); + __ movptr(Address(rcx, JavaThread::exception_handler_pc_offset()), (int32_t)NULL_WORD); + __ movptr(Address(rcx, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); #endif // Clear the exception oop so GC no longer processes it as a root. - __ movl(Address(rcx, JavaThread::exception_oop_offset()), 0); + __ movptr(Address(rcx, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD); - __ popl(rcx); + __ pop(rcx); // rax,: exception oop // rcx: exception handler diff --git a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp index 85befcf4e78..7c0aa6bf556 100644 --- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp @@ -118,12 +118,12 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_ // save registers, fpu state, and flags // We assume caller has already has return address slot on the stack // We push epb twice in this sequence because we want the real rbp, - // to be under the return like a normal enter and we want to use pushad + // to be under the return like a normal enter and we want to use pusha // We push by hand instead of pusing push __ enter(); - __ pushad(); - __ pushfd(); - __ subl(rsp,FPU_regs_live*sizeof(jdouble)); // Push FPU registers space + __ pusha(); + __ pushf(); + __ subptr(rsp,FPU_regs_live*sizeof(jdouble)); // Push FPU registers space __ push_FPU_state(); // Save FPU state & init if (verify_fpu) { @@ -270,12 +270,12 @@ void RegisterSaver::restore_live_registers(MacroAssembler* masm) { __ movdbl(xmm7,Address(rsp,xmm7_off*wordSize)); } __ pop_FPU_state(); - __ addl(rsp,FPU_regs_live*sizeof(jdouble)); // Pop FPU registers + __ addptr(rsp, FPU_regs_live*sizeof(jdouble)); // Pop FPU registers - __ popfd(); - __ popad(); + __ popf(); + __ popa(); // Get the rbp, described implicitly by the frame sender code (no oopMap) - __ popl(rbp); + __ pop(rbp); } @@ -296,10 +296,10 @@ void RegisterSaver::restore_result_registers(MacroAssembler* masm) { } else if( UseSSE >= 2 ) { __ movdbl(xmm0, Address(rsp, xmm0_off*wordSize)); } - __ movl(rax, Address(rsp, rax_off*wordSize)); - __ movl(rdx, Address(rsp, rdx_off*wordSize)); + __ movptr(rax, Address(rsp, rax_off*wordSize)); + __ movptr(rdx, Address(rsp, rdx_off*wordSize)); // Pop all of the register save are off the stack except the return address - __ addl(rsp, return_off * wordSize); + __ addptr(rsp, return_off * wordSize); } // The java_calling_convention describes stack locations as ideal slots on @@ -448,22 +448,22 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, static void patch_callers_callsite(MacroAssembler *masm) { Label L; __ verify_oop(rbx); - __ cmpl(Address(rbx, in_bytes(methodOopDesc::code_offset())), NULL_WORD); + __ cmpptr(Address(rbx, in_bytes(methodOopDesc::code_offset())), (int32_t)NULL_WORD); __ jcc(Assembler::equal, L); // Schedule the branch target address early. // Call into the VM to patch the caller, then jump to compiled callee // rax, isn't live so capture return address while we easily can - __ movl(rax, Address(rsp, 0)); - __ pushad(); - __ pushfd(); + __ movptr(rax, Address(rsp, 0)); + __ pusha(); + __ pushf(); if (UseSSE == 1) { - __ subl(rsp, 2*wordSize); + __ subptr(rsp, 2*wordSize); __ movflt(Address(rsp, 0), xmm0); __ movflt(Address(rsp, wordSize), xmm1); } if (UseSSE >= 2) { - __ subl(rsp, 4*wordSize); + __ subptr(rsp, 4*wordSize); __ movdbl(Address(rsp, 0), xmm0); __ movdbl(Address(rsp, 2*wordSize), xmm1); } @@ -477,26 +477,26 @@ static void patch_callers_callsite(MacroAssembler *masm) { #endif /* COMPILER2 */ // VM needs caller's callsite - __ pushl(rax); + __ push(rax); // VM needs target method - __ pushl(rbx); + __ push(rbx); __ verify_oop(rbx); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite))); - __ addl(rsp, 2*wordSize); + __ addptr(rsp, 2*wordSize); if (UseSSE == 1) { __ movflt(xmm0, Address(rsp, 0)); __ movflt(xmm1, Address(rsp, wordSize)); - __ addl(rsp, 2*wordSize); + __ addptr(rsp, 2*wordSize); } if (UseSSE >= 2) { __ movdbl(xmm0, Address(rsp, 0)); __ movdbl(xmm1, Address(rsp, 2*wordSize)); - __ addl(rsp, 4*wordSize); + __ addptr(rsp, 4*wordSize); } - __ popfd(); - __ popad(); + __ popf(); + __ popa(); __ bind(L); } @@ -506,13 +506,13 @@ static void tag_stack(MacroAssembler *masm, const BasicType sig, int st_off) { if (TaggedStackInterpreter) { int tag_offset = st_off + Interpreter::expr_tag_offset_in_bytes(0); if (sig == T_OBJECT || sig == T_ARRAY) { - __ movl(Address(rsp, tag_offset), frame::TagReference); + __ movptr(Address(rsp, tag_offset), frame::TagReference); } else if (sig == T_LONG || sig == T_DOUBLE) { int next_tag_offset = st_off + Interpreter::expr_tag_offset_in_bytes(1); - __ movl(Address(rsp, next_tag_offset), frame::TagValue); - __ movl(Address(rsp, tag_offset), frame::TagValue); + __ movptr(Address(rsp, next_tag_offset), frame::TagValue); + __ movptr(Address(rsp, tag_offset), frame::TagValue); } else { - __ movl(Address(rsp, tag_offset), frame::TagValue); + __ movptr(Address(rsp, tag_offset), frame::TagValue); } } } @@ -561,12 +561,12 @@ static void gen_c2i_adapter(MacroAssembler *masm, int extraspace = total_args_passed * Interpreter::stackElementSize(); // Get return address - __ popl(rax); + __ pop(rax); // set senderSP value - __ movl(rsi, rsp); + __ movptr(rsi, rsp); - __ subl(rsp, extraspace); + __ subptr(rsp, extraspace); // Now write the args into the outgoing interpreter space for (int i = 0; i < total_args_passed; i++) { @@ -577,6 +577,8 @@ static void gen_c2i_adapter(MacroAssembler *masm, // st_off points to lowest address on stack. int st_off = ((total_args_passed - 1) - i) * Interpreter::stackElementSize(); + int next_off = st_off - Interpreter::stackElementSize(); + // Say 4 args: // i st_off // 0 12 T_LONG @@ -596,18 +598,25 @@ static void gen_c2i_adapter(MacroAssembler *masm, if (!r_2->is_valid()) { __ movl(rdi, Address(rsp, ld_off)); - __ movl(Address(rsp, st_off), rdi); + __ movptr(Address(rsp, st_off), rdi); tag_stack(masm, sig_bt[i], st_off); } else { // ld_off == LSW, ld_off+VMRegImpl::stack_slot_size == MSW // st_off == MSW, st_off-wordSize == LSW - int next_off = st_off - Interpreter::stackElementSize(); - __ movl(rdi, Address(rsp, ld_off)); - __ movl(Address(rsp, next_off), rdi); - __ movl(rdi, Address(rsp, ld_off + wordSize)); - __ movl(Address(rsp, st_off), rdi); + __ movptr(rdi, Address(rsp, ld_off)); + __ movptr(Address(rsp, next_off), rdi); +#ifndef _LP64 + __ movptr(rdi, Address(rsp, ld_off + wordSize)); + __ movptr(Address(rsp, st_off), rdi); +#else +#ifdef ASSERT + // Overwrite the unused slot with known junk + __ mov64(rax, CONST64(0xdeadffffdeadaaaa)); + __ movptr(Address(rsp, st_off), rax); +#endif /* ASSERT */ +#endif // _LP64 tag_stack(masm, sig_bt[i], next_off); } } else if (r_1->is_Register()) { @@ -617,7 +626,22 @@ static void gen_c2i_adapter(MacroAssembler *masm, tag_stack(masm, sig_bt[i], st_off); } else { // long/double in gpr - ShouldNotReachHere(); + NOT_LP64(ShouldNotReachHere()); + // Two VMRegs can be T_OBJECT, T_ADDRESS, T_DOUBLE, T_LONG + // T_DOUBLE and T_LONG use two slots in the interpreter + if ( sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) { + // long/double in gpr +#ifdef ASSERT + // Overwrite the unused slot with known junk + LP64_ONLY(__ mov64(rax, CONST64(0xdeadffffdeadaaab))); + __ movptr(Address(rsp, st_off), rax); +#endif /* ASSERT */ + __ movptr(Address(rsp, next_off), r); + tag_stack(masm, sig_bt[i], next_off); + } else { + __ movptr(Address(rsp, st_off), r); + tag_stack(masm, sig_bt[i], st_off); + } } } else { assert(r_1->is_XMMRegister(), ""); @@ -632,9 +656,9 @@ static void gen_c2i_adapter(MacroAssembler *masm, } // Schedule the branch target address early. - __ movl(rcx, Address(rbx, in_bytes(methodOopDesc::interpreter_entry_offset()))); + __ movptr(rcx, Address(rbx, in_bytes(methodOopDesc::interpreter_entry_offset()))); // And repush original return address - __ pushl(rax); + __ push(rax); __ jmp(rcx); } @@ -645,11 +669,11 @@ static void move_i2c_double(MacroAssembler *masm, XMMRegister r, Register saved_ int next_val_off = ld_off - Interpreter::stackElementSize(); if (TaggedStackInterpreter) { // use tag slot temporarily for MSW - __ movl(rsi, Address(saved_sp, ld_off)); - __ movl(Address(saved_sp, next_val_off+wordSize), rsi); + __ movptr(rsi, Address(saved_sp, ld_off)); + __ movptr(Address(saved_sp, next_val_off+wordSize), rsi); __ movdbl(r, Address(saved_sp, next_val_off)); // restore tag - __ movl(Address(saved_sp, next_val_off+wordSize), frame::TagValue); + __ movptr(Address(saved_sp, next_val_off+wordSize), frame::TagValue); } else { __ movdbl(r, Address(saved_sp, next_val_off)); } @@ -685,7 +709,7 @@ static void gen_i2c_adapter(MacroAssembler *masm, // code goes non-entrant while we get args ready. // Pick up the return address - __ movl(rax, Address(rsp, 0)); + __ movptr(rax, Address(rsp, 0)); // If UseSSE >= 2 then no cleanup is needed on the return to the // interpreter so skip fixing up the return entry point unless @@ -696,10 +720,10 @@ static void gen_i2c_adapter(MacroAssembler *masm, // cleanup than if the interpreter returned to the call stub. ExternalAddress stub_return_address(StubRoutines::_call_stub_return_address); - __ cmp32(rax, stub_return_address.addr()); + __ cmpptr(rax, stub_return_address.addr()); __ jcc(Assembler::notEqual, chk_int); - assert(StubRoutines::i486::get_call_stub_compiled_return() != NULL, "must be set"); - __ lea(rax, ExternalAddress(StubRoutines::i486::get_call_stub_compiled_return())); + assert(StubRoutines::x86::get_call_stub_compiled_return() != NULL, "must be set"); + __ lea(rax, ExternalAddress(StubRoutines::x86::get_call_stub_compiled_return())); __ jmp(skip); // It must be the interpreter since we never get here via a c2i (unlike Azul) @@ -708,13 +732,13 @@ static void gen_i2c_adapter(MacroAssembler *masm, #ifdef ASSERT { Label ok; - __ cmpl(Address(rax, -8), Interpreter::return_sentinel); + __ cmpl(Address(rax, -2*wordSize), Interpreter::return_sentinel); __ jcc(Assembler::equal, ok); __ int3(); __ bind(ok); } #endif // ASSERT - __ movl(rax, Address(rax, -4)); + __ movptr(rax, Address(rax, -wordSize)); __ bind(skip); } @@ -723,7 +747,7 @@ static void gen_i2c_adapter(MacroAssembler *masm, // Must preserve original SP for loading incoming arguments because // we need to align the outgoing SP for compiled code. - __ movl(rdi, rsp); + __ movptr(rdi, rsp); // Cut-out for having no stack args. Since up to 2 int/oop args are passed // in registers, we will occasionally have no stack args. @@ -737,24 +761,24 @@ static void gen_i2c_adapter(MacroAssembler *masm, comp_words_on_stack = round_to(comp_args_on_stack*4, wordSize)>>LogBytesPerWord; // Round up to miminum stack alignment, in wordSize comp_words_on_stack = round_to(comp_words_on_stack, 2); - __ subl(rsp, comp_words_on_stack * wordSize); + __ subptr(rsp, comp_words_on_stack * wordSize); } // Align the outgoing SP - __ andl(rsp, -(StackAlignmentInBytes)); + __ andptr(rsp, -(StackAlignmentInBytes)); // push the return address on the stack (note that pushing, rather // than storing it, yields the correct frame alignment for the callee) - __ pushl(rax); + __ push(rax); // Put saved SP in another register const Register saved_sp = rax; - __ movl(saved_sp, rdi); + __ movptr(saved_sp, rdi); // Will jump to the compiled code just as if compiled code was doing it. // Pre-load the register-jump target early, to schedule it better. - __ movl(rdi, Address(rbx, in_bytes(methodOopDesc::from_compiled_offset()))); + __ movptr(rdi, Address(rbx, in_bytes(methodOopDesc::from_compiled_offset()))); // Now generate the shuffle code. Pick up all register args and move the // rest through the floating point stack top. @@ -794,7 +818,7 @@ static void gen_i2c_adapter(MacroAssembler *masm, // __ fld_s(Address(saved_sp, ld_off)); // __ fstp_s(Address(rsp, st_off)); __ movl(rsi, Address(saved_sp, ld_off)); - __ movl(Address(rsp, st_off), rsi); + __ movptr(Address(rsp, st_off), rsi); } else { // Interpreter local[n] == MSW, local[n+1] == LSW however locals // are accessed as negative so LSW is at LOW address @@ -803,20 +827,44 @@ static void gen_i2c_adapter(MacroAssembler *masm, // st_off is LSW (i.e. reg.first()) // __ fld_d(Address(saved_sp, next_off)); // __ fstp_d(Address(rsp, st_off)); - __ movl(rsi, Address(saved_sp, next_off)); - __ movl(Address(rsp, st_off), rsi); - __ movl(rsi, Address(saved_sp, ld_off)); - __ movl(Address(rsp, st_off + wordSize), rsi); + // + // We are using two VMRegs. This can be either T_OBJECT, T_ADDRESS, T_LONG, or T_DOUBLE + // the interpreter allocates two slots but only uses one for thr T_LONG or T_DOUBLE case + // So we must adjust where to pick up the data to match the interpreter. + // + // Interpreter local[n] == MSW, local[n+1] == LSW however locals + // are accessed as negative so LSW is at LOW address + + // ld_off is MSW so get LSW + const int offset = (NOT_LP64(true ||) sig_bt[i]==T_LONG||sig_bt[i]==T_DOUBLE)? + next_off : ld_off; + __ movptr(rsi, Address(saved_sp, offset)); + __ movptr(Address(rsp, st_off), rsi); +#ifndef _LP64 + __ movptr(rsi, Address(saved_sp, ld_off)); + __ movptr(Address(rsp, st_off + wordSize), rsi); +#endif // _LP64 } } else if (r_1->is_Register()) { // Register argument Register r = r_1->as_Register(); assert(r != rax, "must be different"); if (r_2->is_valid()) { + // + // We are using two VMRegs. This can be either T_OBJECT, T_ADDRESS, T_LONG, or T_DOUBLE + // the interpreter allocates two slots but only uses one for thr T_LONG or T_DOUBLE case + // So we must adjust where to pick up the data to match the interpreter. + + const int offset = (NOT_LP64(true ||) sig_bt[i]==T_LONG||sig_bt[i]==T_DOUBLE)? + next_off : ld_off; + + // this can be a misaligned move + __ movptr(r, Address(saved_sp, offset)); +#ifndef _LP64 assert(r_2->as_Register() != rax, "need another temporary register"); // Remember r_1 is low address (and LSB on x86) // So r_2 gets loaded from high address regardless of the platform - __ movl(r_2->as_Register(), Address(saved_sp, ld_off)); - __ movl(r, Address(saved_sp, next_off)); + __ movptr(r_2->as_Register(), Address(saved_sp, ld_off)); +#endif // _LP64 } else { __ movl(r, Address(saved_sp, ld_off)); } @@ -841,13 +889,13 @@ static void gen_i2c_adapter(MacroAssembler *masm, // and the vm will find there should this case occur. __ get_thread(rax); - __ movl(Address(rax, JavaThread::callee_target_offset()), rbx); + __ movptr(Address(rax, JavaThread::callee_target_offset()), rbx); // move methodOop to rax, in case we end up in an c2i adapter. // the c2i adapters expect methodOop in rax, (c2) because c2's // resolve stubs return the result (the method) in rax,. // I'd love to fix this. - __ movl(rax, rbx); + __ mov(rax, rbx); __ jmp(rdi); } @@ -883,16 +931,16 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm Label missed; __ verify_oop(holder); - __ movl(temp, Address(receiver, oopDesc::klass_offset_in_bytes())); + __ movptr(temp, Address(receiver, oopDesc::klass_offset_in_bytes())); __ verify_oop(temp); - __ cmpl(temp, Address(holder, compiledICHolderOopDesc::holder_klass_offset())); - __ movl(rbx, Address(holder, compiledICHolderOopDesc::holder_method_offset())); + __ cmpptr(temp, Address(holder, compiledICHolderOopDesc::holder_klass_offset())); + __ movptr(rbx, Address(holder, compiledICHolderOopDesc::holder_method_offset())); __ jcc(Assembler::notEqual, missed); // Method might have been compiled since the call site was patched to // interpreted if that is the case treat it as a miss so we can get // the call site corrected. - __ cmpl(Address(rbx, in_bytes(methodOopDesc::code_offset())), NULL_WORD); + __ cmpptr(Address(rbx, in_bytes(methodOopDesc::code_offset())), (int32_t)NULL_WORD); __ jcc(Assembler::equal, skip_fixup); __ bind(missed); @@ -953,17 +1001,20 @@ static void simple_move32(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { // stack to stack // __ ld(FP, reg2offset(src.first()) + STACK_BIAS, L5); // __ st(L5, SP, reg2offset(dst.first()) + STACK_BIAS); - __ movl(rax, Address(rbp, reg2offset_in(src.first()))); - __ movl(Address(rsp, reg2offset_out(dst.first())), rax); + __ movl2ptr(rax, Address(rbp, reg2offset_in(src.first()))); + __ movptr(Address(rsp, reg2offset_out(dst.first())), rax); } else { // stack to reg - __ movl(dst.first()->as_Register(), Address(rbp, reg2offset_in(src.first()))); + __ movl2ptr(dst.first()->as_Register(), Address(rbp, reg2offset_in(src.first()))); } } else if (dst.first()->is_stack()) { // reg to stack - __ movl(Address(rsp, reg2offset_out(dst.first())), src.first()->as_Register()); + // no need to sign extend on 64bit + __ movptr(Address(rsp, reg2offset_out(dst.first())), src.first()->as_Register()); } else { - __ movl(dst.first()->as_Register(), src.first()->as_Register()); + if (dst.first() != src.first()) { + __ mov(dst.first()->as_Register(), src.first()->as_Register()); + } } } @@ -987,12 +1038,12 @@ static void object_move(MacroAssembler* masm, // Oop is already on the stack as an argument Register rHandle = rax; Label nil; - __ xorl(rHandle, rHandle); - __ cmpl(Address(rbp, reg2offset_in(src.first())), NULL_WORD); + __ xorptr(rHandle, rHandle); + __ cmpptr(Address(rbp, reg2offset_in(src.first())), (int32_t)NULL_WORD); __ jcc(Assembler::equal, nil); - __ leal(rHandle, Address(rbp, reg2offset_in(src.first()))); + __ lea(rHandle, Address(rbp, reg2offset_in(src.first()))); __ bind(nil); - __ movl(Address(rsp, reg2offset_out(dst.first())), rHandle); + __ movptr(Address(rsp, reg2offset_out(dst.first())), rHandle); int offset_in_older_frame = src.first()->reg2stack() + SharedRuntime::out_preserve_stack_slots(); map->set_oop(VMRegImpl::stack2reg(offset_in_older_frame + framesize_in_slots)); @@ -1007,15 +1058,15 @@ static void object_move(MacroAssembler* masm, int oop_slot = (rOop == rcx ? 0 : 1) * VMRegImpl::slots_per_word + oop_handle_offset; int offset = oop_slot*VMRegImpl::stack_slot_size; Label skip; - __ movl(Address(rsp, offset), rOop); + __ movptr(Address(rsp, offset), rOop); map->set_oop(VMRegImpl::stack2reg(oop_slot)); - __ xorl(rHandle, rHandle); - __ cmpl(rOop, NULL_WORD); + __ xorptr(rHandle, rHandle); + __ cmpptr(rOop, (int32_t)NULL_WORD); __ jcc(Assembler::equal, skip); - __ leal(rHandle, Address(rsp, offset)); + __ lea(rHandle, Address(rsp, offset)); __ bind(skip); // Store the handle parameter - __ movl(Address(rsp, reg2offset_out(dst.first())), rHandle); + __ movptr(Address(rsp, reg2offset_out(dst.first())), rHandle); if (is_receiver) { *receiver_offset = offset; } @@ -1033,7 +1084,7 @@ static void float_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { if (src.first()->is_stack()) { __ movl(rax, Address(rbp, reg2offset_in(src.first()))); - __ movl(Address(rsp, reg2offset_out(dst.first())), rax); + __ movptr(Address(rsp, reg2offset_out(dst.first())), rax); } else { // reg to stack __ movflt(Address(rsp, reg2offset_out(dst.first())), src.first()->as_XMMRegister()); @@ -1050,10 +1101,10 @@ static void long_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { if (src.first()->is_stack() && dst.first()->is_stack()) { assert(src.second()->is_stack() && dst.second()->is_stack(), "must be all stack"); - __ movl(rax, Address(rbp, reg2offset_in(src.first()))); - __ movl(rbx, Address(rbp, reg2offset_in(src.second()))); - __ movl(Address(rsp, reg2offset_out(dst.first())), rax); - __ movl(Address(rsp, reg2offset_out(dst.second())), rbx); + __ movptr(rax, Address(rbp, reg2offset_in(src.first()))); + NOT_LP64(__ movptr(rbx, Address(rbp, reg2offset_in(src.second())))); + __ movptr(Address(rsp, reg2offset_out(dst.first())), rax); + NOT_LP64(__ movptr(Address(rsp, reg2offset_out(dst.second())), rbx)); } else { ShouldNotReachHere(); } @@ -1074,10 +1125,10 @@ static void double_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { if (src.first()->is_stack()) { // source is all stack - __ movl(rax, Address(rbp, reg2offset_in(src.first()))); - __ movl(rbx, Address(rbp, reg2offset_in(src.second()))); - __ movl(Address(rsp, reg2offset_out(dst.first())), rax); - __ movl(Address(rsp, reg2offset_out(dst.second())), rbx); + __ movptr(rax, Address(rbp, reg2offset_in(src.first()))); + NOT_LP64(__ movptr(rbx, Address(rbp, reg2offset_in(src.second())))); + __ movptr(Address(rsp, reg2offset_out(dst.first())), rax); + NOT_LP64(__ movptr(Address(rsp, reg2offset_out(dst.second())), rbx)); } else { // reg to stack // No worries about stack alignment @@ -1098,11 +1149,11 @@ void SharedRuntime::save_native_result(MacroAssembler *masm, BasicType ret_type, break; case T_VOID: break; case T_LONG: - __ movl(Address(rbp, -wordSize), rax); - __ movl(Address(rbp, -2*wordSize), rdx); + __ movptr(Address(rbp, -wordSize), rax); + NOT_LP64(__ movptr(Address(rbp, -2*wordSize), rdx)); break; default: { - __ movl(Address(rbp, -wordSize), rax); + __ movptr(Address(rbp, -wordSize), rax); } } } @@ -1118,12 +1169,12 @@ void SharedRuntime::restore_native_result(MacroAssembler *masm, BasicType ret_ty __ fld_d(Address(rbp, -2*wordSize)); break; case T_LONG: - __ movl(rax, Address(rbp, -wordSize)); - __ movl(rdx, Address(rbp, -2*wordSize)); + __ movptr(rax, Address(rbp, -wordSize)); + NOT_LP64(__ movptr(rdx, Address(rbp, -2*wordSize))); break; case T_VOID: break; default: { - __ movl(rax, Address(rbp, -wordSize)); + __ movptr(rax, Address(rbp, -wordSize)); } } } @@ -1268,7 +1319,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, __ verify_oop(receiver); - __ cmpl(ic_reg, Address(receiver, oopDesc::klass_offset_in_bytes())); + __ cmpptr(ic_reg, Address(receiver, oopDesc::klass_offset_in_bytes())); __ jcc(Assembler::equal, hit); __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); @@ -1291,23 +1342,23 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, Label slowCase; Register receiver = rcx; Register result = rax; - __ movl(result, Address(receiver, oopDesc::mark_offset_in_bytes())); + __ movptr(result, Address(receiver, oopDesc::mark_offset_in_bytes())); // check if locked - __ testl (result, markOopDesc::unlocked_value); + __ testptr(result, markOopDesc::unlocked_value); __ jcc (Assembler::zero, slowCase); if (UseBiasedLocking) { // Check if biased and fall through to runtime if so - __ testl (result, markOopDesc::biased_lock_bit_in_place); + __ testptr(result, markOopDesc::biased_lock_bit_in_place); __ jcc (Assembler::notZero, slowCase); } // get hash - __ andl (result, markOopDesc::hash_mask_in_place); + __ andptr(result, markOopDesc::hash_mask_in_place); // test if hashCode exists __ jcc (Assembler::zero, slowCase); - __ shrl (result, markOopDesc::hash_shift); + __ shrptr(result, markOopDesc::hash_shift); __ ret(0); __ bind (slowCase); } @@ -1329,7 +1380,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // Generate a new frame for the wrapper. __ enter(); // -2 because return address is already present and so is saved rbp, - __ subl(rsp, stack_size - 2*wordSize); + __ subptr(rsp, stack_size - 2*wordSize); // Frame is now completed as far a size and linkage. @@ -1450,13 +1501,13 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, __ movoop(oop_handle_reg, JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror())); // Now handlize the static class mirror it's known not-null. - __ movl(Address(rsp, klass_offset), oop_handle_reg); + __ movptr(Address(rsp, klass_offset), oop_handle_reg); map->set_oop(VMRegImpl::stack2reg(klass_slot_offset)); // Now get the handle - __ leal(oop_handle_reg, Address(rsp, klass_offset)); + __ lea(oop_handle_reg, Address(rsp, klass_offset)); // store the klass handle as second argument - __ movl(Address(rsp, wordSize), oop_handle_reg); + __ movptr(Address(rsp, wordSize), oop_handle_reg); } // Change state to native (we save the return address in the thread, since it might not @@ -1497,14 +1548,14 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, const int mark_word_offset = BasicLock::displaced_header_offset_in_bytes(); // Get the handle (the 2nd argument) - __ movl(oop_handle_reg, Address(rsp, wordSize)); + __ movptr(oop_handle_reg, Address(rsp, wordSize)); // Get address of the box - __ leal(lock_reg, Address(rbp, lock_slot_rbp_offset)); + __ lea(lock_reg, Address(rbp, lock_slot_rbp_offset)); // Load the oop from the handle - __ movl(obj_reg, Address(oop_handle_reg, 0)); + __ movptr(obj_reg, Address(oop_handle_reg, 0)); if (UseBiasedLocking) { // Note that oop_handle_reg is trashed during this call @@ -1512,13 +1563,13 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, } // Load immediate 1 into swap_reg %rax, - __ movl(swap_reg, 1); + __ movptr(swap_reg, 1); // Load (object->mark() | 1) into swap_reg %rax, - __ orl(swap_reg, Address(obj_reg, 0)); + __ orptr(swap_reg, Address(obj_reg, 0)); // Save (object->mark() | 1) into BasicLock's displaced header - __ movl(Address(lock_reg, mark_word_offset), swap_reg); + __ movptr(Address(lock_reg, mark_word_offset), swap_reg); if (os::is_MP()) { __ lock(); @@ -1526,7 +1577,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // src -> dest iff dest == rax, else rax, <- dest // *obj_reg = lock_reg iff *obj_reg == rax, else rax, = *(obj_reg) - __ cmpxchg(lock_reg, Address(obj_reg, 0)); + __ cmpxchgptr(lock_reg, Address(obj_reg, 0)); __ jcc(Assembler::equal, lock_done); // Test if the oopMark is an obvious stack pointer, i.e., @@ -1538,18 +1589,18 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // least significant 2 bits clear. // NOTE: the oopMark is in swap_reg %rax, as the result of cmpxchg - __ subl(swap_reg, rsp); - __ andl(swap_reg, 3 - os::vm_page_size()); + __ subptr(swap_reg, rsp); + __ andptr(swap_reg, 3 - os::vm_page_size()); // Save the test result, for recursive case, the result is zero - __ movl(Address(lock_reg, mark_word_offset), swap_reg); + __ movptr(Address(lock_reg, mark_word_offset), swap_reg); __ jcc(Assembler::notEqual, slow_path_lock); // Slow path will re-enter here __ bind(lock_done); if (UseBiasedLocking) { // Re-fetch oop_handle_reg as we trashed it above - __ movl(oop_handle_reg, Address(rsp, wordSize)); + __ movptr(oop_handle_reg, Address(rsp, wordSize)); } } @@ -1559,8 +1610,8 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // get JNIEnv* which is first argument to native - __ leal(rdx, Address(thread, in_bytes(JavaThread::jni_environment_offset()))); - __ movl(Address(rsp, 0), rdx); + __ 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); @@ -1575,7 +1626,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // Unpack native results. switch (ret_type) { case T_BOOLEAN: __ c2bool(rax); break; - case T_CHAR : __ andl(rax, 0xFFFF); break; + case T_CHAR : __ andptr(rax, 0xFFFF); break; case T_BYTE : __ sign_extend_byte (rax); break; case T_SHORT : __ sign_extend_short(rax); break; case T_INT : /* nothing to do */ break; @@ -1602,7 +1653,10 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, if(os::is_MP()) { if (UseMembar) { - __ membar(); // Force this write out before the read below + // Force this write out before the read below + __ membar(Assembler::Membar_mask_bits( + Assembler::LoadLoad | Assembler::LoadStore | + Assembler::StoreLoad | Assembler::StoreStore)); } else { // Write serialization page so VM thread can do a pseudo remote membar. // We use the current thread pointer to calculate a thread specific @@ -1636,7 +1690,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // by hand. // save_native_result(masm, ret_type, stack_slots); - __ pushl(thread); + __ push(thread); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans))); __ increment(rsp, wordSize); @@ -1669,7 +1723,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, Label done; // Get locked oop from the handle we passed to jni - __ movl(obj_reg, Address(oop_handle_reg, 0)); + __ movptr(obj_reg, Address(oop_handle_reg, 0)); if (UseBiasedLocking) { __ biased_locking_exit(obj_reg, rbx, done); @@ -1677,7 +1731,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // Simple recursive lock? - __ cmpl(Address(rbp, lock_slot_rbp_offset), NULL_WORD); + __ cmpptr(Address(rbp, lock_slot_rbp_offset), (int32_t)NULL_WORD); __ jcc(Assembler::equal, done); // Must save rax, if if it is live now because cmpxchg must use it @@ -1686,10 +1740,10 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, } // get old displaced header - __ movl(rbx, Address(rbp, lock_slot_rbp_offset)); + __ movptr(rbx, Address(rbp, lock_slot_rbp_offset)); // get address of the stack lock - __ leal(rax, Address(rbp, lock_slot_rbp_offset)); + __ lea(rax, Address(rbp, lock_slot_rbp_offset)); // Atomic swap old header if oop still contains the stack lock if (os::is_MP()) { @@ -1698,7 +1752,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // src -> dest iff dest == rax, else rax, <- dest // *obj_reg = rbx, iff *obj_reg == rax, else rax, = *(obj_reg) - __ cmpxchg(rbx, Address(obj_reg, 0)); + __ cmpxchgptr(rbx, Address(obj_reg, 0)); __ jcc(Assembler::notEqual, slow_path_unlock); // slow path re-enters here @@ -1729,20 +1783,20 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // Unpack oop result if (ret_type == T_OBJECT || ret_type == T_ARRAY) { Label L; - __ cmpl(rax, NULL_WORD); + __ cmpptr(rax, (int32_t)NULL_WORD); __ jcc(Assembler::equal, L); - __ movl(rax, Address(rax, 0)); + __ movptr(rax, Address(rax, 0)); __ bind(L); __ verify_oop(rax); } // reset handle block - __ movl(rcx, Address(thread, JavaThread::active_handles_offset())); + __ movptr(rcx, Address(thread, JavaThread::active_handles_offset())); - __ movl(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), 0); + __ movptr(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); // Any exception pending? - __ cmpl(Address(thread, in_bytes(Thread::pending_exception_offset())), NULL_WORD); + __ cmpptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); __ jcc(Assembler::notEqual, exception_pending); @@ -1782,15 +1836,15 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // has last_Java_frame setup. No exceptions so do vanilla call not call_VM // args are (oop obj, BasicLock* lock, JavaThread* thread) - __ pushl(thread); - __ pushl(lock_reg); - __ pushl(obj_reg); + __ push(thread); + __ push(lock_reg); + __ push(obj_reg); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_locking_C))); - __ addl(rsp, 3*wordSize); + __ addptr(rsp, 3*wordSize); #ifdef ASSERT { Label L; - __ cmpl(Address(thread, in_bytes(Thread::pending_exception_offset())), (int)NULL_WORD); + __ cmpptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int)NULL_WORD); __ jcc(Assembler::equal, L); __ stop("no pending exception allowed on exit from monitorenter"); __ bind(L); @@ -1810,29 +1864,29 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, } // Save pending exception around call to VM (which contains an EXCEPTION_MARK) - __ pushl(Address(thread, in_bytes(Thread::pending_exception_offset()))); - __ movl(Address(thread, in_bytes(Thread::pending_exception_offset())), NULL_WORD); + __ pushptr(Address(thread, in_bytes(Thread::pending_exception_offset()))); + __ movptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); // should be a peal // +wordSize because of the push above - __ leal(rax, Address(rbp, lock_slot_rbp_offset)); - __ pushl(rax); + __ lea(rax, Address(rbp, lock_slot_rbp_offset)); + __ push(rax); - __ pushl(obj_reg); + __ push(obj_reg); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C))); - __ addl(rsp, 2*wordSize); + __ addptr(rsp, 2*wordSize); #ifdef ASSERT { Label L; - __ cmpl(Address(thread, in_bytes(Thread::pending_exception_offset())), NULL_WORD); + __ cmpptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); __ jcc(Assembler::equal, L); __ stop("no pending exception allowed on exit complete_monitor_unlocking_C"); __ bind(L); } #endif /* ASSERT */ - __ popl(Address(thread, in_bytes(Thread::pending_exception_offset()))); + __ popptr(Address(thread, in_bytes(Thread::pending_exception_offset()))); if (ret_type == T_FLOAT || ret_type == T_DOUBLE ) { restore_native_result(masm, ret_type, stack_slots); @@ -2320,7 +2374,7 @@ void SharedRuntime::generate_deopt_blob() { map = RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words); // Normal deoptimization - __ pushl(Deoptimization::Unpack_deopt); + __ push(Deoptimization::Unpack_deopt); __ jmp(cont); int reexecute_offset = __ pc() - start; @@ -2331,7 +2385,7 @@ void SharedRuntime::generate_deopt_blob() { // No need to update map as each call to save_live_registers will produce identical oopmap (void) RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words); - __ pushl(Deoptimization::Unpack_reexecute); + __ push(Deoptimization::Unpack_reexecute); __ jmp(cont); int exception_offset = __ pc() - start; @@ -2344,8 +2398,8 @@ void SharedRuntime::generate_deopt_blob() { // unpack_with_exception_in_tls entry point. __ get_thread(rdi); - __ movl(Address(rdi, JavaThread::exception_pc_offset()), rdx); - __ movl(Address(rdi, JavaThread::exception_oop_offset()), rax); + __ movptr(Address(rdi, JavaThread::exception_pc_offset()), rdx); + __ movptr(Address(rdi, JavaThread::exception_oop_offset()), rax); int exception_in_tls_offset = __ pc() - start; @@ -2360,7 +2414,7 @@ void SharedRuntime::generate_deopt_blob() { // make room on stack for the return address // It will be patched later with the throwing pc. The correct value is not // available now because loading it from memory would destroy registers. - __ pushl(0); + __ push(0); // Save everything in sight. @@ -2370,24 +2424,24 @@ void SharedRuntime::generate_deopt_blob() { // Now it is safe to overwrite any register // store the correct deoptimization type - __ pushl(Deoptimization::Unpack_exception); + __ push(Deoptimization::Unpack_exception); // load throwing pc from JavaThread and patch it as the return address // of the current frame. Then clear the field in JavaThread __ get_thread(rdi); - __ movl(rdx, Address(rdi, JavaThread::exception_pc_offset())); - __ movl(Address(rbp, wordSize), rdx); - __ movl(Address(rdi, JavaThread::exception_pc_offset()), NULL_WORD); + __ movptr(rdx, Address(rdi, JavaThread::exception_pc_offset())); + __ movptr(Address(rbp, wordSize), rdx); + __ movptr(Address(rdi, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); #ifdef ASSERT // verify that there is really an exception oop in JavaThread - __ movl(rax, Address(rdi, JavaThread::exception_oop_offset())); + __ movptr(rax, Address(rdi, JavaThread::exception_oop_offset())); __ verify_oop(rax); // verify that there is no pending exception Label no_pending_exception; - __ movl(rax, Address(rdi, Thread::pending_exception_offset())); - __ testl(rax, rax); + __ movptr(rax, Address(rdi, Thread::pending_exception_offset())); + __ testptr(rax, rax); __ jcc(Assembler::zero, no_pending_exception); __ stop("must not have pending exception here"); __ bind(no_pending_exception); @@ -2402,7 +2456,7 @@ void SharedRuntime::generate_deopt_blob() { // Call C code. Need thread and this frame, but NOT official VM entry // crud. We cannot block on this call, no GC can happen. __ get_thread(rcx); - __ pushl(rcx); + __ push(rcx); // fetch_unroll_info needs to call last_java_frame() __ set_last_Java_frame(rcx, noreg, noreg, NULL); @@ -2414,35 +2468,35 @@ void SharedRuntime::generate_deopt_blob() { oop_maps->add_gc_map( __ pc()-start, map); // Discard arg to fetch_unroll_info - __ popl(rcx); + __ pop(rcx); __ get_thread(rcx); __ reset_last_Java_frame(rcx, false, false); // Load UnrollBlock into EDI - __ movl(rdi, rax); + __ mov(rdi, rax); // Move the unpack kind to a safe place in the UnrollBlock because // we are very short of registers Address unpack_kind(rdi, Deoptimization::UnrollBlock::unpack_kind_offset_in_bytes()); // retrieve the deopt kind from where we left it. - __ popl(rax); + __ pop(rax); __ movl(unpack_kind, rax); // save the unpack_kind value Label noException; __ cmpl(rax, Deoptimization::Unpack_exception); // Was exception pending? __ jcc(Assembler::notEqual, noException); - __ movl(rax, Address(rcx, JavaThread::exception_oop_offset())); - __ movl(rdx, Address(rcx, JavaThread::exception_pc_offset())); - __ movl(Address(rcx, JavaThread::exception_oop_offset()), NULL_WORD); - __ movl(Address(rcx, JavaThread::exception_pc_offset()), NULL_WORD); + __ movptr(rax, Address(rcx, JavaThread::exception_oop_offset())); + __ movptr(rdx, Address(rcx, JavaThread::exception_pc_offset())); + __ movptr(Address(rcx, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD); + __ movptr(Address(rcx, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); __ verify_oop(rax); // Overwrite the result registers with the exception results. - __ movl(Address(rsp, RegisterSaver::raxOffset()*wordSize), rax); - __ movl(Address(rsp, RegisterSaver::rdxOffset()*wordSize), rdx); + __ movptr(Address(rsp, RegisterSaver::raxOffset()*wordSize), rax); + __ movptr(Address(rsp, RegisterSaver::rdxOffset()*wordSize), rdx); __ bind(noException); @@ -2467,7 +2521,7 @@ void SharedRuntime::generate_deopt_blob() { // when we are done the return to frame 3 will still be on the stack. // Pop deoptimized frame - __ addl(rsp,Address(rdi,Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset_in_bytes())); + __ addptr(rsp, Address(rdi,Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset_in_bytes())); // sp should be pointing at the return address to the caller (3) @@ -2478,12 +2532,12 @@ void SharedRuntime::generate_deopt_blob() { } // Load array of frame pcs into ECX - __ movl(rcx,Address(rdi,Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); + __ movptr(rcx,Address(rdi,Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); - __ popl(rsi); // trash the old pc + __ pop(rsi); // trash the old pc // Load array of frame sizes into ESI - __ movl(rsi,Address(rdi,Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes())); + __ movptr(rsi,Address(rdi,Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes())); Address counter(rdi, Deoptimization::UnrollBlock::counter_temp_offset_in_bytes()); @@ -2491,7 +2545,7 @@ void SharedRuntime::generate_deopt_blob() { __ movl(counter, rbx); // Pick up the initial fp we should save - __ movl(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_fp_offset_in_bytes())); + __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_fp_offset_in_bytes())); // Now adjust the caller's stack to make up for the extra locals // but record the original sp so that we can save it in the skeletal interpreter @@ -2499,43 +2553,44 @@ void SharedRuntime::generate_deopt_blob() { // value and not the "real" sp value. Address sp_temp(rdi, Deoptimization::UnrollBlock::sender_sp_temp_offset_in_bytes()); - __ movl(sp_temp, rsp); - __ subl(rsp, Address(rdi, Deoptimization::UnrollBlock::caller_adjustment_offset_in_bytes())); + __ movptr(sp_temp, rsp); + __ movl2ptr(rbx, Address(rdi, Deoptimization::UnrollBlock::caller_adjustment_offset_in_bytes())); + __ subptr(rsp, rbx); // Push interpreter frames in a loop Label loop; __ bind(loop); - __ movl(rbx, Address(rsi, 0)); // Load frame size + __ movptr(rbx, Address(rsi, 0)); // Load frame size #ifdef CC_INTERP - __ subl(rbx, 4*wordSize); // we'll push pc and ebp by hand and + __ subptr(rbx, 4*wordSize); // we'll push pc and ebp by hand and #ifdef ASSERT - __ pushl(0xDEADDEAD); // Make a recognizable pattern - __ pushl(0xDEADDEAD); + __ push(0xDEADDEAD); // Make a recognizable pattern + __ push(0xDEADDEAD); #else /* ASSERT */ - __ subl(rsp, 2*wordSize); // skip the "static long no_param" + __ subptr(rsp, 2*wordSize); // skip the "static long no_param" #endif /* ASSERT */ #else /* CC_INTERP */ - __ subl(rbx, 2*wordSize); // we'll push pc and rbp, by hand + __ subptr(rbx, 2*wordSize); // we'll push pc and rbp, by hand #endif /* CC_INTERP */ - __ pushl(Address(rcx, 0)); // save return address + __ pushptr(Address(rcx, 0)); // save return address __ enter(); // save old & set new rbp, - __ subl(rsp, rbx); // Prolog! - __ movl(rbx, sp_temp); // sender's sp + __ subptr(rsp, rbx); // Prolog! + __ movptr(rbx, sp_temp); // sender's sp #ifdef CC_INTERP - __ movl(Address(rbp, + __ movptr(Address(rbp, -(sizeof(BytecodeInterpreter)) + in_bytes(byte_offset_of(BytecodeInterpreter, _sender_sp))), rbx); // Make it walkable #else /* CC_INTERP */ // This value is corrected by layout_activation_impl - __ movl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD ); - __ movl(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), rbx); // Make it walkable + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD ); + __ movptr(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), rbx); // Make it walkable #endif /* CC_INTERP */ - __ movl(sp_temp, rsp); // pass to next frame - __ addl(rsi, 4); // Bump array pointer (sizes) - __ addl(rcx, 4); // Bump array pointer (pcs) - __ decrement(counter); // decrement counter + __ movptr(sp_temp, rsp); // pass to next frame + __ addptr(rsi, wordSize); // Bump array pointer (sizes) + __ addptr(rcx, wordSize); // Bump array pointer (pcs) + __ decrementl(counter); // decrement counter __ jcc(Assembler::notZero, loop); - __ pushl(Address(rcx, 0)); // save final return address + __ pushptr(Address(rcx, 0)); // save final return address // Re-push self-frame __ enter(); // save old & set new rbp, @@ -2543,11 +2598,11 @@ void SharedRuntime::generate_deopt_blob() { // Return address and rbp, are in place // We'll push additional args later. Just allocate a full sized // register save area - __ subl(rsp, (frame_size_in_words-additional_words - 2) * wordSize); + __ subptr(rsp, (frame_size_in_words-additional_words - 2) * wordSize); // Restore frame locals after moving the frame - __ movl(Address(rsp, RegisterSaver::raxOffset()*wordSize), rax); - __ movl(Address(rsp, RegisterSaver::rdxOffset()*wordSize), rdx); + __ movptr(Address(rsp, RegisterSaver::raxOffset()*wordSize), rax); + __ movptr(Address(rsp, RegisterSaver::rdxOffset()*wordSize), rdx); __ fstp_d(Address(rsp, RegisterSaver::fpResultOffset()*wordSize)); // Pop float stack and store in local if( UseSSE>=2 ) __ movdbl(Address(rsp, RegisterSaver::xmm0Offset()*wordSize), xmm0); if( UseSSE==1 ) __ movflt(Address(rsp, RegisterSaver::xmm0Offset()*wordSize), xmm0); @@ -2556,7 +2611,7 @@ void SharedRuntime::generate_deopt_blob() { __ pushl(unpack_kind); // get the unpack_kind value __ get_thread(rcx); - __ pushl(rcx); + __ push(rcx); // set last_Java_sp, last_Java_fp __ set_last_Java_frame(rcx, noreg, rbp, NULL); @@ -2569,14 +2624,14 @@ void SharedRuntime::generate_deopt_blob() { oop_maps->add_gc_map( __ pc()-start, new OopMap( frame_size_in_words, 0 )); // rax, contains the return result type - __ pushl(rax); + __ push(rax); __ get_thread(rcx); __ reset_last_Java_frame(rcx, false, false); // Collect return values - __ movl(rax,Address(rsp, (RegisterSaver::raxOffset() + additional_words + 1)*wordSize)); - __ movl(rdx,Address(rsp, (RegisterSaver::rdxOffset() + additional_words + 1)*wordSize)); + __ movptr(rax,Address(rsp, (RegisterSaver::raxOffset() + additional_words + 1)*wordSize)); + __ movptr(rdx,Address(rsp, (RegisterSaver::rdxOffset() + additional_words + 1)*wordSize)); // Clear floating point stack before returning to interpreter __ empty_FPU_stack(); @@ -2637,12 +2692,12 @@ void SharedRuntime::generate_uncommon_trap_blob() { address start = __ pc(); // Push self-frame. - __ subl(rsp, return_off*wordSize); // Epilog! + __ subptr(rsp, return_off*wordSize); // Epilog! // rbp, is an implicitly saved callee saved register (i.e. the calling // convention will save restore it in prolog/epilog) Other than that // there are no callee save registers no that adapter frames are gone. - __ movl(Address(rsp, rbp_off*wordSize),rbp); + __ movptr(Address(rsp, rbp_off*wordSize), rbp); // Clear the floating point exception stack __ empty_FPU_stack(); @@ -2654,7 +2709,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { // Call C code. Need thread but NOT official VM entry // crud. We cannot block on this call, no GC can happen. Call should // capture callee-saved registers as well as return values. - __ movl(Address(rsp, arg0_off*wordSize),rdx); + __ movptr(Address(rsp, arg0_off*wordSize), rdx); // argument already in ECX __ movl(Address(rsp, arg1_off*wordSize),rcx); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap))); @@ -2671,7 +2726,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { __ reset_last_Java_frame(rcx, false, false); // Load UnrollBlock into EDI - __ movl(rdi, rax); + __ movptr(rdi, rax); // Pop all the frames we must move/replace. // @@ -2681,10 +2736,11 @@ void SharedRuntime::generate_uncommon_trap_blob() { // 3: caller of deopting frame (could be compiled/interpreted). // Pop self-frame. We have no frame, and must rely only on EAX and ESP. - __ addl(rsp,(framesize-1)*wordSize); // Epilog! + __ addptr(rsp,(framesize-1)*wordSize); // Epilog! // Pop deoptimized frame - __ addl(rsp,Address(rdi,Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset_in_bytes())); + __ movl2ptr(rcx, Address(rdi,Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset_in_bytes())); + __ addptr(rsp, rcx); // sp should be pointing at the return address to the caller (3) @@ -2698,10 +2754,10 @@ void SharedRuntime::generate_uncommon_trap_blob() { // Load array of frame pcs into ECX __ movl(rcx,Address(rdi,Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); - __ popl(rsi); // trash the pc + __ pop(rsi); // trash the pc // Load array of frame sizes into ESI - __ movl(rsi,Address(rdi,Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes())); + __ movptr(rsi,Address(rdi,Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes())); Address counter(rdi, Deoptimization::UnrollBlock::counter_temp_offset_in_bytes()); @@ -2709,7 +2765,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { __ movl(counter, rbx); // Pick up the initial fp we should save - __ movl(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_fp_offset_in_bytes())); + __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_fp_offset_in_bytes())); // Now adjust the caller's stack to make up for the extra locals // but record the original sp so that we can save it in the skeletal interpreter @@ -2717,47 +2773,48 @@ void SharedRuntime::generate_uncommon_trap_blob() { // value and not the "real" sp value. Address sp_temp(rdi, Deoptimization::UnrollBlock::sender_sp_temp_offset_in_bytes()); - __ movl(sp_temp, rsp); - __ subl(rsp, Address(rdi, Deoptimization::UnrollBlock::caller_adjustment_offset_in_bytes())); + __ movptr(sp_temp, rsp); + __ movl(rbx, Address(rdi, Deoptimization::UnrollBlock::caller_adjustment_offset_in_bytes())); + __ subptr(rsp, rbx); // Push interpreter frames in a loop Label loop; __ bind(loop); - __ movl(rbx, Address(rsi, 0)); // Load frame size + __ movptr(rbx, Address(rsi, 0)); // Load frame size #ifdef CC_INTERP - __ subl(rbx, 4*wordSize); // we'll push pc and ebp by hand and + __ subptr(rbx, 4*wordSize); // we'll push pc and ebp by hand and #ifdef ASSERT - __ pushl(0xDEADDEAD); // Make a recognizable pattern - __ pushl(0xDEADDEAD); // (parm to RecursiveInterpreter...) + __ push(0xDEADDEAD); // Make a recognizable pattern + __ push(0xDEADDEAD); // (parm to RecursiveInterpreter...) #else /* ASSERT */ - __ subl(rsp, 2*wordSize); // skip the "static long no_param" + __ subptr(rsp, 2*wordSize); // skip the "static long no_param" #endif /* ASSERT */ #else /* CC_INTERP */ - __ subl(rbx, 2*wordSize); // we'll push pc and rbp, by hand + __ subptr(rbx, 2*wordSize); // we'll push pc and rbp, by hand #endif /* CC_INTERP */ - __ pushl(Address(rcx, 0)); // save return address + __ pushptr(Address(rcx, 0)); // save return address __ enter(); // save old & set new rbp, - __ subl(rsp, rbx); // Prolog! - __ movl(rbx, sp_temp); // sender's sp + __ subptr(rsp, rbx); // Prolog! + __ movptr(rbx, sp_temp); // sender's sp #ifdef CC_INTERP - __ movl(Address(rbp, + __ movptr(Address(rbp, -(sizeof(BytecodeInterpreter)) + in_bytes(byte_offset_of(BytecodeInterpreter, _sender_sp))), rbx); // Make it walkable #else /* CC_INTERP */ // This value is corrected by layout_activation_impl - __ movl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD ); - __ movl(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), rbx); // Make it walkable + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD ); + __ movptr(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), rbx); // Make it walkable #endif /* CC_INTERP */ - __ movl(sp_temp, rsp); // pass to next frame - __ addl(rsi, 4); // Bump array pointer (sizes) - __ addl(rcx, 4); // Bump array pointer (pcs) - __ decrement(counter); // decrement counter + __ movptr(sp_temp, rsp); // pass to next frame + __ addptr(rsi, wordSize); // Bump array pointer (sizes) + __ addptr(rcx, wordSize); // Bump array pointer (pcs) + __ decrementl(counter); // decrement counter __ jcc(Assembler::notZero, loop); - __ pushl(Address(rcx, 0)); // save final return address + __ pushptr(Address(rcx, 0)); // save final return address // Re-push self-frame __ enter(); // save old & set new rbp, - __ subl(rsp, (framesize-2) * wordSize); // Prolog! + __ subptr(rsp, (framesize-2) * wordSize); // Prolog! // set last_Java_sp, last_Java_fp @@ -2767,7 +2824,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { // Call C code. Need thread but NOT official VM entry // crud. We cannot block on this call, no GC can happen. Call should // restore return values to their stack-slots with the new SP. - __ movl(Address(rsp,arg0_off*wordSize),rdi); + __ movptr(Address(rsp,arg0_off*wordSize),rdi); __ movl(Address(rsp,arg1_off*wordSize), Deoptimization::Unpack_uncommon_trap); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames))); // Set an oopmap for the call site @@ -2824,7 +2881,7 @@ static SafepointBlob* generate_handler_blob(address call_ptr, bool cause_return) // Otherwise we push space for a return address that the safepoint // handler will install later to make the stack walking sensible. if( !cause_return ) - __ pushl(rbx); // Make room for return address (or push it again) + __ push(rbx); // Make room for return address (or push it again) map = RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words, false); @@ -2834,13 +2891,13 @@ static SafepointBlob* generate_handler_blob(address call_ptr, bool cause_return) // Push thread argument and setup last_Java_sp __ get_thread(java_thread); - __ pushl(java_thread); + __ push(java_thread); __ set_last_Java_frame(java_thread, noreg, noreg, NULL); // if this was not a poll_return then we need to correct the return address now. if( !cause_return ) { - __ movl(rax, Address(java_thread, JavaThread::saved_exception_pc_offset())); - __ movl(Address(rbp, wordSize), rax); + __ movptr(rax, Address(java_thread, JavaThread::saved_exception_pc_offset())); + __ movptr(Address(rbp, wordSize), rax); } // do the call @@ -2854,7 +2911,7 @@ static SafepointBlob* generate_handler_blob(address call_ptr, bool cause_return) oop_maps->add_gc_map( __ pc() - start, map); // Discard arg - __ popl(rcx); + __ pop(rcx); Label noException; @@ -2862,7 +2919,7 @@ static SafepointBlob* generate_handler_blob(address call_ptr, bool cause_return) __ get_thread(java_thread); __ reset_last_Java_frame(java_thread, false, false); - __ cmpl(Address(java_thread, Thread::pending_exception_offset()), NULL_WORD); + __ cmpptr(Address(java_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::equal, noException); // Exception pending @@ -2919,7 +2976,7 @@ static RuntimeStub* generate_resolve_blob(address destination, const char* name) const Register thread = rdi; __ get_thread(rdi); - __ pushl(thread); + __ push(thread); __ set_last_Java_frame(thread, noreg, rbp, NULL); __ call(RuntimeAddress(destination)); @@ -2933,20 +2990,20 @@ static RuntimeStub* generate_resolve_blob(address destination, const char* name) // rax, contains the address we are going to jump to assuming no exception got installed - __ addl(rsp, wordSize); + __ addptr(rsp, wordSize); // clear last_Java_sp __ reset_last_Java_frame(thread, true, false); // check for pending exceptions Label pending; - __ cmpl(Address(thread, Thread::pending_exception_offset()), NULL_WORD); + __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::notEqual, pending); // get the returned methodOop - __ movl(rbx, Address(thread, JavaThread::vm_result_offset())); - __ movl(Address(rsp, RegisterSaver::rbx_offset() * wordSize), rbx); + __ movptr(rbx, Address(thread, JavaThread::vm_result_offset())); + __ movptr(Address(rsp, RegisterSaver::rbx_offset() * wordSize), rbx); - __ movl(Address(rsp, RegisterSaver::rax_offset() * wordSize), rax); + __ movptr(Address(rsp, RegisterSaver::rax_offset() * wordSize), rax); RegisterSaver::restore_live_registers(masm); @@ -2963,8 +3020,8 @@ static RuntimeStub* generate_resolve_blob(address destination, const char* name) // exception pending => remove activation and forward to exception handler __ get_thread(thread); - __ movl(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); - __ movl(rax, Address(thread, Thread::pending_exception_offset())); + __ movptr(Address(thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD); + __ movptr(rax, Address(thread, Thread::pending_exception_offset())); __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); // ------------- diff --git a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp index b2d4a6513ac..26e7e148968 100644 --- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp @@ -120,6 +120,7 @@ class RegisterSaver { // values on its own static int rax_offset_in_bytes(void) { return BytesPerInt * rax_off; } + static int rdx_offset_in_bytes(void) { return BytesPerInt * rdx_off; } static int rbx_offset_in_bytes(void) { return BytesPerInt * rbx_off; } static int xmm0_offset_in_bytes(void) { return BytesPerInt * xmm0_off; } static int return_offset_in_bytes(void) { return BytesPerInt * return_off; } @@ -152,7 +153,7 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_ __ push_CPU_state(); // Push a multiple of 16 bytes if (frame::arg_reg_save_area_bytes != 0) { // Allocate argument register save area - __ subq(rsp, frame::arg_reg_save_area_bytes); + __ subptr(rsp, frame::arg_reg_save_area_bytes); } // Set an oopmap for the call site. This oopmap will map all @@ -266,12 +267,12 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_ void RegisterSaver::restore_live_registers(MacroAssembler* masm) { if (frame::arg_reg_save_area_bytes != 0) { // Pop arg register save area - __ addq(rsp, frame::arg_reg_save_area_bytes); + __ addptr(rsp, frame::arg_reg_save_area_bytes); } // Recover CPU state __ pop_CPU_state(); // Get the rbp described implicitly by the calling convention (no oopMap) - __ popq(rbp); + __ pop(rbp); } void RegisterSaver::restore_result_registers(MacroAssembler* masm) { @@ -285,9 +286,11 @@ void RegisterSaver::restore_result_registers(MacroAssembler* masm) { // Restore fp result register __ movdbl(xmm0, Address(rsp, xmm0_offset_in_bytes())); // Restore integer result register - __ movq(rax, Address(rsp, rax_offset_in_bytes())); + __ movptr(rax, Address(rsp, rax_offset_in_bytes())); + __ movptr(rdx, Address(rsp, rdx_offset_in_bytes())); + // Pop all of the register save are off the stack except the return address - __ addq(rsp, return_offset_in_bytes()); + __ addptr(rsp, return_offset_in_bytes()); } // The java_calling_convention describes stack locations as ideal slots on @@ -407,18 +410,18 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, static void patch_callers_callsite(MacroAssembler *masm) { Label L; __ verify_oop(rbx); - __ cmpq(Address(rbx, in_bytes(methodOopDesc::code_offset())), (int)NULL_WORD); + __ cmpptr(Address(rbx, in_bytes(methodOopDesc::code_offset())), (int32_t)NULL_WORD); __ jcc(Assembler::equal, L); // Save the current stack pointer - __ movq(r13, rsp); + __ mov(r13, rsp); // Schedule the branch target address early. // Call into the VM to patch the caller, then jump to compiled callee // rax isn't live so capture return address while we easily can - __ movq(rax, Address(rsp, 0)); + __ movptr(rax, Address(rsp, 0)); // align stack so push_CPU_state doesn't fault - __ andq(rsp, -(StackAlignmentInBytes)); + __ andptr(rsp, -(StackAlignmentInBytes)); __ push_CPU_state(); @@ -430,20 +433,20 @@ static void patch_callers_callsite(MacroAssembler *masm) { // Allocate argument register save area if (frame::arg_reg_save_area_bytes != 0) { - __ subq(rsp, frame::arg_reg_save_area_bytes); + __ subptr(rsp, frame::arg_reg_save_area_bytes); } - __ movq(c_rarg0, rbx); - __ movq(c_rarg1, rax); + __ mov(c_rarg0, rbx); + __ mov(c_rarg1, rax); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite))); // De-allocate argument register save area if (frame::arg_reg_save_area_bytes != 0) { - __ addq(rsp, frame::arg_reg_save_area_bytes); + __ addptr(rsp, frame::arg_reg_save_area_bytes); } __ pop_CPU_state(); // restore sp - __ movq(rsp, r13); + __ mov(rsp, r13); __ bind(L); } @@ -452,13 +455,13 @@ static void tag_stack(MacroAssembler *masm, const BasicType sig, int st_off) { if (TaggedStackInterpreter) { int tag_offset = st_off + Interpreter::expr_tag_offset_in_bytes(0); if (sig == T_OBJECT || sig == T_ARRAY) { - __ mov64(Address(rsp, tag_offset), frame::TagReference); + __ movptr(Address(rsp, tag_offset), (int32_t) frame::TagReference); } else if (sig == T_LONG || sig == T_DOUBLE) { int next_tag_offset = st_off + Interpreter::expr_tag_offset_in_bytes(1); - __ mov64(Address(rsp, next_tag_offset), frame::TagValue); - __ mov64(Address(rsp, tag_offset), frame::TagValue); + __ movptr(Address(rsp, next_tag_offset), (int32_t) frame::TagValue); + __ movptr(Address(rsp, tag_offset), (int32_t) frame::TagValue); } else { - __ mov64(Address(rsp, tag_offset), frame::TagValue); + __ movptr(Address(rsp, tag_offset), (int32_t) frame::TagValue); } } } @@ -490,15 +493,15 @@ static void gen_c2i_adapter(MacroAssembler *masm, extraspace = round_to(extraspace, 2*wordSize); // Get return address - __ popq(rax); + __ pop(rax); // set senderSP value - __ movq(r13, rsp); + __ mov(r13, rsp); - __ subq(rsp, extraspace); + __ subptr(rsp, extraspace); // Store the return address in the expected location - __ movq(Address(rsp, 0), rax); + __ movptr(Address(rsp, 0), rax); // Now write the args into the outgoing interpreter space for (int i = 0; i < total_args_passed; i++) { @@ -537,7 +540,7 @@ static void gen_c2i_adapter(MacroAssembler *masm, if (!r_2->is_valid()) { // sign extend?? __ movl(rax, Address(rsp, ld_off)); - __ movq(Address(rsp, st_off), rax); + __ movptr(Address(rsp, st_off), rax); tag_stack(masm, sig_bt[i], st_off); } else { @@ -553,7 +556,7 @@ static void gen_c2i_adapter(MacroAssembler *masm, #ifdef ASSERT // Overwrite the unused slot with known junk __ mov64(rax, CONST64(0xdeadffffdeadaaaa)); - __ movq(Address(rsp, st_off), rax); + __ movptr(Address(rsp, st_off), rax); #endif /* ASSERT */ tag_stack(masm, sig_bt[i], next_off); } else { @@ -576,12 +579,12 @@ static void gen_c2i_adapter(MacroAssembler *masm, #ifdef ASSERT // Overwrite the unused slot with known junk __ mov64(rax, CONST64(0xdeadffffdeadaaab)); - __ movq(Address(rsp, st_off), rax); + __ movptr(Address(rsp, st_off), rax); #endif /* ASSERT */ __ movq(Address(rsp, next_off), r); tag_stack(masm, sig_bt[i], next_off); } else { - __ movq(Address(rsp, st_off), r); + __ movptr(Address(rsp, st_off), r); tag_stack(masm, sig_bt[i], st_off); } } @@ -595,7 +598,7 @@ static void gen_c2i_adapter(MacroAssembler *masm, #ifdef ASSERT // Overwrite the unused slot with known junk __ mov64(rax, CONST64(0xdeadffffdeadaaac)); - __ movq(Address(rsp, st_off), rax); + __ movptr(Address(rsp, st_off), rax); #endif /* ASSERT */ __ movdbl(Address(rsp, next_off), r_1->as_XMMRegister()); tag_stack(masm, sig_bt[i], next_off); @@ -604,7 +607,7 @@ static void gen_c2i_adapter(MacroAssembler *masm, } // Schedule the branch target address early. - __ movq(rcx, Address(rbx, in_bytes(methodOopDesc::interpreter_entry_offset()))); + __ movptr(rcx, Address(rbx, in_bytes(methodOopDesc::interpreter_entry_offset()))); __ jmp(rcx); } @@ -631,7 +634,7 @@ static void gen_i2c_adapter(MacroAssembler *masm, // save code can segv when fxsave instructions find improperly // aligned stack pointer. - __ movq(rax, Address(rsp, 0)); + __ movptr(rax, Address(rsp, 0)); // Cut-out for having no stack args. Since up to 2 int/oop args are passed // in registers, we will occasionally have no stack args. @@ -645,20 +648,20 @@ static void gen_i2c_adapter(MacroAssembler *masm, comp_words_on_stack = round_to(comp_args_on_stack*VMRegImpl::stack_slot_size, wordSize)>>LogBytesPerWord; // Round up to miminum stack alignment, in wordSize comp_words_on_stack = round_to(comp_words_on_stack, 2); - __ subq(rsp, comp_words_on_stack * wordSize); + __ subptr(rsp, comp_words_on_stack * wordSize); } // Ensure compiled code always sees stack at proper alignment - __ andq(rsp, -16); + __ andptr(rsp, -16); // push the return address and misalign the stack that youngest frame always sees // as far as the placement of the call instruction - __ pushq(rax); + __ push(rax); // Will jump to the compiled code just as if compiled code was doing it. // Pre-load the register-jump target early, to schedule it better. - __ movq(r11, Address(rbx, in_bytes(methodOopDesc::from_compiled_offset()))); + __ movptr(r11, Address(rbx, in_bytes(methodOopDesc::from_compiled_offset()))); // Now generate the shuffle code. Pick up all register args and move the // rest through the floating point stack top. @@ -697,7 +700,7 @@ static void gen_i2c_adapter(MacroAssembler *masm, if (!r_2->is_valid()) { // sign extend??? __ movl(rax, Address(r13, ld_off)); - __ movq(Address(rsp, st_off), rax); + __ movptr(Address(rsp, st_off), rax); } else { // // We are using two optoregs. This can be either T_OBJECT, T_ADDRESS, T_LONG, or T_DOUBLE @@ -751,12 +754,12 @@ static void gen_i2c_adapter(MacroAssembler *masm, // is possible. So we stash the desired callee in the thread // and the vm will find there should this case occur. - __ movq(Address(r15_thread, JavaThread::callee_target_offset()), rbx); + __ movptr(Address(r15_thread, JavaThread::callee_target_offset()), rbx); // put methodOop where a c2i would expect should we end up there // only needed becaus eof c2 resolve stubs return methodOop as a result in // rax - __ movq(rax, rbx); + __ mov(rax, rbx); __ jmp(r11); } @@ -792,8 +795,8 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm __ load_klass(temp, receiver); __ verify_oop(temp); - __ cmpq(temp, Address(holder, compiledICHolderOopDesc::holder_klass_offset())); - __ movq(rbx, Address(holder, compiledICHolderOopDesc::holder_method_offset())); + __ cmpptr(temp, Address(holder, compiledICHolderOopDesc::holder_klass_offset())); + __ movptr(rbx, Address(holder, compiledICHolderOopDesc::holder_method_offset())); __ jcc(Assembler::equal, ok); __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); @@ -801,7 +804,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm // Method might have been compiled since the call site was patched to // interpreted if that is the case treat it as a miss so we can get // the call site corrected. - __ cmpq(Address(rbx, in_bytes(methodOopDesc::code_offset())), (int)NULL_WORD); + __ cmpptr(Address(rbx, in_bytes(methodOopDesc::code_offset())), (int32_t)NULL_WORD); __ jcc(Assembler::equal, skip_fixup); __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); } @@ -980,10 +983,10 @@ static void object_move(MacroAssembler* masm, *receiver_offset = (offset_in_older_frame + framesize_in_slots) * VMRegImpl::stack_slot_size; } - __ cmpq(Address(rbp, reg2offset_in(src.first())), (int)NULL_WORD); - __ leaq(rHandle, Address(rbp, reg2offset_in(src.first()))); + __ cmpptr(Address(rbp, reg2offset_in(src.first())), (int32_t)NULL_WORD); + __ lea(rHandle, Address(rbp, reg2offset_in(src.first()))); // conditionally move a NULL - __ cmovq(Assembler::equal, rHandle, Address(rbp, reg2offset_in(src.first()))); + __ cmovptr(Assembler::equal, rHandle, Address(rbp, reg2offset_in(src.first()))); } else { // Oop is in an a register we must store it to the space we reserve @@ -1011,20 +1014,20 @@ static void object_move(MacroAssembler* masm, map->set_oop(VMRegImpl::stack2reg(oop_slot)); // Store oop in handle area, may be NULL - __ movq(Address(rsp, offset), rOop); + __ movptr(Address(rsp, offset), rOop); if (is_receiver) { *receiver_offset = offset; } - __ cmpq(rOop, (int)NULL); - __ leaq(rHandle, Address(rsp, offset)); + __ cmpptr(rOop, (int32_t)NULL_WORD); + __ lea(rHandle, Address(rsp, offset)); // conditionally move a NULL from the handle area where it was just stored - __ cmovq(Assembler::equal, rHandle, Address(rsp, offset)); + __ cmovptr(Assembler::equal, rHandle, Address(rsp, offset)); } // If arg is on the stack then place it otherwise it is already in correct reg. if (dst.first()->is_stack()) { - __ movq(Address(rsp, reg2offset_out(dst.first())), rHandle); + __ movptr(Address(rsp, reg2offset_out(dst.first())), rHandle); } } @@ -1039,7 +1042,7 @@ static void float_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { if (src.first()->is_stack()) { if (dst.first()->is_stack()) { __ movl(rax, Address(rbp, reg2offset_in(src.first()))); - __ movq(Address(rsp, reg2offset_out(dst.first())), rax); + __ movptr(Address(rsp, reg2offset_out(dst.first())), rax); } else { // stack to reg assert(dst.first()->is_XMMRegister(), "only expect xmm registers as parameters"); @@ -1068,7 +1071,7 @@ static void long_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { if (src.is_single_phys_reg() ) { if (dst.is_single_phys_reg()) { if (dst.first() != src.first()) { - __ movq(dst.first()->as_Register(), src.first()->as_Register()); + __ mov(dst.first()->as_Register(), src.first()->as_Register()); } } else { assert(dst.is_single_reg(), "not a stack pair"); @@ -1124,7 +1127,7 @@ void SharedRuntime::save_native_result(MacroAssembler *masm, BasicType ret_type, break; case T_VOID: break; default: { - __ movq(Address(rbp, -wordSize), rax); + __ movptr(Address(rbp, -wordSize), rax); } } } @@ -1141,7 +1144,7 @@ void SharedRuntime::restore_native_result(MacroAssembler *masm, BasicType ret_ty break; case T_VOID: break; default: { - __ movq(rax, Address(rbp, -wordSize)); + __ movptr(rax, Address(rbp, -wordSize)); } } } @@ -1149,9 +1152,9 @@ void SharedRuntime::restore_native_result(MacroAssembler *masm, BasicType ret_ty static void save_args(MacroAssembler *masm, int arg_count, int first_arg, VMRegPair *args) { for ( int i = first_arg ; i < arg_count ; i++ ) { if (args[i].first()->is_Register()) { - __ pushq(args[i].first()->as_Register()); + __ push(args[i].first()->as_Register()); } else if (args[i].first()->is_XMMRegister()) { - __ subq(rsp, 2*wordSize); + __ subptr(rsp, 2*wordSize); __ movdbl(Address(rsp, 0), args[i].first()->as_XMMRegister()); } } @@ -1160,10 +1163,10 @@ static void save_args(MacroAssembler *masm, int arg_count, int first_arg, VMRegP static void restore_args(MacroAssembler *masm, int arg_count, int first_arg, VMRegPair *args) { for ( int i = arg_count - 1 ; i >= first_arg ; i-- ) { if (args[i].first()->is_Register()) { - __ popq(args[i].first()->as_Register()); + __ pop(args[i].first()->as_Register()); } else if (args[i].first()->is_XMMRegister()) { __ movdbl(args[i].first()->as_XMMRegister(), Address(rsp, 0)); - __ addq(rsp, 2*wordSize); + __ addptr(rsp, 2*wordSize); } } } @@ -1303,16 +1306,16 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, Label exception_pending; __ verify_oop(receiver); - __ pushq(tmp); // spill (any other registers free here???) + __ push(tmp); // spill (any other registers free here???) __ load_klass(tmp, receiver); __ cmpq(ic_reg, tmp); __ jcc(Assembler::equal, ok); - __ popq(tmp); + __ pop(tmp); __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); __ bind(ok); - __ popq(tmp); + __ pop(tmp); // Verified entry point must be aligned __ align(8); @@ -1335,7 +1338,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // Generate a new frame for the wrapper. __ enter(); // -2 because return address is already present and so is saved rbp - __ subq(rsp, stack_size - 2*wordSize); + __ subptr(rsp, stack_size - 2*wordSize); // Frame is now completed as far as size and linkage. @@ -1344,9 +1347,9 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, #ifdef ASSERT { Label L; - __ movq(rax, rsp); - __ andq(rax, -16); // must be 16 byte boundry (see amd64 ABI) - __ cmpq(rax, rsp); + __ mov(rax, rsp); + __ andptr(rax, -16); // must be 16 byte boundry (see amd64 ABI) + __ cmpptr(rax, rsp); __ jcc(Assembler::equal, L); __ stop("improperly aligned stack"); __ bind(L); @@ -1467,13 +1470,13 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, __ movoop(oop_handle_reg, JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror())); // Now handlize the static class mirror it's known not-null. - __ movq(Address(rsp, klass_offset), oop_handle_reg); + __ movptr(Address(rsp, klass_offset), oop_handle_reg); map->set_oop(VMRegImpl::stack2reg(klass_slot_offset)); // Now get the handle - __ leaq(oop_handle_reg, Address(rsp, klass_offset)); + __ lea(oop_handle_reg, Address(rsp, klass_offset)); // store the klass handle as second argument - __ movq(c_rarg1, oop_handle_reg); + __ movptr(c_rarg1, oop_handle_reg); // and protect the arg if we must spill c_arg--; } @@ -1521,14 +1524,14 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, const int mark_word_offset = BasicLock::displaced_header_offset_in_bytes(); // Get the handle (the 2nd argument) - __ movq(oop_handle_reg, c_rarg1); + __ mov(oop_handle_reg, c_rarg1); // Get address of the box - __ leaq(lock_reg, Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size)); + __ lea(lock_reg, Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size)); // Load the oop from the handle - __ movq(obj_reg, Address(oop_handle_reg, 0)); + __ movptr(obj_reg, Address(oop_handle_reg, 0)); if (UseBiasedLocking) { __ biased_locking_enter(lock_reg, obj_reg, swap_reg, rscratch1, false, lock_done, &slow_path_lock); @@ -1538,17 +1541,17 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, __ movl(swap_reg, 1); // Load (object->mark() | 1) into swap_reg %rax - __ orq(swap_reg, Address(obj_reg, 0)); + __ orptr(swap_reg, Address(obj_reg, 0)); // Save (object->mark() | 1) into BasicLock's displaced header - __ movq(Address(lock_reg, mark_word_offset), swap_reg); + __ movptr(Address(lock_reg, mark_word_offset), swap_reg); if (os::is_MP()) { __ lock(); } // src -> dest iff dest == rax else rax <- dest - __ cmpxchgq(lock_reg, Address(obj_reg, 0)); + __ cmpxchgptr(lock_reg, Address(obj_reg, 0)); __ jcc(Assembler::equal, lock_done); // Hmm should this move to the slow path code area??? @@ -1562,11 +1565,11 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // least significant 2 bits clear. // NOTE: the oopMark is in swap_reg %rax as the result of cmpxchg - __ subq(swap_reg, rsp); - __ andq(swap_reg, 3 - os::vm_page_size()); + __ subptr(swap_reg, rsp); + __ andptr(swap_reg, 3 - os::vm_page_size()); // Save the test result, for recursive case, the result is zero - __ movq(Address(lock_reg, mark_word_offset), swap_reg); + __ movptr(Address(lock_reg, mark_word_offset), swap_reg); __ jcc(Assembler::notEqual, slow_path_lock); // Slow path will re-enter here @@ -1580,21 +1583,21 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // get JNIEnv* which is first argument to native - __ leaq(c_rarg0, Address(r15_thread, in_bytes(JavaThread::jni_environment_offset()))); + __ lea(c_rarg0, Address(r15_thread, in_bytes(JavaThread::jni_environment_offset()))); // Now set thread in native - __ mov64(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_native); + __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_native); __ call(RuntimeAddress(method->native_function())); // Either restore the MXCSR register after returning from the JNI Call // or verify that it wasn't changed. if (RestoreMXCSROnJNICalls) { - __ ldmxcsr(ExternalAddress(StubRoutines::amd64::mxcsr_std())); + __ ldmxcsr(ExternalAddress(StubRoutines::x86::mxcsr_std())); } else if (CheckJNICalls ) { - __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::amd64::verify_mxcsr_entry()))); + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::verify_mxcsr_entry()))); } @@ -1624,7 +1627,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // VM thread changes sync state to synchronizing and suspends threads for GC. // Thread A is resumed to finish this native method, but doesn't block here since it // didn't see any synchronization is progress, and escapes. - __ mov64(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_native_trans); + __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_native_trans); if(os::is_MP()) { if (UseMembar) { @@ -1662,12 +1665,12 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // by hand. // save_native_result(masm, ret_type, stack_slots); - __ movq(c_rarg0, r15_thread); - __ movq(r12, rsp); // remember sp - __ subq(rsp, frame::arg_reg_save_area_bytes); // windows - __ andq(rsp, -16); // align stack as required by ABI + __ mov(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, JavaThread::check_special_condition_for_native_trans))); - __ movq(rsp, r12); // restore sp + __ mov(rsp, r12); // restore sp __ reinit_heapbase(); // Restore any method result value restore_native_result(masm, ret_type, stack_slots); @@ -1691,7 +1694,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, if (method->is_synchronized()) { // Get locked oop from the handle we passed to jni - __ movq(obj_reg, Address(oop_handle_reg, 0)); + __ movptr(obj_reg, Address(oop_handle_reg, 0)); Label done; @@ -1701,7 +1704,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // Simple recursive lock? - __ cmpq(Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size), (int)NULL_WORD); + __ cmpptr(Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size), (int32_t)NULL_WORD); __ jcc(Assembler::equal, done); // Must save rax if if it is live now because cmpxchg must use it @@ -1711,15 +1714,15 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // get address of the stack lock - __ leaq(rax, Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size)); + __ lea(rax, Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size)); // get old displaced header - __ movq(old_hdr, Address(rax, 0)); + __ movptr(old_hdr, Address(rax, 0)); // Atomic swap old header if oop still contains the stack lock if (os::is_MP()) { __ lock(); } - __ cmpxchgq(old_hdr, Address(obj_reg, 0)); + __ cmpxchgptr(old_hdr, Address(obj_reg, 0)); __ jcc(Assembler::notEqual, slow_path_unlock); // slow path re-enters here @@ -1746,23 +1749,23 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // Unpack oop result if (ret_type == T_OBJECT || ret_type == T_ARRAY) { Label L; - __ testq(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, L); - __ movq(rax, Address(rax, 0)); + __ movptr(rax, Address(rax, 0)); __ bind(L); __ verify_oop(rax); } // reset handle block - __ movq(rcx, Address(r15_thread, JavaThread::active_handles_offset())); - __ movptr(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), (int)NULL_WORD); + __ 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? - __ cmpq(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int)NULL_WORD); + __ cmpptr(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); __ jcc(Assembler::notEqual, exception_pending); // Return @@ -1790,9 +1793,9 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // protect the args we've loaded save_args(masm, total_c_args, c_arg, out_regs); - __ movq(c_rarg0, obj_reg); - __ movq(c_rarg1, lock_reg); - __ movq(c_rarg2, r15_thread); + __ mov(c_rarg0, obj_reg); + __ mov(c_rarg1, lock_reg); + __ mov(c_rarg2, r15_thread); // Not a leaf but we have last_Java_frame setup as we want __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_locking_C), 3); @@ -1800,7 +1803,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, #ifdef ASSERT { Label L; - __ cmpq(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int)NULL_WORD); + __ cmpptr(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); __ jcc(Assembler::equal, L); __ stop("no pending exception allowed on exit from monitorenter"); __ bind(L); @@ -1820,32 +1823,32 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, save_native_result(masm, ret_type, stack_slots); } - __ leaq(c_rarg1, Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size)); + __ lea(c_rarg1, Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size)); - __ movq(c_rarg0, obj_reg); - __ movq(r12, rsp); // remember sp - __ subq(rsp, frame::arg_reg_save_area_bytes); // windows - __ andq(rsp, -16); // align stack as required by ABI + __ mov(c_rarg0, obj_reg); + __ mov(r12, rsp); // remember sp + __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows + __ andptr(rsp, -16); // align stack as required by ABI // Save pending exception around call to VM (which contains an EXCEPTION_MARK) // NOTE that obj_reg == rbx currently - __ movq(rbx, Address(r15_thread, in_bytes(Thread::pending_exception_offset()))); - __ movptr(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int)NULL_WORD); + __ movptr(rbx, Address(r15_thread, in_bytes(Thread::pending_exception_offset()))); + __ movptr(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C))); - __ movq(rsp, r12); // restore sp + __ mov(rsp, r12); // restore sp __ reinit_heapbase(); #ifdef ASSERT { Label L; - __ cmpq(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int)NULL_WORD); + __ cmpptr(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int)NULL_WORD); __ jcc(Assembler::equal, L); __ stop("no pending exception allowed on exit complete_monitor_unlocking_C"); __ bind(L); } #endif /* ASSERT */ - __ movq(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), rbx); + __ movptr(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), rbx); if (ret_type == T_FLOAT || ret_type == T_DOUBLE ) { restore_native_result(masm, ret_type, stack_slots); @@ -1860,11 +1863,11 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, __ bind(reguard); save_native_result(masm, ret_type, stack_slots); - __ movq(r12, rsp); // remember sp - __ subq(rsp, frame::arg_reg_save_area_bytes); // windows - __ andq(rsp, -16); // align stack as required by ABI + __ 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::reguard_yellow_pages))); - __ movq(rsp, r12); // restore sp + __ mov(rsp, r12); // restore sp __ reinit_heapbase(); restore_native_result(masm, ret_type, stack_slots); // and continue @@ -2574,19 +2577,74 @@ void SharedRuntime::generate_deopt_blob() { // Normal deoptimization. Save exec mode for unpack_frames. __ movl(r14, Deoptimization::Unpack_deopt); // callee-saved __ jmp(cont); + + int reexecute_offset = __ pc() - start; + + // Reexecute case + // return address is the pc describes what bci to do re-execute at + + // No need to update map as each call to save_live_registers will produce identical oopmap + (void) RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words); + + __ movl(r14, Deoptimization::Unpack_reexecute); // callee-saved + __ jmp(cont); + int exception_offset = __ pc() - start; // Prolog for exception case - // Push throwing pc as return address - __ pushq(rdx); + // all registers are dead at this entry point, except for rax, and + // rdx which contain the exception oop and exception pc + // respectively. Set them in TLS and fall thru to the + // unpack_with_exception_in_tls entry point. + + __ movptr(Address(r15_thread, JavaThread::exception_pc_offset()), rdx); + __ movptr(Address(r15_thread, JavaThread::exception_oop_offset()), rax); + + int exception_in_tls_offset = __ pc() - start; + + // new implementation because exception oop is now passed in JavaThread + + // Prolog for exception case + // All registers must be preserved because they might be used by LinearScan + // Exceptiop oop and throwing PC are passed in JavaThread + // tos: stack at point of call to method that threw the exception (i.e. only + // args are on the stack, no return address) + + // make room on stack for the return address + // It will be patched later with the throwing pc. The correct value is not + // available now because loading it from memory would destroy registers. + __ push(0); // Save everything in sight. map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words); + // Now it is safe to overwrite any register + // Deopt during an exception. Save exec mode for unpack_frames. __ movl(r14, Deoptimization::Unpack_exception); // callee-saved + // load throwing pc from JavaThread and patch it as the return address + // of the current frame. Then clear the field in JavaThread + + __ movptr(rdx, Address(r15_thread, JavaThread::exception_pc_offset())); + __ movptr(Address(rbp, wordSize), rdx); + __ movptr(Address(r15_thread, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); + +#ifdef ASSERT + // verify that there is really an exception oop in JavaThread + __ movptr(rax, Address(r15_thread, JavaThread::exception_oop_offset())); + __ verify_oop(rax); + + // verify that there is no pending exception + Label no_pending_exception; + __ movptr(rax, Address(r15_thread, Thread::pending_exception_offset())); + __ testptr(rax, rax); + __ jcc(Assembler::zero, no_pending_exception); + __ stop("must not have pending exception here"); + __ bind(no_pending_exception); +#endif + __ bind(cont); // Call C code. Need thread and this frame, but NOT official VM entry @@ -2599,15 +2657,15 @@ void SharedRuntime::generate_deopt_blob() { __ set_last_Java_frame(noreg, noreg, NULL); #ifdef ASSERT { Label L; - __ cmpq(Address(r15_thread, + __ cmpptr(Address(r15_thread, JavaThread::last_Java_fp_offset()), - 0); + (int32_t)0); __ jcc(Assembler::equal, L); __ stop("SharedRuntime::generate_deopt_blob: last_Java_fp not cleared"); __ bind(L); } #endif // ASSERT - __ movq(c_rarg0, r15_thread); + __ mov(c_rarg0, r15_thread); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::fetch_unroll_info))); // Need to have an oopmap that tells fetch_unroll_info where to @@ -2617,7 +2675,25 @@ void SharedRuntime::generate_deopt_blob() { __ reset_last_Java_frame(false, false); // Load UnrollBlock* into rdi - __ movq(rdi, rax); + __ mov(rdi, rax); + + Label noException; + __ cmpl(r12, Deoptimization::Unpack_exception); // Was exception pending? + __ jcc(Assembler::notEqual, noException); + __ movptr(rax, Address(r15_thread, JavaThread::exception_oop_offset())); + // QQQ this is useless it was NULL above + __ movptr(rdx, Address(r15_thread, JavaThread::exception_pc_offset())); + __ movptr(Address(r15_thread, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD); + __ movptr(Address(r15_thread, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); + + __ verify_oop(rax); + + // Overwrite the result registers with the exception results. + __ movptr(Address(rsp, RegisterSaver::rax_offset_in_bytes()), rax); + // I think this is useless + __ movptr(Address(rsp, RegisterSaver::rdx_offset_in_bytes()), rdx); + + __ bind(noException); // Only register save data is on the stack. // Now restore the result registers. Everything else is either dead @@ -2640,7 +2716,7 @@ void SharedRuntime::generate_deopt_blob() { // Pop deoptimized frame __ movl(rcx, Address(rdi, Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset_in_bytes())); - __ addq(rsp, rcx); + __ addptr(rsp, rcx); // rsp should be pointing at the return address to the caller (3) @@ -2651,19 +2727,19 @@ void SharedRuntime::generate_deopt_blob() { } // Load address of array of frame pcs into rcx - __ movq(rcx, Address(rdi, Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); + __ movptr(rcx, Address(rdi, Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); // Trash the old pc - __ addq(rsp, wordSize); + __ addptr(rsp, wordSize); // Load address of array of frame sizes into rsi - __ movq(rsi, Address(rdi, Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes())); + __ movptr(rsi, Address(rdi, Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes())); // Load counter into rdx __ movl(rdx, Address(rdi, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes())); // Pick up the initial fp we should save - __ movq(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_fp_offset_in_bytes())); + __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_fp_offset_in_bytes())); // Now adjust the caller's stack to make up for the extra locals // but record the original sp so that we can save it in the skeletal interpreter @@ -2672,41 +2748,56 @@ void SharedRuntime::generate_deopt_blob() { const Register sender_sp = r8; - __ movq(sender_sp, rsp); + __ mov(sender_sp, rsp); __ movl(rbx, Address(rdi, Deoptimization::UnrollBlock:: caller_adjustment_offset_in_bytes())); - __ subq(rsp, rbx); + __ subptr(rsp, rbx); // Push interpreter frames in a loop Label loop; __ bind(loop); - __ movq(rbx, Address(rsi, 0)); // Load frame size - __ subq(rbx, 2*wordSize); // We'll push pc and ebp by hand - __ pushq(Address(rcx, 0)); // Save return address + __ movptr(rbx, Address(rsi, 0)); // Load frame size +#ifdef CC_INTERP + __ subptr(rbx, 4*wordSize); // we'll push pc and ebp by hand and +#ifdef ASSERT + __ push(0xDEADDEAD); // Make a recognizable pattern + __ push(0xDEADDEAD); +#else /* ASSERT */ + __ subptr(rsp, 2*wordSize); // skip the "static long no_param" +#endif /* ASSERT */ +#else + __ subptr(rbx, 2*wordSize); // We'll push pc and ebp by hand +#endif // CC_INTERP + __ pushptr(Address(rcx, 0)); // Save return address __ enter(); // Save old & set new ebp - __ subq(rsp, rbx); // Prolog - __ movq(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), - sender_sp); // Make it walkable + __ subptr(rsp, rbx); // Prolog +#ifdef CC_INTERP + __ movptr(Address(rbp, + -(sizeof(BytecodeInterpreter)) + in_bytes(byte_offset_of(BytecodeInterpreter, _sender_sp))), + sender_sp); // Make it walkable +#else /* CC_INTERP */ // This value is corrected by layout_activation_impl - __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int)NULL_WORD ); - __ movq(sender_sp, rsp); // Pass sender_sp to next frame - __ addq(rsi, wordSize); // Bump array pointer (sizes) - __ addq(rcx, wordSize); // Bump array pointer (pcs) + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD ); + __ movptr(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), sender_sp); // Make it walkable +#endif /* CC_INTERP */ + __ mov(sender_sp, rsp); // Pass sender_sp to next frame + __ addptr(rsi, wordSize); // Bump array pointer (sizes) + __ addptr(rcx, wordSize); // Bump array pointer (pcs) __ decrementl(rdx); // Decrement counter __ jcc(Assembler::notZero, loop); - __ pushq(Address(rcx, 0)); // Save final return address + __ pushptr(Address(rcx, 0)); // Save final return address // Re-push self-frame __ enter(); // Save old & set new ebp // Allocate a full sized register save area. // Return address and rbp are in place, so we allocate two less words. - __ subq(rsp, (frame_size_in_words - 2) * wordSize); + __ subptr(rsp, (frame_size_in_words - 2) * wordSize); // Restore frame locals after moving the frame __ movdbl(Address(rsp, RegisterSaver::xmm0_offset_in_bytes()), xmm0); - __ movq(Address(rsp, RegisterSaver::rax_offset_in_bytes()), rax); + __ movptr(Address(rsp, RegisterSaver::rax_offset_in_bytes()), rax); // Call C code. Need thread but NOT official VM entry // crud. We cannot block on this call, no GC can happen. Call should @@ -2717,7 +2808,7 @@ void SharedRuntime::generate_deopt_blob() { // Use rbp because the frames look interpreted now __ set_last_Java_frame(noreg, rbp, NULL); - __ movq(c_rarg0, r15_thread); + __ mov(c_rarg0, r15_thread); __ movl(c_rarg1, r14); // second arg: exec_mode __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames))); @@ -2729,7 +2820,9 @@ void SharedRuntime::generate_deopt_blob() { // Collect return values __ movdbl(xmm0, Address(rsp, RegisterSaver::xmm0_offset_in_bytes())); - __ movq(rax, Address(rsp, RegisterSaver::rax_offset_in_bytes())); + __ movptr(rax, Address(rsp, RegisterSaver::rax_offset_in_bytes())); + // I think this is useless (throwing pc?) + __ movptr(rdx, Address(rsp, RegisterSaver::rdx_offset_in_bytes())); // Pop self-frame. __ leave(); // Epilog @@ -2740,7 +2833,8 @@ void SharedRuntime::generate_deopt_blob() { // Make sure all code is generated masm->flush(); - _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, 0, frame_size_in_words); + _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words); + _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset); } #ifdef COMPILER2 @@ -2758,10 +2852,10 @@ void SharedRuntime::generate_uncommon_trap_blob() { // Push self-frame. We get here with a return address on the // stack, so rsp is 8-byte aligned until we allocate our frame. - __ subq(rsp, SimpleRuntimeFrame::return_off << LogBytesPerInt); // Epilog! + __ subptr(rsp, SimpleRuntimeFrame::return_off << LogBytesPerInt); // Epilog! // No callee saved registers. rbp is assumed implicitly saved - __ movq(Address(rsp, SimpleRuntimeFrame::rbp_off << LogBytesPerInt), rbp); + __ movptr(Address(rsp, SimpleRuntimeFrame::rbp_off << LogBytesPerInt), rbp); // compiler left unloaded_class_index in j_rarg0 move to where the // runtime expects it. @@ -2776,7 +2870,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { // // UnrollBlock* uncommon_trap(JavaThread* thread, jint unloaded_class_index); - __ movq(c_rarg0, r15_thread); + __ mov(c_rarg0, r15_thread); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap))); // Set an oopmap for the call site @@ -2790,7 +2884,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { __ reset_last_Java_frame(false, false); // Load UnrollBlock* into rdi - __ movq(rdi, rax); + __ mov(rdi, rax); // Pop all the frames we must move/replace. // @@ -2800,13 +2894,13 @@ void SharedRuntime::generate_uncommon_trap_blob() { // 3: caller of deopting frame (could be compiled/interpreted). // Pop self-frame. We have no frame, and must rely only on rax and rsp. - __ addq(rsp, (SimpleRuntimeFrame::framesize - 2) << LogBytesPerInt); // Epilog! + __ addptr(rsp, (SimpleRuntimeFrame::framesize - 2) << LogBytesPerInt); // Epilog! // Pop deoptimized frame (int) __ movl(rcx, Address(rdi, Deoptimization::UnrollBlock:: size_of_deoptimized_frame_offset_in_bytes())); - __ addq(rsp, rcx); + __ addptr(rsp, rcx); // rsp should be pointing at the return address to the caller (3) @@ -2817,17 +2911,17 @@ void SharedRuntime::generate_uncommon_trap_blob() { } // Load address of array of frame pcs into rcx (address*) - __ movq(rcx, - Address(rdi, - Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); + __ movptr(rcx, + Address(rdi, + Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); // Trash the return pc - __ addq(rsp, wordSize); + __ addptr(rsp, wordSize); // Load address of array of frame sizes into rsi (intptr_t*) - __ movq(rsi, Address(rdi, - Deoptimization::UnrollBlock:: - frame_sizes_offset_in_bytes())); + __ movptr(rsi, Address(rdi, + Deoptimization::UnrollBlock:: + frame_sizes_offset_in_bytes())); // Counter __ movl(rdx, Address(rdi, @@ -2835,9 +2929,9 @@ void SharedRuntime::generate_uncommon_trap_blob() { number_of_frames_offset_in_bytes())); // (int) // Pick up the initial fp we should save - __ movq(rbp, - Address(rdi, - Deoptimization::UnrollBlock::initial_fp_offset_in_bytes())); + __ movptr(rbp, + Address(rdi, + Deoptimization::UnrollBlock::initial_fp_offset_in_bytes())); // Now adjust the caller's stack to make up for the extra locals but // record the original sp so that we can save it in the skeletal @@ -2846,34 +2940,34 @@ void SharedRuntime::generate_uncommon_trap_blob() { const Register sender_sp = r8; - __ movq(sender_sp, rsp); + __ mov(sender_sp, rsp); __ movl(rbx, Address(rdi, Deoptimization::UnrollBlock:: caller_adjustment_offset_in_bytes())); // (int) - __ subq(rsp, rbx); + __ subptr(rsp, rbx); // Push interpreter frames in a loop Label loop; __ bind(loop); - __ movq(rbx, Address(rsi, 0)); // Load frame size - __ subq(rbx, 2 * wordSize); // We'll push pc and rbp by hand - __ pushq(Address(rcx, 0)); // Save return address - __ enter(); // Save old & set new rbp - __ subq(rsp, rbx); // Prolog - __ movq(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), - sender_sp); // Make it walkable + __ movptr(rbx, Address(rsi, 0)); // Load frame size + __ subptr(rbx, 2 * wordSize); // We'll push pc and rbp by hand + __ pushptr(Address(rcx, 0)); // Save return address + __ enter(); // Save old & set new rbp + __ subptr(rsp, rbx); // Prolog + __ movptr(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), + sender_sp); // Make it walkable // This value is corrected by layout_activation_impl - __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int)NULL_WORD ); - __ movq(sender_sp, rsp); // Pass sender_sp to next frame - __ addq(rsi, wordSize); // Bump array pointer (sizes) - __ addq(rcx, wordSize); // Bump array pointer (pcs) - __ decrementl(rdx); // Decrement counter + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD ); + __ mov(sender_sp, rsp); // Pass sender_sp to next frame + __ addptr(rsi, wordSize); // Bump array pointer (sizes) + __ addptr(rcx, wordSize); // Bump array pointer (pcs) + __ decrementl(rdx); // Decrement counter __ jcc(Assembler::notZero, loop); - __ pushq(Address(rcx, 0)); // Save final return address + __ pushptr(Address(rcx, 0)); // Save final return address // Re-push self-frame __ enter(); // Save old & set new rbp - __ subq(rsp, (SimpleRuntimeFrame::framesize - 4) << LogBytesPerInt); + __ subptr(rsp, (SimpleRuntimeFrame::framesize - 4) << LogBytesPerInt); // Prolog // Use rbp because the frames look interpreted now @@ -2886,7 +2980,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { // // BasicType unpack_frames(JavaThread* thread, int exec_mode); - __ movq(c_rarg0, r15_thread); + __ mov(c_rarg0, r15_thread); __ movl(c_rarg1, Deoptimization::Unpack_uncommon_trap); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames))); @@ -2933,7 +3027,7 @@ static SafepointBlob* generate_handler_blob(address call_ptr, bool cause_return) // Make room for return address (or push it again) if (!cause_return) { - __ pushq(rbx); + __ push(rbx); } // Save registers, fpu state, and flags @@ -2950,12 +3044,12 @@ static SafepointBlob* generate_handler_blob(address call_ptr, bool cause_return) if (!cause_return) { // overwrite the dummy value we pushed on entry - __ movq(c_rarg0, Address(r15_thread, JavaThread::saved_exception_pc_offset())); - __ movq(Address(rbp, wordSize), c_rarg0); + __ movptr(c_rarg0, Address(r15_thread, JavaThread::saved_exception_pc_offset())); + __ movptr(Address(rbp, wordSize), c_rarg0); } // Do the call - __ movq(c_rarg0, r15_thread); + __ mov(c_rarg0, r15_thread); __ call(RuntimeAddress(call_ptr)); // Set an oopmap for the call site. This oopmap will map all @@ -2969,7 +3063,7 @@ static SafepointBlob* generate_handler_blob(address call_ptr, bool cause_return) __ reset_last_Java_frame(false, false); - __ cmpq(Address(r15_thread, Thread::pending_exception_offset()), (int)NULL_WORD); + __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::equal, noException); // Exception pending @@ -3023,7 +3117,7 @@ static RuntimeStub* generate_resolve_blob(address destination, const char* name) __ set_last_Java_frame(noreg, noreg, NULL); - __ movq(c_rarg0, r15_thread); + __ mov(c_rarg0, r15_thread); __ call(RuntimeAddress(destination)); @@ -3040,14 +3134,14 @@ static RuntimeStub* generate_resolve_blob(address destination, const char* name) __ reset_last_Java_frame(false, false); // check for pending exceptions Label pending; - __ cmpq(Address(r15_thread, Thread::pending_exception_offset()), (int)NULL_WORD); + __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::notEqual, pending); // get the returned methodOop - __ movq(rbx, Address(r15_thread, JavaThread::vm_result_offset())); - __ movq(Address(rsp, RegisterSaver::rbx_offset_in_bytes()), rbx); + __ movptr(rbx, Address(r15_thread, JavaThread::vm_result_offset())); + __ movptr(Address(rsp, RegisterSaver::rbx_offset_in_bytes()), rbx); - __ movq(Address(rsp, RegisterSaver::rax_offset_in_bytes()), rax); + __ movptr(Address(rsp, RegisterSaver::rax_offset_in_bytes()), rax); RegisterSaver::restore_live_registers(masm); @@ -3065,7 +3159,7 @@ static RuntimeStub* generate_resolve_blob(address destination, const char* name) __ movptr(Address(r15_thread, JavaThread::vm_result_offset()), (int)NULL_WORD); - __ movq(rax, Address(r15_thread, Thread::pending_exception_offset())); + __ movptr(rax, Address(r15_thread, Thread::pending_exception_offset())); __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); // ------------- @@ -3154,8 +3248,8 @@ void OptoRuntime::generate_exception_blob() { address start = __ pc(); // Exception pc is 'return address' for stack walker - __ pushq(rdx); - __ subq(rsp, SimpleRuntimeFrame::return_off << LogBytesPerInt); // Prolog + __ push(rdx); + __ subptr(rsp, SimpleRuntimeFrame::return_off << LogBytesPerInt); // Prolog // Save callee-saved registers. See x86_64.ad. @@ -3163,14 +3257,14 @@ void OptoRuntime::generate_exception_blob() { // convention will save restore it in prolog/epilog) Other than that // there are no callee save registers now that adapter frames are gone. - __ movq(Address(rsp, SimpleRuntimeFrame::rbp_off << LogBytesPerInt), rbp); + __ movptr(Address(rsp, SimpleRuntimeFrame::rbp_off << LogBytesPerInt), rbp); // Store exception in Thread object. We cannot pass any arguments to the // handle_exception call, since we do not want to make any assumption // about the size of the frame where the exception happened in. // c_rarg0 is either rdi (Linux) or rcx (Windows). - __ movq(Address(r15_thread, JavaThread::exception_oop_offset()),rax); - __ movq(Address(r15_thread, JavaThread::exception_pc_offset()), rdx); + __ movptr(Address(r15_thread, JavaThread::exception_oop_offset()),rax); + __ movptr(Address(r15_thread, JavaThread::exception_pc_offset()), rdx); // This call does all the hard work. It checks if an exception handler // exists in the method. @@ -3181,7 +3275,7 @@ void OptoRuntime::generate_exception_blob() { // address OptoRuntime::handle_exception_C(JavaThread* thread) __ set_last_Java_frame(noreg, noreg, NULL); - __ movq(c_rarg0, r15_thread); + __ mov(c_rarg0, r15_thread); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, OptoRuntime::handle_exception_C))); // Set an oopmap for the call site. This oopmap will only be used if we @@ -3202,20 +3296,20 @@ void OptoRuntime::generate_exception_blob() { // convention will save restore it in prolog/epilog) Other than that // there are no callee save registers no that adapter frames are gone. - __ movq(rbp, Address(rsp, SimpleRuntimeFrame::rbp_off << LogBytesPerInt)); + __ movptr(rbp, Address(rsp, SimpleRuntimeFrame::rbp_off << LogBytesPerInt)); - __ addq(rsp, SimpleRuntimeFrame::return_off << LogBytesPerInt); // Epilog - __ popq(rdx); // No need for exception pc anymore + __ addptr(rsp, SimpleRuntimeFrame::return_off << LogBytesPerInt); // Epilog + __ pop(rdx); // No need for exception pc anymore // rax: exception handler // We have a handler in rax (could be deopt blob). - __ movq(r8, rax); + __ mov(r8, rax); // Get the exception oop - __ movq(rax, Address(r15_thread, JavaThread::exception_oop_offset())); + __ movptr(rax, Address(r15_thread, JavaThread::exception_oop_offset())); // Get the exception pc in case we are deoptimized - __ movq(rdx, Address(r15_thread, JavaThread::exception_pc_offset())); + __ movptr(rdx, Address(r15_thread, JavaThread::exception_pc_offset())); #ifdef ASSERT __ movptr(Address(r15_thread, JavaThread::exception_handler_pc_offset()), (int)NULL_WORD); __ movptr(Address(r15_thread, JavaThread::exception_pc_offset()), (int)NULL_WORD); diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp index 9d17fce5ff3..ad2606e99f3 100644 --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ // see the comment in stubRoutines.hpp #define __ _masm-> +#define a__ ((Assembler*)_masm)-> #ifdef PRODUCT #define BLOCK_COMMENT(str) /* nothing */ @@ -67,7 +68,7 @@ class StubGenerator: public StubCodeGenerator { #define inc_counter_np(counter) (0) #else void inc_counter_np_(int& counter) { - __ increment(ExternalAddress((address)&counter)); + __ incrementl(ExternalAddress((address)&counter)); } #define inc_counter_np(counter) \ BLOCK_COMMENT("inc_counter " #counter); \ @@ -137,16 +138,16 @@ class StubGenerator: public StubCodeGenerator { // stub code __ enter(); - __ movl(rcx, parameter_size); // parameter counter - __ shll(rcx, Interpreter::logStackElementSize()); // convert parameter count to bytes - __ addl(rcx, locals_count_in_bytes); // reserve space for register saves - __ subl(rsp, rcx); - __ andl(rsp, -(StackAlignmentInBytes)); // Align stack + __ movptr(rcx, parameter_size); // parameter counter + __ shlptr(rcx, Interpreter::logStackElementSize()); // convert parameter count to bytes + __ addptr(rcx, locals_count_in_bytes); // reserve space for register saves + __ subptr(rsp, rcx); + __ andptr(rsp, -(StackAlignmentInBytes)); // Align stack // save rdi, rsi, & rbx, according to C calling conventions - __ movl(saved_rdi, rdi); - __ movl(saved_rsi, rsi); - __ movl(saved_rbx, rbx); + __ movptr(saved_rdi, rdi); + __ movptr(saved_rsi, rsi); + __ movptr(saved_rbx, rbx); // save and initialize %mxcsr if (sse_save) { Label skip_ldmx; @@ -166,8 +167,8 @@ class StubGenerator: public StubCodeGenerator { #ifdef ASSERT // make sure we have no pending exceptions { Label L; - __ movl(rcx, thread); - __ cmpl(Address(rcx, Thread::pending_exception_offset()), NULL_WORD); + __ movptr(rcx, thread); + __ cmpptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::equal, L); __ stop("StubRoutines::call_stub: entered with pending exception"); __ bind(L); @@ -189,20 +190,20 @@ class StubGenerator: public StubCodeGenerator { // source is rdx[rcx: N-1..0] // dest is rsp[rbx: 0..N-1] - __ movl(rdx, parameters); // parameter pointer - __ xorl(rbx, rbx); + __ movptr(rdx, parameters); // parameter pointer + __ xorptr(rbx, rbx); __ BIND(loop); if (TaggedStackInterpreter) { - __ movl(rax, Address(rdx, rcx, Interpreter::stackElementScale(), + __ movptr(rax, Address(rdx, rcx, Interpreter::stackElementScale(), -2*wordSize)); // get tag - __ movl(Address(rsp, rbx, Interpreter::stackElementScale(), + __ movptr(Address(rsp, rbx, Interpreter::stackElementScale(), Interpreter::expr_tag_offset_in_bytes(0)), rax); // store tag } // get parameter - __ movl(rax, Address(rdx, rcx, Interpreter::stackElementScale(), -wordSize)); - __ movl(Address(rsp, rbx, Interpreter::stackElementScale(), + __ movptr(rax, Address(rdx, rcx, Interpreter::stackElementScale(), -wordSize)); + __ movptr(Address(rsp, rbx, Interpreter::stackElementScale(), Interpreter::expr_offset_in_bytes(0)), rax); // store parameter __ increment(rbx); __ decrement(rcx); @@ -210,9 +211,9 @@ class StubGenerator: public StubCodeGenerator { // call Java function __ BIND(parameters_done); - __ movl(rbx, method); // get methodOop - __ movl(rax, entry_point); // get entry_point - __ movl(rsi, rsp); // set sender sp + __ movptr(rbx, method); // get methodOop + __ movptr(rax, entry_point); // get entry_point + __ mov(rsi, rsp); // set sender sp BLOCK_COMMENT("call Java function"); __ call(rax); @@ -225,7 +226,7 @@ class StubGenerator: public StubCodeGenerator { // store result depending on type // (everything that is not T_LONG, T_FLOAT or T_DOUBLE is treated as T_INT) - __ movl(rdi, result); + __ movptr(rdi, result); Label is_long, is_float, is_double, exit; __ movl(rsi, result_type); __ cmpl(rsi, T_LONG); @@ -243,7 +244,7 @@ class StubGenerator: public StubCodeGenerator { __ verify_FPU(0, "generate_call_stub"); // pop parameters - __ leal(rsp, rsp_after_call); + __ lea(rsp, rsp_after_call); // restore %mxcsr if (sse_save) { @@ -251,13 +252,13 @@ class StubGenerator: public StubCodeGenerator { } // restore rdi, rsi and rbx, - __ movl(rbx, saved_rbx); - __ movl(rsi, saved_rsi); - __ movl(rdi, saved_rdi); - __ addl(rsp, 4*wordSize); + __ movptr(rbx, saved_rbx); + __ movptr(rsi, saved_rsi); + __ movptr(rdi, saved_rdi); + __ addptr(rsp, 4*wordSize); // return - __ popl(rbp); + __ pop(rbp); __ ret(0); // handle return types different from T_INT @@ -291,7 +292,7 @@ class StubGenerator: public StubCodeGenerator { // return above that handles interpreter returns. BLOCK_COMMENT("call_stub_compiled_return:"); - StubRoutines::i486::set_call_stub_compiled_return( __ pc()); + StubRoutines::x86::set_call_stub_compiled_return( __ pc()); #ifdef COMPILER2 if (UseSSE >= 2) { @@ -337,12 +338,12 @@ class StubGenerator: public StubCodeGenerator { address start = __ pc(); // get thread directly - __ movl(rcx, thread); + __ movptr(rcx, thread); #ifdef ASSERT // verify that threads correspond { Label L; __ get_thread(rbx); - __ cmpl(rbx, rcx); + __ cmpptr(rbx, rcx); __ jcc(Assembler::equal, L); __ stop("StubRoutines::catch_exception: threads must correspond"); __ bind(L); @@ -350,7 +351,7 @@ class StubGenerator: public StubCodeGenerator { #endif // set pending exception __ verify_oop(rax); - __ movl(Address(rcx, Thread::pending_exception_offset()), rax ); + __ movptr(Address(rcx, Thread::pending_exception_offset()), rax ); __ lea(Address(rcx, Thread::exception_file_offset ()), ExternalAddress((address)__FILE__)); __ movl(Address(rcx, Thread::exception_line_offset ()), __LINE__ ); @@ -389,7 +390,7 @@ class StubGenerator: public StubCodeGenerator { // make sure this code is only executed if there is a pending exception { Label L; __ get_thread(rcx); - __ cmpl(Address(rcx, Thread::pending_exception_offset()), NULL_WORD); + __ cmpptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::notEqual, L); __ stop("StubRoutines::forward exception: no pending exception (1)"); __ bind(L); @@ -397,21 +398,21 @@ class StubGenerator: public StubCodeGenerator { #endif // compute exception handler into rbx, - __ movl(rax, Address(rsp, 0)); + __ movptr(rax, Address(rsp, 0)); BLOCK_COMMENT("call exception_handler_for_return_address"); __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), rax); - __ movl(rbx, rax); + __ mov(rbx, rax); // setup rax, & rdx, remove return address & clear pending exception __ get_thread(rcx); - __ popl(rdx); - __ movl(rax, Address(rcx, Thread::pending_exception_offset())); - __ movl(Address(rcx, Thread::pending_exception_offset()), NULL_WORD); + __ pop(rdx); + __ movptr(rax, Address(rcx, Thread::pending_exception_offset())); + __ movptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD); #ifdef ASSERT // make sure exception is set { Label L; - __ testl(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::notEqual, L); __ stop("StubRoutines::forward exception: no pending exception (2)"); __ bind(L); @@ -447,13 +448,13 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, "StubRoutines", "atomic_xchg"); address start = __ pc(); - __ pushl(rdx); + __ push(rdx); Address exchange(rsp, 2 * wordSize); Address dest_addr(rsp, 3 * wordSize); __ movl(rax, exchange); - __ movl(rdx, dest_addr); - __ xchg(rax, Address(rdx, 0)); - __ popl(rdx); + __ movptr(rdx, dest_addr); + __ xchgl(rax, Address(rdx, 0)); + __ pop(rdx); __ ret(0); return start; @@ -476,8 +477,8 @@ class StubGenerator: public StubCodeGenerator { if (CheckJNICalls && UseSSE > 0 ) { Label ok_ret; ExternalAddress mxcsr_std(StubRoutines::addr_mxcsr_std()); - __ pushl(rax); - __ subl(rsp, wordSize); // allocate a temp location + __ push(rax); + __ subptr(rsp, wordSize); // allocate a temp location __ stmxcsr(mxcsr_save); __ movl(rax, mxcsr_save); __ andl(rax, MXCSR_MASK); @@ -489,8 +490,8 @@ class StubGenerator: public StubCodeGenerator { __ ldmxcsr(mxcsr_std); __ bind(ok_ret); - __ addl(rsp, wordSize); - __ popl(rax); + __ addptr(rsp, wordSize); + __ pop(rax); } __ ret(0); @@ -514,8 +515,8 @@ class StubGenerator: public StubCodeGenerator { if (CheckJNICalls) { Label ok_ret; - __ pushl(rax); - __ subl(rsp, wordSize); // allocate a temp location + __ push(rax); + __ subptr(rsp, wordSize); // allocate a temp location __ fnstcw(fpu_cntrl_wrd_save); __ movl(rax, fpu_cntrl_wrd_save); __ andl(rax, FPU_CNTRL_WRD_MASK); @@ -528,8 +529,8 @@ class StubGenerator: public StubCodeGenerator { __ fldcw(fpu_std); __ bind(ok_ret); - __ addl(rsp, wordSize); - __ popl(rax); + __ addptr(rsp, wordSize); + __ pop(rax); } __ ret(0); @@ -563,22 +564,22 @@ class StubGenerator: public StubCodeGenerator { assert(FPUStateSizeInWords == 27, "update stack layout"); // Save outgoing argument to stack across push_FPU_state() - __ subl(rsp, wordSize * 2); + __ subptr(rsp, wordSize * 2); __ fstp_d(Address(rsp, 0)); // Save CPU & FPU state - __ pushl(rbx); - __ pushl(rcx); - __ pushl(rsi); - __ pushl(rdi); - __ pushl(rbp); + __ push(rbx); + __ push(rcx); + __ push(rsi); + __ push(rdi); + __ push(rbp); __ push_FPU_state(); // push_FPU_state() resets the FP top of stack // Load original double into FP top of stack __ fld_d(Address(rsp, saved_argument_off * wordSize)); // Store double into stack as outgoing argument - __ subl(rsp, wordSize*2); + __ subptr(rsp, wordSize*2); __ fst_d(Address(rsp, 0)); // Prepare FPU for doing math in C-land @@ -592,12 +593,12 @@ class StubGenerator: public StubCodeGenerator { // Restore CPU & FPU state __ pop_FPU_state(); - __ popl(rbp); - __ popl(rdi); - __ popl(rsi); - __ popl(rcx); - __ popl(rbx); - __ addl(rsp, wordSize * 2); + __ pop(rbp); + __ pop(rdi); + __ pop(rsi); + __ pop(rcx); + __ pop(rbx); + __ addptr(rsp, wordSize * 2); __ ret(0); @@ -613,13 +614,13 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access"); address start = __ pc(); - __ pushl(0); // hole for return address-to-be - __ pushad(); // push registers + __ push(0); // hole for return address-to-be + __ pusha(); // push registers Address next_pc(rsp, RegisterImpl::number_of_registers * BytesPerWord); BLOCK_COMMENT("call handle_unsafe_access"); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, handle_unsafe_access))); - __ movl(next_pc, rax); // stuff next address - __ popad(); + __ movptr(next_pc, rax); // stuff next address + __ popa(); __ ret(0); // jump to next address return start; @@ -643,62 +644,62 @@ class StubGenerator: public StubCodeGenerator { // [tos + 5]: saved rax, - saved by caller and bashed Label exit, error; - __ pushfd(); - __ increment(ExternalAddress((address) StubRoutines::verify_oop_count_addr())); - __ pushl(rdx); // save rdx + __ pushf(); + __ incrementl(ExternalAddress((address) StubRoutines::verify_oop_count_addr())); + __ push(rdx); // save rdx // make sure object is 'reasonable' - __ movl(rax, Address(rsp, 4 * wordSize)); // get object - __ testl(rax, rax); + __ movptr(rax, Address(rsp, 4 * wordSize)); // get object + __ testptr(rax, rax); __ jcc(Assembler::zero, exit); // if obj is NULL it is ok // Check if the oop is in the right area of memory const int oop_mask = Universe::verify_oop_mask(); const int oop_bits = Universe::verify_oop_bits(); - __ movl(rdx, rax); - __ andl(rdx, oop_mask); - __ cmpl(rdx, oop_bits); + __ mov(rdx, rax); + __ andptr(rdx, oop_mask); + __ cmpptr(rdx, oop_bits); __ jcc(Assembler::notZero, error); // make sure klass is 'reasonable' - __ movl(rax, Address(rax, oopDesc::klass_offset_in_bytes())); // get klass - __ testl(rax, rax); + __ movptr(rax, Address(rax, oopDesc::klass_offset_in_bytes())); // get klass + __ testptr(rax, rax); __ jcc(Assembler::zero, error); // if klass is NULL it is broken // Check if the klass is in the right area of memory const int klass_mask = Universe::verify_klass_mask(); const int klass_bits = Universe::verify_klass_bits(); - __ movl(rdx, rax); - __ andl(rdx, klass_mask); - __ cmpl(rdx, klass_bits); + __ mov(rdx, rax); + __ andptr(rdx, klass_mask); + __ cmpptr(rdx, klass_bits); __ jcc(Assembler::notZero, error); // make sure klass' klass is 'reasonable' - __ movl(rax, Address(rax, oopDesc::klass_offset_in_bytes())); // get klass' klass - __ testl(rax, rax); + __ movptr(rax, Address(rax, oopDesc::klass_offset_in_bytes())); // get klass' klass + __ testptr(rax, rax); __ jcc(Assembler::zero, error); // if klass' klass is NULL it is broken - __ movl(rdx, rax); - __ andl(rdx, klass_mask); - __ cmpl(rdx, klass_bits); + __ mov(rdx, rax); + __ andptr(rdx, klass_mask); + __ cmpptr(rdx, klass_bits); __ jcc(Assembler::notZero, error); // if klass not in right area // of memory it is broken too. // return if everything seems ok __ bind(exit); - __ movl(rax, Address(rsp, 5 * wordSize)); // get saved rax, back - __ popl(rdx); // restore rdx - __ popfd(); // restore EFLAGS + __ movptr(rax, Address(rsp, 5 * wordSize)); // get saved rax, back + __ pop(rdx); // restore rdx + __ popf(); // restore EFLAGS __ ret(3 * wordSize); // pop arguments // handle errors __ bind(error); - __ movl(rax, Address(rsp, 5 * wordSize)); // get saved rax, back - __ popl(rdx); // get saved rdx back - __ popfd(); // get saved EFLAGS off stack -- will be ignored - __ pushad(); // push registers (eip = return address & msg are already pushed) + __ movptr(rax, Address(rsp, 5 * wordSize)); // get saved rax, back + __ pop(rdx); // get saved rdx back + __ popf(); // get saved EFLAGS off stack -- will be ignored + __ pusha(); // push registers (eip = return address & msg are already pushed) BLOCK_COMMENT("call MacroAssembler::debug"); - __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug))); - __ popad(); + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug32))); + __ popa(); __ ret(3 * wordSize); // pop arguments return start; } @@ -717,12 +718,12 @@ class StubGenerator: public StubCodeGenerator { case BarrierSet::G1SATBCT: case BarrierSet::G1SATBCTLogging: { - __ pushad(); // push registers - __ pushl(count); - __ pushl(start); + __ pusha(); // push registers + __ push(count); + __ push(start); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre)); __ addl(esp, wordSize * 2); - __ popad(); + __ popa(); } break; case BarrierSet::CardTableModRef: @@ -753,12 +754,12 @@ class StubGenerator: public StubCodeGenerator { case BarrierSet::G1SATBCT: case BarrierSet::G1SATBCTLogging: { - __ pushad(); // push registers - __ pushl(count); - __ pushl(start); + __ pusha(); // push registers + __ push(count); + __ push(start); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post)); __ addl(esp, wordSize * 2); - __ popad(); + __ popa(); } break; @@ -774,14 +775,14 @@ class StubGenerator: public StubCodeGenerator { const Register end = count; // elements count; end == start+count-1 assert_different_registers(start, end); - __ leal(end, Address(start, count, Address::times_4, -4)); - __ shrl(start, CardTableModRefBS::card_shift); - __ shrl(end, CardTableModRefBS::card_shift); - __ subl(end, start); // end --> count + __ lea(end, Address(start, count, Address::times_ptr, -wordSize)); + __ shrptr(start, CardTableModRefBS::card_shift); + __ shrptr(end, CardTableModRefBS::card_shift); + __ subptr(end, start); // end --> count __ BIND(L_loop); - ExternalAddress base((address)ct->byte_map_base); - Address index(start, count, Address::times_1, 0); - __ movbyte(ArrayAddress(base, index), 0); + intptr_t disp = (intptr_t) ct->byte_map_base; + Address cardtable(start, count, Address::times_1, disp); + __ movb(cardtable, 0); __ decrement(count); __ jcc(Assembler::greaterEqual, L_loop); } @@ -823,7 +824,7 @@ class StubGenerator: public StubCodeGenerator { __ movq(Address(from, to_from, Address::times_1, 40), mmx5); __ movq(Address(from, to_from, Address::times_1, 48), mmx6); __ movq(Address(from, to_from, Address::times_1, 56), mmx7); - __ addl(from, 64); + __ addptr(from, 64); __ BIND(L_copy_64_bytes); __ subl(qword_count, 8); __ jcc(Assembler::greaterEqual, L_copy_64_bytes_loop); @@ -835,7 +836,7 @@ class StubGenerator: public StubCodeGenerator { __ BIND(L_copy_8_bytes); __ movq(mmx0, Address(from, 0)); __ movq(Address(from, to_from, Address::times_1), mmx0); - __ addl(from, 8); + __ addptr(from, 8); __ decrement(qword_count); __ jcc(Assembler::greater, L_copy_8_bytes); __ BIND(L_exit); @@ -852,7 +853,7 @@ class StubGenerator: public StubCodeGenerator { Label L_0_count, L_exit, L_skip_align1, L_skip_align2, L_copy_byte; Label L_copy_2_bytes, L_copy_4_bytes, L_copy_64_bytes; - int shift = Address::times_4 - sf; + int shift = Address::times_ptr - sf; const Register from = rsi; // source array address const Register to = rdi; // destination array address @@ -861,22 +862,22 @@ class StubGenerator: public StubCodeGenerator { const Register saved_to = rdx; // saved destination array address __ enter(); // required for proper stackwalking of RuntimeStub frame - __ pushl(rsi); - __ pushl(rdi); - __ movl(from , Address(rsp, 12+ 4)); - __ movl(to , Address(rsp, 12+ 8)); + __ push(rsi); + __ push(rdi); + __ movptr(from , Address(rsp, 12+ 4)); + __ movptr(to , Address(rsp, 12+ 8)); __ movl(count, Address(rsp, 12+ 12)); if (t == T_OBJECT) { __ testl(count, count); __ jcc(Assembler::zero, L_0_count); gen_write_ref_array_pre_barrier(to, count); - __ movl(saved_to, to); // save 'to' + __ mov(saved_to, to); // save 'to' } *entry = __ pc(); // Entry point from conjoint arraycopy stub. BLOCK_COMMENT("Entry:"); - __ subl(to, from); // to --> to_from + __ subptr(to, from); // to --> to_from __ cmpl(count, 2< to_from + __ subptr(to, from); // to --> to_from if (VM_Version::supports_mmx()) { mmx_copy_forward(from, to_from, count); } else { @@ -1153,14 +1154,14 @@ class StubGenerator: public StubCodeGenerator { __ BIND(L_copy_8_bytes_loop); __ fild_d(Address(from, 0)); __ fistp_d(Address(from, to_from, Address::times_1)); - __ addl(from, 8); + __ addptr(from, 8); __ BIND(L_copy_8_bytes); __ decrement(count); __ jcc(Assembler::greaterEqual, L_copy_8_bytes_loop); } inc_copy_counter_np(T_LONG); __ leave(); // required for proper stackwalking of RuntimeStub frame - __ xorl(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ ret(0); return start; } @@ -1178,20 +1179,20 @@ class StubGenerator: public StubCodeGenerator { const Register end_from = rax; // source array end address __ enter(); // required for proper stackwalking of RuntimeStub frame - __ movl(from , Address(rsp, 8+0)); // from - __ movl(to , Address(rsp, 8+4)); // to - __ movl(count, Address(rsp, 8+8)); // count + __ movptr(from , Address(rsp, 8+0)); // from + __ movptr(to , Address(rsp, 8+4)); // to + __ movl2ptr(count, Address(rsp, 8+8)); // count *entry = __ pc(); // Entry point from generic arraycopy stub. BLOCK_COMMENT("Entry:"); // arrays overlap test - __ cmpl(to, from); + __ cmpptr(to, from); RuntimeAddress nooverlap(nooverlap_target); __ jump_cc(Assembler::belowEqual, nooverlap); - __ leal(end_from, Address(from, count, Address::times_8, 0)); - __ cmpl(to, end_from); - __ movl(from, Address(rsp, 8)); // from + __ lea(end_from, Address(from, count, Address::times_8, 0)); + __ cmpptr(to, end_from); + __ movptr(from, Address(rsp, 8)); // from __ jump_cc(Assembler::aboveEqual, nooverlap); __ jmpb(L_copy_8_bytes); @@ -1214,7 +1215,7 @@ class StubGenerator: public StubCodeGenerator { } inc_copy_counter_np(T_LONG); __ leave(); // required for proper stackwalking of RuntimeStub frame - __ xorl(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ ret(0); return start; } @@ -1251,14 +1252,14 @@ class StubGenerator: public StubCodeGenerator { Address super_cache_addr( sub_klass, sc_offset); // if the pointers are equal, we are done (e.g., String[] elements) - __ cmpl(sub_klass, super_klass_addr); + __ cmpptr(sub_klass, super_klass_addr); __ jcc(Assembler::equal, L_success); // check the supertype display: - __ movl(temp, super_check_offset_addr); + __ movl2ptr(temp, super_check_offset_addr); Address super_check_addr(sub_klass, temp, Address::times_1, 0); - __ movl(temp, super_check_addr); // load displayed supertype - __ cmpl(temp, super_klass_addr); // test the super type + __ movptr(temp, super_check_addr); // load displayed supertype + __ cmpptr(temp, super_klass_addr); // test the super type __ jcc(Assembler::equal, L_success); // if it was a primary super, we can just fail immediately @@ -1271,31 +1272,31 @@ class StubGenerator: public StubCodeGenerator { { // The repne_scan instruction uses fixed registers, which we must spill. // (We need a couple more temps in any case.) - __ pushl(rax); - __ pushl(rcx); - __ pushl(rdi); + __ push(rax); + __ push(rcx); + __ push(rdi); assert_different_registers(sub_klass, rax, rcx, rdi); - __ movl(rdi, secondary_supers_addr); + __ movptr(rdi, secondary_supers_addr); // Load the array length. __ movl(rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes())); // Skip to start of data. - __ addl(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + __ addptr(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); // Scan rcx words at [edi] for occurance of rax, // Set NZ/Z based on last compare - __ movl(rax, super_klass_addr); + __ movptr(rax, super_klass_addr); __ repne_scan(); // Unspill the temp. registers: - __ popl(rdi); - __ popl(rcx); - __ popl(rax); + __ pop(rdi); + __ pop(rcx); + __ pop(rax); } __ jcc(Assembler::notEqual, L_failure); // Success. Cache the super we found and proceed in triumph. - __ movl(temp, super_klass_addr); // note: rax, is dead - __ movl(super_cache_addr, temp); + __ movptr(temp, super_klass_addr); // note: rax, is dead + __ movptr(super_cache_addr, temp); if (!fall_through_on_success) __ jmp(L_success); @@ -1338,9 +1339,9 @@ class StubGenerator: public StubCodeGenerator { __ enter(); // required for proper stackwalking of RuntimeStub frame - __ pushl(rsi); - __ pushl(rdi); - __ pushl(rbx); + __ push(rsi); + __ push(rdi); + __ push(rbx); Address from_arg(rsp, 16+ 4); // from Address to_arg(rsp, 16+ 8); // to @@ -1349,9 +1350,9 @@ class StubGenerator: public StubCodeGenerator { Address ckval_arg(rsp, 16+20); // super_klass // Load up: - __ movl(from, from_arg); - __ movl(to, to_arg); - __ movl(length, length_arg); + __ movptr(from, from_arg); + __ movptr(to, to_arg); + __ movl2ptr(length, length_arg); *entry = __ pc(); // Entry point from generic arraycopy stub. BLOCK_COMMENT("Entry:"); @@ -1364,28 +1365,28 @@ class StubGenerator: public StubCodeGenerator { // checked. // Loop-invariant addresses. They are exclusive end pointers. - Address end_from_addr(from, length, Address::times_4, 0); - Address end_to_addr(to, length, Address::times_4, 0); + Address end_from_addr(from, length, Address::times_ptr, 0); + Address end_to_addr(to, length, Address::times_ptr, 0); Register end_from = from; // re-use Register end_to = to; // re-use Register count = length; // re-use // Loop-variant addresses. They assume post-incremented count < 0. - Address from_element_addr(end_from, count, Address::times_4, 0); - Address to_element_addr(end_to, count, Address::times_4, 0); + Address from_element_addr(end_from, count, Address::times_ptr, 0); + Address to_element_addr(end_to, count, Address::times_ptr, 0); Address elem_klass_addr(elem, oopDesc::klass_offset_in_bytes()); // Copy from low to high addresses, indexed from the end of each array. - __ leal(end_from, end_from_addr); - __ leal(end_to, end_to_addr); + __ lea(end_from, end_from_addr); + __ lea(end_to, end_to_addr); gen_write_ref_array_pre_barrier(to, count); assert(length == count, ""); // else fix next line: - __ negl(count); // negate and test the length + __ negptr(count); // negate and test the length __ jccb(Assembler::notZero, L_load_element); // Empty array: Nothing to do. - __ xorl(rax, rax); // return 0 on (trivial) success + __ xorptr(rax, rax); // return 0 on (trivial) success __ jmp(L_done); // ======== begin loop ======== @@ -1396,20 +1397,20 @@ class StubGenerator: public StubCodeGenerator { __ align(16); __ BIND(L_store_element); - __ movl(to_element_addr, elem); // store the oop + __ movptr(to_element_addr, elem); // store the oop __ increment(count); // increment the count toward zero __ jccb(Assembler::zero, L_do_card_marks); // ======== loop entry is here ======== __ BIND(L_load_element); - __ movl(elem, from_element_addr); // load the oop - __ testl(elem, elem); + __ movptr(elem, from_element_addr); // load the oop + __ testptr(elem, elem); __ jccb(Assembler::zero, L_store_element); // (Could do a trick here: Remember last successful non-null // element stored and make a quick oop equality check on it.) - __ movl(elem_klass, elem_klass_addr); // query the object klass + __ movptr(elem_klass, elem_klass_addr); // query the object klass generate_type_check(elem_klass, ckoff_arg, ckval_arg, temp, &L_store_element, NULL); // (On fall-through, we have failed the element type check.) @@ -1420,25 +1421,25 @@ class StubGenerator: public StubCodeGenerator { // Emit GC store barriers for the oops we have copied (length_arg + count), // and report their number to the caller. __ addl(count, length_arg); // transfers = (length - remaining) - __ movl(rax, count); // save the value - __ notl(rax); // report (-1^K) to caller - __ movl(to, to_arg); // reload + __ movl2ptr(rax, count); // save the value + __ notptr(rax); // report (-1^K) to caller + __ movptr(to, to_arg); // reload assert_different_registers(to, count, rax); gen_write_ref_array_post_barrier(to, count); __ jmpb(L_done); // Come here on success only. __ BIND(L_do_card_marks); - __ movl(count, length_arg); - __ movl(to, to_arg); // reload + __ movl2ptr(count, length_arg); + __ movptr(to, to_arg); // reload gen_write_ref_array_post_barrier(to, count); - __ xorl(rax, rax); // return 0 on success + __ xorptr(rax, rax); // return 0 on success // Common exit point (success or failure). __ BIND(L_done); - __ popl(rbx); - __ popl(rdi); - __ popl(rsi); + __ pop(rbx); + __ pop(rdi); + __ pop(rsi); inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr); __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -1480,24 +1481,24 @@ class StubGenerator: public StubCodeGenerator { const Register count = rcx; // elements count __ enter(); // required for proper stackwalking of RuntimeStub frame - __ pushl(rsi); - __ pushl(rdi); + __ push(rsi); + __ push(rdi); Address from_arg(rsp, 12+ 4); // from Address to_arg(rsp, 12+ 8); // to Address count_arg(rsp, 12+12); // byte count // Load up: - __ movl(from , from_arg); - __ movl(to , to_arg); - __ movl(count, count_arg); + __ movptr(from , from_arg); + __ movptr(to , to_arg); + __ movl2ptr(count, count_arg); // bump this on entry, not on exit: inc_counter_np(SharedRuntime::_unsafe_array_copy_ctr); const Register bits = rsi; - __ movl(bits, from); - __ orl(bits, to); - __ orl(bits, count); + __ mov(bits, from); + __ orptr(bits, to); + __ orptr(bits, count); __ testl(bits, BytesPerLong-1); __ jccb(Assembler::zero, L_long_aligned); @@ -1509,20 +1510,20 @@ class StubGenerator: public StubCodeGenerator { __ jump_cc(Assembler::notZero, RuntimeAddress(byte_copy_entry)); __ BIND(L_short_aligned); - __ shrl(count, LogBytesPerShort); // size => short_count + __ shrptr(count, LogBytesPerShort); // size => short_count __ movl(count_arg, count); // update 'count' __ jump(RuntimeAddress(short_copy_entry)); __ BIND(L_int_aligned); - __ shrl(count, LogBytesPerInt); // size => int_count + __ shrptr(count, LogBytesPerInt); // size => int_count __ movl(count_arg, count); // update 'count' __ jump(RuntimeAddress(int_copy_entry)); __ BIND(L_long_aligned); - __ shrl(count, LogBytesPerLong); // size => qword_count + __ shrptr(count, LogBytesPerLong); // size => qword_count __ movl(count_arg, count); // update 'count' - __ popl(rdi); // Do pops here since jlong_arraycopy stub does not do it. - __ popl(rsi); + __ pop(rdi); // Do pops here since jlong_arraycopy stub does not do it. + __ pop(rsi); __ jump(RuntimeAddress(long_copy_entry)); return start; @@ -1595,8 +1596,8 @@ class StubGenerator: public StubCodeGenerator { address start = __ pc(); __ enter(); // required for proper stackwalking of RuntimeStub frame - __ pushl(rsi); - __ pushl(rdi); + __ push(rsi); + __ push(rdi); // bump this on entry, not on exit: inc_counter_np(SharedRuntime::_generic_array_copy_ctr); @@ -1629,27 +1630,27 @@ class StubGenerator: public StubCodeGenerator { const Register length = rcx; // transfer count // if (src == NULL) return -1; - __ movl(src, SRC); // src oop - __ testl(src, src); + __ movptr(src, SRC); // src oop + __ testptr(src, src); __ jccb(Assembler::zero, L_failed_0); // if (src_pos < 0) return -1; - __ movl(src_pos, SRC_POS); // src_pos + __ movl2ptr(src_pos, SRC_POS); // src_pos __ testl(src_pos, src_pos); __ jccb(Assembler::negative, L_failed_0); // if (dst == NULL) return -1; - __ movl(dst, DST); // dst oop - __ testl(dst, dst); + __ movptr(dst, DST); // dst oop + __ testptr(dst, dst); __ jccb(Assembler::zero, L_failed_0); // if (dst_pos < 0) return -1; - __ movl(dst_pos, DST_POS); // dst_pos + __ movl2ptr(dst_pos, DST_POS); // dst_pos __ testl(dst_pos, dst_pos); __ jccb(Assembler::negative, L_failed_0); // if (length < 0) return -1; - __ movl(length, LENGTH); // length + __ movl2ptr(length, LENGTH); // length __ testl(length, length); __ jccb(Assembler::negative, L_failed_0); @@ -1657,18 +1658,18 @@ class StubGenerator: public StubCodeGenerator { Address src_klass_addr(src, oopDesc::klass_offset_in_bytes()); Address dst_klass_addr(dst, oopDesc::klass_offset_in_bytes()); const Register rcx_src_klass = rcx; // array klass - __ movl(rcx_src_klass, Address(src, oopDesc::klass_offset_in_bytes())); + __ movptr(rcx_src_klass, Address(src, oopDesc::klass_offset_in_bytes())); #ifdef ASSERT // assert(src->klass() != NULL); BLOCK_COMMENT("assert klasses not null"); { Label L1, L2; - __ testl(rcx_src_klass, rcx_src_klass); + __ testptr(rcx_src_klass, rcx_src_klass); __ jccb(Assembler::notZero, L2); // it is broken if klass is NULL __ bind(L1); __ stop("broken null klass"); __ bind(L2); - __ cmpl(dst_klass_addr, 0); + __ cmpptr(dst_klass_addr, (int32_t)NULL_WORD); __ jccb(Assembler::equal, L1); // this would be broken also BLOCK_COMMENT("assert done"); } @@ -1692,7 +1693,7 @@ class StubGenerator: public StubCodeGenerator { __ jcc(Assembler::equal, L_objArray); // if (src->klass() != dst->klass()) return -1; - __ cmpl(rcx_src_klass, dst_klass_addr); + __ cmpptr(rcx_src_klass, dst_klass_addr); __ jccb(Assembler::notEqual, L_failed_0); const Register rcx_lh = rcx; // layout helper @@ -1726,12 +1727,12 @@ class StubGenerator: public StubCodeGenerator { const Register dst_array = dst; // dst array offset const Register rdi_elsize = rdi; // log2 element size - __ movl(rsi_offset, rcx_lh); - __ shrl(rsi_offset, Klass::_lh_header_size_shift); - __ andl(rsi_offset, Klass::_lh_header_size_mask); // array_offset - __ addl(src_array, rsi_offset); // src array offset - __ addl(dst_array, rsi_offset); // dst array offset - __ andl(rcx_lh, Klass::_lh_log2_element_size_mask); // log2 elsize + __ mov(rsi_offset, rcx_lh); + __ shrptr(rsi_offset, Klass::_lh_header_size_shift); + __ andptr(rsi_offset, Klass::_lh_header_size_mask); // array_offset + __ addptr(src_array, rsi_offset); // src array offset + __ addptr(dst_array, rsi_offset); // dst array offset + __ andptr(rcx_lh, Klass::_lh_log2_element_size_mask); // log2 elsize // next registers should be set before the jump to corresponding stub const Register from = src; // source array address @@ -1743,17 +1744,17 @@ class StubGenerator: public StubCodeGenerator { #define COUNT Address(rsp, 12+12) // Only for oop arraycopy BLOCK_COMMENT("scale indexes to element size"); - __ movl(rsi, SRC_POS); // src_pos - __ shll(rsi); // src_pos << rcx (log2 elsize) + __ movl2ptr(rsi, SRC_POS); // src_pos + __ shlptr(rsi); // src_pos << rcx (log2 elsize) assert(src_array == from, ""); - __ addl(from, rsi); // from = src_array + SRC_POS << log2 elsize - __ movl(rdi, DST_POS); // dst_pos - __ shll(rdi); // dst_pos << rcx (log2 elsize) + __ addptr(from, rsi); // from = src_array + SRC_POS << log2 elsize + __ movl2ptr(rdi, DST_POS); // dst_pos + __ shlptr(rdi); // dst_pos << rcx (log2 elsize) assert(dst_array == to, ""); - __ addl(to, rdi); // to = dst_array + DST_POS << log2 elsize - __ movl(FROM, from); // src_addr - __ movl(rdi_elsize, rcx_lh); // log2 elsize - __ movl(count, LENGTH); // elements count + __ addptr(to, rdi); // to = dst_array + DST_POS << log2 elsize + __ movptr(FROM, from); // src_addr + __ mov(rdi_elsize, rcx_lh); // log2 elsize + __ movl2ptr(count, LENGTH); // elements count BLOCK_COMMENT("choose copy loop based on element size"); __ cmpl(rdi_elsize, 0); @@ -1767,15 +1768,15 @@ class StubGenerator: public StubCodeGenerator { __ cmpl(rdi_elsize, LogBytesPerLong); __ jccb(Assembler::notEqual, L_failed); #endif - __ popl(rdi); // Do pops here since jlong_arraycopy stub does not do it. - __ popl(rsi); + __ pop(rdi); // Do pops here since jlong_arraycopy stub does not do it. + __ pop(rsi); __ jump(RuntimeAddress(entry_jlong_arraycopy)); __ BIND(L_failed); - __ xorl(rax, rax); - __ notl(rax); // return -1 - __ popl(rdi); - __ popl(rsi); + __ xorptr(rax, rax); + __ notptr(rax); // return -1 + __ pop(rdi); + __ pop(rsi); __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -1785,7 +1786,7 @@ class StubGenerator: public StubCodeGenerator { Label L_plain_copy, L_checkcast_copy; // test array classes for subtyping - __ cmpl(rcx_src_klass, dst_klass_addr); // usual case is exact equality + __ cmpptr(rcx_src_klass, dst_klass_addr); // usual case is exact equality __ jccb(Assembler::notEqual, L_checkcast_copy); // Identically typed arrays can be copied without element-wise checks. @@ -1793,15 +1794,15 @@ class StubGenerator: public StubCodeGenerator { arraycopy_range_checks(src, src_pos, dst, dst_pos, LENGTH, L_failed); __ BIND(L_plain_copy); - __ movl(count, LENGTH); // elements count - __ movl(src_pos, SRC_POS); // reload src_pos - __ leal(from, Address(src, src_pos, Address::times_4, - arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr - __ movl(dst_pos, DST_POS); // reload dst_pos - __ leal(to, Address(dst, dst_pos, Address::times_4, - arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr - __ movl(FROM, from); // src_addr - __ movl(TO, to); // dst_addr + __ movl2ptr(count, LENGTH); // elements count + __ movl2ptr(src_pos, SRC_POS); // reload src_pos + __ lea(from, Address(src, src_pos, Address::times_ptr, + arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr + __ movl2ptr(dst_pos, DST_POS); // reload dst_pos + __ lea(to, Address(dst, dst_pos, Address::times_ptr, + arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr + __ movptr(FROM, from); // src_addr + __ movptr(TO, to); // dst_addr __ movl(COUNT, count); // count __ jump(RuntimeAddress(entry_oop_arraycopy)); @@ -1821,37 +1822,37 @@ class StubGenerator: public StubCodeGenerator { Address dst_klass_lh_addr(rsi_dst_klass, lh_offset); // Before looking at dst.length, make sure dst is also an objArray. - __ movl(rsi_dst_klass, dst_klass_addr); + __ movptr(rsi_dst_klass, dst_klass_addr); __ cmpl(dst_klass_lh_addr, objArray_lh); __ jccb(Assembler::notEqual, L_failed); // It is safe to examine both src.length and dst.length. - __ movl(src_pos, SRC_POS); // reload rsi + __ movl2ptr(src_pos, SRC_POS); // reload rsi arraycopy_range_checks(src, src_pos, dst, dst_pos, LENGTH, L_failed); // (Now src_pos and dst_pos are killed, but not src and dst.) // We'll need this temp (don't forget to pop it after the type check). - __ pushl(rbx); + __ push(rbx); Register rbx_src_klass = rbx; - __ movl(rbx_src_klass, rcx_src_klass); // spill away from rcx - __ movl(rsi_dst_klass, dst_klass_addr); + __ mov(rbx_src_klass, rcx_src_klass); // spill away from rcx + __ movptr(rsi_dst_klass, dst_klass_addr); Address super_check_offset_addr(rsi_dst_klass, sco_offset); Label L_fail_array_check; generate_type_check(rbx_src_klass, super_check_offset_addr, dst_klass_addr, rdi_temp, NULL, &L_fail_array_check); // (On fall-through, we have passed the array type check.) - __ popl(rbx); + __ pop(rbx); __ jmp(L_plain_copy); __ BIND(L_fail_array_check); // Reshuffle arguments so we can call checkcast_arraycopy: // match initial saves for checkcast_arraycopy - // pushl(rsi); // already done; see above - // pushl(rdi); // already done; see above - // pushl(rbx); // already done; see above + // push(rsi); // already done; see above + // push(rdi); // already done; see above + // push(rbx); // already done; see above // Marshal outgoing arguments now, freeing registers. Address from_arg(rsp, 16+ 4); // from @@ -1866,24 +1867,24 @@ class StubGenerator: public StubCodeGenerator { // push rbx, changed the incoming offsets (why not just use rbp,??) // assert(SRC_POS_arg.disp() == SRC_POS.disp() + 4, ""); - __ movl(rbx, Address(rsi_dst_klass, ek_offset)); - __ movl(length, LENGTH_arg); // reload elements count - __ movl(src_pos, SRC_POS_arg); // reload src_pos - __ movl(dst_pos, DST_POS_arg); // reload dst_pos + __ movptr(rbx, Address(rsi_dst_klass, ek_offset)); + __ movl2ptr(length, LENGTH_arg); // reload elements count + __ movl2ptr(src_pos, SRC_POS_arg); // reload src_pos + __ movl2ptr(dst_pos, DST_POS_arg); // reload dst_pos - __ movl(ckval_arg, rbx); // destination element type + __ movptr(ckval_arg, rbx); // destination element type __ movl(rbx, Address(rbx, sco_offset)); __ movl(ckoff_arg, rbx); // corresponding class check offset __ movl(length_arg, length); // outgoing length argument - __ leal(from, Address(src, src_pos, Address::times_4, + __ lea(from, Address(src, src_pos, Address::times_ptr, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); - __ movl(from_arg, from); + __ movptr(from_arg, from); - __ leal(to, Address(dst, dst_pos, Address::times_4, + __ lea(to, Address(dst, dst_pos, Address::times_ptr, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); - __ movl(to_arg, to); + __ movptr(to_arg, to); __ jump(RuntimeAddress(entry_checkcast_arraycopy)); } @@ -1934,10 +1935,10 @@ class StubGenerator: public StubCodeGenerator { &entry_jint_arraycopy, "jint_arraycopy"); StubRoutines::_oop_disjoint_arraycopy = - generate_disjoint_copy(T_OBJECT, true, Address::times_4, &entry, + generate_disjoint_copy(T_OBJECT, true, Address::times_ptr, &entry, "oop_disjoint_arraycopy"); StubRoutines::_oop_arraycopy = - generate_conjoint_copy(T_OBJECT, true, Address::times_4, entry, + generate_conjoint_copy(T_OBJECT, true, Address::times_ptr, entry, &entry_oop_arraycopy, "oop_arraycopy"); StubRoutines::_jlong_disjoint_arraycopy = @@ -2037,21 +2038,21 @@ class StubGenerator: public StubCodeGenerator { Register java_thread = rbx; __ get_thread(java_thread); if (restore_saved_exception_pc) { - __ movl(rax, Address(java_thread, in_bytes(JavaThread::saved_exception_pc_offset()))); - __ pushl(rax); + __ movptr(rax, Address(java_thread, in_bytes(JavaThread::saved_exception_pc_offset()))); + __ push(rax); } __ enter(); // required for proper stackwalking of RuntimeStub frame // pc and rbp, already pushed - __ subl(rsp, (framesize-2) * wordSize); // prolog + __ subptr(rsp, (framesize-2) * wordSize); // prolog // Frame is now completed as far as size and linkage. int frame_complete = __ pc() - start; // push java thread (becomes first argument of C function) - __ movl(Address(rsp, thread_off * wordSize), java_thread); + __ movptr(Address(rsp, thread_off * wordSize), java_thread); // Set up last_Java_sp and last_Java_fp __ set_last_Java_frame(java_thread, rsp, rbp, NULL); @@ -2075,7 +2076,7 @@ class StubGenerator: public StubCodeGenerator { // check for pending exceptions #ifdef ASSERT Label L; - __ cmpl(Address(java_thread, Thread::pending_exception_offset()), NULL_WORD); + __ cmpptr(Address(java_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::notEqual, L); __ should_not_reach_here(); __ bind(L); @@ -2137,8 +2138,8 @@ class StubGenerator: public StubCodeGenerator { // platform dependent create_control_words(); - StubRoutines::i486::_verify_mxcsr_entry = generate_verify_mxcsr(); - StubRoutines::i486::_verify_fpu_cntrl_wrd_entry = generate_verify_fpu_cntrl_wrd(); + StubRoutines::x86::_verify_mxcsr_entry = generate_verify_mxcsr(); + StubRoutines::x86::_verify_fpu_cntrl_wrd_entry = generate_verify_fpu_cntrl_wrd(); StubRoutines::_d2i_wrapper = generate_d2i_wrapper(T_INT, CAST_FROM_FN_PTR(address, SharedRuntime::d2i)); StubRoutines::_d2l_wrapper = generate_d2i_wrapper(T_LONG, diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp index 68188361b50..6964a1eb048 100644 --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp @@ -31,6 +31,7 @@ #define __ _masm-> #define TIMES_OOP (UseCompressedOops ? Address::times_4 : Address::times_8) +#define a__ ((Assembler*)_masm)-> #ifdef PRODUCT #define BLOCK_COMMENT(str) /* nothing */ @@ -210,32 +211,32 @@ class StubGenerator: public StubCodeGenerator { // stub code __ enter(); - __ subq(rsp, -rsp_after_call_off * wordSize); + __ subptr(rsp, -rsp_after_call_off * wordSize); // save register parameters #ifndef _WIN64 - __ movq(parameters, c_rarg5); // parameters - __ movq(entry_point, c_rarg4); // entry_point + __ movptr(parameters, c_rarg5); // parameters + __ movptr(entry_point, c_rarg4); // entry_point #endif - __ movq(method, c_rarg3); // method - __ movl(result_type, c_rarg2); // result type - __ movq(result, c_rarg1); // result - __ movq(call_wrapper, c_rarg0); // call wrapper + __ movptr(method, c_rarg3); // method + __ movl(result_type, c_rarg2); // result type + __ movptr(result, c_rarg1); // result + __ movptr(call_wrapper, c_rarg0); // call wrapper // save regs belonging to calling function - __ movq(rbx_save, rbx); - __ movq(r12_save, r12); - __ movq(r13_save, r13); - __ movq(r14_save, r14); - __ movq(r15_save, r15); + __ movptr(rbx_save, rbx); + __ movptr(r12_save, r12); + __ movptr(r13_save, r13); + __ movptr(r14_save, r14); + __ movptr(r15_save, r15); #ifdef _WIN64 const Address rdi_save(rbp, rdi_off * wordSize); const Address rsi_save(rbp, rsi_off * wordSize); - __ movq(rsi_save, rsi); - __ movq(rdi_save, rdi); + __ movptr(rsi_save, rsi); + __ movptr(rdi_save, rdi); #else const Address mxcsr_save(rbp, mxcsr_off * wordSize); { @@ -243,7 +244,7 @@ class StubGenerator: public StubCodeGenerator { __ stmxcsr(mxcsr_save); __ movl(rax, mxcsr_save); __ andl(rax, MXCSR_MASK); // Only check control and mask bits - ExternalAddress mxcsr_std(StubRoutines::amd64::mxcsr_std()); + ExternalAddress mxcsr_std(StubRoutines::x86::mxcsr_std()); __ cmp32(rax, mxcsr_std); __ jcc(Assembler::equal, skip_ldmx); __ ldmxcsr(mxcsr_std); @@ -252,14 +253,14 @@ class StubGenerator: public StubCodeGenerator { #endif // Load up thread register - __ movq(r15_thread, thread); + __ movptr(r15_thread, thread); __ reinit_heapbase(); #ifdef ASSERT // make sure we have no pending exceptions { Label L; - __ cmpq(Address(r15_thread, Thread::pending_exception_offset()), (int)NULL_WORD); + __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::equal, L); __ stop("StubRoutines::call_stub: entered with pending exception"); __ bind(L); @@ -274,25 +275,25 @@ class StubGenerator: public StubCodeGenerator { __ jcc(Assembler::zero, parameters_done); Label loop; - __ movq(c_rarg2, parameters); // parameter pointer - __ movl(c_rarg1, c_rarg3); // parameter counter is in c_rarg1 + __ movptr(c_rarg2, parameters); // parameter pointer + __ movl(c_rarg1, c_rarg3); // parameter counter is in c_rarg1 __ BIND(loop); if (TaggedStackInterpreter) { - __ movq(rax, Address(c_rarg2, 0)); // get tag - __ addq(c_rarg2, wordSize); // advance to next tag - __ pushq(rax); // pass tag + __ movl(rax, Address(c_rarg2, 0)); // get tag + __ addptr(c_rarg2, wordSize); // advance to next tag + __ push(rax); // pass tag } - __ movq(rax, Address(c_rarg2, 0)); // get parameter - __ addq(c_rarg2, wordSize); // advance to next parameter - __ decrementl(c_rarg1); // decrement counter - __ pushq(rax); // pass parameter + __ movptr(rax, Address(c_rarg2, 0));// get parameter + __ addptr(c_rarg2, wordSize); // advance to next parameter + __ decrementl(c_rarg1); // decrement counter + __ push(rax); // pass parameter __ jcc(Assembler::notZero, loop); // call Java function __ BIND(parameters_done); - __ movq(rbx, method); // get methodOop - __ movq(c_rarg1, entry_point); // get entry_point - __ movq(r13, rsp); // set sender sp + __ movptr(rbx, method); // get methodOop + __ movptr(c_rarg1, entry_point); // get entry_point + __ mov(r13, rsp); // set sender sp BLOCK_COMMENT("call Java function"); __ call(c_rarg1); @@ -301,7 +302,7 @@ class StubGenerator: public StubCodeGenerator { // store result depending on type (everything that is not // T_OBJECT, T_LONG, T_FLOAT or T_DOUBLE is treated as T_INT) - __ movq(c_rarg0, result); + __ movptr(c_rarg0, result); Label is_long, is_float, is_double, exit; __ movl(c_rarg1, result_type); __ cmpl(c_rarg1, T_OBJECT); @@ -319,16 +320,16 @@ class StubGenerator: public StubCodeGenerator { __ BIND(exit); // pop parameters - __ leaq(rsp, rsp_after_call); + __ lea(rsp, rsp_after_call); #ifdef ASSERT // verify that threads correspond { Label L, S; - __ cmpq(r15_thread, thread); + __ cmpptr(r15_thread, thread); __ jcc(Assembler::notEqual, S); __ get_thread(rbx); - __ cmpq(r15_thread, rbx); + __ cmpptr(r15_thread, rbx); __ jcc(Assembler::equal, L); __ bind(S); __ jcc(Assembler::equal, L); @@ -338,24 +339,24 @@ class StubGenerator: public StubCodeGenerator { #endif // restore regs belonging to calling function - __ movq(r15, r15_save); - __ movq(r14, r14_save); - __ movq(r13, r13_save); - __ movq(r12, r12_save); - __ movq(rbx, rbx_save); + __ movptr(r15, r15_save); + __ movptr(r14, r14_save); + __ movptr(r13, r13_save); + __ movptr(r12, r12_save); + __ movptr(rbx, rbx_save); #ifdef _WIN64 - __ movq(rdi, rdi_save); - __ movq(rsi, rsi_save); + __ movptr(rdi, rdi_save); + __ movptr(rsi, rsi_save); #else __ ldmxcsr(mxcsr_save); #endif // restore rsp - __ addq(rsp, -rsp_after_call_off * wordSize); + __ addptr(rsp, -rsp_after_call_off * wordSize); // return - __ popq(rbp); + __ pop(rbp); __ ret(0); // handle return types different from T_INT @@ -398,10 +399,10 @@ class StubGenerator: public StubCodeGenerator { // verify that threads correspond { Label L, S; - __ cmpq(r15_thread, thread); + __ cmpptr(r15_thread, thread); __ jcc(Assembler::notEqual, S); __ get_thread(rbx); - __ cmpq(r15_thread, rbx); + __ cmpptr(r15_thread, rbx); __ jcc(Assembler::equal, L); __ bind(S); __ stop("StubRoutines::catch_exception: threads must correspond"); @@ -412,9 +413,9 @@ class StubGenerator: public StubCodeGenerator { // set pending exception __ verify_oop(rax); - __ movq(Address(r15_thread, Thread::pending_exception_offset()), rax); + __ movptr(Address(r15_thread, Thread::pending_exception_offset()), rax); __ lea(rscratch1, ExternalAddress((address)__FILE__)); - __ movq(Address(r15_thread, Thread::exception_file_offset()), rscratch1); + __ movptr(Address(r15_thread, Thread::exception_file_offset()), rscratch1); __ movl(Address(r15_thread, Thread::exception_line_offset()), (int) __LINE__); // complete return to VM @@ -453,7 +454,7 @@ class StubGenerator: public StubCodeGenerator { // make sure this code is only executed if there is a pending exception { Label L; - __ cmpq(Address(r15_thread, Thread::pending_exception_offset()), (int) NULL); + __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t) NULL); __ jcc(Assembler::notEqual, L); __ stop("StubRoutines::forward exception: no pending exception (1)"); __ bind(L); @@ -461,23 +462,23 @@ class StubGenerator: public StubCodeGenerator { #endif // compute exception handler into rbx - __ movq(c_rarg0, Address(rsp, 0)); + __ movptr(c_rarg0, Address(rsp, 0)); BLOCK_COMMENT("call exception_handler_for_return_address"); __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), c_rarg0); - __ movq(rbx, rax); + __ mov(rbx, rax); // setup rax & rdx, remove return address & clear pending exception - __ popq(rdx); - __ movq(rax, Address(r15_thread, Thread::pending_exception_offset())); + __ pop(rdx); + __ movptr(rax, Address(r15_thread, Thread::pending_exception_offset())); __ movptr(Address(r15_thread, Thread::pending_exception_offset()), (int)NULL_WORD); #ifdef ASSERT // make sure exception is set { Label L; - __ testq(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::notEqual, L); __ stop("StubRoutines::forward exception: no pending exception (2)"); __ bind(L); @@ -525,8 +526,8 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, "StubRoutines", "atomic_xchg_ptr"); address start = __ pc(); - __ movq(rax, c_rarg0); // Copy to eax we need a return value anyhow - __ xchgq(rax, Address(c_rarg1, 0)); // automatic LOCK + __ movptr(rax, c_rarg0); // Copy to eax we need a return value anyhow + __ xchgptr(rax, Address(c_rarg1, 0)); // automatic LOCK __ ret(0); return start; @@ -619,10 +620,10 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, "StubRoutines", "atomic_add_ptr"); address start = __ pc(); - __ movq(rax, c_rarg0); // Copy to eax we need a return value anyhow + __ movptr(rax, c_rarg0); // Copy to eax we need a return value anyhow if ( os::is_MP() ) __ lock(); - __ xaddl(Address(c_rarg1, 0), c_rarg0); - __ addl(rax, c_rarg0); + __ xaddptr(Address(c_rarg1, 0), c_rarg0); + __ addptr(rax, c_rarg0); __ ret(0); return start; @@ -655,9 +656,9 @@ class StubGenerator: public StubCodeGenerator { address start = __ pc(); __ enter(); - __ movq(rax, old_fp); // callers fp - __ movq(rax, older_fp); // the frame for ps() - __ popq(rbp); + __ movptr(rax, old_fp); // callers fp + __ movptr(rax, older_fp); // the frame for ps() + __ pop(rbp); __ ret(0); return start; @@ -678,21 +679,21 @@ class StubGenerator: public StubCodeGenerator { if (CheckJNICalls) { Label ok_ret; - __ pushq(rax); - __ subq(rsp, wordSize); // allocate a temp location + __ push(rax); + __ subptr(rsp, wordSize); // allocate a temp location __ stmxcsr(mxcsr_save); __ movl(rax, mxcsr_save); __ andl(rax, MXCSR_MASK); // Only check control and mask bits - __ cmpl(rax, *(int *)(StubRoutines::amd64::mxcsr_std())); + __ cmpl(rax, *(int *)(StubRoutines::x86::mxcsr_std())); __ jcc(Assembler::equal, ok_ret); __ warn("MXCSR changed by native JNI code, use -XX:+RestoreMXCSROnJNICall"); - __ ldmxcsr(ExternalAddress(StubRoutines::amd64::mxcsr_std())); + __ ldmxcsr(ExternalAddress(StubRoutines::x86::mxcsr_std())); __ bind(ok_ret); - __ addq(rsp, wordSize); - __ popq(rax); + __ addptr(rsp, wordSize); + __ pop(rax); } __ ret(0); @@ -708,10 +709,10 @@ class StubGenerator: public StubCodeGenerator { Label L; - __ pushq(rax); - __ pushq(c_rarg3); - __ pushq(c_rarg2); - __ pushq(c_rarg1); + __ push(rax); + __ push(c_rarg3); + __ push(c_rarg2); + __ push(c_rarg1); __ movl(rax, 0x7f800000); __ xorl(c_rarg3, c_rarg3); @@ -726,12 +727,12 @@ class StubGenerator: public StubCodeGenerator { __ cmovl(Assembler::positive, c_rarg3, rax); __ bind(L); - __ movq(inout, c_rarg3); + __ movptr(inout, c_rarg3); - __ popq(c_rarg1); - __ popq(c_rarg2); - __ popq(c_rarg3); - __ popq(rax); + __ pop(c_rarg1); + __ pop(c_rarg2); + __ pop(c_rarg3); + __ pop(rax); __ ret(0); @@ -745,10 +746,10 @@ class StubGenerator: public StubCodeGenerator { Label L; - __ pushq(rax); - __ pushq(c_rarg3); - __ pushq(c_rarg2); - __ pushq(c_rarg1); + __ push(rax); + __ push(c_rarg3); + __ push(c_rarg2); + __ push(c_rarg1); __ movl(rax, 0x7f800000); __ xorl(c_rarg3, c_rarg3); @@ -760,15 +761,15 @@ class StubGenerator: public StubCodeGenerator { __ testl(c_rarg2, c_rarg2); // signed ? min_jlong : max_jlong __ mov64(c_rarg3, 0x8000000000000000); __ mov64(rax, 0x7fffffffffffffff); - __ cmovq(Assembler::positive, c_rarg3, rax); + __ cmov(Assembler::positive, c_rarg3, rax); __ bind(L); - __ movq(inout, c_rarg3); + __ movptr(inout, c_rarg3); - __ popq(c_rarg1); - __ popq(c_rarg2); - __ popq(c_rarg3); - __ popq(rax); + __ pop(c_rarg1); + __ pop(c_rarg2); + __ pop(c_rarg3); + __ pop(rax); __ ret(0); @@ -783,19 +784,19 @@ class StubGenerator: public StubCodeGenerator { Label L; - __ pushq(rax); - __ pushq(c_rarg3); - __ pushq(c_rarg2); - __ pushq(c_rarg1); - __ pushq(c_rarg0); + __ push(rax); + __ push(c_rarg3); + __ push(c_rarg2); + __ push(c_rarg1); + __ push(c_rarg0); __ movl(rax, 0x7ff00000); __ movq(c_rarg2, inout); __ movl(c_rarg3, c_rarg2); - __ movq(c_rarg1, c_rarg2); - __ movq(c_rarg0, c_rarg2); + __ mov(c_rarg1, c_rarg2); + __ mov(c_rarg0, c_rarg2); __ negl(c_rarg3); - __ shrq(c_rarg1, 0x20); + __ shrptr(c_rarg1, 0x20); __ orl(c_rarg3, c_rarg2); __ andl(c_rarg1, 0x7fffffff); __ xorl(c_rarg2, c_rarg2); @@ -803,19 +804,19 @@ class StubGenerator: public StubCodeGenerator { __ orl(c_rarg1, c_rarg3); __ cmpl(rax, c_rarg1); __ jcc(Assembler::negative, L); // NaN -> 0 - __ testq(c_rarg0, c_rarg0); // signed ? min_jint : max_jint + __ testptr(c_rarg0, c_rarg0); // signed ? min_jint : max_jint __ movl(c_rarg2, 0x80000000); __ movl(rax, 0x7fffffff); - __ cmovl(Assembler::positive, c_rarg2, rax); + __ cmov(Assembler::positive, c_rarg2, rax); __ bind(L); - __ movq(inout, c_rarg2); + __ movptr(inout, c_rarg2); - __ popq(c_rarg0); - __ popq(c_rarg1); - __ popq(c_rarg2); - __ popq(c_rarg3); - __ popq(rax); + __ pop(c_rarg0); + __ pop(c_rarg1); + __ pop(c_rarg2); + __ pop(c_rarg3); + __ pop(rax); __ ret(0); @@ -830,19 +831,19 @@ class StubGenerator: public StubCodeGenerator { Label L; - __ pushq(rax); - __ pushq(c_rarg3); - __ pushq(c_rarg2); - __ pushq(c_rarg1); - __ pushq(c_rarg0); + __ push(rax); + __ push(c_rarg3); + __ push(c_rarg2); + __ push(c_rarg1); + __ push(c_rarg0); __ movl(rax, 0x7ff00000); __ movq(c_rarg2, inout); __ movl(c_rarg3, c_rarg2); - __ movq(c_rarg1, c_rarg2); - __ movq(c_rarg0, c_rarg2); + __ mov(c_rarg1, c_rarg2); + __ mov(c_rarg0, c_rarg2); __ negl(c_rarg3); - __ shrq(c_rarg1, 0x20); + __ shrptr(c_rarg1, 0x20); __ orl(c_rarg3, c_rarg2); __ andl(c_rarg1, 0x7fffffff); __ xorl(c_rarg2, c_rarg2); @@ -858,11 +859,11 @@ class StubGenerator: public StubCodeGenerator { __ bind(L); __ movq(inout, c_rarg2); - __ popq(c_rarg0); - __ popq(c_rarg1); - __ popq(c_rarg2); - __ popq(c_rarg3); - __ popq(rax); + __ pop(c_rarg0); + __ pop(c_rarg1); + __ pop(c_rarg2); + __ pop(c_rarg3); + __ pop(rax); __ ret(0); @@ -889,17 +890,17 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access"); address start = __ pc(); - __ pushq(0); // hole for return address-to-be - __ pushaq(); // push registers + __ push(0); // hole for return address-to-be + __ pusha(); // push registers Address next_pc(rsp, RegisterImpl::number_of_registers * BytesPerWord); - __ subq(rsp, frame::arg_reg_save_area_bytes); + __ subptr(rsp, frame::arg_reg_save_area_bytes); BLOCK_COMMENT("call handle_unsafe_access"); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, handle_unsafe_access))); - __ addq(rsp, frame::arg_reg_save_area_bytes); + __ addptr(rsp, frame::arg_reg_save_area_bytes); - __ movq(next_pc, rax); // stuff next address - __ popaq(); + __ movptr(next_pc, rax); // stuff next address + __ popa(); __ ret(0); // jump to next address return start; @@ -926,14 +927,14 @@ class StubGenerator: public StubCodeGenerator { Label exit, error; - __ pushfq(); + __ pushf(); __ incrementl(ExternalAddress((address) StubRoutines::verify_oop_count_addr())); - __ pushq(r12); + __ push(r12); // save c_rarg2 and c_rarg3 - __ pushq(c_rarg2); - __ pushq(c_rarg3); + __ push(c_rarg2); + __ push(c_rarg3); enum { // After previous pushes. @@ -946,17 +947,17 @@ class StubGenerator: public StubCodeGenerator { }; // get object - __ movq(rax, Address(rsp, oop_to_verify)); + __ movptr(rax, Address(rsp, oop_to_verify)); // make sure object is 'reasonable' - __ testq(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, exit); // if obj is NULL it is OK // Check if the oop is in the right area of memory - __ movq(c_rarg2, rax); + __ movptr(c_rarg2, rax); __ movptr(c_rarg3, (int64_t) Universe::verify_oop_mask()); - __ andq(c_rarg2, c_rarg3); + __ andptr(c_rarg2, c_rarg3); __ movptr(c_rarg3, (int64_t) Universe::verify_oop_bits()); - __ cmpq(c_rarg2, c_rarg3); + __ cmpptr(c_rarg2, c_rarg3); __ jcc(Assembler::notZero, error); // set r12 to heapbase for load_klass() @@ -964,46 +965,46 @@ class StubGenerator: public StubCodeGenerator { // make sure klass is 'reasonable' __ load_klass(rax, rax); // get klass - __ testq(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, error); // if klass is NULL it is broken // Check if the klass is in the right area of memory - __ movq(c_rarg2, rax); + __ mov(c_rarg2, rax); __ movptr(c_rarg3, (int64_t) Universe::verify_klass_mask()); - __ andq(c_rarg2, c_rarg3); + __ andptr(c_rarg2, c_rarg3); __ movptr(c_rarg3, (int64_t) Universe::verify_klass_bits()); - __ cmpq(c_rarg2, c_rarg3); + __ cmpptr(c_rarg2, c_rarg3); __ jcc(Assembler::notZero, error); // make sure klass' klass is 'reasonable' __ load_klass(rax, rax); - __ testq(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, error); // if klass' klass is NULL it is broken // Check if the klass' klass is in the right area of memory __ movptr(c_rarg3, (int64_t) Universe::verify_klass_mask()); - __ andq(rax, c_rarg3); + __ andptr(rax, c_rarg3); __ movptr(c_rarg3, (int64_t) Universe::verify_klass_bits()); - __ cmpq(rax, c_rarg3); + __ cmpptr(rax, c_rarg3); __ jcc(Assembler::notZero, error); // return if everything seems ok __ bind(exit); - __ movq(rax, Address(rsp, saved_rax)); // get saved rax back - __ popq(c_rarg3); // restore c_rarg3 - __ popq(c_rarg2); // restore c_rarg2 - __ popq(r12); // restore r12 - __ popfq(); // restore flags + __ movptr(rax, Address(rsp, saved_rax)); // get saved rax back + __ pop(c_rarg3); // restore c_rarg3 + __ pop(c_rarg2); // restore c_rarg2 + __ pop(r12); // restore r12 + __ popf(); // restore flags __ ret(3 * wordSize); // pop caller saved stuff // handle errors __ bind(error); - __ movq(rax, Address(rsp, saved_rax)); // get saved rax back - __ popq(c_rarg3); // get saved c_rarg3 back - __ popq(c_rarg2); // get saved c_rarg2 back - __ popq(r12); // get saved r12 back - __ popfq(); // get saved flags off stack -- + __ movptr(rax, Address(rsp, saved_rax)); // get saved rax back + __ pop(c_rarg3); // get saved c_rarg3 back + __ pop(c_rarg2); // get saved c_rarg2 back + __ pop(r12); // get saved r12 back + __ popf(); // get saved flags off stack -- // will be ignored - __ pushaq(); // push registers + __ pusha(); // push registers // (rip is already // already pushed) // debug(char* msg, int64_t pc, int64_t regs[]) @@ -1016,17 +1017,17 @@ class StubGenerator: public StubCodeGenerator { // * [tos + 19] saved rax - saved by caller and bashed // * = popped on exit - __ movq(c_rarg0, Address(rsp, error_msg)); // pass address of error message - __ movq(c_rarg1, Address(rsp, return_addr)); // pass return address - __ movq(c_rarg2, rsp); // pass address of regs on stack - __ movq(r12, rsp); // remember rsp - __ subq(rsp, frame::arg_reg_save_area_bytes);// windows - __ andq(rsp, -16); // align stack as required by ABI + __ movptr(c_rarg0, Address(rsp, error_msg)); // pass address of error message + __ movptr(c_rarg1, Address(rsp, return_addr)); // pass return address + __ movq(c_rarg2, rsp); // pass address of regs on stack + __ mov(r12, rsp); // remember rsp + __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows + __ andptr(rsp, -16); // align stack as required by ABI BLOCK_COMMENT("call MacroAssembler::debug"); - __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug))); - __ movq(rsp, r12); // restore rsp - __ popaq(); // pop registers (includes r12) - __ ret(3 * wordSize); // pop caller saved stuff + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug64))); + __ mov(rsp, r12); // restore rsp + __ popa(); // pop registers (includes r12) + __ ret(3 * wordSize); // pop caller saved stuff return start; } @@ -1088,16 +1089,16 @@ class StubGenerator: public StubCodeGenerator { const Register count = c_rarg2; const Register end_from = rax; - __ cmpq(to, from); - __ leaq(end_from, Address(from, count, sf, 0)); + __ cmpptr(to, from); + __ lea(end_from, Address(from, count, sf, 0)); if (NOLp == NULL) { ExternalAddress no_overlap(no_overlap_target); __ jump_cc(Assembler::belowEqual, no_overlap); - __ cmpq(to, end_from); + __ cmpptr(to, end_from); __ jump_cc(Assembler::aboveEqual, no_overlap); } else { __ jcc(Assembler::belowEqual, (*NOLp)); - __ cmpq(to, end_from); + __ cmpptr(to, end_from); __ jcc(Assembler::aboveEqual, (*NOLp)); } } @@ -1121,14 +1122,14 @@ class StubGenerator: public StubCodeGenerator { assert(c_rarg0 == rcx && c_rarg1 == rdx && c_rarg2 == r8 && c_rarg3 == r9, "unexpected argument registers"); if (nargs >= 4) - __ movq(rax, r9); // r9 is also saved_rdi - __ movq(saved_rdi, rdi); - __ movq(saved_rsi, rsi); - __ movq(rdi, rcx); // c_rarg0 - __ movq(rsi, rdx); // c_rarg1 - __ movq(rdx, r8); // c_rarg2 + __ mov(rax, r9); // r9 is also saved_rdi + __ movptr(saved_rdi, rdi); + __ movptr(saved_rsi, rsi); + __ mov(rdi, rcx); // c_rarg0 + __ mov(rsi, rdx); // c_rarg1 + __ mov(rdx, r8); // c_rarg2 if (nargs >= 4) - __ movq(rcx, rax); // c_rarg3 (via rax) + __ mov(rcx, rax); // c_rarg3 (via rax) #else assert(c_rarg0 == rdi && c_rarg1 == rsi && c_rarg2 == rdx && c_rarg3 == rcx, "unexpected argument registers"); @@ -1139,8 +1140,8 @@ class StubGenerator: public StubCodeGenerator { const Register saved_rdi = r9; const Register saved_rsi = r10; #ifdef _WIN64 - __ movq(rdi, saved_rdi); - __ movq(rsi, saved_rsi); + __ movptr(rdi, saved_rdi); + __ movptr(rsi, saved_rsi); #endif } @@ -1160,11 +1161,11 @@ class StubGenerator: public StubCodeGenerator { case BarrierSet::G1SATBCT: case BarrierSet::G1SATBCTLogging: { - __ pushaq(); // push registers - __ movq(c_rarg0, addr); - __ movq(c_rarg1, count); + __ pusha(); // push registers + __ movptr(c_rarg0, addr); + __ movptr(c_rarg1, count); __ call(RuntimeAddress(BarrierSet::static_write_ref_array_pre)); - __ popaq(); + __ popa(); } break; case BarrierSet::CardTableModRef: @@ -1197,16 +1198,16 @@ class StubGenerator: public StubCodeGenerator { case BarrierSet::G1SATBCTLogging: { - __ pushaq(); // push registers (overkill) + __ pusha(); // push registers (overkill) // must compute element count unless barrier set interface is changed (other platforms supply count) assert_different_registers(start, end, scratch); - __ leaq(scratch, Address(end, wordSize)); - __ subq(scratch, start); - __ shrq(scratch, LogBytesPerWord); - __ movq(c_rarg0, start); - __ movq(c_rarg1, scratch); + __ lea(scratch, Address(end, wordSize)); + __ subptr(scratch, start); + __ shrptr(scratch, LogBytesPerWord); + __ mov(c_rarg0, start); + __ mov(c_rarg1, scratch); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post)); - __ popaq(); + __ popa(); } break; #endif // 0 G1 - only @@ -1218,16 +1219,24 @@ class StubGenerator: public StubCodeGenerator { Label L_loop; - __ shrq(start, CardTableModRefBS::card_shift); - __ shrq(end, CardTableModRefBS::card_shift); - __ subq(end, start); // number of bytes to copy + __ shrptr(start, CardTableModRefBS::card_shift); + __ shrptr(end, CardTableModRefBS::card_shift); + __ subptr(end, start); // number of bytes to copy + + intptr_t disp = (intptr_t) ct->byte_map_base; + if (__ is_simm32(disp)) { + Address cardtable(noreg, noreg, Address::no_scale, disp); + __ lea(scratch, cardtable); + } else { + ExternalAddress cardtable((address)disp); + __ lea(scratch, cardtable); + } const Register count = end; // 'end' register contains bytes count now - __ lea(scratch, ExternalAddress((address)ct->byte_map_base)); - __ addq(start, scratch); + __ addptr(start, scratch); __ BIND(L_loop); __ movb(Address(start, count, Address::times_1), 0); - __ decrementq(count); + __ decrement(count); __ jcc(Assembler::greaterEqual, L_loop); } } @@ -1259,9 +1268,9 @@ class StubGenerator: public StubCodeGenerator { __ movq(to, Address(end_from, qword_count, Address::times_8, - 0)); __ movq(Address(end_to, qword_count, Address::times_8, - 0), to); __ BIND(L_copy_32_bytes); - __ addq(qword_count, 4); + __ addptr(qword_count, 4); __ jcc(Assembler::lessEqual, L_loop); - __ subq(qword_count, 4); + __ subptr(qword_count, 4); __ jcc(Assembler::less, L_copy_8_bytes); // Copy trailing qwords } @@ -1292,9 +1301,9 @@ class StubGenerator: public StubCodeGenerator { __ movq(to, Address(from, qword_count, Address::times_8, 0)); __ movq(Address(dest, qword_count, Address::times_8, 0), to); __ BIND(L_copy_32_bytes); - __ subq(qword_count, 4); + __ subptr(qword_count, 4); __ jcc(Assembler::greaterEqual, L_loop); - __ addq(qword_count, 4); + __ addptr(qword_count, 4); __ jcc(Assembler::greater, L_copy_8_bytes); // Copy trailing qwords } @@ -1346,45 +1355,45 @@ class StubGenerator: public StubCodeGenerator { // r9 and r10 may be used to save non-volatile registers // 'from', 'to' and 'count' are now valid - __ movq(byte_count, count); - __ shrq(count, 3); // count => qword_count + __ movptr(byte_count, count); + __ shrptr(count, 3); // count => qword_count // Copy from low to high addresses. Use 'to' as scratch. - __ leaq(end_from, Address(from, qword_count, Address::times_8, -8)); - __ leaq(end_to, Address(to, qword_count, Address::times_8, -8)); - __ negq(qword_count); // make the count negative + __ lea(end_from, Address(from, qword_count, Address::times_8, -8)); + __ lea(end_to, Address(to, qword_count, Address::times_8, -8)); + __ negptr(qword_count); // make the count negative __ jmp(L_copy_32_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); __ movq(rax, Address(end_from, qword_count, Address::times_8, 8)); __ movq(Address(end_to, qword_count, Address::times_8, 8), rax); - __ incrementq(qword_count); + __ increment(qword_count); __ jcc(Assembler::notZero, L_copy_8_bytes); // Check for and copy trailing dword __ BIND(L_copy_4_bytes); - __ testq(byte_count, 4); + __ testl(byte_count, 4); __ jccb(Assembler::zero, L_copy_2_bytes); __ movl(rax, Address(end_from, 8)); __ movl(Address(end_to, 8), rax); - __ addq(end_from, 4); - __ addq(end_to, 4); + __ addptr(end_from, 4); + __ addptr(end_to, 4); // Check for and copy trailing word __ BIND(L_copy_2_bytes); - __ testq(byte_count, 2); + __ testl(byte_count, 2); __ jccb(Assembler::zero, L_copy_byte); __ movw(rax, Address(end_from, 8)); __ movw(Address(end_to, 8), rax); - __ addq(end_from, 2); - __ addq(end_to, 2); + __ addptr(end_from, 2); + __ addptr(end_to, 2); // Check for and copy trailing byte __ BIND(L_copy_byte); - __ testq(byte_count, 1); + __ testl(byte_count, 1); __ jccb(Assembler::zero, L_exit); __ movb(rax, Address(end_from, 8)); __ movb(Address(end_to, 8), rax); @@ -1392,7 +1401,7 @@ class StubGenerator: public StubCodeGenerator { __ BIND(L_exit); inc_counter_np(SharedRuntime::_jbyte_array_copy_ctr); restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -1442,28 +1451,28 @@ class StubGenerator: public StubCodeGenerator { // r9 and r10 may be used to save non-volatile registers // 'from', 'to' and 'count' are now valid - __ movq(byte_count, count); - __ shrq(count, 3); // count => qword_count + __ movptr(byte_count, count); + __ shrptr(count, 3); // count => qword_count // Copy from high to low addresses. // Check for and copy trailing byte - __ testq(byte_count, 1); + __ testl(byte_count, 1); __ jcc(Assembler::zero, L_copy_2_bytes); __ movb(rax, Address(from, byte_count, Address::times_1, -1)); __ movb(Address(to, byte_count, Address::times_1, -1), rax); - __ decrementq(byte_count); // Adjust for possible trailing word + __ decrement(byte_count); // Adjust for possible trailing word // Check for and copy trailing word __ BIND(L_copy_2_bytes); - __ testq(byte_count, 2); + __ testl(byte_count, 2); __ jcc(Assembler::zero, L_copy_4_bytes); __ movw(rax, Address(from, byte_count, Address::times_1, -2)); __ movw(Address(to, byte_count, Address::times_1, -2), rax); // Check for and copy trailing dword __ BIND(L_copy_4_bytes); - __ testq(byte_count, 4); + __ testl(byte_count, 4); __ jcc(Assembler::zero, L_copy_32_bytes); __ movl(rax, Address(from, qword_count, Address::times_8)); __ movl(Address(to, qword_count, Address::times_8), rax); @@ -1473,12 +1482,12 @@ class StubGenerator: public StubCodeGenerator { __ BIND(L_copy_8_bytes); __ movq(rax, Address(from, qword_count, Address::times_8, -8)); __ movq(Address(to, qword_count, Address::times_8, -8), rax); - __ decrementq(qword_count); + __ decrement(qword_count); __ jcc(Assembler::notZero, L_copy_8_bytes); inc_counter_np(SharedRuntime::_jbyte_array_copy_ctr); restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -1487,7 +1496,7 @@ class StubGenerator: public StubCodeGenerator { inc_counter_np(SharedRuntime::_jbyte_array_copy_ctr); restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -1540,20 +1549,20 @@ class StubGenerator: public StubCodeGenerator { // r9 and r10 may be used to save non-volatile registers // 'from', 'to' and 'count' are now valid - __ movq(word_count, count); - __ shrq(count, 2); // count => qword_count + __ movptr(word_count, count); + __ shrptr(count, 2); // count => qword_count // Copy from low to high addresses. Use 'to' as scratch. - __ leaq(end_from, Address(from, qword_count, Address::times_8, -8)); - __ leaq(end_to, Address(to, qword_count, Address::times_8, -8)); - __ negq(qword_count); + __ lea(end_from, Address(from, qword_count, Address::times_8, -8)); + __ lea(end_to, Address(to, qword_count, Address::times_8, -8)); + __ negptr(qword_count); __ jmp(L_copy_32_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); __ movq(rax, Address(end_from, qword_count, Address::times_8, 8)); __ movq(Address(end_to, qword_count, Address::times_8, 8), rax); - __ incrementq(qword_count); + __ increment(qword_count); __ jcc(Assembler::notZero, L_copy_8_bytes); // Original 'dest' is trashed, so we can't use it as a @@ -1561,17 +1570,17 @@ class StubGenerator: public StubCodeGenerator { // Check for and copy trailing dword __ BIND(L_copy_4_bytes); - __ testq(word_count, 2); + __ testl(word_count, 2); __ jccb(Assembler::zero, L_copy_2_bytes); __ movl(rax, Address(end_from, 8)); __ movl(Address(end_to, 8), rax); - __ addq(end_from, 4); - __ addq(end_to, 4); + __ addptr(end_from, 4); + __ addptr(end_to, 4); // Check for and copy trailing word __ BIND(L_copy_2_bytes); - __ testq(word_count, 1); + __ testl(word_count, 1); __ jccb(Assembler::zero, L_exit); __ movw(rax, Address(end_from, 8)); __ movw(Address(end_to, 8), rax); @@ -1579,7 +1588,7 @@ class StubGenerator: public StubCodeGenerator { __ BIND(L_exit); inc_counter_np(SharedRuntime::_jshort_array_copy_ctr); restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -1629,20 +1638,20 @@ class StubGenerator: public StubCodeGenerator { // r9 and r10 may be used to save non-volatile registers // 'from', 'to' and 'count' are now valid - __ movq(word_count, count); - __ shrq(count, 2); // count => qword_count + __ movptr(word_count, count); + __ shrptr(count, 2); // count => qword_count // Copy from high to low addresses. Use 'to' as scratch. // Check for and copy trailing word - __ testq(word_count, 1); + __ testl(word_count, 1); __ jccb(Assembler::zero, L_copy_4_bytes); __ movw(rax, Address(from, word_count, Address::times_2, -2)); __ movw(Address(to, word_count, Address::times_2, -2), rax); // Check for and copy trailing dword __ BIND(L_copy_4_bytes); - __ testq(word_count, 2); + __ testl(word_count, 2); __ jcc(Assembler::zero, L_copy_32_bytes); __ movl(rax, Address(from, qword_count, Address::times_8)); __ movl(Address(to, qword_count, Address::times_8), rax); @@ -1652,12 +1661,12 @@ class StubGenerator: public StubCodeGenerator { __ BIND(L_copy_8_bytes); __ movq(rax, Address(from, qword_count, Address::times_8, -8)); __ movq(Address(to, qword_count, Address::times_8, -8), rax); - __ decrementq(qword_count); + __ decrement(qword_count); __ jcc(Assembler::notZero, L_copy_8_bytes); inc_counter_np(SharedRuntime::_jshort_array_copy_ctr); restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -1666,7 +1675,7 @@ class StubGenerator: public StubCodeGenerator { inc_counter_np(SharedRuntime::_jshort_array_copy_ctr); restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -1730,25 +1739,25 @@ class StubGenerator: public StubCodeGenerator { } // 'from', 'to' and 'count' are now valid - __ movq(dword_count, count); - __ shrq(count, 1); // count => qword_count + __ movptr(dword_count, count); + __ shrptr(count, 1); // count => qword_count // Copy from low to high addresses. Use 'to' as scratch. - __ leaq(end_from, Address(from, qword_count, Address::times_8, -8)); - __ leaq(end_to, Address(to, qword_count, Address::times_8, -8)); - __ negq(qword_count); + __ lea(end_from, Address(from, qword_count, Address::times_8, -8)); + __ lea(end_to, Address(to, qword_count, Address::times_8, -8)); + __ negptr(qword_count); __ jmp(L_copy_32_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); __ movq(rax, Address(end_from, qword_count, Address::times_8, 8)); __ movq(Address(end_to, qword_count, Address::times_8, 8), rax); - __ incrementq(qword_count); + __ increment(qword_count); __ jcc(Assembler::notZero, L_copy_8_bytes); // Check for and copy trailing dword __ BIND(L_copy_4_bytes); - __ testq(dword_count, 1); // Only byte test since the value is 0 or 1 + __ testl(dword_count, 1); // Only byte test since the value is 0 or 1 __ jccb(Assembler::zero, L_exit); __ movl(rax, Address(end_from, 8)); __ movl(Address(end_to, 8), rax); @@ -1760,7 +1769,7 @@ class StubGenerator: public StubCodeGenerator { } inc_counter_np(SharedRuntime::_jint_array_copy_ctr); restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -1817,13 +1826,13 @@ class StubGenerator: public StubCodeGenerator { assert_clean_int(count, rax); // Make sure 'count' is clean int. // 'from', 'to' and 'count' are now valid - __ movq(dword_count, count); - __ shrq(count, 1); // count => qword_count + __ movptr(dword_count, count); + __ shrptr(count, 1); // count => qword_count // Copy from high to low addresses. Use 'to' as scratch. // Check for and copy trailing dword - __ testq(dword_count, 1); + __ testl(dword_count, 1); __ jcc(Assembler::zero, L_copy_32_bytes); __ movl(rax, Address(from, dword_count, Address::times_4, -4)); __ movl(Address(to, dword_count, Address::times_4, -4), rax); @@ -1833,7 +1842,7 @@ class StubGenerator: public StubCodeGenerator { __ BIND(L_copy_8_bytes); __ movq(rax, Address(from, qword_count, Address::times_8, -8)); __ movq(Address(to, qword_count, Address::times_8, -8), rax); - __ decrementq(qword_count); + __ decrement(qword_count); __ jcc(Assembler::notZero, L_copy_8_bytes); inc_counter_np(SharedRuntime::_jint_array_copy_ctr); @@ -1841,7 +1850,7 @@ class StubGenerator: public StubCodeGenerator { __ jmp(L_exit); } restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -1856,7 +1865,7 @@ class StubGenerator: public StubCodeGenerator { gen_write_ref_array_post_barrier(to, end_to, rax); } restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -1913,16 +1922,16 @@ class StubGenerator: public StubCodeGenerator { // 'from', 'to' and 'qword_count' are now valid // Copy from low to high addresses. Use 'to' as scratch. - __ leaq(end_from, Address(from, qword_count, Address::times_8, -8)); - __ leaq(end_to, Address(to, qword_count, Address::times_8, -8)); - __ negq(qword_count); + __ lea(end_from, Address(from, qword_count, Address::times_8, -8)); + __ lea(end_to, Address(to, qword_count, Address::times_8, -8)); + __ negptr(qword_count); __ jmp(L_copy_32_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); __ movq(rax, Address(end_from, qword_count, Address::times_8, 8)); __ movq(Address(end_to, qword_count, Address::times_8, 8), rax); - __ incrementq(qword_count); + __ increment(qword_count); __ jcc(Assembler::notZero, L_copy_8_bytes); if (is_oop) { @@ -1930,7 +1939,7 @@ class StubGenerator: public StubCodeGenerator { } else { inc_counter_np(SharedRuntime::_jlong_array_copy_ctr); restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); } @@ -1946,7 +1955,7 @@ class StubGenerator: public StubCodeGenerator { inc_counter_np(SharedRuntime::_jlong_array_copy_ctr); } restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -2000,7 +2009,7 @@ class StubGenerator: public StubCodeGenerator { if (is_oop) { // Save to and count for store barrier - __ movq(saved_count, qword_count); + __ movptr(saved_count, qword_count); // No registers are destroyed by this call gen_write_ref_array_pre_barrier(to, saved_count); } @@ -2011,7 +2020,7 @@ class StubGenerator: public StubCodeGenerator { __ BIND(L_copy_8_bytes); __ movq(rax, Address(from, qword_count, Address::times_8, -8)); __ movq(Address(to, qword_count, Address::times_8, -8), rax); - __ decrementq(qword_count); + __ decrement(qword_count); __ jcc(Assembler::notZero, L_copy_8_bytes); if (is_oop) { @@ -2019,7 +2028,7 @@ class StubGenerator: public StubCodeGenerator { } else { inc_counter_np(SharedRuntime::_jlong_array_copy_ctr); restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); } @@ -2029,14 +2038,14 @@ class StubGenerator: public StubCodeGenerator { if (is_oop) { __ BIND(L_exit); - __ leaq(rcx, Address(to, saved_count, Address::times_8, -8)); + __ lea(rcx, Address(to, saved_count, Address::times_8, -8)); gen_write_ref_array_post_barrier(to, rcx, rax); inc_counter_np(SharedRuntime::_oop_array_copy_ctr); } else { inc_counter_np(SharedRuntime::_jlong_array_copy_ctr); } restore_arg_regs(); - __ xorq(rax, rax); // return 0 + __ xorptr(rax, rax); // return 0 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -2065,12 +2074,12 @@ class StubGenerator: public StubCodeGenerator { Address super_cache_addr( sub_klass, sc_offset); // if the pointers are equal, we are done (e.g., String[] elements) - __ cmpq(super_klass, sub_klass); + __ cmpptr(super_klass, sub_klass); __ jcc(Assembler::equal, L_success); // check the supertype display: Address super_check_addr(sub_klass, super_check_offset, Address::times_1, 0); - __ cmpq(super_klass, super_check_addr); // test the super type + __ cmpptr(super_klass, super_check_addr); // test the super type __ jcc(Assembler::equal, L_success); // if it was a primary super, we can just fail immediately @@ -2083,38 +2092,38 @@ class StubGenerator: public StubCodeGenerator { // This code is rarely used, so simplicity is a virtue here. inc_counter_np(SharedRuntime::_partial_subtype_ctr); { - __ pushq(rax); - __ pushq(rcx); - __ pushq(rdi); + __ push(rax); + __ push(rcx); + __ push(rdi); assert_different_registers(sub_klass, super_klass, rax, rcx, rdi); - __ movq(rdi, secondary_supers_addr); + __ movptr(rdi, secondary_supers_addr); // Load the array length. __ movl(rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes())); // Skip to start of data. - __ addq(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + __ addptr(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); // Scan rcx words at [rdi] for occurance of rax // Set NZ/Z based on last compare - __ movq(rax, super_klass); + __ movptr(rax, super_klass); if (UseCompressedOops) { // Compare against compressed form. Don't need to uncompress because // looks like orig rax is restored in popq below. __ encode_heap_oop(rax); __ repne_scanl(); } else { - __ repne_scanq(); + __ repne_scan(); } // Unspill the temp. registers: - __ popq(rdi); - __ popq(rcx); - __ popq(rax); + __ pop(rdi); + __ pop(rcx); + __ pop(rax); __ jcc(Assembler::notEqual, L_miss); } // Success. Cache the super we found and proceed in triumph. - __ movq(super_cache_addr, super_klass); // note: rax is dead + __ movptr(super_cache_addr, super_klass); // note: rax is dead __ jmp(L_success); // Fall through on failure! @@ -2194,16 +2203,16 @@ class StubGenerator: public StubCodeGenerator { saved_rip_offset, saved_rarg0_offset }; - __ subq(rsp, saved_rbp_offset * wordSize); - __ movq(Address(rsp, saved_r13_offset * wordSize), r13); - __ movq(Address(rsp, saved_r14_offset * wordSize), r14); + __ subptr(rsp, saved_rbp_offset * wordSize); + __ movptr(Address(rsp, saved_r13_offset * wordSize), r13); + __ movptr(Address(rsp, saved_r14_offset * wordSize), r14); setup_arg_regs(4); // from => rdi, to => rsi, length => rdx // ckoff => rcx, ckval => r8 // r9 and r10 may be used to save non-volatile registers #ifdef _WIN64 // last argument (#4) is on stack on Win64 const int ckval_offset = saved_rarg0_offset + 4; - __ movq(ckval, Address(rsp, ckval_offset * wordSize)); + __ movptr(ckval, Address(rsp, ckval_offset * wordSize)); #endif // check that int operands are properly extended to size_t @@ -2234,15 +2243,15 @@ class StubGenerator: public StubCodeGenerator { gen_write_ref_array_pre_barrier(to, count); // Copy from low to high addresses, indexed from the end of each array. - __ leaq(end_from, end_from_addr); - __ leaq(end_to, end_to_addr); - __ movq(r14_length, length); // save a copy of the length - assert(length == count, ""); // else fix next line: - __ negq(count); // negate and test the length + __ lea(end_from, end_from_addr); + __ lea(end_to, end_to_addr); + __ movptr(r14_length, length); // save a copy of the length + assert(length == count, ""); // else fix next line: + __ negptr(count); // negate and test the length __ jcc(Assembler::notZero, L_load_element); // Empty array: Nothing to do. - __ xorq(rax, rax); // return 0 on (trivial) success + __ xorptr(rax, rax); // return 0 on (trivial) success __ jmp(L_done); // ======== begin loop ======== @@ -2254,13 +2263,13 @@ class StubGenerator: public StubCodeGenerator { __ BIND(L_store_element); __ store_heap_oop(to_element_addr, rax_oop); // store the oop - __ incrementq(count); // increment the count toward zero + __ increment(count); // increment the count toward zero __ jcc(Assembler::zero, L_do_card_marks); // ======== loop entry is here ======== __ BIND(L_load_element); __ load_heap_oop(rax_oop, from_element_addr); // load the oop - __ testq(rax_oop, rax_oop); + __ testptr(rax_oop, rax_oop); __ jcc(Assembler::zero, L_store_element); __ load_klass(r11_klass, rax_oop);// query the object klass @@ -2272,23 +2281,23 @@ class StubGenerator: public StubCodeGenerator { // Emit GC store barriers for the oops we have copied (r14 + rdx), // and report their number to the caller. assert_different_registers(rax, r14_length, count, to, end_to, rcx); - __ leaq(end_to, to_element_addr); + __ lea(end_to, to_element_addr); gen_write_ref_array_post_barrier(to, end_to, rcx); - __ movq(rax, r14_length); // original oops - __ addq(rax, count); // K = (original - remaining) oops - __ notq(rax); // report (-1^K) to caller + __ movptr(rax, r14_length); // original oops + __ addptr(rax, count); // K = (original - remaining) oops + __ notptr(rax); // report (-1^K) to caller __ jmp(L_done); // Come here on success only. __ BIND(L_do_card_marks); - __ addq(end_to, -wordSize); // make an inclusive end pointer + __ addptr(end_to, -wordSize); // make an inclusive end pointer gen_write_ref_array_post_barrier(to, end_to, rcx); - __ xorq(rax, rax); // return 0 on success + __ xorptr(rax, rax); // return 0 on success // Common exit point (success or failure). __ BIND(L_done); - __ movq(r13, Address(rsp, saved_r13_offset * wordSize)); - __ movq(r14, Address(rsp, saved_r14_offset * wordSize)); + __ movptr(r13, Address(rsp, saved_r13_offset * wordSize)); + __ movptr(r14, Address(rsp, saved_r14_offset * wordSize)); inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr); restore_arg_regs(); __ leave(); // required for proper stackwalking of RuntimeStub frame @@ -2331,9 +2340,9 @@ class StubGenerator: public StubCodeGenerator { // bump this on entry, not on exit: inc_counter_np(SharedRuntime::_unsafe_array_copy_ctr); - __ movq(bits, from); - __ orq(bits, to); - __ orq(bits, size); + __ mov(bits, from); + __ orptr(bits, to); + __ orptr(bits, size); __ testb(bits, BytesPerLong-1); __ jccb(Assembler::zero, L_long_aligned); @@ -2345,15 +2354,15 @@ class StubGenerator: public StubCodeGenerator { __ jump_cc(Assembler::notZero, RuntimeAddress(byte_copy_entry)); __ BIND(L_short_aligned); - __ shrq(size, LogBytesPerShort); // size => short_count + __ shrptr(size, LogBytesPerShort); // size => short_count __ jump(RuntimeAddress(short_copy_entry)); __ BIND(L_int_aligned); - __ shrq(size, LogBytesPerInt); // size => int_count + __ shrptr(size, LogBytesPerInt); // size => int_count __ jump(RuntimeAddress(int_copy_entry)); __ BIND(L_long_aligned); - __ shrq(size, LogBytesPerLong); // size => qword_count + __ shrptr(size, LogBytesPerLong); // size => qword_count __ jump(RuntimeAddress(long_copy_entry)); return start; @@ -2461,7 +2470,7 @@ class StubGenerator: public StubCodeGenerator { // // if (src == NULL) return -1; - __ testq(src, src); // src oop + __ testptr(src, src); // src oop size_t j1off = __ offset(); __ jccb(Assembler::zero, L_failed_0); @@ -2470,7 +2479,7 @@ class StubGenerator: public StubCodeGenerator { __ jccb(Assembler::negative, L_failed_0); // if (dst == NULL) return -1; - __ testq(dst, dst); // dst oop + __ testptr(dst, dst); // dst oop __ jccb(Assembler::zero, L_failed_0); // if (dst_pos < 0) return -1; @@ -2501,7 +2510,7 @@ class StubGenerator: public StubCodeGenerator { // assert(src->klass() != NULL); BLOCK_COMMENT("assert klasses not null"); { Label L1, L2; - __ testq(r10_src_klass, r10_src_klass); + __ testptr(r10_src_klass, r10_src_klass); __ jcc(Assembler::notZero, L2); // it is broken if klass is NULL __ bind(L1); __ stop("broken null klass"); @@ -2566,9 +2575,9 @@ class StubGenerator: public StubCodeGenerator { __ movl(r10_offset, rax_lh); __ shrl(r10_offset, Klass::_lh_header_size_shift); - __ andq(r10_offset, Klass::_lh_header_size_mask); // array_offset - __ addq(src, r10_offset); // src array offset - __ addq(dst, r10_offset); // dst array offset + __ andptr(r10_offset, Klass::_lh_header_size_mask); // array_offset + __ addptr(src, r10_offset); // src array offset + __ addptr(dst, r10_offset); // dst array offset BLOCK_COMMENT("choose copy loop based on element size"); __ andl(rax_lh, Klass::_lh_log2_element_size_mask); // rax_lh -> rax_elsize @@ -2583,25 +2592,25 @@ class StubGenerator: public StubCodeGenerator { __ BIND(L_copy_bytes); __ cmpl(rax_elsize, 0); __ jccb(Assembler::notEqual, L_copy_shorts); - __ leaq(from, Address(src, src_pos, Address::times_1, 0));// src_addr - __ leaq(to, Address(dst, dst_pos, Address::times_1, 0));// dst_addr - __ movslq(count, r11_length); // length + __ lea(from, Address(src, src_pos, Address::times_1, 0));// src_addr + __ lea(to, Address(dst, dst_pos, Address::times_1, 0));// dst_addr + __ movl2ptr(count, r11_length); // length __ jump(RuntimeAddress(byte_copy_entry)); __ BIND(L_copy_shorts); __ cmpl(rax_elsize, LogBytesPerShort); __ jccb(Assembler::notEqual, L_copy_ints); - __ leaq(from, Address(src, src_pos, Address::times_2, 0));// src_addr - __ leaq(to, Address(dst, dst_pos, Address::times_2, 0));// dst_addr - __ movslq(count, r11_length); // length + __ lea(from, Address(src, src_pos, Address::times_2, 0));// src_addr + __ lea(to, Address(dst, dst_pos, Address::times_2, 0));// dst_addr + __ movl2ptr(count, r11_length); // length __ jump(RuntimeAddress(short_copy_entry)); __ BIND(L_copy_ints); __ cmpl(rax_elsize, LogBytesPerInt); __ jccb(Assembler::notEqual, L_copy_longs); - __ leaq(from, Address(src, src_pos, Address::times_4, 0));// src_addr - __ leaq(to, Address(dst, dst_pos, Address::times_4, 0));// dst_addr - __ movslq(count, r11_length); // length + __ lea(from, Address(src, src_pos, Address::times_4, 0));// src_addr + __ lea(to, Address(dst, dst_pos, Address::times_4, 0));// dst_addr + __ movl2ptr(count, r11_length); // length __ jump(RuntimeAddress(int_copy_entry)); __ BIND(L_copy_longs); @@ -2613,9 +2622,9 @@ class StubGenerator: public StubCodeGenerator { __ bind(L); } #endif - __ leaq(from, Address(src, src_pos, Address::times_8, 0));// src_addr - __ leaq(to, Address(dst, dst_pos, Address::times_8, 0));// dst_addr - __ movslq(count, r11_length); // length + __ lea(from, Address(src, src_pos, Address::times_8, 0));// src_addr + __ lea(to, Address(dst, dst_pos, Address::times_8, 0));// dst_addr + __ movl2ptr(count, r11_length); // length __ jump(RuntimeAddress(long_copy_entry)); // objArrayKlass @@ -2632,11 +2641,11 @@ class StubGenerator: public StubCodeGenerator { arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length, r10, L_failed); - __ leaq(from, Address(src, src_pos, TIMES_OOP, + __ lea(from, Address(src, src_pos, TIMES_OOP, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr - __ leaq(to, Address(dst, dst_pos, TIMES_OOP, - arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr - __ movslq(count, r11_length); // length + __ lea(to, Address(dst, dst_pos, TIMES_OOP, + arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr + __ movl2ptr(count, r11_length); // length __ BIND(L_plain_copy); __ jump(RuntimeAddress(oop_copy_entry)); @@ -2663,9 +2672,9 @@ class StubGenerator: public StubCodeGenerator { #endif // Marshal the base address arguments now, freeing registers. - __ leaq(from, Address(src, src_pos, TIMES_OOP, + __ lea(from, Address(src, src_pos, TIMES_OOP, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); - __ leaq(to, Address(dst, dst_pos, TIMES_OOP, + __ lea(to, Address(dst, dst_pos, TIMES_OOP, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); __ movl(count, C_RARG4); // length (reloaded) Register sco_temp = c_rarg3; // this register is free now @@ -2683,19 +2692,19 @@ class StubGenerator: public StubCodeGenerator { // Fetch destination element klass from the objArrayKlass header. int ek_offset = (klassOopDesc::header_size() * HeapWordSize + objArrayKlass::element_klass_offset_in_bytes()); - __ movq(r11_dst_klass, Address(r11_dst_klass, ek_offset)); + __ movptr(r11_dst_klass, Address(r11_dst_klass, ek_offset)); __ movl(sco_temp, Address(r11_dst_klass, sco_offset)); assert_clean_int(sco_temp, rax); // the checkcast_copy loop needs two extra arguments: assert(c_rarg3 == sco_temp, "#3 already in place"); - __ movq(C_RARG4, r11_dst_klass); // dst.klass.element_klass + __ movptr(C_RARG4, r11_dst_klass); // dst.klass.element_klass __ jump(RuntimeAddress(checkcast_copy_entry)); } __ BIND(L_failed); - __ xorq(rax, rax); - __ notq(rax); // return -1 + __ xorptr(rax, rax); + __ notptr(rax); // return -1 __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -2798,10 +2807,10 @@ class StubGenerator: public StubCodeGenerator { // thread-local storage and also sets up last_Java_sp slightly // differently than the real call_VM if (restore_saved_exception_pc) { - __ movq(rax, - Address(r15_thread, - in_bytes(JavaThread::saved_exception_pc_offset()))); - __ pushq(rax); + __ movptr(rax, + Address(r15_thread, + in_bytes(JavaThread::saved_exception_pc_offset()))); + __ push(rax); } __ enter(); // required for proper stackwalking of RuntimeStub frame @@ -2809,7 +2818,7 @@ class StubGenerator: public StubCodeGenerator { assert(is_even(framesize/2), "sp not 16-byte aligned"); // return address and rbp are already in place - __ subq(rsp, (framesize-4) << LogBytesPerInt); // prolog + __ subptr(rsp, (framesize-4) << LogBytesPerInt); // prolog int frame_complete = __ pc() - start; @@ -2817,7 +2826,7 @@ class StubGenerator: public StubCodeGenerator { __ set_last_Java_frame(rsp, rbp, NULL); // Call runtime - __ movq(c_rarg0, r15_thread); + __ movptr(c_rarg0, r15_thread); BLOCK_COMMENT("call runtime_entry"); __ call(RuntimeAddress(runtime_entry)); @@ -2833,8 +2842,8 @@ class StubGenerator: public StubCodeGenerator { // check for pending exceptions #ifdef ASSERT Label L; - __ cmpq(Address(r15_thread, Thread::pending_exception_offset()), - (int) NULL); + __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), + (int32_t) NULL_WORD); __ jcc(Assembler::notEqual, L); __ should_not_reach_here(); __ bind(L); @@ -2857,7 +2866,7 @@ class StubGenerator: public StubCodeGenerator { // Generates all stubs and initializes the entry points // This platform-specific stub is needed by generate_call_stub() - StubRoutines::amd64::_mxcsr_std = generate_fp_mask("mxcsr_std", 0x0000000000001F80); + StubRoutines::x86::_mxcsr_std = generate_fp_mask("mxcsr_std", 0x0000000000001F80); // entry points that exist in all platforms Note: This is code // that could be shared among different platforms - however the @@ -2886,9 +2895,9 @@ class StubGenerator: public StubCodeGenerator { generate_handler_for_unsafe_access(); // platform dependent - StubRoutines::amd64::_get_previous_fp_entry = generate_get_previous_fp(); + StubRoutines::x86::_get_previous_fp_entry = generate_get_previous_fp(); - StubRoutines::amd64::_verify_mxcsr_entry = generate_verify_mxcsr(); + StubRoutines::x86::_verify_mxcsr_entry = generate_verify_mxcsr(); } void generate_all() { @@ -2940,15 +2949,15 @@ class StubGenerator: public StubCodeGenerator { false); // entry points that are platform specific - StubRoutines::amd64::_f2i_fixup = generate_f2i_fixup(); - StubRoutines::amd64::_f2l_fixup = generate_f2l_fixup(); - StubRoutines::amd64::_d2i_fixup = generate_d2i_fixup(); - StubRoutines::amd64::_d2l_fixup = generate_d2l_fixup(); + StubRoutines::x86::_f2i_fixup = generate_f2i_fixup(); + StubRoutines::x86::_f2l_fixup = generate_f2l_fixup(); + StubRoutines::x86::_d2i_fixup = generate_d2i_fixup(); + StubRoutines::x86::_d2l_fixup = generate_d2l_fixup(); - StubRoutines::amd64::_float_sign_mask = generate_fp_mask("float_sign_mask", 0x7FFFFFFF7FFFFFFF); - StubRoutines::amd64::_float_sign_flip = generate_fp_mask("float_sign_flip", 0x8000000080000000); - StubRoutines::amd64::_double_sign_mask = generate_fp_mask("double_sign_mask", 0x7FFFFFFFFFFFFFFF); - StubRoutines::amd64::_double_sign_flip = generate_fp_mask("double_sign_flip", 0x8000000000000000); + StubRoutines::x86::_float_sign_mask = generate_fp_mask("float_sign_mask", 0x7FFFFFFF7FFFFFFF); + StubRoutines::x86::_float_sign_flip = generate_fp_mask("float_sign_flip", 0x8000000080000000); + StubRoutines::x86::_double_sign_mask = generate_fp_mask("double_sign_mask", 0x7FFFFFFFFFFFFFFF); + StubRoutines::x86::_double_sign_flip = generate_fp_mask("double_sign_flip", 0x8000000000000000); // support for verify_oop (must happen after universe_init) StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop(); diff --git a/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.cpp b/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.cpp index 285eef97ef0..d46d510a8a4 100644 --- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,6 @@ // Implementation of the platform-specific part of StubRoutines - for // a description of how to extend it, see the stubRoutines.hpp file. -address StubRoutines::i486::_verify_mxcsr_entry = NULL; -address StubRoutines::i486::_verify_fpu_cntrl_wrd_entry= NULL; -address StubRoutines::i486::_call_stub_compiled_return = NULL; +address StubRoutines::x86::_verify_mxcsr_entry = NULL; +address StubRoutines::x86::_verify_fpu_cntrl_wrd_entry= NULL; +address StubRoutines::x86::_call_stub_compiled_return = NULL; diff --git a/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.hpp b/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.hpp index 8f79b51ecb2..57e75534fce 100644 --- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.hpp +++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.hpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ enum platform_dependent_constants { code_size2 = 22000 // simply increase if too small (assembler will crash if too small) }; -class i486 { +class x86 { friend class StubGenerator; friend class VMStructs; @@ -54,4 +54,4 @@ class i486 { }; static bool returns_to_call_stub(address return_pc) { return (return_pc == _call_stub_return_address) || - return_pc == i486::get_call_stub_compiled_return(); } + return_pc == x86::get_call_stub_compiled_return(); } diff --git a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp index 7979f3f0b99..a3483cf928c 100644 --- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,16 +28,16 @@ // Implementation of the platform-specific part of StubRoutines - for // a description of how to extend it, see the stubRoutines.hpp file. -address StubRoutines::amd64::_get_previous_fp_entry = NULL; +address StubRoutines::x86::_get_previous_fp_entry = NULL; -address StubRoutines::amd64::_verify_mxcsr_entry = NULL; +address StubRoutines::x86::_verify_mxcsr_entry = NULL; -address StubRoutines::amd64::_f2i_fixup = NULL; -address StubRoutines::amd64::_f2l_fixup = NULL; -address StubRoutines::amd64::_d2i_fixup = NULL; -address StubRoutines::amd64::_d2l_fixup = NULL; -address StubRoutines::amd64::_float_sign_mask = NULL; -address StubRoutines::amd64::_float_sign_flip = NULL; -address StubRoutines::amd64::_double_sign_mask = NULL; -address StubRoutines::amd64::_double_sign_flip = NULL; -address StubRoutines::amd64::_mxcsr_std = NULL; +address StubRoutines::x86::_f2i_fixup = NULL; +address StubRoutines::x86::_f2l_fixup = NULL; +address StubRoutines::x86::_d2i_fixup = NULL; +address StubRoutines::x86::_d2l_fixup = NULL; +address StubRoutines::x86::_float_sign_mask = NULL; +address StubRoutines::x86::_float_sign_flip = NULL; +address StubRoutines::x86::_double_sign_mask = NULL; +address StubRoutines::x86::_double_sign_flip = NULL; +address StubRoutines::x86::_mxcsr_std = NULL; diff --git a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp index da7e8fd56a5..7cf06f479ff 100644 --- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp +++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,13 +30,13 @@ static bool returns_to_call_stub(address return_pc) { return return_pc == _ enum platform_dependent_constants { - code_size1 = 9000, // simply increase if too small (assembler will + code_size1 = 19000, // simply increase if too small (assembler will // crash if too small) code_size2 = 22000 // simply increase if too small (assembler will // crash if too small) }; -class amd64 { +class x86 { friend class StubGenerator; private: diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp index 61eb99b99b2..ca186af69a1 100644 --- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,9 +43,9 @@ address TemplateInterpreterGenerator::generate_StackOverflowError_handler() { // #ifdef ASSERT { Label L; - __ leal(rax, Address(rbp, + __ lea(rax, Address(rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize)); - __ cmpl(rax, rsp); // rax, = maximal rsp for current rbp, + __ cmpptr(rax, rsp); // rax, = maximal rsp for current rbp, // (stack grows negative) __ jcc(Assembler::aboveEqual, L); // check if frame is complete __ stop ("interpreter frame not set up"); @@ -80,7 +80,7 @@ address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler(con address TemplateInterpreterGenerator::generate_ClassCastException_handler() { address entry = __ pc(); // object is at TOS - __ popl(rax); + __ pop(rax); // expression stack must be empty before entering the VM if an exception // happened __ empty_expression_stack(); @@ -97,7 +97,7 @@ address TemplateInterpreterGenerator::generate_exception_handler_common(const ch address entry = __ pc(); if (pass_oop) { // object is at TOS - __ popl(rbx); + __ pop(rbx); } // expression stack must be empty before entering the VM if an exception happened __ empty_expression_stack(); @@ -110,7 +110,7 @@ address TemplateInterpreterGenerator::generate_exception_handler_common(const ch if (message != NULL) { __ lea(rbx, ExternalAddress((address)message)); } else { - __ movl(rbx, NULL_WORD); + __ movptr(rbx, (int32_t)NULL_WORD); } __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::create_exception), rax, rbx); } @@ -123,7 +123,7 @@ address TemplateInterpreterGenerator::generate_exception_handler_common(const ch address TemplateInterpreterGenerator::generate_continuation_for(TosState state) { address entry = __ pc(); // NULL last_sp until next java call - __ movl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ dispatch_next(state); return entry; } @@ -160,32 +160,32 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, // In SSE mode, interpreter returns FP results in xmm0 but they need // to end up back on the FPU so it can operate on them. if (state == ftos && UseSSE >= 1) { - __ subl(rsp, wordSize); + __ subptr(rsp, wordSize); __ movflt(Address(rsp, 0), xmm0); __ fld_s(Address(rsp, 0)); - __ addl(rsp, wordSize); + __ addptr(rsp, wordSize); } else if (state == dtos && UseSSE >= 2) { - __ subl(rsp, 2*wordSize); + __ subptr(rsp, 2*wordSize); __ movdbl(Address(rsp, 0), xmm0); __ fld_d(Address(rsp, 0)); - __ addl(rsp, 2*wordSize); + __ addptr(rsp, 2*wordSize); } __ MacroAssembler::verify_FPU(state == ftos || state == dtos ? 1 : 0, "generate_return_entry_for in interpreter"); // Restore stack bottom in case i2c adjusted stack - __ movl(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); + __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); // and NULL it as marker that rsp is now tos until next java call - __ movl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ restore_bcp(); __ restore_locals(); __ get_cache_and_index_at_bcp(rbx, rcx, 1); __ movl(rbx, Address(rbx, rcx, - Address::times_4, constantPoolCacheOopDesc::base_offset() + + Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::flags_offset())); - __ andl(rbx, 0xFF); - __ leal(rsp, Address(rsp, rbx, Interpreter::stackElementScale())); + __ andptr(rbx, 0xFF); + __ lea(rsp, Address(rsp, rbx, Interpreter::stackElementScale())); __ dispatch_next(state, step); return entry; } @@ -196,29 +196,29 @@ address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, i // In SSE mode, FP results are in xmm0 if (state == ftos && UseSSE > 0) { - __ subl(rsp, wordSize); + __ subptr(rsp, wordSize); __ movflt(Address(rsp, 0), xmm0); __ fld_s(Address(rsp, 0)); - __ addl(rsp, wordSize); + __ addptr(rsp, wordSize); } else if (state == dtos && UseSSE >= 2) { - __ subl(rsp, 2*wordSize); + __ subptr(rsp, 2*wordSize); __ movdbl(Address(rsp, 0), xmm0); __ fld_d(Address(rsp, 0)); - __ addl(rsp, 2*wordSize); + __ addptr(rsp, 2*wordSize); } __ MacroAssembler::verify_FPU(state == ftos || state == dtos ? 1 : 0, "generate_deopt_entry_for in interpreter"); // The stack is not extended by deopt but we must NULL last_sp as this // entry is like a "return". - __ movl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ restore_bcp(); __ restore_locals(); // handle exceptions { Label L; const Register thread = rcx; __ get_thread(thread); - __ cmpl(Address(thread, Thread::pending_exception_offset()), NULL_WORD); + __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::zero, L); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_pending_exception)); __ should_not_reach_here(); @@ -254,14 +254,14 @@ address TemplateInterpreterGenerator::generate_result_handler_for(BasicType type address entry = __ pc(); switch (type) { case T_BOOLEAN: __ c2bool(rax); break; - case T_CHAR : __ andl(rax, 0xFFFF); break; + case T_CHAR : __ andptr(rax, 0xFFFF); break; case T_BYTE : __ sign_extend_byte (rax); break; case T_SHORT : __ sign_extend_short(rax); break; case T_INT : /* nothing to do */ break; case T_DOUBLE : case T_FLOAT : { const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp(); - __ popl(t); // remove return address first + __ pop(t); // remove return address first __ pop_dtos_to_rsp(); // Must return a result for interpreter or compiler. In SSE // mode, results are returned in xmm0 and the FPU stack must @@ -280,13 +280,13 @@ address TemplateInterpreterGenerator::generate_result_handler_for(BasicType type __ fld_d(Address(rsp, 0)); } // and pop the temp - __ addl(rsp, 2 * wordSize); - __ pushl(t); // restore return address + __ addptr(rsp, 2 * wordSize); + __ push(t); // restore return address } break; case T_OBJECT : // retrieve result from frame - __ movl(rax, Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize)); + __ movptr(rax, Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize)); // and verify it __ verify_oop(rax); break; @@ -322,12 +322,12 @@ void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile const Address backedge_counter (rbx, methodOopDesc::backedge_counter_offset() + InvocationCounter::counter_offset()); if (ProfileInterpreter) { // %%% Merge this into methodDataOop - __ increment(Address(rbx,methodOopDesc::interpreter_invocation_counter_offset())); + __ incrementl(Address(rbx,methodOopDesc::interpreter_invocation_counter_offset())); } // Update standard invocation counters __ movl(rax, backedge_counter); // load backedge counter - __ increment(rcx, InvocationCounter::count_increment); + __ incrementl(rcx, InvocationCounter::count_increment); __ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits __ movl(invocation_counter, rcx); // save invocation count @@ -382,10 +382,10 @@ void InterpreterGenerator::generate_counter_overflow(Label* do_continue) { // indicating if the counter overflow occurs at a backwards branch (non-NULL bcp). // The call returns the address of the verified entry point for the method or NULL // if the compilation did not complete (either went background or bailed out). - __ movl(rax, (int)false); + __ movptr(rax, (int32_t)false); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), rax); - __ movl(rbx, Address(rbp, method_offset)); // restore methodOop + __ movptr(rbx, Address(rbp, method_offset)); // restore methodOop // Preserve invariant that rsi/rdi contain bcp/locals of sender frame // and jump to the interpreted entry. @@ -433,7 +433,7 @@ void InterpreterGenerator::generate_stack_overflow_check(void) { Label after_frame_check_pop; - __ pushl(rsi); + __ push(rsi); const Register thread = rsi; @@ -443,43 +443,43 @@ void InterpreterGenerator::generate_stack_overflow_check(void) { const Address stack_size(thread, Thread::stack_size_offset()); // locals + overhead, in bytes - __ leal(rax, Address(noreg, rdx, Interpreter::stackElementScale(), overhead_size)); + __ lea(rax, Address(noreg, rdx, Interpreter::stackElementScale(), overhead_size)); #ifdef ASSERT Label stack_base_okay, stack_size_okay; // verify that thread stack base is non-zero - __ cmpl(stack_base, 0); + __ cmpptr(stack_base, (int32_t)NULL_WORD); __ jcc(Assembler::notEqual, stack_base_okay); __ stop("stack base is zero"); __ bind(stack_base_okay); // verify that thread stack size is non-zero - __ cmpl(stack_size, 0); + __ cmpptr(stack_size, 0); __ jcc(Assembler::notEqual, stack_size_okay); __ stop("stack size is zero"); __ bind(stack_size_okay); #endif // Add stack base to locals and subtract stack size - __ addl(rax, stack_base); - __ subl(rax, stack_size); + __ addptr(rax, stack_base); + __ subptr(rax, stack_size); // Use the maximum number of pages we might bang. const int max_pages = StackShadowPages > (StackRedPages+StackYellowPages) ? StackShadowPages : (StackRedPages+StackYellowPages); - __ addl(rax, max_pages * page_size); + __ addptr(rax, max_pages * page_size); // check against the current stack bottom - __ cmpl(rsp, rax); + __ cmpptr(rsp, rax); __ jcc(Assembler::above, after_frame_check_pop); - __ popl(rsi); // get saved bcp / (c++ prev state ). + __ pop(rsi); // get saved bcp / (c++ prev state ). - __ popl(rax); // get return address + __ pop(rax); // get return address __ jump(ExternalAddress(Interpreter::throw_StackOverflowError_entry())); // all done with frame size check __ bind(after_frame_check_pop); - __ popl(rsi); + __ pop(rsi); __ bind(after_frame_check); } @@ -507,18 +507,18 @@ void InterpreterGenerator::lock_method(void) { const int mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes(); __ movl(rax, access_flags); __ testl(rax, JVM_ACC_STATIC); - __ movl(rax, Address(rdi, Interpreter::local_offset_in_bytes(0))); // get receiver (assume this is frequent case) + __ movptr(rax, Address(rdi, Interpreter::local_offset_in_bytes(0))); // get receiver (assume this is frequent case) __ jcc(Assembler::zero, done); - __ movl(rax, Address(rbx, methodOopDesc::constants_offset())); - __ movl(rax, Address(rax, constantPoolOopDesc::pool_holder_offset_in_bytes())); - __ movl(rax, Address(rax, mirror_offset)); + __ movptr(rax, Address(rbx, methodOopDesc::constants_offset())); + __ movptr(rax, Address(rax, constantPoolOopDesc::pool_holder_offset_in_bytes())); + __ movptr(rax, Address(rax, mirror_offset)); __ bind(done); } // add space for monitor & lock - __ subl(rsp, entry_size); // add space for a monitor entry - __ movl(monitor_block_top, rsp); // set new monitor block top - __ movl(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax); // store object - __ movl(rdx, rsp); // object address + __ subptr(rsp, entry_size); // add space for a monitor entry + __ movptr(monitor_block_top, rsp); // set new monitor block top + __ movptr(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax); // store object + __ mov(rdx, rsp); // object address __ lock_object(rdx); } @@ -528,38 +528,38 @@ void InterpreterGenerator::lock_method(void) { void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { // initialize fixed part of activation frame - __ pushl(rax); // save return address + __ push(rax); // save return address __ enter(); // save old & set new rbp, - __ pushl(rsi); // set sender sp - __ pushl(NULL_WORD); // leave last_sp as null - __ movl(rsi, Address(rbx,methodOopDesc::const_offset())); // get constMethodOop - __ leal(rsi, Address(rsi,constMethodOopDesc::codes_offset())); // get codebase - __ pushl(rbx); // save methodOop + __ push(rsi); // set sender sp + __ push((int32_t)NULL_WORD); // leave last_sp as null + __ movptr(rsi, Address(rbx,methodOopDesc::const_offset())); // get constMethodOop + __ lea(rsi, Address(rsi,constMethodOopDesc::codes_offset())); // get codebase + __ push(rbx); // save methodOop if (ProfileInterpreter) { Label method_data_continue; - __ movl(rdx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); - __ testl(rdx, rdx); + __ movptr(rdx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); + __ testptr(rdx, rdx); __ jcc(Assembler::zero, method_data_continue); - __ addl(rdx, in_bytes(methodDataOopDesc::data_offset())); + __ addptr(rdx, in_bytes(methodDataOopDesc::data_offset())); __ bind(method_data_continue); - __ pushl(rdx); // set the mdp (method data pointer) + __ push(rdx); // set the mdp (method data pointer) } else { - __ pushl(0); + __ push(0); } - __ movl(rdx, Address(rbx, methodOopDesc::constants_offset())); - __ movl(rdx, Address(rdx, constantPoolOopDesc::cache_offset_in_bytes())); - __ pushl(rdx); // set constant pool cache - __ pushl(rdi); // set locals pointer + __ movptr(rdx, Address(rbx, methodOopDesc::constants_offset())); + __ movptr(rdx, Address(rdx, constantPoolOopDesc::cache_offset_in_bytes())); + __ push(rdx); // set constant pool cache + __ push(rdi); // set locals pointer if (native_call) { - __ pushl(0); // no bcp + __ push(0); // no bcp } else { - __ pushl(rsi); // set bcp + __ push(rsi); // set bcp } - __ pushl(0); // reserve word for pointer to expression stack bottom - __ movl(Address(rsp, 0), rsp); // set expression stack bottom + __ push(0); // reserve word for pointer to expression stack bottom + __ movptr(Address(rsp, 0), rsp); // set expression stack bottom } // End of helpers @@ -598,21 +598,21 @@ address InterpreterGenerator::generate_accessor_entry(void) { // these conditions first and use slow path if necessary. // rbx,: method // rcx: receiver - __ movl(rax, Address(rsp, wordSize)); + __ movptr(rax, Address(rsp, wordSize)); // check if local 0 != NULL and read field - __ testl(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, slow_path); - __ movl(rdi, Address(rbx, methodOopDesc::constants_offset())); + __ movptr(rdi, Address(rbx, methodOopDesc::constants_offset())); // read first instruction word and extract bytecode @ 1 and index @ 2 - __ movl(rdx, Address(rbx, methodOopDesc::const_offset())); + __ movptr(rdx, Address(rbx, methodOopDesc::const_offset())); __ movl(rdx, Address(rdx, constMethodOopDesc::codes_offset())); // Shift codes right to get the index on the right. // The bytecode fetched looks like <0xb4><0x2a> __ shrl(rdx, 2*BitsPerByte); __ shll(rdx, exact_log2(in_words(ConstantPoolCacheEntry::size()))); - __ movl(rdi, Address(rdi, constantPoolOopDesc::cache_offset_in_bytes())); + __ movptr(rdi, Address(rdi, constantPoolOopDesc::cache_offset_in_bytes())); // rax,: local 0 // rbx,: method @@ -629,21 +629,21 @@ address InterpreterGenerator::generate_accessor_entry(void) { __ movl(rcx, Address(rdi, rdx, - Address::times_4, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); + Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); __ shrl(rcx, 2*BitsPerByte); __ andl(rcx, 0xFF); __ cmpl(rcx, Bytecodes::_getfield); __ jcc(Assembler::notEqual, slow_path); // Note: constant pool entry is not valid before bytecode is resolved - __ movl(rcx, - Address(rdi, - rdx, - Address::times_4, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f2_offset())); + __ movptr(rcx, + Address(rdi, + rdx, + Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f2_offset())); __ movl(rdx, Address(rdi, rdx, - Address::times_4, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::flags_offset())); + Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::flags_offset())); Label notByte, notShort, notChar; const Address field_address (rax, rcx, Address::times_1); @@ -682,13 +682,14 @@ address InterpreterGenerator::generate_accessor_entry(void) { __ bind(okay); #endif // ASSERT // All the rest are a 32 bit wordsize - __ movl(rax, field_address); + // This is ok for now. Since fast accessors should be going away + __ movptr(rax, field_address); __ bind(xreturn_path); // _ireturn/_areturn - __ popl(rdi); // get return address - __ movl(rsp, rsi); // set sp to sender sp + __ pop(rdi); // get return address + __ mov(rsp, rsi); // set sp to sender sp __ jmp(rdi); // generate a vanilla interpreter entry as the slow path @@ -732,18 +733,18 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // rcx: size of parameters // rsi: sender sp - __ popl(rax); // get return address + __ pop(rax); // get return address // for natives the size of locals is zero // compute beginning of parameters (rdi) - __ leal(rdi, Address(rsp, rcx, Interpreter::stackElementScale(), -wordSize)); + __ lea(rdi, Address(rsp, rcx, Interpreter::stackElementScale(), -wordSize)); // add 2 zero-initialized slots for native calls // NULL result handler - __ pushl(NULL_WORD); + __ push((int32_t)NULL_WORD); // NULL oop temp (mirror or jni oop result) - __ pushl(NULL_WORD); + __ push((int32_t)NULL_WORD); if (inc_counter) __ movl(rcx, invocation_counter); // (pre-)fetch invocation count // initialize fixed part of activation frame @@ -818,8 +819,8 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { { Label L; const Address monitor_block_top (rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize); - __ movl(rax, monitor_block_top); - __ cmpl(rax, rsp); + __ movptr(rax, monitor_block_top); + __ cmpptr(rax, rsp); __ jcc(Assembler::equal, L); __ stop("broken stack frame setup in interpreter"); __ bind(L); @@ -838,19 +839,19 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ get_method(method); __ verify_oop(method); __ load_unsigned_word(t, Address(method, methodOopDesc::size_of_parameters_offset())); - __ shll(t, Interpreter::logStackElementSize()); - __ addl(t, 2*wordSize); // allocate two more slots for JNIEnv and possible mirror - __ subl(rsp, t); - __ andl(rsp, -(StackAlignmentInBytes)); // gcc needs 16 byte aligned stacks to do XMM intrinsics + __ shlptr(t, Interpreter::logStackElementSize()); + __ addptr(t, 2*wordSize); // allocate two more slots for JNIEnv and possible mirror + __ subptr(rsp, t); + __ andptr(rsp, -(StackAlignmentInBytes)); // gcc needs 16 byte aligned stacks to do XMM intrinsics // get signature handler { Label L; - __ movl(t, Address(method, methodOopDesc::signature_handler_offset())); - __ testl(t, t); + __ movptr(t, Address(method, methodOopDesc::signature_handler_offset())); + __ testptr(t, t); __ jcc(Assembler::notZero, L); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), method); __ get_method(method); - __ movl(t, Address(method, methodOopDesc::signature_handler_offset())); + __ movptr(t, Address(method, methodOopDesc::signature_handler_offset())); __ bind(L); } @@ -867,7 +868,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // result handler is in rax, // set result handler - __ movl(Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize), rax); + __ movptr(Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize), rax); // pass mirror handle if static call { Label L; @@ -876,34 +877,34 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ testl(t, JVM_ACC_STATIC); __ jcc(Assembler::zero, L); // get mirror - __ movl(t, Address(method, methodOopDesc:: constants_offset())); - __ movl(t, Address(t, constantPoolOopDesc::pool_holder_offset_in_bytes())); - __ movl(t, Address(t, mirror_offset)); + __ movptr(t, Address(method, methodOopDesc:: constants_offset())); + __ movptr(t, Address(t, constantPoolOopDesc::pool_holder_offset_in_bytes())); + __ movptr(t, Address(t, mirror_offset)); // copy mirror into activation frame - __ movl(Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize), t); + __ movptr(Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize), t); // pass handle to mirror - __ leal(t, Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize)); - __ movl(Address(rsp, wordSize), t); + __ lea(t, Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize)); + __ movptr(Address(rsp, wordSize), t); __ bind(L); } // get native function entry point { Label L; - __ movl(rax, Address(method, methodOopDesc::native_function_offset())); + __ movptr(rax, Address(method, methodOopDesc::native_function_offset())); ExternalAddress unsatisfied(SharedRuntime::native_method_throw_unsatisfied_link_error_entry()); - __ cmp32(rax, unsatisfied.addr()); + __ cmpptr(rax, unsatisfied.addr()); __ jcc(Assembler::notEqual, L); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), method); __ get_method(method); __ verify_oop(method); - __ movl(rax, Address(method, methodOopDesc::native_function_offset())); + __ movptr(rax, Address(method, methodOopDesc::native_function_offset())); __ bind(L); } // pass JNIEnv __ get_thread(thread); - __ leal(t, Address(thread, JavaThread::jni_environment_offset())); - __ movl(Address(rsp, 0), t); + __ lea(t, Address(thread, JavaThread::jni_environment_offset())); + __ movptr(Address(rsp, 0), t); // set_last_Java_frame_before_call // It is enough that the pc() @@ -934,14 +935,14 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ ldmxcsr(ExternalAddress(StubRoutines::addr_mxcsr_std())); } else if (CheckJNICalls ) { - __ call(RuntimeAddress(StubRoutines::i486::verify_mxcsr_entry())); + __ call(RuntimeAddress(StubRoutines::x86::verify_mxcsr_entry())); } } // Either restore the x87 floating pointer control word after returning // from the JNI call or verify that it wasn't changed. if (CheckJNICalls) { - __ call(RuntimeAddress(StubRoutines::i486::verify_fpu_cntrl_wrd_entry())); + __ call(RuntimeAddress(StubRoutines::x86::verify_fpu_cntrl_wrd_entry())); } // save potential result in ST(0) & rdx:rax @@ -975,7 +976,10 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native_trans); if(os::is_MP()) { if (UseMembar) { - __ membar(); // Force this write out before the read below + // Force this write out before the read below + __ membar(Assembler::Membar_mask_bits( + Assembler::LoadLoad | Assembler::LoadStore | + Assembler::StoreLoad | Assembler::StoreStore)); } else { // Write serialization page so VM thread can do a pseudo remote membar. // We use the current thread pointer to calculate a thread specific @@ -1008,7 +1012,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // preserved and correspond to the bcp/locals pointers. So we do a runtime call // by hand. // - __ pushl(thread); + __ push(thread); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans))); __ increment(rsp, wordSize); @@ -1023,8 +1027,8 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ reset_last_Java_frame(thread, true, true); // reset handle block - __ movl(t, Address(thread, JavaThread::active_handles_offset())); - __ movl(Address(t, JNIHandleBlock::top_offset_in_bytes()), 0); + __ movptr(t, Address(thread, JavaThread::active_handles_offset())); + __ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); // If result was an oop then unbox and save it in the frame { Label L; @@ -1033,14 +1037,14 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ cmpptr(Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize), handler.addr()); __ jcc(Assembler::notEqual, no_oop); - __ cmpl(Address(rsp, 0), NULL_WORD); + __ cmpptr(Address(rsp, 0), (int32_t)NULL_WORD); __ pop(ltos); - __ testl(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, store_result); // unbox - __ movl(rax, Address(rax, 0)); + __ movptr(rax, Address(rax, 0)); __ bind(store_result); - __ movl(Address(rbp, (frame::interpreter_frame_oop_temp_offset)*wordSize), rax); + __ movptr(Address(rbp, (frame::interpreter_frame_oop_temp_offset)*wordSize), rax); // keep stack depth as expected by pushing oop which will eventually be discarded __ push(ltos); __ bind(no_oop); @@ -1051,9 +1055,9 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ cmpl(Address(thread, JavaThread::stack_guard_state_offset()), JavaThread::stack_guard_yellow_disabled); __ jcc(Assembler::notEqual, no_reguard); - __ pushad(); + __ pusha(); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages))); - __ popad(); + __ popa(); __ bind(no_reguard); } @@ -1063,12 +1067,12 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // Can't call_VM until bcp is within reasonable. __ get_method(method); // method is junk from thread_in_native to now. __ verify_oop(method); - __ movl(rsi, Address(method,methodOopDesc::const_offset())); // get constMethodOop - __ leal(rsi, Address(rsi,constMethodOopDesc::codes_offset())); // get codebase + __ movptr(rsi, Address(method,methodOopDesc::const_offset())); // get constMethodOop + __ lea(rsi, Address(rsi,constMethodOopDesc::codes_offset())); // get codebase // handle exceptions (exception handling will handle unlocking!) { Label L; - __ cmpl(Address(thread, Thread::pending_exception_offset()), NULL_WORD); + __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::zero, L); // Note: At some point we may want to unify this with the code used in call_VM_base(); // i.e., we should use the StubRoutines::forward_exception code. For now this @@ -1089,10 +1093,10 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // to check that the object has not been unlocked by an explicit monitorexit bytecode. const Address monitor(rbp, frame::interpreter_frame_initial_sp_offset * wordSize - (int)sizeof(BasicObjectLock)); - __ leal(rdx, monitor); // address of first monitor + __ lea(rdx, monitor); // address of first monitor - __ movl(t, Address(rdx, BasicObjectLock::obj_offset_in_bytes())); - __ testl(t, t); + __ movptr(t, Address(rdx, BasicObjectLock::obj_offset_in_bytes())); + __ testptr(t, t); __ jcc(Assembler::notZero, unlock); // Entry already unlocked, need to throw exception @@ -1114,14 +1118,14 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // restore potential result in rdx:rax, call result handler to restore potential result in ST0 & handle result __ pop(ltos); - __ movl(t, Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize)); + __ movptr(t, Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize)); __ call(t); // remove activation - __ movl(t, Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp + __ movptr(t, Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp __ leave(); // remove frame anchor - __ popl(rdi); // get return address - __ movl(rsp, t); // set sp to sender sp + __ pop(rdi); // get return address + __ mov(rsp, t); // set sp to sender sp __ jmp(rdi); if (inc_counter) { @@ -1165,10 +1169,10 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { generate_stack_overflow_check(); // get return address - __ popl(rax); + __ pop(rax); // compute beginning of parameters (rdi) - __ leal(rdi, Address(rsp, rcx, Interpreter::stackElementScale(), -wordSize)); + __ lea(rdi, Address(rsp, rcx, Interpreter::stackElementScale(), -wordSize)); // rdx - # of additional locals // allocate space for locals @@ -1178,8 +1182,10 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { __ testl(rdx, rdx); __ jcc(Assembler::lessEqual, exit); // do nothing if rdx <= 0 __ bind(loop); - if (TaggedStackInterpreter) __ pushl(NULL_WORD); // push tag - __ pushl(NULL_WORD); // initialize local variables + if (TaggedStackInterpreter) { + __ push((int32_t)NULL_WORD); // push tag + } + __ push((int32_t)NULL_WORD); // initialize local variables __ decrement(rdx); // until everything initialized __ jcc(Assembler::greater, loop); __ bind(exit); @@ -1262,8 +1268,8 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { { Label L; const Address monitor_block_top (rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize); - __ movl(rax, monitor_block_top); - __ cmpl(rax, rsp); + __ movptr(rax, monitor_block_top); + __ cmpptr(rax, rsp); __ jcc(Assembler::equal, L); __ stop("broken stack frame setup in interpreter"); __ bind(L); @@ -1283,12 +1289,12 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method), rsi, true); - __ movl(rbx, Address(rbp, method_offset)); // restore methodOop - __ movl(rax, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); - __ movl(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rax); + __ movptr(rbx, Address(rbp, method_offset)); // restore methodOop + __ movptr(rax, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); + __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rax); __ test_method_data_pointer(rax, profile_method_continue); - __ addl(rax, in_bytes(methodDataOopDesc::data_offset())); - __ movl(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rax); + __ addptr(rax, in_bytes(methodDataOopDesc::data_offset())); + __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rax); __ jmp(profile_method_continue); } // Handle overflow of counter and compile method @@ -1482,7 +1488,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // Restore sp to interpreter_frame_last_sp even though we are going // to empty the expression stack for the exception processing. - __ movl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); // rax,: exception // rdx: return address/pc that threw exception __ restore_bcp(); // rsi points to call/send @@ -1544,7 +1550,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // deoptimization blob's unpack entry because of the presence of // adapter frames in C2. Label caller_not_deoptimized; - __ movl(rdx, Address(rbp, frame::return_addr_offset * wordSize)); + __ movptr(rdx, Address(rbp, frame::return_addr_offset * wordSize)); __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::interpreter_contains), rdx); __ testl(rax, rax); __ jcc(Assembler::notZero, caller_not_deoptimized); @@ -1553,10 +1559,10 @@ void TemplateInterpreterGenerator::generate_throw_exception() { __ get_method(rax); __ verify_oop(rax); __ load_unsigned_word(rax, Address(rax, in_bytes(methodOopDesc::size_of_parameters_offset()))); - __ shll(rax, Interpreter::logStackElementSize()); + __ shlptr(rax, Interpreter::logStackElementSize()); __ restore_locals(); - __ subl(rdi, rax); - __ addl(rdi, wordSize); + __ subptr(rdi, rax); + __ addptr(rdi, wordSize); // Save these arguments __ get_thread(rcx); __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, Deoptimization::popframe_preserve_args), rcx, rax, rdi); @@ -1592,8 +1598,8 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // maintain this kind of invariant all the time we call a small // fixup routine to move the mutated arguments onto the top of our // expression stack if necessary. - __ movl(rax, rsp); - __ movl(rbx, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); + __ mov(rax, rsp); + __ movptr(rbx, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); __ get_thread(rcx); // PC must point into interpreter here __ set_last_Java_frame(rcx, noreg, rbp, __ pc()); @@ -1601,8 +1607,8 @@ void TemplateInterpreterGenerator::generate_throw_exception() { __ get_thread(rcx); __ reset_last_Java_frame(rcx, true, true); // Restore the last_sp and null it out - __ movl(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); - __ movl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ restore_bcp(); __ restore_locals(); @@ -1624,13 +1630,13 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // preserve exception over this code sequence __ pop_ptr(rax); __ get_thread(rcx); - __ movl(Address(rcx, JavaThread::vm_result_offset()), rax); + __ movptr(Address(rcx, JavaThread::vm_result_offset()), rax); // remove the activation (without doing throws on illegalMonitorExceptions) __ remove_activation(vtos, rdx, false, true, false); // restore exception __ get_thread(rcx); - __ movl(rax, Address(rcx, JavaThread::vm_result_offset())); - __ movl(Address(rcx, JavaThread::vm_result_offset()), NULL_WORD); + __ movptr(rax, Address(rcx, JavaThread::vm_result_offset())); + __ movptr(Address(rcx, JavaThread::vm_result_offset()), (int32_t)NULL_WORD); __ verify_oop(rax); // Inbetween activations - previous activation type unknown yet @@ -1641,12 +1647,12 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // rdx: return address/pc that threw exception // rsp: expression stack of caller // rbp,: rbp, of caller - __ pushl(rax); // save exception - __ pushl(rdx); // save return address + __ push(rax); // save exception + __ push(rdx); // save return address __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), rdx); - __ movl(rbx, rax); // save exception handler - __ popl(rdx); // restore return address - __ popl(rax); // restore exception + __ mov(rbx, rax); // save exception handler + __ pop(rdx); // restore return address + __ pop(rax); // restore exception // Note that an "issuing PC" is actually the next PC after the call __ jmp(rbx); // jump to exception handler of caller } @@ -1665,7 +1671,7 @@ address TemplateInterpreterGenerator::generate_earlyret_entry_for(TosState state __ load_earlyret_value(state); __ get_thread(rcx); - __ movl(rcx, Address(rcx, JavaThread::jvmti_thread_state_offset())); + __ movptr(rcx, Address(rcx, JavaThread::jvmti_thread_state_offset())); const Address cond_addr(rcx, JvmtiThreadState::earlyret_state_offset()); // Clear the earlyret state @@ -1716,12 +1722,12 @@ address TemplateInterpreterGenerator::generate_trace_code(TosState state) { address entry = __ pc(); // prepare expression stack - __ popl(rcx); // pop return address so expression stack is 'pure' + __ pop(rcx); // pop return address so expression stack is 'pure' __ push(state); // save tosca // pass tosca registers as arguments & call tracer __ call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::trace_bytecode), rcx, rax, rdx); - __ movl(rcx, rax); // make sure return address is not destroyed by pop(state) + __ mov(rcx, rax); // make sure return address is not destroyed by pop(state) __ pop(state); // restore tosca // return @@ -1732,12 +1738,12 @@ address TemplateInterpreterGenerator::generate_trace_code(TosState state) { void TemplateInterpreterGenerator::count_bytecode() { - __ increment(ExternalAddress((address) &BytecodeCounter::_counter_value)); + __ incrementl(ExternalAddress((address) &BytecodeCounter::_counter_value)); } void TemplateInterpreterGenerator::histogram_bytecode(Template* t) { - __ increment(ExternalAddress((address) &BytecodeHistogram::_counters[t->bytecode()])); + __ incrementl(ExternalAddress((address) &BytecodeHistogram::_counters[t->bytecode()])); } @@ -1747,7 +1753,7 @@ void TemplateInterpreterGenerator::histogram_bytecode_pair(Template* t) { __ orl(rbx, ((int)t->bytecode()) << BytecodePairHistogram::log2_number_of_codes); ExternalAddress table((address) BytecodePairHistogram::_counters); Address index(noreg, rbx, Address::times_4); - __ increment(ArrayAddress(table, index)); + __ incrementl(ArrayAddress(table, index)); } diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp index 3f7d4719b5f..9caf33f6b09 100644 --- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp @@ -27,6 +27,8 @@ #define __ _masm-> +#ifndef CC_INTERP + const int method_offset = frame::interpreter_frame_method_offset * wordSize; const int bci_offset = frame::interpreter_frame_bcx_offset * wordSize; const int locals_offset = frame::interpreter_frame_locals_offset * wordSize; @@ -39,11 +41,11 @@ address TemplateInterpreterGenerator::generate_StackOverflowError_handler() { #ifdef ASSERT { Label L; - __ leaq(rax, Address(rbp, - frame::interpreter_frame_monitor_block_top_offset * - wordSize)); - __ cmpq(rax, rsp); // rax = maximal rsp for current rbp (stack - // grows negative) + __ lea(rax, Address(rbp, + frame::interpreter_frame_monitor_block_top_offset * + wordSize)); + __ cmpptr(rax, rsp); // rax = maximal rsp for current rbp (stack + // grows negative) __ jcc(Assembler::aboveEqual, L); // check if frame is complete __ stop ("interpreter frame not set up"); __ bind(L); @@ -84,7 +86,7 @@ address TemplateInterpreterGenerator::generate_ClassCastException_handler() { address entry = __ pc(); // object is at TOS - __ popq(c_rarg1); + __ pop(c_rarg1); // expression stack must be empty before entering the VM if an // exception happened @@ -104,7 +106,7 @@ address TemplateInterpreterGenerator::generate_exception_handler_common( address entry = __ pc(); if (pass_oop) { // object is at TOS - __ popq(c_rarg2); + __ pop(c_rarg2); } // expression stack must be empty before entering the VM if an // exception happened @@ -137,7 +139,7 @@ address TemplateInterpreterGenerator::generate_exception_handler_common( address TemplateInterpreterGenerator::generate_continuation_for(TosState state) { address entry = __ pc(); // NULL last_sp until next java call - __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ dispatch_next(state); return entry; } @@ -153,12 +155,13 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, address entry = __ pc(); // Restore stack bottom in case i2c adjusted stack - __ movq(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); + __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); // and NULL it as marker that esp is now tos until next java call - __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ restore_bcp(); __ restore_locals(); + __ get_cache_and_index_at_bcp(rbx, rcx, 1); __ movl(rbx, Address(rbx, rcx, Address::times_8, @@ -166,7 +169,7 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, 3 * wordSize)); __ andl(rbx, 0xFF); if (TaggedStackInterpreter) __ shll(rbx, 1); // 2 slots per parameter. - __ leaq(rsp, Address(rsp, rbx, Address::times_8)); + __ lea(rsp, Address(rsp, rbx, Address::times_8)); __ dispatch_next(state, step); return entry; } @@ -176,13 +179,13 @@ address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step) { address entry = __ pc(); // NULL last_sp until next java call - __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ restore_bcp(); __ restore_locals(); // handle exceptions { Label L; - __ cmpq(Address(r15_thread, Thread::pending_exception_offset()), (int) NULL); + __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t) NULL_WORD); __ jcc(Assembler::zero, L); __ call_VM(noreg, CAST_FROM_FN_PTR(address, @@ -231,7 +234,7 @@ address TemplateInterpreterGenerator::generate_result_handler_for( case T_DOUBLE : /* nothing to do */ break; case T_OBJECT : // retrieve result from frame - __ movq(rax, Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize)); + __ movptr(rax, Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize)); // and verify it __ verify_oop(rax); break; @@ -336,7 +339,7 @@ void InterpreterGenerator::generate_counter_overflow(Label* do_continue) { InterpreterRuntime::frequency_counter_overflow), c_rarg1); - __ movq(rbx, Address(rbp, method_offset)); // restore methodOop + __ movptr(rbx, Address(rbp, method_offset)); // restore methodOop // Preserve invariant that r13/r14 contain bcp/locals of sender frame // and jump to the interpreted entry. __ jmp(*do_continue, relocInfo::none); @@ -385,36 +388,36 @@ void InterpreterGenerator::generate_stack_overflow_check(void) { const Address stack_size(r15_thread, Thread::stack_size_offset()); // locals + overhead, in bytes - __ movq(rax, rdx); - __ shll(rax, Interpreter::logStackElementSize()); // 2 slots per parameter. - __ addq(rax, overhead_size); + __ mov(rax, rdx); + __ shlptr(rax, Interpreter::logStackElementSize()); // 2 slots per parameter. + __ addptr(rax, overhead_size); #ifdef ASSERT Label stack_base_okay, stack_size_okay; // verify that thread stack base is non-zero - __ cmpq(stack_base, 0); + __ cmpptr(stack_base, (int32_t)NULL_WORD); __ jcc(Assembler::notEqual, stack_base_okay); __ stop("stack base is zero"); __ bind(stack_base_okay); // verify that thread stack size is non-zero - __ cmpq(stack_size, 0); + __ cmpptr(stack_size, 0); __ jcc(Assembler::notEqual, stack_size_okay); __ stop("stack size is zero"); __ bind(stack_size_okay); #endif // Add stack base to locals and subtract stack size - __ addq(rax, stack_base); - __ subq(rax, stack_size); + __ addptr(rax, stack_base); + __ subptr(rax, stack_size); // add in the red and yellow zone sizes - __ addq(rax, (StackRedPages + StackYellowPages) * page_size); + __ addptr(rax, (StackRedPages + StackYellowPages) * page_size); // check against the current stack bottom - __ cmpq(rsp, rax); + __ cmpptr(rsp, rax); __ jcc(Assembler::above, after_frame_check); - __ popq(rax); // get return address + __ pop(rax); // get return address __ jump(ExternalAddress(Interpreter::throw_StackOverflowError_entry())); // all done with frame size check @@ -458,17 +461,17 @@ void InterpreterGenerator::lock_method(void) { __ movl(rax, access_flags); __ testl(rax, JVM_ACC_STATIC); // get receiver (assume this is frequent case) - __ movq(rax, Address(r14, Interpreter::local_offset_in_bytes(0))); + __ movptr(rax, Address(r14, Interpreter::local_offset_in_bytes(0))); __ jcc(Assembler::zero, done); - __ movq(rax, Address(rbx, methodOopDesc::constants_offset())); - __ movq(rax, Address(rax, - constantPoolOopDesc::pool_holder_offset_in_bytes())); - __ movq(rax, Address(rax, mirror_offset)); + __ movptr(rax, Address(rbx, methodOopDesc::constants_offset())); + __ movptr(rax, Address(rax, + constantPoolOopDesc::pool_holder_offset_in_bytes())); + __ movptr(rax, Address(rax, mirror_offset)); #ifdef ASSERT { Label L; - __ testq(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::notZero, L); __ stop("synchronization object is NULL"); __ bind(L); @@ -479,11 +482,11 @@ void InterpreterGenerator::lock_method(void) { } // add space for monitor & lock - __ subq(rsp, entry_size); // add space for a monitor entry - __ movq(monitor_block_top, rsp); // set new monitor block top + __ subptr(rsp, entry_size); // add space for a monitor entry + __ movptr(monitor_block_top, rsp); // set new monitor block top // store object - __ movq(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax); - __ movq(c_rarg1, rsp); // object address + __ movptr(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax); + __ movptr(c_rarg1, rsp); // object address __ lock_object(c_rarg1); } @@ -498,40 +501,187 @@ void InterpreterGenerator::lock_method(void) { // rdx: cp cache void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { // initialize fixed part of activation frame - __ pushq(rax); // save return address + __ push(rax); // save return address __ enter(); // save old & set new rbp - __ pushq(r13); // set sender sp - __ pushq((int)NULL_WORD); // leave last_sp as null - __ movq(r13, Address(rbx, methodOopDesc::const_offset())); // get constMethodOop - __ leaq(r13, Address(r13, constMethodOopDesc::codes_offset())); // get codebase - __ pushq(rbx); // save methodOop + __ push(r13); // set sender sp + __ push((int)NULL_WORD); // leave last_sp as null + __ movptr(r13, Address(rbx, methodOopDesc::const_offset())); // get constMethodOop + __ lea(r13, Address(r13, constMethodOopDesc::codes_offset())); // get codebase + __ push(rbx); // save methodOop if (ProfileInterpreter) { Label method_data_continue; - __ movq(rdx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); - __ testq(rdx, rdx); + __ movptr(rdx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); + __ testptr(rdx, rdx); __ jcc(Assembler::zero, method_data_continue); - __ addq(rdx, in_bytes(methodDataOopDesc::data_offset())); + __ addptr(rdx, in_bytes(methodDataOopDesc::data_offset())); __ bind(method_data_continue); - __ pushq(rdx); // set the mdp (method data pointer) + __ push(rdx); // set the mdp (method data pointer) } else { - __ pushq(0); + __ push(0); } - __ movq(rdx, Address(rbx, methodOopDesc::constants_offset())); - __ movq(rdx, Address(rdx, constantPoolOopDesc::cache_offset_in_bytes())); - __ pushq(rdx); // set constant pool cache - __ pushq(r14); // set locals pointer + __ movptr(rdx, Address(rbx, methodOopDesc::constants_offset())); + __ movptr(rdx, Address(rdx, constantPoolOopDesc::cache_offset_in_bytes())); + __ push(rdx); // set constant pool cache + __ push(r14); // set locals pointer if (native_call) { - __ pushq(0); // no bcp + __ push(0); // no bcp } else { - __ pushq(r13); // set bcp + __ push(r13); // set bcp } - __ pushq(0); // reserve word for pointer to expression stack bottom - __ movq(Address(rsp, 0), rsp); // set expression stack bottom + __ push(0); // reserve word for pointer to expression stack bottom + __ movptr(Address(rsp, 0), rsp); // set expression stack bottom } // End of helpers +// Various method entries +//------------------------------------------------------------------------------------------------------------------------ +// +// + +// Call an accessor method (assuming it is resolved, otherwise drop +// into vanilla (slow path) entry +address InterpreterGenerator::generate_accessor_entry(void) { + // rbx: methodOop + + // r13: senderSP must preserver for slow path, set SP to it on fast path + + address entry_point = __ pc(); + Label xreturn_path; + + // do fastpath for resolved accessor methods + if (UseFastAccessorMethods) { + // Code: _aload_0, _(i|a)getfield, _(i|a)return or any rewrites + // thereof; parameter size = 1 + // Note: We can only use this code if the getfield has been resolved + // and if we don't have a null-pointer exception => check for + // these conditions first and use slow path if necessary. + Label slow_path; + // If we need a safepoint check, generate full interpreter entry. + __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), + SafepointSynchronize::_not_synchronized); + + __ jcc(Assembler::notEqual, slow_path); + // rbx: method + __ movptr(rax, Address(rsp, wordSize)); + + // check if local 0 != NULL and read field + __ testptr(rax, rax); + __ jcc(Assembler::zero, slow_path); + + __ movptr(rdi, Address(rbx, methodOopDesc::constants_offset())); + // read first instruction word and extract bytecode @ 1 and index @ 2 + __ movptr(rdx, Address(rbx, methodOopDesc::const_offset())); + __ movl(rdx, Address(rdx, constMethodOopDesc::codes_offset())); + // Shift codes right to get the index on the right. + // The bytecode fetched looks like <0xb4><0x2a> + __ shrl(rdx, 2 * BitsPerByte); + __ shll(rdx, exact_log2(in_words(ConstantPoolCacheEntry::size()))); + __ movptr(rdi, Address(rdi, constantPoolOopDesc::cache_offset_in_bytes())); + + // rax: local 0 + // rbx: method + // rdx: constant pool cache index + // rdi: constant pool cache + + // check if getfield has been resolved and read constant pool cache entry + // check the validity of the cache entry by testing whether _indices field + // contains Bytecode::_getfield in b1 byte. + assert(in_words(ConstantPoolCacheEntry::size()) == 4, + "adjust shift below"); + __ movl(rcx, + Address(rdi, + rdx, + Address::times_8, + constantPoolCacheOopDesc::base_offset() + + ConstantPoolCacheEntry::indices_offset())); + __ shrl(rcx, 2 * BitsPerByte); + __ andl(rcx, 0xFF); + __ cmpl(rcx, Bytecodes::_getfield); + __ jcc(Assembler::notEqual, slow_path); + + // Note: constant pool entry is not valid before bytecode is resolved + __ movptr(rcx, + Address(rdi, + rdx, + Address::times_8, + constantPoolCacheOopDesc::base_offset() + + ConstantPoolCacheEntry::f2_offset())); + // edx: flags + __ movl(rdx, + Address(rdi, + rdx, + Address::times_8, + constantPoolCacheOopDesc::base_offset() + + ConstantPoolCacheEntry::flags_offset())); + + Label notObj, notInt, notByte, notShort; + const Address field_address(rax, rcx, Address::times_1); + + // Need to differentiate between igetfield, agetfield, bgetfield etc. + // because they are different sizes. + // Use the type from the constant pool cache + __ shrl(rdx, ConstantPoolCacheEntry::tosBits); + // Make sure we don't need to mask edx for tosBits after the above shift + ConstantPoolCacheEntry::verify_tosBits(); + + __ cmpl(rdx, atos); + __ jcc(Assembler::notEqual, notObj); + // atos + __ load_heap_oop(rax, field_address); + __ jmp(xreturn_path); + + __ bind(notObj); + __ cmpl(rdx, itos); + __ jcc(Assembler::notEqual, notInt); + // itos + __ movl(rax, field_address); + __ jmp(xreturn_path); + + __ bind(notInt); + __ cmpl(rdx, btos); + __ jcc(Assembler::notEqual, notByte); + // btos + __ load_signed_byte(rax, field_address); + __ jmp(xreturn_path); + + __ bind(notByte); + __ cmpl(rdx, stos); + __ jcc(Assembler::notEqual, notShort); + // stos + __ load_signed_word(rax, field_address); + __ jmp(xreturn_path); + + __ bind(notShort); +#ifdef ASSERT + Label okay; + __ cmpl(rdx, ctos); + __ jcc(Assembler::equal, okay); + __ stop("what type is this?"); + __ bind(okay); +#endif + // ctos + __ load_unsigned_word(rax, field_address); + + __ bind(xreturn_path); + + // _ireturn/_areturn + __ pop(rdi); + __ mov(rsp, r13); + __ jmp(rdi); + __ ret(0); + + // generate a vanilla interpreter entry as the slow path + __ bind(slow_path); + (void) generate_normal_entry(false); + } else { + (void) generate_normal_entry(false); + } + + return entry_point; +} + // Interpreter stub for calling a native method. (asm interpreter) // This sets up a somewhat different looking stack for calling the // native method than the typical interpreter frame setup. @@ -561,20 +711,20 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // rbx: methodOop // rcx: size of parameters // r13: sender sp - __ popq(rax); // get return address + __ pop(rax); // get return address // for natives the size of locals is zero // compute beginning of parameters (r14) if (TaggedStackInterpreter) __ shll(rcx, 1); // 2 slots per parameter. - __ leaq(r14, Address(rsp, rcx, Address::times_8, -wordSize)); + __ lea(r14, Address(rsp, rcx, Address::times_8, -wordSize)); // add 2 zero-initialized slots for native calls // initialize result_handler slot - __ pushq((int) NULL); + __ push((int) NULL_WORD); // slot for oop temp // (static native method holder mirror/jni oop result) - __ pushq((int) NULL); + __ push((int) NULL_WORD); if (inc_counter) { __ movl(rcx, invocation_counter); // (pre-)fetch invocation count @@ -651,8 +801,8 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { Label L; const Address monitor_block_top(rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize); - __ movq(rax, monitor_block_top); - __ cmpq(rax, rsp); + __ movptr(rax, monitor_block_top); + __ cmpptr(rax, rsp); __ jcc(Assembler::equal, L); __ stop("broken stack frame setup in interpreter"); __ bind(L); @@ -674,22 +824,22 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { methodOopDesc::size_of_parameters_offset())); __ shll(t, Interpreter::logStackElementSize()); - __ subq(rsp, t); - __ subq(rsp, frame::arg_reg_save_area_bytes); // windows - __ andq(rsp, -16); // must be 16 byte boundry (see amd64 ABI) + __ subptr(rsp, t); + __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows + __ andptr(rsp, -16); // must be 16 byte boundry (see amd64 ABI) // get signature handler { Label L; - __ movq(t, Address(method, methodOopDesc::signature_handler_offset())); - __ testq(t, t); + __ movptr(t, Address(method, methodOopDesc::signature_handler_offset())); + __ testptr(t, t); __ jcc(Assembler::notZero, L); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), method); __ get_method(method); - __ movq(t, Address(method, methodOopDesc::signature_handler_offset())); + __ movptr(t, Address(method, methodOopDesc::signature_handler_offset())); __ bind(L); } @@ -711,9 +861,9 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // result handler is in rax // set result handler - __ movq(Address(rbp, - (frame::interpreter_frame_result_handler_offset) * wordSize), - rax); + __ movptr(Address(rbp, + (frame::interpreter_frame_result_handler_offset) * wordSize), + rax); // pass mirror handle if static call { @@ -724,25 +874,25 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ testl(t, JVM_ACC_STATIC); __ jcc(Assembler::zero, L); // get mirror - __ movq(t, Address(method, methodOopDesc::constants_offset())); - __ movq(t, Address(t, constantPoolOopDesc::pool_holder_offset_in_bytes())); - __ movq(t, Address(t, mirror_offset)); + __ movptr(t, Address(method, methodOopDesc::constants_offset())); + __ movptr(t, Address(t, constantPoolOopDesc::pool_holder_offset_in_bytes())); + __ movptr(t, Address(t, mirror_offset)); // copy mirror into activation frame - __ movq(Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize), + __ movptr(Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize), t); // pass handle to mirror - __ leaq(c_rarg1, - Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize)); + __ lea(c_rarg1, + Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize)); __ bind(L); } // get native function entry point { Label L; - __ movq(rax, Address(method, methodOopDesc::native_function_offset())); + __ movptr(rax, Address(method, methodOopDesc::native_function_offset())); ExternalAddress unsatisfied(SharedRuntime::native_method_throw_unsatisfied_link_error_entry()); __ movptr(rscratch2, unsatisfied.addr()); - __ cmpq(rax, rscratch2); + __ cmpptr(rax, rscratch2); __ jcc(Assembler::notEqual, L); __ call_VM(noreg, CAST_FROM_FN_PTR(address, @@ -750,12 +900,12 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { method); __ get_method(method); __ verify_oop(method); - __ movq(rax, Address(method, methodOopDesc::native_function_offset())); + __ movptr(rax, Address(method, methodOopDesc::native_function_offset())); __ bind(L); } // pass JNIEnv - __ leaq(c_rarg0, Address(r15_thread, JavaThread::jni_environment_offset())); + __ lea(c_rarg0, Address(r15_thread, JavaThread::jni_environment_offset())); // It is enough that the pc() points into the right code // segment. It does not have to be the correct return pc. @@ -786,10 +936,10 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // register after returning from the JNI Call or verify that // it wasn't changed during -Xcheck:jni. if (RestoreMXCSROnJNICalls) { - __ ldmxcsr(ExternalAddress(StubRoutines::amd64::mxcsr_std())); + __ ldmxcsr(ExternalAddress(StubRoutines::x86::mxcsr_std())); } else if (CheckJNICalls) { - __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::amd64::verify_mxcsr_entry()))); + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::verify_mxcsr_entry()))); } // NOTE: The order of these pushes is known to frame::interpreter_frame_result @@ -838,12 +988,12 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // preserved and correspond to the bcp/locals pointers. So we do a // runtime call by hand. // - __ movq(c_rarg0, r15_thread); - __ movq(r12, rsp); // remember sp - __ subq(rsp, frame::arg_reg_save_area_bytes); // windows - __ andq(rsp, -16); // align stack as required by ABI + __ mov(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, JavaThread::check_special_condition_for_native_trans))); - __ movq(rsp, r12); // restore sp + __ mov(rsp, r12); // restore sp __ reinit_heapbase(); __ bind(Continue); } @@ -855,8 +1005,8 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ reset_last_Java_frame(true, true); // reset handle block - __ movq(t, Address(r15_thread, JavaThread::active_handles_offset())); - __ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD); + __ movptr(t, Address(r15_thread, JavaThread::active_handles_offset())); + __ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); // If result is an oop unbox and store it in frame where gc will see it // and result handler will pick it up @@ -864,15 +1014,15 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { { Label no_oop, store_result; __ lea(t, ExternalAddress(AbstractInterpreter::result_handler(T_OBJECT))); - __ cmpq(t, Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize)); + __ cmpptr(t, Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize)); __ jcc(Assembler::notEqual, no_oop); // retrieve result __ pop(ltos); - __ testq(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, store_result); - __ movq(rax, Address(rax, 0)); + __ movptr(rax, Address(rax, 0)); __ bind(store_result); - __ movq(Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize), rax); + __ movptr(Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize), rax); // keep stack depth as expected by pushing oop which will eventually be discarde __ push(ltos); __ bind(no_oop); @@ -885,13 +1035,13 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { JavaThread::stack_guard_yellow_disabled); __ jcc(Assembler::notEqual, no_reguard); - __ pushaq(); // XXX only save smashed registers - __ movq(r12, rsp); // remember sp - __ subq(rsp, frame::arg_reg_save_area_bytes); // windows - __ andq(rsp, -16); // align stack as required by ABI + __ pusha(); // XXX only save smashed registers + __ 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::reguard_yellow_pages))); - __ movq(rsp, r12); // restore sp - __ popaq(); // XXX only restore smashed registers + __ mov(rsp, r12); // restore sp + __ popa(); // XXX only restore smashed registers __ reinit_heapbase(); __ bind(no_reguard); @@ -906,12 +1056,12 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // restore r13 to have legal interpreter frame, i.e., bci == 0 <=> // r13 == code_base() - __ movq(r13, Address(method, methodOopDesc::const_offset())); // get constMethodOop - __ leaq(r13, Address(r13, constMethodOopDesc::codes_offset())); // get codebase + __ movptr(r13, Address(method, methodOopDesc::const_offset())); // get constMethodOop + __ lea(r13, Address(r13, constMethodOopDesc::codes_offset())); // get codebase // handle exceptions (exception handling will handle unlocking!) { Label L; - __ cmpq(Address(r15_thread, Thread::pending_exception_offset()), (int) NULL); + __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t) NULL_WORD); __ jcc(Assembler::zero, L); // Note: At some point we may want to unify this with the code // used in call_VM_base(); i.e., we should use the @@ -942,10 +1092,10 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { wordSize - sizeof(BasicObjectLock))); // monitor expect in c_rarg1 for slow unlock path - __ leaq(c_rarg1, monitor); // address of first monitor + __ lea(c_rarg1, monitor); // address of first monitor - __ movq(t, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes())); - __ testq(t, t); + __ movptr(t, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes())); + __ testptr(t, t); __ jcc(Assembler::notZero, unlock); // Entry already unlocked, need to throw exception @@ -973,17 +1123,17 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ pop(ltos); __ pop(dtos); - __ movq(t, Address(rbp, - (frame::interpreter_frame_result_handler_offset) * wordSize)); + __ movptr(t, Address(rbp, + (frame::interpreter_frame_result_handler_offset) * wordSize)); __ call(t); // remove activation - __ movq(t, Address(rbp, - frame::interpreter_frame_sender_sp_offset * - wordSize)); // get sender sp + __ movptr(t, Address(rbp, + frame::interpreter_frame_sender_sp_offset * + wordSize)); // get sender sp __ leave(); // remove frame anchor - __ popq(rdi); // get return address - __ movq(rsp, t); // set sp to sender sp + __ pop(rdi); // get return address + __ mov(rsp, t); // set sp to sender sp __ jmp(rdi); if (inc_counter) { @@ -1032,11 +1182,11 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { generate_stack_overflow_check(); // get return address - __ popq(rax); + __ pop(rax); // compute beginning of parameters (r14) if (TaggedStackInterpreter) __ shll(rcx, 1); // 2 slots per parameter. - __ leaq(r14, Address(rsp, rcx, Address::times_8, -wordSize)); + __ lea(r14, Address(rsp, rcx, Address::times_8, -wordSize)); // rdx - # of additional locals // allocate space for locals @@ -1046,8 +1196,8 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { __ testl(rdx, rdx); __ jcc(Assembler::lessEqual, exit); // do nothing if rdx <= 0 __ bind(loop); - if (TaggedStackInterpreter) __ pushq((int) NULL); // push tag - __ pushq((int) NULL); // initialize local variables + if (TaggedStackInterpreter) __ push((int) NULL_WORD); // push tag + __ push((int) NULL_WORD); // initialize local variables __ decrementl(rdx); // until everything initialized __ jcc(Assembler::greater, loop); __ bind(exit); @@ -1137,8 +1287,8 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { Label L; const Address monitor_block_top (rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize); - __ movq(rax, monitor_block_top); - __ cmpq(rax, rsp); + __ movptr(rax, monitor_block_top); + __ cmpptr(rax, rsp); __ jcc(Assembler::equal, L); __ stop("broken stack frame setup in interpreter"); __ bind(L); @@ -1160,14 +1310,14 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method), r13, true); - __ movq(rbx, Address(rbp, method_offset)); // restore methodOop - __ movq(rax, Address(rbx, - in_bytes(methodOopDesc::method_data_offset()))); - __ movq(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), - rax); + __ movptr(rbx, Address(rbp, method_offset)); // restore methodOop + __ movptr(rax, Address(rbx, + in_bytes(methodOopDesc::method_data_offset()))); + __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), + rax); __ test_method_data_pointer(rax, profile_method_continue); - __ addq(rax, in_bytes(methodDataOopDesc::data_offset())); - __ movq(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), + __ addptr(rax, in_bytes(methodDataOopDesc::data_offset())); + __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rax); __ jmp(profile_method_continue); } @@ -1357,7 +1507,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { Interpreter::_rethrow_exception_entry = __ pc(); // Restore sp to interpreter_frame_last_sp even though we are going // to empty the expression stack for the exception processing. - __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); // rax: exception // rdx: return address/pc that threw exception __ restore_bcp(); // r13 points to call/send @@ -1369,7 +1519,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // rax: exception // r13: exception bcp __ verify_oop(rax); - __ movq(c_rarg1, rax); + __ mov(c_rarg1, rax); // expression stack must be empty before entering the VM in case of // an exception @@ -1424,7 +1574,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // deoptimization blob's unpack entry because of the presence of // adapter frames in C2. Label caller_not_deoptimized; - __ movq(c_rarg1, Address(rbp, frame::return_addr_offset * wordSize)); + __ movptr(c_rarg1, Address(rbp, frame::return_addr_offset * wordSize)); __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::interpreter_contains), c_rarg1); __ testl(rax, rax); @@ -1437,8 +1587,8 @@ void TemplateInterpreterGenerator::generate_throw_exception() { size_of_parameters_offset()))); __ shll(rax, Interpreter::logStackElementSize()); __ restore_locals(); // XXX do we need this? - __ subq(r14, rax); - __ addq(r14, wordSize); + __ subptr(r14, rax); + __ addptr(r14, wordSize); // Save these arguments __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, Deoptimization:: @@ -1477,15 +1627,15 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // maintain this kind of invariant all the time we call a small // fixup routine to move the mutated arguments onto the top of our // expression stack if necessary. - __ movq(c_rarg1, rsp); - __ movq(c_rarg2, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); + __ mov(c_rarg1, rsp); + __ movptr(c_rarg2, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); // PC must point into interpreter here __ set_last_Java_frame(noreg, rbp, __ pc()); __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::popframe_move_outgoing_args), r15_thread, c_rarg1, c_rarg2); __ reset_last_Java_frame(true, true); // Restore the last_sp and null it out - __ movq(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); - __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); + __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ restore_bcp(); // XXX do we need this? __ restore_locals(); // XXX do we need this? @@ -1506,12 +1656,12 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // preserve exception over this code sequence __ pop_ptr(rax); - __ movq(Address(r15_thread, JavaThread::vm_result_offset()), rax); + __ movptr(Address(r15_thread, JavaThread::vm_result_offset()), rax); // remove the activation (without doing throws on illegalMonitorExceptions) __ remove_activation(vtos, rdx, false, true, false); // restore exception - __ movq(rax, Address(r15_thread, JavaThread::vm_result_offset())); - __ movptr(Address(r15_thread, JavaThread::vm_result_offset()), NULL_WORD); + __ movptr(rax, Address(r15_thread, JavaThread::vm_result_offset())); + __ movptr(Address(r15_thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD); __ verify_oop(rax); // In between activations - previous activation type unknown yet @@ -1522,14 +1672,14 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // rdx: return address/pc that threw exception // rsp: expression stack of caller // rbp: ebp of caller - __ pushq(rax); // save exception - __ pushq(rdx); // save return address + __ push(rax); // save exception + __ push(rdx); // save return address __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), rdx); - __ movq(rbx, rax); // save exception handler - __ popq(rdx); // restore return address - __ popq(rax); // restore exception + __ mov(rbx, rax); // save exception handler + __ pop(rdx); // restore return address + __ pop(rax); // restore exception // Note that an "issuing PC" is actually the next PC after the call __ jmp(rbx); // jump to exception // handler of caller @@ -1547,7 +1697,7 @@ address TemplateInterpreterGenerator::generate_earlyret_entry_for(TosState state __ empty_expression_stack(); __ load_earlyret_value(state); - __ movq(rdx, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); + __ movptr(rdx, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); Address cond_addr(rdx, JvmtiThreadState::earlyret_state_offset()); // Clear the earlyret state @@ -1609,21 +1759,21 @@ address TemplateInterpreterGenerator::generate_trace_code(TosState state) { address entry = __ pc(); __ push(state); - __ pushq(c_rarg0); - __ pushq(c_rarg1); - __ pushq(c_rarg2); - __ pushq(c_rarg3); - __ movq(c_rarg2, rax); // Pass itos + __ push(c_rarg0); + __ push(c_rarg1); + __ push(c_rarg2); + __ push(c_rarg3); + __ mov(c_rarg2, rax); // Pass itos #ifdef _WIN64 __ movflt(xmm3, xmm0); // Pass ftos #endif __ call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::trace_bytecode), c_rarg1, c_rarg2, c_rarg3); - __ popq(c_rarg3); - __ popq(c_rarg2); - __ popq(c_rarg1); - __ popq(c_rarg0); + __ pop(c_rarg3); + __ pop(c_rarg2); + __ pop(c_rarg1); + __ pop(c_rarg0); __ pop(state); __ ret(0); // return from result handler @@ -1657,10 +1807,10 @@ void TemplateInterpreterGenerator::trace_bytecode(Template* t) { assert(Interpreter::trace_code(t->tos_in()) != NULL, "entry must have been generated"); - __ movq(r12, rsp); // remember sp - __ andq(rsp, -16); // align stack as required by ABI + __ mov(r12, rsp); // remember sp + __ andptr(rsp, -16); // align stack as required by ABI __ call(RuntimeAddress(Interpreter::trace_code(t->tos_in()))); - __ movq(rsp, r12); // restore sp + __ mov(rsp, r12); // restore sp __ reinit_heapbase(); } @@ -1674,3 +1824,4 @@ void TemplateInterpreterGenerator::stop_interpreter_at() { __ bind(L); } #endif // !PRODUCT +#endif // ! CC_INTERP diff --git a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp index 24e7e12fc85..31c6975ec64 100644 --- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp @@ -119,12 +119,14 @@ void TemplateTable::patch_bytecode(Bytecodes::Code bytecode, Register bc, if (!RewriteBytecodes) return; // the pair bytecodes have already done the load. - if (load_bc_into_scratch) __ movl(bc, bytecode); + if (load_bc_into_scratch) { + __ movl(bc, bytecode); + } Label patch_done; if (JvmtiExport::can_post_breakpoint()) { Label fast_patch; // if a breakpoint is present we can't rewrite the stream directly - __ movzxb(scratch, at_bcp(0)); + __ movzbl(scratch, at_bcp(0)); __ cmpl(scratch, Bytecodes::_breakpoint); __ jcc(Assembler::notEqual, fast_patch); __ get_method(scratch); @@ -169,16 +171,16 @@ void TemplateTable::shouldnotreachhere() { void TemplateTable::aconst_null() { transition(vtos, atos); - __ xorl(rax, rax); + __ xorptr(rax, rax); } void TemplateTable::iconst(int value) { transition(vtos, itos); if (value == 0) { - __ xorl(rax, rax); + __ xorptr(rax, rax); } else { - __ movl(rax, value); + __ movptr(rax, value); } } @@ -186,12 +188,12 @@ void TemplateTable::iconst(int value) { void TemplateTable::lconst(int value) { transition(vtos, ltos); if (value == 0) { - __ xorl(rax, rax); + __ xorptr(rax, rax); } else { - __ movl(rax, value); + __ movptr(rax, value); } assert(value >= 0, "check this code"); - __ xorl(rdx, rdx); + __ xorptr(rdx, rdx); } @@ -223,7 +225,7 @@ void TemplateTable::bipush() { void TemplateTable::sipush() { transition(vtos, itos); __ load_unsigned_word(rax, at_bcp(1)); - __ bswap(rax); + __ bswapl(rax); __ sarl(rax, 16); } @@ -241,7 +243,7 @@ void TemplateTable::ldc(bool wide) { const int tags_offset = typeArrayOopDesc::header_size(T_BYTE) * wordSize; // get type - __ xorl(rdx, rdx); + __ xorptr(rdx, rdx); __ movb(rdx, Address(rax, rbx, Address::times_1, tags_offset)); // unresolved string - get the resolved string @@ -271,7 +273,7 @@ void TemplateTable::ldc(bool wide) { __ cmpl(rdx, JVM_CONSTANT_Float); __ jccb(Assembler::notEqual, notFloat); // ftos - __ fld_s( Address(rcx, rbx, Address::times_4, base_offset)); + __ fld_s( Address(rcx, rbx, Address::times_ptr, base_offset)); __ push(ftos); __ jmp(Done); @@ -288,13 +290,14 @@ void TemplateTable::ldc(bool wide) { #endif Label isOop; // atos and itos - __ movl(rax, Address(rcx, rbx, Address::times_4, base_offset)); // String is only oop type we will see here __ cmpl(rdx, JVM_CONSTANT_String); __ jccb(Assembler::equal, isOop); + __ movl(rax, Address(rcx, rbx, Address::times_ptr, base_offset)); __ push(itos); __ jmp(Done); __ bind(isOop); + __ movptr(rax, Address(rcx, rbx, Address::times_ptr, base_offset)); __ push(atos); if (VerifyOops) { @@ -316,14 +319,14 @@ void TemplateTable::ldc2_w() { __ cmpb(Address(rax, rbx, Address::times_1, tags_offset), JVM_CONSTANT_Double); __ jccb(Assembler::notEqual, Long); // dtos - __ fld_d( Address(rcx, rbx, Address::times_4, base_offset)); + __ fld_d( Address(rcx, rbx, Address::times_ptr, base_offset)); __ push(dtos); __ jmpb(Done); __ bind(Long); // ltos - __ movl(rax, Address(rcx, rbx, Address::times_4, base_offset + 0 * wordSize)); - __ movl(rdx, Address(rcx, rbx, Address::times_4, base_offset + 1 * wordSize)); + __ movptr(rax, Address(rcx, rbx, Address::times_ptr, base_offset + 0 * wordSize)); + NOT_LP64(__ movptr(rdx, Address(rcx, rbx, Address::times_ptr, base_offset + 1 * wordSize))); __ push(ltos); @@ -333,7 +336,7 @@ void TemplateTable::ldc2_w() { void TemplateTable::locals_index(Register reg, int offset) { __ load_unsigned_byte(reg, at_bcp(offset)); - __ negl(reg); + __ negptr(reg); } @@ -399,8 +402,8 @@ void TemplateTable::fast_iload() { void TemplateTable::lload() { transition(vtos, ltos); locals_index(rbx); - __ movl(rax, laddress(rbx)); - __ movl(rdx, haddress(rbx)); + __ movptr(rax, laddress(rbx)); + NOT_LP64(__ movl(rdx, haddress(rbx))); debug_only(__ verify_local_tag(frame::TagCategory2, rbx)); } @@ -421,10 +424,10 @@ void TemplateTable::dload() { // float instruction into ST0 __ movl(rax, laddress(rbx)); __ movl(rdx, haddress(rbx)); - __ pushl(rdx); // push hi first - __ pushl(rax); + __ push(rdx); // push hi first + __ push(rax); __ fld_d(Address(rsp, 0)); - __ addl(rsp, 2*wordSize); + __ addptr(rsp, 2*wordSize); debug_only(__ verify_local_tag(frame::TagCategory2, rbx)); } else { __ fld_d(daddress(rbx)); @@ -435,16 +438,16 @@ void TemplateTable::dload() { void TemplateTable::aload() { transition(vtos, atos); locals_index(rbx); - __ movl(rax, iaddress(rbx)); + __ movptr(rax, aaddress(rbx)); debug_only(__ verify_local_tag(frame::TagReference, rbx)); } void TemplateTable::locals_index_wide(Register reg) { __ movl(reg, at_bcp(2)); - __ bswap(reg); + __ bswapl(reg); __ shrl(reg, 16); - __ negl(reg); + __ negptr(reg); } @@ -459,8 +462,8 @@ void TemplateTable::wide_iload() { void TemplateTable::wide_lload() { transition(vtos, ltos); locals_index_wide(rbx); - __ movl(rax, laddress(rbx)); - __ movl(rdx, haddress(rbx)); + __ movptr(rax, laddress(rbx)); + NOT_LP64(__ movl(rdx, haddress(rbx))); debug_only(__ verify_local_tag(frame::TagCategory2, rbx)); } @@ -481,8 +484,8 @@ void TemplateTable::wide_dload() { // float instruction into ST0 __ movl(rax, laddress(rbx)); __ movl(rdx, haddress(rbx)); - __ pushl(rdx); // push hi first - __ pushl(rax); + __ push(rdx); // push hi first + __ push(rax); __ fld_d(Address(rsp, 0)); __ addl(rsp, 2*wordSize); debug_only(__ verify_local_tag(frame::TagCategory2, rbx)); @@ -495,7 +498,7 @@ void TemplateTable::wide_dload() { void TemplateTable::wide_aload() { transition(vtos, atos); locals_index_wide(rbx); - __ movl(rax, iaddress(rbx)); + __ movptr(rax, aaddress(rbx)); debug_only(__ verify_local_tag(frame::TagReference, rbx)); } @@ -509,12 +512,13 @@ void TemplateTable::index_check_without_pop(Register array, Register index) { // destroys rbx, // check array __ null_check(array, arrayOopDesc::length_offset_in_bytes()); + LP64_ONLY(__ movslq(index, index)); // check index __ cmpl(index, Address(array, arrayOopDesc::length_offset_in_bytes())); if (index != rbx) { // ??? convention: move aberrant index into rbx, for exception message assert(rbx != array, "different registers"); - __ movl(rbx, index); + __ mov(rbx, index); } __ jump_cc(Assembler::aboveEqual, ExternalAddress(Interpreter::_throw_ArrayIndexOutOfBoundsException_entry)); @@ -535,10 +539,10 @@ void TemplateTable::laload() { // rax,: index // rdx: array index_check(rdx, rax); - __ movl(rbx, rax); + __ mov(rbx, rax); // rbx,: index - __ movl(rax, Address(rdx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize)); - __ movl(rdx, Address(rdx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 1 * wordSize)); + __ movptr(rax, Address(rdx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize)); + NOT_LP64(__ movl(rdx, Address(rdx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 1 * wordSize))); } @@ -565,7 +569,7 @@ void TemplateTable::aaload() { // rdx: array index_check(rdx, rax); // kills rbx, // rax,: index - __ movl(rax, Address(rdx, rax, Address::times_4, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); + __ movptr(rax, Address(rdx, rax, Address::times_ptr, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); } @@ -576,7 +580,7 @@ void TemplateTable::baload() { // rax,: index // can do better code for P5 - fix this at some point __ load_signed_byte(rbx, Address(rdx, rax, Address::times_1, arrayOopDesc::base_offset_in_bytes(T_BYTE))); - __ movl(rax, rbx); + __ mov(rax, rbx); } @@ -587,7 +591,7 @@ void TemplateTable::caload() { // rax,: index // can do better code for P5 - may want to improve this at some point __ load_unsigned_word(rbx, Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); - __ movl(rax, rbx); + __ mov(rax, rbx); } // iload followed by caload frequent pair @@ -602,7 +606,7 @@ void TemplateTable::fast_icaload() { index_check(rdx, rax); // rax,: index __ load_unsigned_word(rbx, Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); - __ movl(rax, rbx); + __ mov(rax, rbx); } void TemplateTable::saload() { @@ -612,7 +616,7 @@ void TemplateTable::saload() { // rax,: index // can do better code for P5 - may want to improve this at some point __ load_signed_word(rbx, Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_SHORT))); - __ movl(rax, rbx); + __ mov(rax, rbx); } @@ -625,8 +629,8 @@ void TemplateTable::iload(int n) { void TemplateTable::lload(int n) { transition(vtos, ltos); - __ movl(rax, laddress(n)); - __ movl(rdx, haddress(n)); + __ movptr(rax, laddress(n)); + NOT_LP64(__ movptr(rdx, haddress(n))); debug_only(__ verify_local_tag(frame::TagCategory2, n)); } @@ -645,10 +649,10 @@ void TemplateTable::dload(int n) { // float instruction into ST0 __ movl(rax, laddress(n)); __ movl(rdx, haddress(n)); - __ pushl(rdx); // push hi first - __ pushl(rax); + __ push(rdx); // push hi first + __ push(rax); __ fld_d(Address(rsp, 0)); - __ addl(rsp, 2*wordSize); // reset rsp + __ addptr(rsp, 2*wordSize); // reset rsp debug_only(__ verify_local_tag(frame::TagCategory2, n)); } else { __ fld_d(daddress(n)); @@ -658,7 +662,7 @@ void TemplateTable::dload(int n) { void TemplateTable::aload(int n) { transition(vtos, atos); - __ movl(rax, aaddress(n)); + __ movptr(rax, aaddress(n)); debug_only(__ verify_local_tag(frame::TagReference, n)); } @@ -740,8 +744,8 @@ void TemplateTable::istore() { void TemplateTable::lstore() { transition(ltos, vtos); locals_index(rbx); - __ movl(laddress(rbx), rax); - __ movl(haddress(rbx), rdx); + __ movptr(laddress(rbx), rax); + NOT_LP64(__ movptr(haddress(rbx), rdx)); __ tag_local(frame::TagCategory2, rbx); } @@ -759,12 +763,12 @@ void TemplateTable::dstore() { locals_index(rbx); if (TaggedStackInterpreter) { // Store double on stack and reload into locals nonadjacently - __ subl(rsp, 2 * wordSize); + __ subptr(rsp, 2 * wordSize); __ fstp_d(Address(rsp, 0)); - __ popl(rax); - __ popl(rdx); - __ movl(laddress(rbx), rax); - __ movl(haddress(rbx), rdx); + __ pop(rax); + __ pop(rdx); + __ movptr(laddress(rbx), rax); + __ movptr(haddress(rbx), rdx); __ tag_local(frame::TagCategory2, rbx); } else { __ fstp_d(daddress(rbx)); @@ -776,7 +780,7 @@ void TemplateTable::astore() { transition(vtos, vtos); __ pop_ptr(rax, rdx); // will need to pop tag too locals_index(rbx); - __ movl(aaddress(rbx), rax); + __ movptr(aaddress(rbx), rax); __ tag_local(rdx, rbx); // need to store same tag in local may be returnAddr } @@ -794,8 +798,8 @@ void TemplateTable::wide_lstore() { transition(vtos, vtos); __ pop_l(rax, rdx); locals_index_wide(rbx); - __ movl(laddress(rbx), rax); - __ movl(haddress(rbx), rdx); + __ movptr(laddress(rbx), rax); + NOT_LP64(__ movl(haddress(rbx), rdx)); __ tag_local(frame::TagCategory2, rbx); } @@ -814,7 +818,7 @@ void TemplateTable::wide_astore() { transition(vtos, vtos); __ pop_ptr(rax, rdx); locals_index_wide(rbx); - __ movl(aaddress(rbx), rax); + __ movptr(aaddress(rbx), rax); __ tag_local(rdx, rbx); } @@ -838,8 +842,8 @@ void TemplateTable::lastore() { // rdx: high(value) index_check(rcx, rbx); // prefer index in rbx, // rbx,: index - __ movl(Address(rcx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize), rax); - __ movl(Address(rcx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 1 * wordSize), rdx); + __ movptr(Address(rcx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize), rax); + NOT_LP64(__ movl(Address(rcx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 1 * wordSize), rdx)); } @@ -869,21 +873,21 @@ void TemplateTable::aastore() { Label is_null, ok_is_subtype, done; transition(vtos, vtos); // stack: ..., array, index, value - __ movl(rax, at_tos()); // Value + __ movptr(rax, at_tos()); // Value __ movl(rcx, at_tos_p1()); // Index - __ movl(rdx, at_tos_p2()); // Array + __ movptr(rdx, at_tos_p2()); // Array index_check_without_pop(rdx, rcx); // kills rbx, // do array store check - check for NULL value first - __ testl(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, is_null); // Move subklass into EBX - __ movl(rbx, Address(rax, oopDesc::klass_offset_in_bytes())); + __ movptr(rbx, Address(rax, oopDesc::klass_offset_in_bytes())); // Move superklass into EAX - __ movl(rax, Address(rdx, oopDesc::klass_offset_in_bytes())); - __ movl(rax, Address(rax, sizeof(oopDesc) + objArrayKlass::element_klass_offset_in_bytes())); - // Compress array+index*4+12 into a single register. Frees ECX. - __ leal(rdx, Address(rdx, rcx, Address::times_4, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); + __ movptr(rax, Address(rdx, oopDesc::klass_offset_in_bytes())); + __ movptr(rax, Address(rax, sizeof(oopDesc) + objArrayKlass::element_klass_offset_in_bytes())); + // Compress array+index*wordSize+12 into a single register. Frees ECX. + __ lea(rdx, Address(rdx, rcx, Address::times_ptr, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // Generate subtype check. Blows ECX. Resets EDI to locals. // Superklass in EAX. Subklass in EBX. @@ -895,19 +899,19 @@ void TemplateTable::aastore() { // Come here on success __ bind(ok_is_subtype); - __ movl(rax, at_rsp()); // Value - __ movl(Address(rdx, 0), rax); + __ movptr(rax, at_rsp()); // Value + __ movptr(Address(rdx, 0), rax); __ store_check(rdx); __ jmpb(done); // Have a NULL in EAX, EDX=array, ECX=index. Store NULL at ary[idx] __ bind(is_null); __ profile_null_seen(rbx); - __ movl(Address(rdx, rcx, Address::times_4, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), rax); + __ movptr(Address(rdx, rcx, Address::times_ptr, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), rax); // Pop stack arguments __ bind(done); - __ addl(rsp, 3 * Interpreter::stackElementSize()); + __ addptr(rsp, 3 * Interpreter::stackElementSize()); } @@ -947,8 +951,8 @@ void TemplateTable::istore(int n) { void TemplateTable::lstore(int n) { transition(ltos, vtos); - __ movl(laddress(n), rax); - __ movl(haddress(n), rdx); + __ movptr(laddress(n), rax); + NOT_LP64(__ movptr(haddress(n), rdx)); __ tag_local(frame::TagCategory2, n); } @@ -963,10 +967,10 @@ void TemplateTable::fstore(int n) { void TemplateTable::dstore(int n) { transition(dtos, vtos); if (TaggedStackInterpreter) { - __ subl(rsp, 2 * wordSize); + __ subptr(rsp, 2 * wordSize); __ fstp_d(Address(rsp, 0)); - __ popl(rax); - __ popl(rdx); + __ pop(rax); + __ pop(rdx); __ movl(laddress(n), rax); __ movl(haddress(n), rdx); __ tag_local(frame::TagCategory2, n); @@ -979,20 +983,20 @@ void TemplateTable::dstore(int n) { void TemplateTable::astore(int n) { transition(vtos, vtos); __ pop_ptr(rax, rdx); - __ movl(aaddress(n), rax); + __ movptr(aaddress(n), rax); __ tag_local(rdx, n); } void TemplateTable::pop() { transition(vtos, vtos); - __ addl(rsp, Interpreter::stackElementSize()); + __ addptr(rsp, Interpreter::stackElementSize()); } void TemplateTable::pop2() { transition(vtos, vtos); - __ addl(rsp, 2*Interpreter::stackElementSize()); + __ addptr(rsp, 2*Interpreter::stackElementSize()); } @@ -1099,14 +1103,14 @@ void TemplateTable::iop2(Operation op) { transition(itos, itos); switch (op) { case add : __ pop_i(rdx); __ addl (rax, rdx); break; - case sub : __ movl(rdx, rax); __ pop_i(rax); __ subl (rax, rdx); break; + case sub : __ mov(rdx, rax); __ pop_i(rax); __ subl (rax, rdx); break; case mul : __ pop_i(rdx); __ imull(rax, rdx); break; case _and : __ pop_i(rdx); __ andl (rax, rdx); break; case _or : __ pop_i(rdx); __ orl (rax, rdx); break; case _xor : __ pop_i(rdx); __ xorl (rax, rdx); break; - case shl : __ movl(rcx, rax); __ pop_i(rax); __ shll (rax); break; // implicit masking of lower 5 bits by Intel shift instr. - case shr : __ movl(rcx, rax); __ pop_i(rax); __ sarl (rax); break; // implicit masking of lower 5 bits by Intel shift instr. - case ushr : __ movl(rcx, rax); __ pop_i(rax); __ shrl (rax); break; // implicit masking of lower 5 bits by Intel shift instr. + case shl : __ mov(rcx, rax); __ pop_i(rax); __ shll (rax); break; // implicit masking of lower 5 bits by Intel shift instr. + case shr : __ mov(rcx, rax); __ pop_i(rax); __ sarl (rax); break; // implicit masking of lower 5 bits by Intel shift instr. + case ushr : __ mov(rcx, rax); __ pop_i(rax); __ shrl (rax); break; // implicit masking of lower 5 bits by Intel shift instr. default : ShouldNotReachHere(); } } @@ -1118,7 +1122,7 @@ void TemplateTable::lop2(Operation op) { switch (op) { case add : __ addl(rax, rbx); __ adcl(rdx, rcx); break; case sub : __ subl(rbx, rax); __ sbbl(rcx, rdx); - __ movl(rax, rbx); __ movl(rdx, rcx); break; + __ mov(rax, rbx); __ mov(rdx, rcx); break; case _and: __ andl(rax, rbx); __ andl(rdx, rcx); break; case _or : __ orl (rax, rbx); __ orl (rdx, rcx); break; case _xor: __ xorl(rax, rbx); __ xorl(rdx, rcx); break; @@ -1129,7 +1133,7 @@ void TemplateTable::lop2(Operation op) { void TemplateTable::idiv() { transition(itos, itos); - __ movl(rcx, rax); + __ mov(rcx, rax); __ pop_i(rax); // Note: could xor rax, and rcx and compare with (-1 ^ min_int). If // they are not equal, one could do a normal division (no correction @@ -1141,52 +1145,52 @@ void TemplateTable::idiv() { void TemplateTable::irem() { transition(itos, itos); - __ movl(rcx, rax); + __ mov(rcx, rax); __ pop_i(rax); // Note: could xor rax, and rcx and compare with (-1 ^ min_int). If // they are not equal, one could do a normal division (no correction // needed), which may speed up this implementation for the common case. // (see also JVM spec., p.243 & p.271) __ corrected_idivl(rcx); - __ movl(rax, rdx); + __ mov(rax, rdx); } void TemplateTable::lmul() { transition(ltos, ltos); __ pop_l(rbx, rcx); - __ pushl(rcx); __ pushl(rbx); - __ pushl(rdx); __ pushl(rax); + __ push(rcx); __ push(rbx); + __ push(rdx); __ push(rax); __ lmul(2 * wordSize, 0); - __ addl(rsp, 4 * wordSize); // take off temporaries + __ addptr(rsp, 4 * wordSize); // take off temporaries } void TemplateTable::ldiv() { transition(ltos, ltos); __ pop_l(rbx, rcx); - __ pushl(rcx); __ pushl(rbx); - __ pushl(rdx); __ pushl(rax); + __ push(rcx); __ push(rbx); + __ push(rdx); __ push(rax); // check if y = 0 __ orl(rax, rdx); __ jump_cc(Assembler::zero, ExternalAddress(Interpreter::_throw_ArithmeticException_entry)); __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::ldiv)); - __ addl(rsp, 4 * wordSize); // take off temporaries + __ addptr(rsp, 4 * wordSize); // take off temporaries } void TemplateTable::lrem() { transition(ltos, ltos); __ pop_l(rbx, rcx); - __ pushl(rcx); __ pushl(rbx); - __ pushl(rdx); __ pushl(rax); + __ push(rcx); __ push(rbx); + __ push(rdx); __ push(rax); // check if y = 0 __ orl(rax, rdx); __ jump_cc(Assembler::zero, ExternalAddress(Interpreter::_throw_ArithmeticException_entry)); __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::lrem)); - __ addl(rsp, 4 * wordSize); + __ addptr(rsp, 4 * wordSize); } @@ -1200,7 +1204,7 @@ void TemplateTable::lshl() { void TemplateTable::lshr() { transition(itos, ltos); - __ movl(rcx, rax); // get shift count + __ mov(rcx, rax); // get shift count __ pop_l(rax, rdx); // get shift value __ lshr(rdx, rax, true); } @@ -1208,7 +1212,7 @@ void TemplateTable::lshr() { void TemplateTable::lushr() { transition(itos, ltos); - __ movl(rcx, rax); // get shift count + __ mov(rcx, rax); // get shift count __ pop_l(rax, rdx); // get shift value __ lshr(rdx, rax); } @@ -1226,7 +1230,7 @@ void TemplateTable::fop2(Operation op) { default : ShouldNotReachHere(); } __ f2ieee(); - __ popl(rax); // pop float thing off + __ pop(rax); // pop float thing off } @@ -1280,8 +1284,8 @@ void TemplateTable::dop2(Operation op) { } __ d2ieee(); // Pop double precision number from rsp. - __ popl(rax); - __ popl(rdx); + __ pop(rax); + __ pop(rdx); } @@ -1321,7 +1325,7 @@ void TemplateTable::wide_iinc() { transition(vtos, vtos); __ movl(rdx, at_bcp(4)); // get constant locals_index_wide(rbx); - __ bswap(rdx); // swap bytes & sign-extend constant + __ bswapl(rdx); // swap bytes & sign-extend constant __ sarl(rdx, 16); __ addl(iaddress(rbx), rdx); // Note: should probably use only one movl to get both @@ -1375,62 +1379,65 @@ void TemplateTable::convert() { #endif // ASSERT // Conversion - // (Note: use pushl(rcx)/popl(rcx) for 1/2-word stack-ptr manipulation) + // (Note: use push(rcx)/pop(rcx) for 1/2-word stack-ptr manipulation) switch (bytecode()) { case Bytecodes::_i2l: __ extend_sign(rdx, rax); break; case Bytecodes::_i2f: - __ pushl(rax); // store int on tos + __ push(rax); // store int on tos __ fild_s(at_rsp()); // load int to ST0 __ f2ieee(); // truncate to float size - __ popl(rcx); // adjust rsp + __ pop(rcx); // adjust rsp break; case Bytecodes::_i2d: - __ pushl(rax); // add one slot for d2ieee() - __ pushl(rax); // store int on tos + __ push(rax); // add one slot for d2ieee() + __ push(rax); // store int on tos __ fild_s(at_rsp()); // load int to ST0 __ d2ieee(); // truncate to double size - __ popl(rcx); // adjust rsp - __ popl(rcx); + __ pop(rcx); // adjust rsp + __ pop(rcx); break; case Bytecodes::_i2b: __ shll(rax, 24); // truncate upper 24 bits __ sarl(rax, 24); // and sign-extend byte + LP64_ONLY(__ movsbl(rax, rax)); break; case Bytecodes::_i2c: __ andl(rax, 0xFFFF); // truncate upper 16 bits + LP64_ONLY(__ movzwl(rax, rax)); break; case Bytecodes::_i2s: __ shll(rax, 16); // truncate upper 16 bits __ sarl(rax, 16); // and sign-extend short + LP64_ONLY(__ movswl(rax, rax)); break; case Bytecodes::_l2i: /* nothing to do */ break; case Bytecodes::_l2f: - __ pushl(rdx); // store long on tos - __ pushl(rax); + __ push(rdx); // store long on tos + __ push(rax); __ fild_d(at_rsp()); // load long to ST0 __ f2ieee(); // truncate to float size - __ popl(rcx); // adjust rsp - __ popl(rcx); + __ pop(rcx); // adjust rsp + __ pop(rcx); break; case Bytecodes::_l2d: - __ pushl(rdx); // store long on tos - __ pushl(rax); + __ push(rdx); // store long on tos + __ push(rax); __ fild_d(at_rsp()); // load long to ST0 __ d2ieee(); // truncate to double size - __ popl(rcx); // adjust rsp - __ popl(rcx); + __ pop(rcx); // adjust rsp + __ pop(rcx); break; case Bytecodes::_f2i: - __ pushl(rcx); // reserve space for argument + __ push(rcx); // reserve space for argument __ fstp_s(at_rsp()); // pass float argument on stack __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2i), 1); break; case Bytecodes::_f2l: - __ pushl(rcx); // reserve space for argument + __ push(rcx); // reserve space for argument __ fstp_s(at_rsp()); // pass float argument on stack __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2l), 1); break; @@ -1438,21 +1445,21 @@ void TemplateTable::convert() { /* nothing to do */ break; case Bytecodes::_d2i: - __ pushl(rcx); // reserve space for argument - __ pushl(rcx); + __ push(rcx); // reserve space for argument + __ push(rcx); __ fstp_d(at_rsp()); // pass double argument on stack __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2i), 2); break; case Bytecodes::_d2l: - __ pushl(rcx); // reserve space for argument - __ pushl(rcx); + __ push(rcx); // reserve space for argument + __ push(rcx); __ fstp_d(at_rsp()); // pass double argument on stack __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2l), 2); break; case Bytecodes::_d2f: - __ pushl(rcx); // reserve space for f2ieee() + __ push(rcx); // reserve space for f2ieee() __ f2ieee(); // truncate to float size - __ popl(rcx); // adjust rsp + __ pop(rcx); // adjust rsp break; default : ShouldNotReachHere(); @@ -1465,7 +1472,7 @@ void TemplateTable::lcmp() { // y = rdx:rax __ pop_l(rbx, rcx); // get x = rcx:rbx __ lcmp2int(rcx, rbx, rdx, rax);// rcx := cmp(x, y) - __ movl(rax, rcx); + __ mov(rax, rcx); } @@ -1476,9 +1483,9 @@ void TemplateTable::float_cmp(bool is_float, int unordered_result) { } else { __ pop_dtos_to_rsp(); __ fld_d(at_rsp()); - __ popl(rdx); + __ pop(rdx); } - __ popl(rcx); + __ pop(rcx); __ fcmp2int(rax, unordered_result < 0); } @@ -1493,8 +1500,10 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { // Load up EDX with the branch displacement __ movl(rdx, at_bcp(1)); - __ bswap(rdx); + __ bswapl(rdx); if (!is_wide) __ sarl(rdx, 16); + LP64_ONLY(__ movslq(rdx, rdx)); + // Handle all the JSR stuff here, then exit. // It's much shorter and cleaner than intermingling with the @@ -1504,10 +1513,10 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { __ load_unsigned_byte(rbx, Address(rsi, rdx, Address::times_1, 0)); // compute return address as bci in rax, - __ leal(rax, at_bcp((is_wide ? 5 : 3) - in_bytes(constMethodOopDesc::codes_offset()))); - __ subl(rax, Address(rcx, methodOopDesc::const_offset())); + __ lea(rax, at_bcp((is_wide ? 5 : 3) - in_bytes(constMethodOopDesc::codes_offset()))); + __ subptr(rax, Address(rcx, methodOopDesc::const_offset())); // Adjust the bcp in ESI by the displacement in EDX - __ addl(rsi, rdx); + __ addptr(rsi, rdx); // Push return address __ push_i(rax); // jsr returns vtos @@ -1518,7 +1527,7 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { // Normal (non-jsr) branch handling // Adjust the bcp in ESI by the displacement in EDX - __ addl(rsi, rdx); + __ addptr(rsi, rdx); assert(UseLoopCounter || !UseOnStackReplacement, "on-stack-replacement requires loop counters"); Label backedge_counter_overflow; @@ -1537,7 +1546,7 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { // increment counter __ movl(rax, Address(rcx, be_offset)); // load backedge counter - __ increment(rax, InvocationCounter::count_increment); // increment counter + __ incrementl(rax, InvocationCounter::count_increment); // increment counter __ movl(Address(rcx, be_offset), rax); // store counter __ movl(rax, Address(rcx, inv_offset)); // load invocation counter @@ -1565,7 +1574,7 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { // routine while the method is being compiled, add a second test to make // sure the overflow function is called only once every overflow_frequency. const int overflow_frequency = 1024; - __ andl(rbx, overflow_frequency-1); + __ andptr(rbx, overflow_frequency-1); __ jcc(Assembler::zero, backedge_counter_overflow); } @@ -1596,14 +1605,14 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { __ bind(profile_method); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method), rsi); __ load_unsigned_byte(rbx, Address(rsi, 0)); // restore target bytecode - __ movl(rcx, Address(rbp, method_offset)); - __ movl(rcx, Address(rcx, in_bytes(methodOopDesc::method_data_offset()))); - __ movl(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rcx); + __ movptr(rcx, Address(rbp, method_offset)); + __ movptr(rcx, Address(rcx, in_bytes(methodOopDesc::method_data_offset()))); + __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rcx); __ test_method_data_pointer(rcx, dispatch); // offset non-null mdp by MDO::data_offset() + IR::profile_method() - __ addl(rcx, in_bytes(methodDataOopDesc::data_offset())); - __ addl(rcx, rax); - __ movl(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rcx); + __ addptr(rcx, in_bytes(methodDataOopDesc::data_offset())); + __ addptr(rcx, rax); + __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rcx); __ jmp(dispatch); } @@ -1611,8 +1620,8 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { // invocation counter overflow __ bind(backedge_counter_overflow); - __ negl(rdx); - __ addl(rdx, rsi); // branch bcp + __ negptr(rdx); + __ addptr(rdx, rsi); // branch bcp call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), rdx); __ load_unsigned_byte(rbx, Address(rsi, 0)); // restore target bytecode @@ -1621,7 +1630,7 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { // rdx: scratch // rdi: locals pointer // rsi: bcp - __ testl(rax, rax); // test result + __ testptr(rax, rax); // test result __ jcc(Assembler::zero, dispatch); // no osr if null // nmethod may have been invalidated (VM may block upon call_VM return) __ movl(rcx, Address(rax, nmethod::entry_bci_offset())); @@ -1632,19 +1641,19 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { // We need to prepare to execute the OSR method. First we must // migrate the locals and monitors off of the stack. - __ movl(rbx, rax); // save the nmethod + __ mov(rbx, rax); // save the nmethod const Register thread = rcx; __ get_thread(thread); call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::OSR_migration_begin)); // rax, is OSR buffer, move it to expected parameter location - __ movl(rcx, rax); + __ mov(rcx, rax); // pop the interpreter frame - __ movl(rdx, Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp + __ movptr(rdx, Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp __ leave(); // remove frame anchor - __ popl(rdi); // get return address - __ movl(rsp, rdx); // set sp to sender sp + __ pop(rdi); // get return address + __ mov(rsp, rdx); // set sp to sender sp Label skip; @@ -1663,29 +1672,29 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { __ jcc(Assembler::notEqual, chkint); // yes adjust to the specialized call stub return. - assert(StubRoutines::i486::get_call_stub_compiled_return() != NULL, "must be set"); - __ lea(rdi, ExternalAddress(StubRoutines::i486::get_call_stub_compiled_return())); + assert(StubRoutines::x86::get_call_stub_compiled_return() != NULL, "must be set"); + __ lea(rdi, ExternalAddress(StubRoutines::x86::get_call_stub_compiled_return())); __ jmp(skip); __ bind(chkint); // Are we returning to the interpreter? Look for sentinel - __ cmpl(Address(rdi, -8), Interpreter::return_sentinel); + __ cmpl(Address(rdi, -2*wordSize), Interpreter::return_sentinel); __ jcc(Assembler::notEqual, skip); // Adjust to compiled return back to interpreter - __ movl(rdi, Address(rdi, -4)); + __ movptr(rdi, Address(rdi, -wordSize)); __ bind(skip); // Align stack pointer for compiled code (note that caller is // responsible for undoing this fixup by remembering the old SP // in an rbp,-relative location) - __ andl(rsp, -(StackAlignmentInBytes)); + __ andptr(rsp, -(StackAlignmentInBytes)); // push the (possibly adjusted) return address - __ pushl(rdi); + __ push(rdi); // and begin the OSR nmethod __ jmp(Address(rbx, nmethod::osr_entry_point_offset())); @@ -1723,7 +1732,7 @@ void TemplateTable::if_nullcmp(Condition cc) { transition(atos, vtos); // assume branch is more often taken than not (loops use backward branches) Label not_taken; - __ testl(rax, rax); + __ testptr(rax, rax); __ jcc(j_not(cc), not_taken); branch(false, false); __ bind(not_taken); @@ -1736,7 +1745,7 @@ void TemplateTable::if_acmp(Condition cc) { // assume branch is more often taken than not (loops use backward branches) Label not_taken; __ pop_ptr(rdx); - __ cmpl(rdx, rax); + __ cmpptr(rdx, rax); __ jcc(j_not(cc), not_taken); branch(false, false); __ bind(not_taken); @@ -1747,12 +1756,12 @@ void TemplateTable::if_acmp(Condition cc) { void TemplateTable::ret() { transition(vtos, vtos); locals_index(rbx); - __ movl(rbx, iaddress(rbx)); // get return bci, compute return bcp + __ movptr(rbx, iaddress(rbx)); // get return bci, compute return bcp __ profile_ret(rbx, rcx); __ get_method(rax); - __ movl(rsi, Address(rax, methodOopDesc::const_offset())); - __ leal(rsi, Address(rsi, rbx, Address::times_1, - constMethodOopDesc::codes_offset())); + __ movptr(rsi, Address(rax, methodOopDesc::const_offset())); + __ lea(rsi, Address(rsi, rbx, Address::times_1, + constMethodOopDesc::codes_offset())); __ dispatch_next(vtos); } @@ -1760,11 +1769,11 @@ void TemplateTable::ret() { void TemplateTable::wide_ret() { transition(vtos, vtos); locals_index_wide(rbx); - __ movl(rbx, iaddress(rbx)); // get return bci, compute return bcp + __ movptr(rbx, iaddress(rbx)); // get return bci, compute return bcp __ profile_ret(rbx, rcx); __ get_method(rax); - __ movl(rsi, Address(rax, methodOopDesc::const_offset())); - __ leal(rsi, Address(rsi, rbx, Address::times_1, constMethodOopDesc::codes_offset())); + __ movptr(rsi, Address(rax, methodOopDesc::const_offset())); + __ lea(rsi, Address(rsi, rbx, Address::times_1, constMethodOopDesc::codes_offset())); __ dispatch_next(vtos); } @@ -1773,13 +1782,13 @@ void TemplateTable::tableswitch() { Label default_case, continue_execution; transition(itos, vtos); // align rsi - __ leal(rbx, at_bcp(wordSize)); - __ andl(rbx, -wordSize); + __ lea(rbx, at_bcp(wordSize)); + __ andptr(rbx, -wordSize); // load lo & hi __ movl(rcx, Address(rbx, 1 * wordSize)); __ movl(rdx, Address(rbx, 2 * wordSize)); - __ bswap(rcx); - __ bswap(rdx); + __ bswapl(rcx); + __ bswapl(rdx); // check against lo & hi __ cmpl(rax, rcx); __ jccb(Assembler::less, default_case); @@ -1787,13 +1796,13 @@ void TemplateTable::tableswitch() { __ jccb(Assembler::greater, default_case); // lookup dispatch offset __ subl(rax, rcx); - __ movl(rdx, Address(rbx, rax, Address::times_4, 3 * wordSize)); + __ movl(rdx, Address(rbx, rax, Address::times_4, 3 * BytesPerInt)); __ profile_switch_case(rax, rbx, rcx); // continue execution __ bind(continue_execution); - __ bswap(rdx); + __ bswapl(rdx); __ load_unsigned_byte(rbx, Address(rsi, rdx, Address::times_1)); - __ addl(rsi, rdx); + __ addptr(rsi, rdx); __ dispatch_only(vtos); // handle default __ bind(default_case); @@ -1812,21 +1821,21 @@ void TemplateTable::lookupswitch() { void TemplateTable::fast_linearswitch() { transition(itos, vtos); Label loop_entry, loop, found, continue_execution; - // bswap rax, so we can avoid bswapping the table entries - __ bswap(rax); + // bswapl rax, so we can avoid bswapping the table entries + __ bswapl(rax); // align rsi - __ leal(rbx, at_bcp(wordSize)); // btw: should be able to get rid of this instruction (change offsets below) - __ andl(rbx, -wordSize); + __ lea(rbx, at_bcp(wordSize)); // btw: should be able to get rid of this instruction (change offsets below) + __ andptr(rbx, -wordSize); // set counter __ movl(rcx, Address(rbx, wordSize)); - __ bswap(rcx); + __ bswapl(rcx); __ jmpb(loop_entry); // table search __ bind(loop); __ cmpl(rax, Address(rbx, rcx, Address::times_8, 2 * wordSize)); __ jccb(Assembler::equal, found); __ bind(loop_entry); - __ decrement(rcx); + __ decrementl(rcx); __ jcc(Assembler::greaterEqual, loop); // default case __ profile_switch_default(rax); @@ -1838,9 +1847,9 @@ void TemplateTable::fast_linearswitch() { __ profile_switch_case(rcx, rax, rbx); // continue execution __ bind(continue_execution); - __ bswap(rdx); + __ bswapl(rdx); __ load_unsigned_byte(rbx, Address(rsi, rdx, Address::times_1)); - __ addl(rsi, rdx); + __ addptr(rsi, rdx); __ dispatch_only(vtos); } @@ -1882,13 +1891,13 @@ void TemplateTable::fast_binaryswitch() { // setup array __ save_bcp(); - __ leal(array, at_bcp(3*wordSize)); // btw: should be able to get rid of this instruction (change offsets below) - __ andl(array, -wordSize); + __ lea(array, at_bcp(3*wordSize)); // btw: should be able to get rid of this instruction (change offsets below) + __ andptr(array, -wordSize); // initialize i & j __ xorl(i, i); // i = 0; __ movl(j, Address(array, -wordSize)); // j = length(array); // Convert j into native byteordering - __ bswap(j); + __ bswapl(j); // and start Label entry; __ jmp(entry); @@ -1906,19 +1915,19 @@ void TemplateTable::fast_binaryswitch() { // } // Convert array[h].match to native byte-ordering before compare __ movl(temp, Address(array, h, Address::times_8, 0*wordSize)); - __ bswap(temp); + __ bswapl(temp); __ cmpl(key, temp); if (VM_Version::supports_cmov()) { __ cmovl(Assembler::less , j, h); // j = h if (key < array[h].fast_match()) __ cmovl(Assembler::greaterEqual, i, h); // i = h if (key >= array[h].fast_match()) } else { Label set_i, end_of_if; - __ jccb(Assembler::greaterEqual, set_i); // { - __ movl(j, h); // j = h; - __ jmp(end_of_if); // } - __ bind(set_i); // else { - __ movl(i, h); // i = h; - __ bind(end_of_if); // } + __ jccb(Assembler::greaterEqual, set_i); // { + __ mov(j, h); // j = h; + __ jmp(end_of_if); // } + __ bind(set_i); // else { + __ mov(i, h); // i = h; + __ bind(end_of_if); // } } // while (i+1 < j) __ bind(entry); @@ -1931,30 +1940,32 @@ void TemplateTable::fast_binaryswitch() { Label default_case; // Convert array[i].match to native byte-ordering before compare __ movl(temp, Address(array, i, Address::times_8, 0*wordSize)); - __ bswap(temp); + __ bswapl(temp); __ cmpl(key, temp); __ jcc(Assembler::notEqual, default_case); // entry found -> j = offset __ movl(j , Address(array, i, Address::times_8, 1*wordSize)); __ profile_switch_case(i, key, array); - __ bswap(j); + __ bswapl(j); + LP64_ONLY(__ movslq(j, j)); __ restore_bcp(); __ restore_locals(); // restore rdi __ load_unsigned_byte(rbx, Address(rsi, j, Address::times_1)); - __ addl(rsi, j); + __ addptr(rsi, j); __ dispatch_only(vtos); // default case -> j = default offset __ bind(default_case); __ profile_switch_default(i); __ movl(j, Address(array, -2*wordSize)); - __ bswap(j); + __ bswapl(j); + LP64_ONLY(__ movslq(j, j)); __ restore_bcp(); __ restore_locals(); // restore rdi __ load_unsigned_byte(rbx, Address(rsi, j, Address::times_1)); - __ addl(rsi, j); + __ addptr(rsi, j); __ dispatch_only(vtos); } @@ -1965,8 +1976,8 @@ void TemplateTable::_return(TosState state) { if (_desc->bytecode() == Bytecodes::_return_register_finalizer) { assert(state == vtos, "only valid state"); - __ movl(rax, aaddress(0)); - __ movl(rdi, Address(rax, oopDesc::klass_offset_in_bytes())); + __ movptr(rax, aaddress(0)); + __ movptr(rdi, Address(rax, oopDesc::klass_offset_in_bytes())); __ movl(rdi, Address(rdi, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc))); __ testl(rdi, JVM_ACC_HAS_FINALIZER); Label skip_register_finalizer; @@ -2007,10 +2018,10 @@ void TemplateTable::_return(TosState state) { // requirement (1) but miss the volatile-store-volatile-load case. This final // case is placed after volatile-stores although it could just as well go // before volatile-loads. -void TemplateTable::volatile_barrier( ) { +void TemplateTable::volatile_barrier(Assembler::Membar_mask_bits order_constraint ) { // Helper function to insert a is-volatile test and memory barrier if( !os::is_MP() ) return; // Not needed on single CPU - __ membar(); + __ membar(order_constraint); } void TemplateTable::resolve_cache_and_index(int byte_no, Register Rcache, Register index) { @@ -2023,10 +2034,13 @@ void TemplateTable::resolve_cache_and_index(int byte_no, Register Rcache, Regist const int shift_count = (1 + byte_no)*BitsPerByte; Label resolved; __ get_cache_and_index_at_bcp(Rcache, index, 1); - __ movl(temp, Address(Rcache, index, Address::times_4, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); + __ movl(temp, Address(Rcache, + index, + Address::times_ptr, + constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); __ shrl(temp, shift_count); // have we resolved this bytecode? - __ andl(temp, 0xFF); + __ andptr(temp, 0xFF); __ cmpl(temp, (int)bytecode()); __ jcc(Assembler::equal, resolved); @@ -2062,16 +2076,16 @@ void TemplateTable::load_field_cp_cache_entry(Register obj, ByteSize cp_base_offset = constantPoolCacheOopDesc::base_offset(); // Field offset - __ movl(off, Address(cache, index, Address::times_4, - in_bytes(cp_base_offset + ConstantPoolCacheEntry::f2_offset()))); + __ movptr(off, Address(cache, index, Address::times_ptr, + in_bytes(cp_base_offset + ConstantPoolCacheEntry::f2_offset()))); // Flags - __ movl(flags, Address(cache, index, Address::times_4, + __ movl(flags, Address(cache, index, Address::times_ptr, in_bytes(cp_base_offset + ConstantPoolCacheEntry::flags_offset()))); // klass overwrite register if (is_static) { - __ movl(obj, Address(cache, index, Address::times_4, - in_bytes(cp_base_offset + ConstantPoolCacheEntry::f1_offset()))); + __ movptr(obj, Address(cache, index, Address::times_ptr, + in_bytes(cp_base_offset + ConstantPoolCacheEntry::f1_offset()))); } } @@ -2104,12 +2118,11 @@ void TemplateTable::load_invoke_cp_cache_entry(int byte_no, resolve_cache_and_index(byte_no, cache, index); - assert(wordSize == 4, "adjust code below"); - __ movl(method, Address(cache, index, Address::times_4, method_offset)); + __ movptr(method, Address(cache, index, Address::times_ptr, method_offset)); if (itable_index != noreg) { - __ movl(itable_index, Address(cache, index, Address::times_4, index_offset)); + __ movptr(itable_index, Address(cache, index, Address::times_ptr, index_offset)); } - __ movl(flags , Address(cache, index, Address::times_4, flags_offset )); + __ movl(flags , Address(cache, index, Address::times_ptr, flags_offset )); } @@ -2129,11 +2142,11 @@ void TemplateTable::jvmti_post_field_access(Register cache, __ jcc(Assembler::zero, L1); // cache entry pointer - __ addl(cache, in_bytes(constantPoolCacheOopDesc::base_offset())); + __ addptr(cache, in_bytes(constantPoolCacheOopDesc::base_offset())); __ shll(index, LogBytesPerWord); - __ addl(cache, index); + __ addptr(cache, index); if (is_static) { - __ movl(rax, 0); // NULL object reference + __ xorptr(rax, rax); // NULL object reference } else { __ pop(atos); // Get the object __ verify_oop(rax); @@ -2177,7 +2190,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) { __ shrl(flags, ConstantPoolCacheEntry::tosBits); assert(btos == 0, "change code, btos != 0"); // btos - __ andl(flags, 0x0f); + __ andptr(flags, 0x0f); __ jcc(Assembler::notZero, notByte); __ load_signed_byte(rax, lo ); @@ -2245,10 +2258,10 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) { // Generate code as if volatile. There just aren't enough registers to // save that information and this code is faster than the test. __ fild_d(lo); // Must load atomically - __ subl(rsp,2*wordSize); // Make space for store + __ subptr(rsp,2*wordSize); // Make space for store __ fistp_d(Address(rsp,0)); - __ popl(rax); - __ popl(rdx); + __ pop(rax); + __ pop(rdx); __ push(ltos); // Don't rewrite to _fast_lgetfield for potential volatile case. @@ -2319,16 +2332,16 @@ void TemplateTable::jvmti_post_field_mod(Register cache, Register index, bool is if (is_static) { // Life is simple. Null out the object pointer. - __ xorl(rbx, rbx); + __ xorptr(rbx, rbx); } else { // Life is harder. The stack holds the value on top, followed by the object. // We don't know the size of the value, though; it could be one or two words // depending on its type. As a result, we must find the type to determine where // the object is. Label two_word, valsize_known; - __ movl(rcx, Address(rax, rdx, Address::times_4, in_bytes(cp_base_offset + + __ movl(rcx, Address(rax, rdx, Address::times_ptr, in_bytes(cp_base_offset + ConstantPoolCacheEntry::flags_offset()))); - __ movl(rbx, rsp); + __ mov(rbx, rsp); __ shrl(rcx, ConstantPoolCacheEntry::tosBits); // Make sure we don't need to mask rcx for tosBits after the above shift ConstantPoolCacheEntry::verify_tosBits(); @@ -2336,22 +2349,22 @@ void TemplateTable::jvmti_post_field_mod(Register cache, Register index, bool is __ jccb(Assembler::equal, two_word); __ cmpl(rcx, dtos); __ jccb(Assembler::equal, two_word); - __ addl(rbx, Interpreter::expr_offset_in_bytes(1)); // one word jvalue (not ltos, dtos) + __ addptr(rbx, Interpreter::expr_offset_in_bytes(1)); // one word jvalue (not ltos, dtos) __ jmpb(valsize_known); __ bind(two_word); - __ addl(rbx, Interpreter::expr_offset_in_bytes(2)); // two words jvalue + __ addptr(rbx, Interpreter::expr_offset_in_bytes(2)); // two words jvalue __ bind(valsize_known); // setup object pointer - __ movl(rbx, Address(rbx, 0)); + __ movptr(rbx, Address(rbx, 0)); } // cache entry pointer - __ addl(rax, in_bytes(cp_base_offset)); + __ addptr(rax, in_bytes(cp_base_offset)); __ shll(rdx, LogBytesPerWord); - __ addl(rax, rdx); + __ addptr(rax, rdx); // object (tos) - __ movl(rcx, rsp); + __ mov(rcx, rsp); // rbx,: object pointer set up above (NULL if static) // rax,: cache entry pointer // rcx: jvalue object on the stack @@ -2426,7 +2439,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) { __ pop(atos); if (!is_static) pop_and_check_object(obj); - __ movl(lo, rax ); + __ movptr(lo, rax ); __ store_check(obj, lo); // Need to mark card if (!is_static) { patch_bytecode(Bytecodes::_fast_aputfield, rcx, rbx); @@ -2472,12 +2485,14 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) { if (!is_static) pop_and_check_object(obj); // Replace with real volatile test - __ pushl(rdx); - __ pushl(rax); // Must update atomically with FIST + __ push(rdx); + __ push(rax); // Must update atomically with FIST __ fild_d(Address(rsp,0)); // So load into FPU register __ fistp_d(lo); // and put into memory atomically - __ addl(rsp,2*wordSize); - volatile_barrier(); + __ addptr(rsp, 2*wordSize); + // volatile_barrier(); + volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad | + Assembler::StoreStore)); // Don't rewrite volatile version __ jmp(notVolatile); @@ -2485,8 +2500,8 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) { __ pop(ltos); // overwrites rdx if (!is_static) pop_and_check_object(obj); - __ movl(hi, rdx); - __ movl(lo, rax); + NOT_LP64(__ movptr(hi, rdx)); + __ movptr(lo, rax); if (!is_static) { patch_bytecode(Bytecodes::_fast_lputfield, rcx, rbx); } @@ -2527,7 +2542,8 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) { // Check for volatile store __ testl(rdx, rdx); __ jcc(Assembler::zero, notVolatile); - volatile_barrier( ); + volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad | + Assembler::StoreStore)); __ bind(notVolatile); } @@ -2552,10 +2568,10 @@ void TemplateTable::jvmti_post_fast_field_mod() { __ pop_ptr(rbx); // copy the object pointer from tos __ verify_oop(rbx); __ push_ptr(rbx); // put the object pointer back on tos - __ subl(rsp, sizeof(jvalue)); // add space for a jvalue object - __ movl(rcx, rsp); + __ subptr(rsp, sizeof(jvalue)); // add space for a jvalue object + __ mov(rcx, rsp); __ push_ptr(rbx); // save object pointer so we can steal rbx, - __ movl(rbx, 0); + __ xorptr(rbx, rbx); const Address lo_value(rcx, rbx, Address::times_1, 0*wordSize); const Address hi_value(rcx, rbx, Address::times_1, 1*wordSize); switch (bytecode()) { // load values into the jvalue object @@ -2563,21 +2579,28 @@ void TemplateTable::jvmti_post_fast_field_mod() { case Bytecodes::_fast_sputfield: __ movw(lo_value, rax); break; case Bytecodes::_fast_cputfield: __ movw(lo_value, rax); break; case Bytecodes::_fast_iputfield: __ movl(lo_value, rax); break; - case Bytecodes::_fast_lputfield: __ movl(hi_value, rdx); __ movl(lo_value, rax); break; + case Bytecodes::_fast_lputfield: + NOT_LP64(__ movptr(hi_value, rdx)); + __ movptr(lo_value, rax); + break; + // need to call fld_s() after fstp_s() to restore the value for below case Bytecodes::_fast_fputfield: __ fstp_s(lo_value); __ fld_s(lo_value); break; + // need to call fld_d() after fstp_d() to restore the value for below case Bytecodes::_fast_dputfield: __ fstp_d(lo_value); __ fld_d(lo_value); break; + // since rcx is not an object we don't call store_check() here - case Bytecodes::_fast_aputfield: __ movl(lo_value, rax); break; + case Bytecodes::_fast_aputfield: __ movptr(lo_value, rax); break; + default: ShouldNotReachHere(); } __ pop_ptr(rbx); // restore copy of object pointer // Save rax, and sometimes rdx because call_VM() will clobber them, // then use them for JVM/DI purposes - __ pushl(rax); - if (bytecode() == Bytecodes::_fast_lputfield) __ pushl(rdx); + __ push(rax); + if (bytecode() == Bytecodes::_fast_lputfield) __ push(rdx); // access constant pool cache entry __ get_cache_entry_pointer_at_bcp(rax, rdx, 1); __ verify_oop(rbx); @@ -2585,9 +2608,9 @@ void TemplateTable::jvmti_post_fast_field_mod() { // rax,: cache entry pointer // rcx: jvalue object on the stack __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_modification), rbx, rax, rcx); - if (bytecode() == Bytecodes::_fast_lputfield) __ popl(rdx); // restore high value - __ popl(rax); // restore lower value - __ addl(rsp, sizeof(jvalue)); // release jvalue object space + if (bytecode() == Bytecodes::_fast_lputfield) __ pop(rdx); // restore high value + __ pop(rax); // restore lower value + __ addptr(rsp, sizeof(jvalue)); // release jvalue object space __ bind(L2); } } @@ -2603,12 +2626,12 @@ void TemplateTable::fast_storefield(TosState state) { __ get_cache_and_index_at_bcp(rcx, rbx, 1); // test for volatile with rdx but rdx is tos register for lputfield. - if (bytecode() == Bytecodes::_fast_lputfield) __ pushl(rdx); - __ movl(rdx, Address(rcx, rbx, Address::times_4, in_bytes(base + + if (bytecode() == Bytecodes::_fast_lputfield) __ push(rdx); + __ movl(rdx, Address(rcx, rbx, Address::times_ptr, in_bytes(base + ConstantPoolCacheEntry::flags_offset()))); // replace index with field offset from cache entry - __ movl(rbx, Address(rcx, rbx, Address::times_4, in_bytes(base + ConstantPoolCacheEntry::f2_offset()))); + __ movptr(rbx, Address(rcx, rbx, Address::times_ptr, in_bytes(base + ConstantPoolCacheEntry::f2_offset()))); // Doug Lea believes this is not needed with current Sparcs (TSO) and Intel (PSO). // volatile_barrier( ); @@ -2620,7 +2643,7 @@ void TemplateTable::fast_storefield(TosState state) { __ testl(rdx, rdx); __ jcc(Assembler::zero, notVolatile); - if (bytecode() == Bytecodes::_fast_lputfield) __ popl(rdx); + if (bytecode() == Bytecodes::_fast_lputfield) __ pop(rdx); // Get object from stack pop_and_check_object(rcx); @@ -2635,22 +2658,26 @@ void TemplateTable::fast_storefield(TosState state) { case Bytecodes::_fast_sputfield: // fall through case Bytecodes::_fast_cputfield: __ movw(lo, rax); break; case Bytecodes::_fast_iputfield: __ movl(lo, rax); break; - case Bytecodes::_fast_lputfield: __ movl(hi, rdx); __ movl(lo, rax); break; + case Bytecodes::_fast_lputfield: + NOT_LP64(__ movptr(hi, rdx)); + __ movptr(lo, rax); + break; case Bytecodes::_fast_fputfield: __ fstp_s(lo); break; case Bytecodes::_fast_dputfield: __ fstp_d(lo); break; - case Bytecodes::_fast_aputfield: __ movl(lo, rax); __ store_check(rcx, lo); break; + case Bytecodes::_fast_aputfield: __ movptr(lo, rax); __ store_check(rcx, lo); break; default: ShouldNotReachHere(); } Label done; - volatile_barrier( ); + volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad | + Assembler::StoreStore)); __ jmpb(done); // Same code as above, but don't need rdx to test for volatile. __ bind(notVolatile); - if (bytecode() == Bytecodes::_fast_lputfield) __ popl(rdx); + if (bytecode() == Bytecodes::_fast_lputfield) __ pop(rdx); // Get object from stack pop_and_check_object(rcx); @@ -2661,10 +2688,13 @@ void TemplateTable::fast_storefield(TosState state) { case Bytecodes::_fast_sputfield: // fall through case Bytecodes::_fast_cputfield: __ movw(lo, rax); break; case Bytecodes::_fast_iputfield: __ movl(lo, rax); break; - case Bytecodes::_fast_lputfield: __ movl(hi, rdx); __ movl(lo, rax); break; + case Bytecodes::_fast_lputfield: + NOT_LP64(__ movptr(hi, rdx)); + __ movptr(lo, rax); + break; case Bytecodes::_fast_fputfield: __ fstp_s(lo); break; case Bytecodes::_fast_dputfield: __ fstp_d(lo); break; - case Bytecodes::_fast_aputfield: __ movl(lo, rax); __ store_check(rcx, lo); break; + case Bytecodes::_fast_aputfield: __ movptr(lo, rax); __ store_check(rcx, lo); break; default: ShouldNotReachHere(); } @@ -2697,7 +2727,10 @@ void TemplateTable::fast_accessfield(TosState state) { // access constant pool cache __ get_cache_and_index_at_bcp(rcx, rbx, 1); // replace index with field offset from cache entry - __ movl(rbx, Address(rcx, rbx, Address::times_4, in_bytes(constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f2_offset()))); + __ movptr(rbx, Address(rcx, + rbx, + Address::times_ptr, + in_bytes(constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f2_offset()))); // rax,: object @@ -2709,14 +2742,14 @@ void TemplateTable::fast_accessfield(TosState state) { // access field switch (bytecode()) { - case Bytecodes::_fast_bgetfield: __ movsxb(rax, lo ); break; + case Bytecodes::_fast_bgetfield: __ movsbl(rax, lo ); break; case Bytecodes::_fast_sgetfield: __ load_signed_word(rax, lo ); break; case Bytecodes::_fast_cgetfield: __ load_unsigned_word(rax, lo ); break; case Bytecodes::_fast_igetfield: __ movl(rax, lo); break; case Bytecodes::_fast_lgetfield: __ stop("should not be rewritten"); break; case Bytecodes::_fast_fgetfield: __ fld_s(lo); break; case Bytecodes::_fast_dgetfield: __ fld_d(lo); break; - case Bytecodes::_fast_agetfield: __ movl(rax, lo); __ verify_oop(rax); break; + case Bytecodes::_fast_agetfield: __ movptr(rax, lo); __ verify_oop(rax); break; default: ShouldNotReachHere(); } @@ -2728,11 +2761,14 @@ void TemplateTable::fast_accessfield(TosState state) { void TemplateTable::fast_xaccess(TosState state) { transition(vtos, state); // get receiver - __ movl(rax, aaddress(0)); + __ movptr(rax, aaddress(0)); debug_only(__ verify_local_tag(frame::TagReference, 0)); // access constant pool cache __ get_cache_and_index_at_bcp(rcx, rdx, 2); - __ movl(rbx, Address(rcx, rdx, Address::times_4, in_bytes(constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f2_offset()))); + __ movptr(rbx, Address(rcx, + rdx, + Address::times_ptr, + in_bytes(constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f2_offset()))); // make sure exception is reported in correct bcp range (getfield is next instruction) __ increment(rsi); __ null_check(rax); @@ -2740,7 +2776,7 @@ void TemplateTable::fast_xaccess(TosState state) { if (state == itos) { __ movl(rax, lo); } else if (state == atos) { - __ movl(rax, lo); + __ movptr(rax, lo); __ verify_oop(rax); } else if (state == ftos) { __ fld_s(lo); @@ -2784,7 +2820,7 @@ void TemplateTable::prepare_invoke(Register method, Register index, int byte_no, __ movl(recv, flags); __ andl(recv, 0xFF); // recv count is 0 based? - __ movl(recv, Address(rsp, recv, Interpreter::stackElementScale(), -Interpreter::expr_offset_in_bytes(1))); + __ movptr(recv, Address(rsp, recv, Interpreter::stackElementScale(), -Interpreter::expr_offset_in_bytes(1))); __ verify_oop(recv); } @@ -2794,7 +2830,7 @@ void TemplateTable::prepare_invoke(Register method, Register index, int byte_no, } if (save_flags) { - __ movl(rsi, flags); + __ mov(rsi, flags); } // compute return type @@ -2802,20 +2838,19 @@ void TemplateTable::prepare_invoke(Register method, Register index, int byte_no, // Make sure we don't need to mask flags for tosBits after the above shift ConstantPoolCacheEntry::verify_tosBits(); // load return address - { const int table = - is_invokeinterface - ? (int)Interpreter::return_5_addrs_by_index_table() - : (int)Interpreter::return_3_addrs_by_index_table(); - __ movl(flags, Address(noreg, flags, Address::times_4, table)); + { + ExternalAddress table(is_invokeinterface ? (address)Interpreter::return_5_addrs_by_index_table() : + (address)Interpreter::return_3_addrs_by_index_table()); + __ movptr(flags, ArrayAddress(table, Address(noreg, flags, Address::times_ptr))); } // push return address - __ pushl(flags); + __ push(flags); // Restore flag value from the constant pool cache, and restore rsi // for later null checks. rsi is the bytecode pointer if (save_flags) { - __ movl(flags, rsi); + __ mov(flags, rsi); __ restore_bcp(); } } @@ -2852,7 +2887,7 @@ void TemplateTable::invokevirtual_helper(Register index, Register recv, // get receiver klass __ null_check(recv, oopDesc::klass_offset_in_bytes()); // Keep recv in rcx for callee expects it there - __ movl(rax, Address(recv, oopDesc::klass_offset_in_bytes())); + __ movptr(rax, Address(recv, oopDesc::klass_offset_in_bytes())); __ verify_oop(rax); // profile this call @@ -2861,7 +2896,7 @@ void TemplateTable::invokevirtual_helper(Register index, Register recv, // get target methodOop & entry point const int base = instanceKlass::vtable_start_offset() * wordSize; assert(vtableEntry::size() * wordSize == 4, "adjust the scaling in the code below"); - __ movl(method, Address(rax, index, Address::times_4, base + vtableEntry::method_offset_in_bytes())); + __ movptr(method, Address(rax, index, Address::times_ptr, base + vtableEntry::method_offset_in_bytes())); __ jump_from_interpreted(method, rdx); } @@ -2927,19 +2962,19 @@ void TemplateTable::invokeinterface(int byte_no) { // Get receiver klass into rdx - also a null check __ restore_locals(); // restore rdi - __ movl(rdx, Address(rcx, oopDesc::klass_offset_in_bytes())); + __ movptr(rdx, Address(rcx, oopDesc::klass_offset_in_bytes())); __ verify_oop(rdx); // profile this call __ profile_virtual_call(rdx, rsi, rdi); - __ movl(rdi, rdx); // Save klassOop in rdi + __ mov(rdi, rdx); // Save klassOop in rdi // Compute start of first itableOffsetEntry (which is at the end of the vtable) const int base = instanceKlass::vtable_start_offset() * wordSize; - assert(vtableEntry::size() * wordSize == 4, "adjust the scaling in the code below"); + assert(vtableEntry::size() * wordSize == (1 << (int)Address::times_ptr), "adjust the scaling in the code below"); __ movl(rsi, Address(rdx, instanceKlass::vtable_length_offset() * wordSize)); // Get length of vtable - __ leal(rdx, Address(rdx, rsi, Address::times_4, base)); + __ lea(rdx, Address(rdx, rsi, Address::times_4, base)); if (HeapWordsPerLong > 1) { // Round up to align_object_offset boundary __ round_to(rdx, BytesPerLong); @@ -2949,20 +2984,20 @@ void TemplateTable::invokeinterface(int byte_no) { __ jmpb(entry); __ bind(search); - __ addl(rdx, itableOffsetEntry::size() * wordSize); + __ addptr(rdx, itableOffsetEntry::size() * wordSize); __ bind(entry); // Check that the entry is non-null. A null entry means that the receiver // class doesn't implement the interface, and wasn't the same as the // receiver class checked when the interface was resolved. - __ pushl(rdx); - __ movl(rdx, Address(rdx, itableOffsetEntry::interface_offset_in_bytes())); - __ testl(rdx, rdx); + __ push(rdx); + __ movptr(rdx, Address(rdx, itableOffsetEntry::interface_offset_in_bytes())); + __ testptr(rdx, rdx); __ jcc(Assembler::notZero, interface_ok); // throw exception - __ popl(rdx); // pop saved register first. - __ popl(rbx); // pop return address (pushed by prepare_invoke) + __ pop(rdx); // pop saved register first. + __ pop(rbx); // pop return address (pushed by prepare_invoke) __ restore_bcp(); // rsi must be correct for exception handler (was destroyed) __ restore_locals(); // make sure locals pointer is correct as well (was destroyed) __ call_VM(noreg, CAST_FROM_FN_PTR(address, @@ -2971,15 +3006,15 @@ void TemplateTable::invokeinterface(int byte_no) { __ should_not_reach_here(); __ bind(interface_ok); - __ popl(rdx); + __ pop(rdx); - __ cmpl(rax, Address(rdx, itableOffsetEntry::interface_offset_in_bytes())); + __ cmpptr(rax, Address(rdx, itableOffsetEntry::interface_offset_in_bytes())); __ jcc(Assembler::notEqual, search); __ movl(rdx, Address(rdx, itableOffsetEntry::offset_offset_in_bytes())); - __ addl(rdx, rdi); // Add offset to klassOop - assert(itableMethodEntry::size() * wordSize == 4, "adjust the scaling in the code below"); - __ movl(rbx, Address(rdx, rbx, Address::times_4)); + __ addptr(rdx, rdi); // Add offset to klassOop + assert(itableMethodEntry::size() * wordSize == (1 << (int)Address::times_ptr), "adjust the scaling in the code below"); + __ movptr(rbx, Address(rdx, rbx, Address::times_ptr)); // rbx,: methodOop to call // rcx: receiver // Check for abstract method error @@ -2987,12 +3022,12 @@ void TemplateTable::invokeinterface(int byte_no) { // interpreter entry point and a conditional jump to it in case of a null // method. { Label L; - __ testl(rbx, rbx); + __ testptr(rbx, rbx); __ jcc(Assembler::notZero, L); // throw exception // note: must restore interpreter registers to canonical // state for exception handling to work correctly! - __ popl(rbx); // pop return address (pushed by prepare_invoke) + __ pop(rbx); // pop return address (pushed by prepare_invoke) __ restore_bcp(); // rsi must be correct for exception handler (was destroyed) __ restore_locals(); // make sure locals pointer is correct as well (was destroyed) __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError)); @@ -3023,8 +3058,8 @@ void TemplateTable::_new() { __ get_cpool_and_tags(rcx, rax); // get instanceKlass - __ movl(rcx, Address(rcx, rdx, Address::times_4, sizeof(constantPoolOopDesc))); - __ pushl(rcx); // save the contexts of klass for initializing the header + __ movptr(rcx, Address(rcx, rdx, Address::times_ptr, sizeof(constantPoolOopDesc))); + __ push(rcx); // save the contexts of klass for initializing the header // make sure the class we're about to instantiate has been resolved. // Note: slow_case does a pop of stack, which is why we loaded class/pushed above @@ -3057,11 +3092,11 @@ void TemplateTable::_new() { const Register thread = rcx; __ get_thread(thread); - __ movl(rax, Address(thread, in_bytes(JavaThread::tlab_top_offset()))); - __ leal(rbx, Address(rax, rdx, Address::times_1)); - __ cmpl(rbx, Address(thread, in_bytes(JavaThread::tlab_end_offset()))); + __ movptr(rax, Address(thread, in_bytes(JavaThread::tlab_top_offset()))); + __ lea(rbx, Address(rax, rdx, Address::times_1)); + __ cmpptr(rbx, Address(thread, in_bytes(JavaThread::tlab_end_offset()))); __ jcc(Assembler::above, allow_shared_alloc ? allocate_shared : slow_case); - __ movl(Address(thread, in_bytes(JavaThread::tlab_top_offset())), rbx); + __ movptr(Address(thread, in_bytes(JavaThread::tlab_top_offset())), rbx); if (ZeroTLAB) { // the fields have been already cleared __ jmp(initialize_header); @@ -3079,9 +3114,9 @@ void TemplateTable::_new() { Label retry; __ bind(retry); - __ mov32(rax, heap_top); - __ leal(rbx, Address(rax, rdx, Address::times_1)); - __ cmp32(rbx, ExternalAddress((address)Universe::heap()->end_addr())); + __ movptr(rax, heap_top); + __ lea(rbx, Address(rax, rdx, Address::times_1)); + __ cmpptr(rbx, ExternalAddress((address)Universe::heap()->end_addr())); __ jcc(Assembler::above, slow_case); // Compare rax, with the top addr, and if still equal, store the new @@ -3091,8 +3126,7 @@ void TemplateTable::_new() { // rax,: object begin // rbx,: object end // rdx: instance size in bytes - if (os::is_MP()) __ lock(); - __ cmpxchgptr(rbx, heap_top); + __ locked_cmpxchgptr(rbx, heap_top); // if someone beat us on the allocation, try again, otherwise continue __ jcc(Assembler::notEqual, retry); @@ -3124,8 +3158,8 @@ void TemplateTable::_new() { // initialize remaining object fields: rdx was a multiple of 8 { Label loop; __ bind(loop); - __ movl(Address(rax, rdx, Address::times_8, sizeof(oopDesc) - 1*oopSize), rcx); - __ movl(Address(rax, rdx, Address::times_8, sizeof(oopDesc) - 2*oopSize), rcx); + __ movptr(Address(rax, rdx, Address::times_8, sizeof(oopDesc) - 1*oopSize), rcx); + NOT_LP64(__ movptr(Address(rax, rdx, Address::times_8, sizeof(oopDesc) - 2*oopSize), rcx)); __ decrement(rdx); __ jcc(Assembler::notZero, loop); } @@ -3133,15 +3167,15 @@ void TemplateTable::_new() { // initialize object header only. __ bind(initialize_header); if (UseBiasedLocking) { - __ popl(rcx); // get saved klass back in the register. - __ movl(rbx, Address(rcx, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); - __ movl(Address(rax, oopDesc::mark_offset_in_bytes ()), rbx); + __ pop(rcx); // get saved klass back in the register. + __ movptr(rbx, Address(rcx, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + __ movptr(Address(rax, oopDesc::mark_offset_in_bytes ()), rbx); } else { - __ movl(Address(rax, oopDesc::mark_offset_in_bytes ()), - (int)markOopDesc::prototype()); // header - __ popl(rcx); // get saved klass back in the register. + __ movptr(Address(rax, oopDesc::mark_offset_in_bytes ()), + (int32_t)markOopDesc::prototype()); // header + __ pop(rcx); // get saved klass back in the register. } - __ movl(Address(rax, oopDesc::klass_offset_in_bytes()), rcx); // klass + __ movptr(Address(rax, oopDesc::klass_offset_in_bytes()), rcx); // klass { SkipIfEqual skip_if(_masm, &DTraceAllocProbes, 0); @@ -3157,7 +3191,7 @@ void TemplateTable::_new() { // slow case __ bind(slow_case); - __ popl(rcx); // restore stack pointer to what it was when we came in. + __ pop(rcx); // restore stack pointer to what it was when we came in. __ get_constant_pool(rax); __ get_unsigned_2_byte_index_at_bcp(rdx, 1); call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::_new), rax, rdx); @@ -3194,7 +3228,7 @@ void TemplateTable::arraylength() { void TemplateTable::checkcast() { transition(atos, atos); Label done, is_null, ok_is_subtype, quicked, resolved; - __ testl(rax, rax); // Object is in EAX + __ testptr(rax, rax); // Object is in EAX __ jcc(Assembler::zero, is_null); // Get cpool & tags index @@ -3211,24 +3245,24 @@ void TemplateTable::checkcast() { // Get superklass in EAX and subklass in EBX __ bind(quicked); - __ movl(rdx, rax); // Save object in EDX; EAX needed for subtype check - __ movl(rax, Address(rcx, rbx, Address::times_4, sizeof(constantPoolOopDesc))); + __ mov(rdx, rax); // Save object in EDX; EAX needed for subtype check + __ movptr(rax, Address(rcx, rbx, Address::times_ptr, sizeof(constantPoolOopDesc))); __ bind(resolved); - __ movl(rbx, Address(rdx, oopDesc::klass_offset_in_bytes())); + __ movptr(rbx, Address(rdx, oopDesc::klass_offset_in_bytes())); // Generate subtype check. Blows ECX. Resets EDI. Object in EDX. // Superklass in EAX. Subklass in EBX. __ gen_subtype_check( rbx, ok_is_subtype ); // Come here on failure - __ pushl(rdx); + __ push(rdx); // object is at TOS __ jump(ExternalAddress(Interpreter::_throw_ClassCastException_entry)); // Come here on success __ bind(ok_is_subtype); - __ movl(rax,rdx); // Restore object in EDX + __ mov(rax,rdx); // Restore object in EDX // Collect counts on whether this check-cast sees NULLs a lot or not. if (ProfileInterpreter) { @@ -3245,7 +3279,7 @@ void TemplateTable::checkcast() { void TemplateTable::instanceof() { transition(atos, itos); Label done, is_null, ok_is_subtype, quicked, resolved; - __ testl(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, is_null); // Get cpool & tags index @@ -3258,13 +3292,13 @@ void TemplateTable::instanceof() { __ push(atos); call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc) ); __ pop_ptr(rdx); - __ movl(rdx, Address(rdx, oopDesc::klass_offset_in_bytes())); + __ movptr(rdx, Address(rdx, oopDesc::klass_offset_in_bytes())); __ jmp(resolved); // Get superklass in EAX and subklass in EDX __ bind(quicked); - __ movl(rdx, Address(rax, oopDesc::klass_offset_in_bytes())); - __ movl(rax, Address(rcx, rbx, Address::times_4, sizeof(constantPoolOopDesc))); + __ movptr(rdx, Address(rax, oopDesc::klass_offset_in_bytes())); + __ movptr(rax, Address(rcx, rbx, Address::times_ptr, sizeof(constantPoolOopDesc))); __ bind(resolved); @@ -3306,7 +3340,7 @@ void TemplateTable::_breakpoint() { // get the unpatched byte code __ get_method(rcx); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::get_original_bytecode_at), rcx, rsi); - __ movl(rbx, rax); + __ mov(rbx, rax); // post the breakpoint event __ get_method(rcx); @@ -3362,50 +3396,50 @@ void TemplateTable::monitorenter() { // find a free slot in the monitor block (result in rdx) { Label entry, loop, exit; - __ movl(rcx, monitor_block_top); // points to current entry, starting with top-most entry - __ leal(rbx, monitor_block_bot); // points to word before bottom of monitor block + __ movptr(rcx, monitor_block_top); // points to current entry, starting with top-most entry + __ lea(rbx, monitor_block_bot); // points to word before bottom of monitor block __ jmpb(entry); __ bind(loop); - __ cmpl(Address(rcx, BasicObjectLock::obj_offset_in_bytes()), NULL_WORD); // check if current entry is used + __ cmpptr(Address(rcx, BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD); // check if current entry is used // TODO - need new func here - kbt if (VM_Version::supports_cmov()) { - __ cmovl(Assembler::equal, rdx, rcx); // if not used then remember entry in rdx + __ cmov(Assembler::equal, rdx, rcx); // if not used then remember entry in rdx } else { Label L; __ jccb(Assembler::notEqual, L); - __ movl(rdx, rcx); // if not used then remember entry in rdx + __ mov(rdx, rcx); // if not used then remember entry in rdx __ bind(L); } - __ cmpl(rax, Address(rcx, BasicObjectLock::obj_offset_in_bytes())); // check if current entry is for same object - __ jccb(Assembler::equal, exit); // if same object then stop searching - __ addl(rcx, entry_size); // otherwise advance to next entry + __ cmpptr(rax, Address(rcx, BasicObjectLock::obj_offset_in_bytes())); // check if current entry is for same object + __ jccb(Assembler::equal, exit); // if same object then stop searching + __ addptr(rcx, entry_size); // otherwise advance to next entry __ bind(entry); - __ cmpl(rcx, rbx); // check if bottom reached + __ cmpptr(rcx, rbx); // check if bottom reached __ jcc(Assembler::notEqual, loop); // if not at bottom then check this entry __ bind(exit); } - __ testl(rdx, rdx); // check if a slot has been found - __ jccb(Assembler::notZero, allocated); // if found, continue with that one + __ testptr(rdx, rdx); // check if a slot has been found + __ jccb(Assembler::notZero, allocated); // if found, continue with that one // allocate one if there's no free slot { Label entry, loop; // 1. compute new pointers // rsp: old expression stack top - __ movl(rdx, monitor_block_bot); // rdx: old expression stack bottom - __ subl(rsp, entry_size); // move expression stack top - __ subl(rdx, entry_size); // move expression stack bottom - __ movl(rcx, rsp); // set start value for copy loop - __ movl(monitor_block_bot, rdx); // set new monitor block top + __ movptr(rdx, monitor_block_bot); // rdx: old expression stack bottom + __ subptr(rsp, entry_size); // move expression stack top + __ subptr(rdx, entry_size); // move expression stack bottom + __ mov(rcx, rsp); // set start value for copy loop + __ movptr(monitor_block_bot, rdx); // set new monitor block top __ jmp(entry); // 2. move expression stack contents __ bind(loop); - __ movl(rbx, Address(rcx, entry_size)); // load expression stack word from old location - __ movl(Address(rcx, 0), rbx); // and store it at new location - __ addl(rcx, wordSize); // advance to next word + __ movptr(rbx, Address(rcx, entry_size)); // load expression stack word from old location + __ movptr(Address(rcx, 0), rbx); // and store it at new location + __ addptr(rcx, wordSize); // advance to next word __ bind(entry); - __ cmpl(rcx, rdx); // check if bottom reached + __ cmpptr(rcx, rdx); // check if bottom reached __ jcc(Assembler::notEqual, loop); // if not at bottom then copy next word } @@ -3417,7 +3451,7 @@ void TemplateTable::monitorenter() { // The object has already been poped from the stack, so the expression stack looks correct. __ increment(rsi); - __ movl(Address(rdx, BasicObjectLock::obj_offset_in_bytes()), rax); // store object + __ movptr(Address(rdx, BasicObjectLock::obj_offset_in_bytes()), rax); // store object __ lock_object(rdx); // check to make sure this monitor doesn't cause stack overflow after locking @@ -3442,16 +3476,16 @@ void TemplateTable::monitorexit() { // find matching slot { Label entry, loop; - __ movl(rdx, monitor_block_top); // points to current entry, starting with top-most entry - __ leal(rbx, monitor_block_bot); // points to word before bottom of monitor block + __ movptr(rdx, monitor_block_top); // points to current entry, starting with top-most entry + __ lea(rbx, monitor_block_bot); // points to word before bottom of monitor block __ jmpb(entry); __ bind(loop); - __ cmpl(rax, Address(rdx, BasicObjectLock::obj_offset_in_bytes())); // check if current entry is for same object + __ cmpptr(rax, Address(rdx, BasicObjectLock::obj_offset_in_bytes())); // check if current entry is for same object __ jcc(Assembler::equal, found); // if same object then stop searching - __ addl(rdx, entry_size); // otherwise advance to next entry + __ addptr(rdx, entry_size); // otherwise advance to next entry __ bind(entry); - __ cmpl(rdx, rbx); // check if bottom reached + __ cmpptr(rdx, rbx); // check if bottom reached __ jcc(Assembler::notEqual, loop); // if not at bottom then check this entry } @@ -3476,7 +3510,8 @@ void TemplateTable::monitorexit() { void TemplateTable::wide() { transition(vtos, vtos); __ load_unsigned_byte(rbx, at_bcp(1)); - __ jmp(Address(noreg, rbx, Address::times_4, int(Interpreter::_wentry_point))); + ExternalAddress wtable((address)Interpreter::_wentry_point); + __ jump(ArrayAddress(wtable, Address(noreg, rbx, Address::times_ptr))); // Note: the rsi increment step is part of the individual wide bytecode implementations } @@ -3490,10 +3525,10 @@ void TemplateTable::multianewarray() { // last dim is on top of stack; we want address of first one: // first_addr = last_addr + (ndims - 1) * stackElementSize - 1*wordsize // the latter wordSize to point to the beginning of the array. - __ leal( rax, Address(rsp, rax, Interpreter::stackElementScale(), -wordSize)); + __ lea( rax, Address(rsp, rax, Interpreter::stackElementScale(), -wordSize)); call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::multianewarray), rax); // pass in rax, __ load_unsigned_byte(rbx, at_bcp(3)); - __ leal(rsp, Address(rsp, rbx, Interpreter::stackElementScale())); // get rid of counts + __ lea(rsp, Address(rsp, rbx, Interpreter::stackElementScale())); // get rid of counts } #endif /* !CC_INTERP */ diff --git a/hotspot/src/cpu/x86/vm/templateTable_x86_32.hpp b/hotspot/src/cpu/x86/vm/templateTable_x86_32.hpp index 58f09235684..8625720c7a0 100644 --- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.hpp +++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.hpp @@ -1,5 +1,5 @@ /* - * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ Bytecodes::Code code); static void invokevirtual_helper(Register index, Register recv, Register flags); - static void volatile_barrier( ); + static void volatile_barrier(Assembler::Membar_mask_bits order_constraint ); // Helpers static void index_check(Register array, Register index); diff --git a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp index c831b0cdc38..b239d635b43 100644 --- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp @@ -25,6 +25,8 @@ #include "incls/_precompiled.incl" #include "incls/_templateTable_x86_64.cpp.incl" +#ifndef CC_INTERP + #define __ _masm-> // Platform-dependent initialization @@ -317,7 +319,7 @@ void TemplateTable::ldc(bool wide) { __ jmp(Done); __ bind(isOop); - __ movq(rax, Address(rcx, rbx, Address::times_8, base_offset)); + __ movptr(rax, Address(rcx, rbx, Address::times_8, base_offset)); __ push_ptr(rax); if (VerifyOops) { @@ -355,8 +357,8 @@ void TemplateTable::ldc2_w() { void TemplateTable::locals_index(Register reg, int offset) { __ load_unsigned_byte(reg, at_bcp(offset)); - __ negq(reg); - if (TaggedStackInterpreter) __ shlq(reg, 1); // index = index*2 + __ negptr(reg); + if (TaggedStackInterpreter) __ shlptr(reg, 1); // index = index*2 } void TemplateTable::iload() { @@ -443,7 +445,7 @@ void TemplateTable::dload() { void TemplateTable::aload() { transition(vtos, atos); locals_index(rbx); - __ movq(rax, aaddress(rbx)); + __ movptr(rax, aaddress(rbx)); debug_only(__ verify_local_tag(frame::TagReference, rbx)); } @@ -451,8 +453,8 @@ void TemplateTable::locals_index_wide(Register reg) { __ movl(reg, at_bcp(2)); __ bswapl(reg); __ shrl(reg, 16); - __ negq(reg); - if (TaggedStackInterpreter) __ shlq(reg, 1); // index = index*2 + __ negptr(reg); + if (TaggedStackInterpreter) __ shlptr(reg, 1); // index = index*2 } void TemplateTable::wide_iload() { @@ -486,7 +488,7 @@ void TemplateTable::wide_dload() { void TemplateTable::wide_aload() { transition(vtos, atos); locals_index_wide(rbx); - __ movq(rax, aaddress(rbx)); + __ movptr(rax, aaddress(rbx)); debug_only(__ verify_local_tag(frame::TagReference, rbx)); } @@ -495,7 +497,7 @@ void TemplateTable::index_check(Register array, Register index) { // check array __ null_check(array, arrayOopDesc::length_offset_in_bytes()); // sign extend index for use by indexed load - __ movslq(index, index); + __ movl2ptr(index, index); // check index __ cmpl(index, Address(array, arrayOopDesc::length_offset_in_bytes())); if (index != rbx) { @@ -642,7 +644,7 @@ void TemplateTable::dload(int n) { void TemplateTable::aload(int n) { transition(vtos, atos); - __ movq(rax, aaddress(n)); + __ movptr(rax, aaddress(n)); debug_only(__ verify_local_tag(frame::TagReference, n)); } @@ -757,7 +759,7 @@ void TemplateTable::astore() { transition(vtos, vtos); __ pop_ptr(rax, rdx); // will need to pop tag too locals_index(rbx); - __ movq(aaddress(rbx), rax); + __ movptr(aaddress(rbx), rax); __ tag_local(rdx, rbx); // store tag from stack, might be returnAddr } @@ -797,7 +799,7 @@ void TemplateTable::wide_astore() { transition(vtos, vtos); __ pop_ptr(rax, rdx); // will need to pop tag too locals_index_wide(rbx); - __ movq(aaddress(rbx), rax); + __ movptr(aaddress(rbx), rax); __ tag_local(rdx, rbx); // store tag from stack, might be returnAddr } @@ -861,25 +863,25 @@ void TemplateTable::aastore() { Label is_null, ok_is_subtype, done; transition(vtos, vtos); // stack: ..., array, index, value - __ movq(rax, at_tos()); // value + __ movptr(rax, at_tos()); // value __ movl(rcx, at_tos_p1()); // index - __ movq(rdx, at_tos_p2()); // array + __ movptr(rdx, at_tos_p2()); // array index_check(rdx, rcx); // kills rbx // do array store check - check for NULL value first - __ testq(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, is_null); // Move subklass into rbx __ load_klass(rbx, rax); // Move superklass into rax __ load_klass(rax, rdx); - __ movq(rax, Address(rax, - sizeof(oopDesc) + - objArrayKlass::element_klass_offset_in_bytes())); + __ movptr(rax, Address(rax, + sizeof(oopDesc) + + objArrayKlass::element_klass_offset_in_bytes())); // Compress array + index*oopSize + 12 into a single register. Frees rcx. - __ leaq(rdx, Address(rdx, rcx, - UseCompressedOops ? Address::times_4 : Address::times_8, - arrayOopDesc::base_offset_in_bytes(T_OBJECT))); + __ lea(rdx, Address(rdx, rcx, + UseCompressedOops ? Address::times_4 : Address::times_8, + arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // Generate subtype check. Blows rcx, rdi // Superklass in rax. Subklass in rbx. @@ -891,7 +893,7 @@ void TemplateTable::aastore() { // Come here on success __ bind(ok_is_subtype); - __ movq(rax, at_tos()); // Value + __ movptr(rax, at_tos()); // Value __ store_heap_oop(Address(rdx, 0), rax); __ store_check(rdx); __ jmp(done); @@ -906,7 +908,7 @@ void TemplateTable::aastore() { // Pop stack arguments __ bind(done); - __ addq(rsp, 3 * Interpreter::stackElementSize()); + __ addptr(rsp, 3 * Interpreter::stackElementSize()); } void TemplateTable::bastore() { @@ -968,18 +970,18 @@ void TemplateTable::dstore(int n) { void TemplateTable::astore(int n) { transition(vtos, vtos); __ pop_ptr(rax, rdx); - __ movq(aaddress(n), rax); + __ movptr(aaddress(n), rax); __ tag_local(rdx, n); } void TemplateTable::pop() { transition(vtos, vtos); - __ addq(rsp, Interpreter::stackElementSize()); + __ addptr(rsp, Interpreter::stackElementSize()); } void TemplateTable::pop2() { transition(vtos, vtos); - __ addq(rsp, 2 * Interpreter::stackElementSize()); + __ addptr(rsp, 2 * Interpreter::stackElementSize()); } void TemplateTable::dup() { @@ -1090,11 +1092,11 @@ void TemplateTable::iop2(Operation op) { void TemplateTable::lop2(Operation op) { transition(ltos, ltos); switch (op) { - case add : __ pop_l(rdx); __ addq (rax, rdx); break; - case sub : __ movq(rdx, rax); __ pop_l(rax); __ subq (rax, rdx); break; - case _and : __ pop_l(rdx); __ andq (rax, rdx); break; - case _or : __ pop_l(rdx); __ orq (rax, rdx); break; - case _xor : __ pop_l(rdx); __ xorq (rax, rdx); break; + case add : __ pop_l(rdx); __ addptr (rax, rdx); break; + case sub : __ mov(rdx, rax); __ pop_l(rax); __ subptr (rax, rdx); break; + case _and : __ pop_l(rdx); __ andptr (rax, rdx); break; + case _or : __ pop_l(rdx); __ orptr (rax, rdx); break; + case _xor : __ pop_l(rdx); __ xorptr (rax, rdx); break; default : ShouldNotReachHere(); } } @@ -1130,7 +1132,7 @@ void TemplateTable::lmul() { void TemplateTable::ldiv() { transition(ltos, ltos); - __ movq(rcx, rax); + __ mov(rcx, rax); __ pop_l(rax); // generate explicit div0 check __ testq(rcx, rcx); @@ -1145,7 +1147,7 @@ void TemplateTable::ldiv() { void TemplateTable::lrem() { transition(ltos, ltos); - __ movq(rcx, rax); + __ mov(rcx, rax); __ pop_l(rax); __ testq(rcx, rcx); __ jump_cc(Assembler::zero, @@ -1155,7 +1157,7 @@ void TemplateTable::lrem() { // needed), which may speed up this implementation for the common case. // (see also JVM spec., p.243 & p.271) __ corrected_idivq(rcx); // kills rbx - __ movq(rax, rdx); + __ mov(rax, rdx); } void TemplateTable::lshl() { @@ -1184,7 +1186,7 @@ void TemplateTable::fop2(Operation op) { switch (op) { case add: __ addss(xmm0, at_rsp()); - __ addq(rsp, Interpreter::stackElementSize()); + __ addptr(rsp, Interpreter::stackElementSize()); break; case sub: __ movflt(xmm1, xmm0); @@ -1193,7 +1195,7 @@ void TemplateTable::fop2(Operation op) { break; case mul: __ mulss(xmm0, at_rsp()); - __ addq(rsp, Interpreter::stackElementSize()); + __ addptr(rsp, Interpreter::stackElementSize()); break; case div: __ movflt(xmm1, xmm0); @@ -1216,7 +1218,7 @@ void TemplateTable::dop2(Operation op) { switch (op) { case add: __ addsd(xmm0, at_rsp()); - __ addq(rsp, 2 * Interpreter::stackElementSize()); + __ addptr(rsp, 2 * Interpreter::stackElementSize()); break; case sub: __ movdbl(xmm1, xmm0); @@ -1225,7 +1227,7 @@ void TemplateTable::dop2(Operation op) { break; case mul: __ mulsd(xmm0, at_rsp()); - __ addq(rsp, 2 * Interpreter::stackElementSize()); + __ addptr(rsp, 2 * Interpreter::stackElementSize()); break; case div: __ movdbl(xmm1, xmm0); @@ -1486,7 +1488,7 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { if (!is_wide) { __ sarl(rdx, 16); } - __ movslq(rdx, rdx); + __ movl2ptr(rdx, rdx); // Handle all the JSR stuff here, then exit. // It's much shorter and cleaner than intermingling with the non-JSR @@ -1496,11 +1498,11 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { __ load_unsigned_byte(rbx, Address(r13, rdx, Address::times_1, 0)); // compute return address as bci in rax - __ leaq(rax, at_bcp((is_wide ? 5 : 3) - + __ lea(rax, at_bcp((is_wide ? 5 : 3) - in_bytes(constMethodOopDesc::codes_offset()))); - __ subq(rax, Address(rcx, methodOopDesc::const_offset())); + __ subptr(rax, Address(rcx, methodOopDesc::const_offset())); // Adjust the bcp in r13 by the displacement in rdx - __ addq(r13, rdx); + __ addptr(r13, rdx); // jsr returns atos that is not an oop __ push_i(rax); __ dispatch_only(vtos); @@ -1510,7 +1512,7 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { // Normal (non-jsr) branch handling // Adjust the bcp in r13 by the displacement in rdx - __ addq(r13, rdx); + __ addptr(r13, rdx); assert(UseLoopCounter || !UseOnStackReplacement, "on-stack-replacement requires loop counters"); @@ -1594,25 +1596,25 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method), r13); __ load_unsigned_byte(rbx, Address(r13, 0)); // restore target bytecode - __ movq(rcx, Address(rbp, method_offset)); - __ movq(rcx, Address(rcx, - in_bytes(methodOopDesc::method_data_offset()))); - __ movq(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), - rcx); + __ movptr(rcx, Address(rbp, method_offset)); + __ movptr(rcx, Address(rcx, + in_bytes(methodOopDesc::method_data_offset()))); + __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), + rcx); __ test_method_data_pointer(rcx, dispatch); // offset non-null mdp by MDO::data_offset() + IR::profile_method() - __ addq(rcx, in_bytes(methodDataOopDesc::data_offset())); - __ addq(rcx, rax); - __ movq(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), - rcx); + __ addptr(rcx, in_bytes(methodDataOopDesc::data_offset())); + __ addptr(rcx, rax); + __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), + rcx); __ jmp(dispatch); } if (UseOnStackReplacement) { // invocation counter overflow __ bind(backedge_counter_overflow); - __ negq(rdx); - __ addq(rdx, r13); // branch bcp + __ negptr(rdx); + __ addptr(rdx, r13); // branch bcp // IcoResult frequency_counter_overflow([JavaThread*], address branch_bcp) __ call_VM(noreg, CAST_FROM_FN_PTR(address, @@ -1625,7 +1627,7 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { // rdx: scratch // r14: locals pointer // r13: bcp - __ testq(rax, rax); // test result + __ testptr(rax, rax); // test result __ jcc(Assembler::zero, dispatch); // no osr if null // nmethod may have been invalidated (VM may block upon call_VM return) __ movl(rcx, Address(rax, nmethod::entry_bci_offset())); @@ -1636,12 +1638,12 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { // We need to prepare to execute the OSR method. First we must // migrate the locals and monitors off of the stack. - __ movq(r13, rax); // save the nmethod + __ mov(r13, rax); // save the nmethod call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::OSR_migration_begin)); // eax is OSR buffer, move it to expected parameter location - __ movq(j_rarg0, rax); + __ mov(j_rarg0, rax); // We use j_rarg definitions here so that registers don't conflict as parameter // registers change across platforms as we are in the midst of a calling @@ -1651,18 +1653,18 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { const Register sender_sp = j_rarg1; // pop the interpreter frame - __ movq(sender_sp, Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp + __ movptr(sender_sp, Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp __ leave(); // remove frame anchor - __ popq(retaddr); // get return address - __ movq(rsp, sender_sp); // set sp to sender sp + __ pop(retaddr); // get return address + __ mov(rsp, sender_sp); // set sp to sender sp // Ensure compiled code always sees stack at proper alignment - __ andq(rsp, -(StackAlignmentInBytes)); + __ andptr(rsp, -(StackAlignmentInBytes)); // unlike x86 we need no specialized return from compiled code // to the interpreter or the call stub. // push the return address - __ pushq(retaddr); + __ push(retaddr); // and begin the OSR nmethod __ jmp(Address(r13, nmethod::osr_entry_point_offset())); @@ -1698,7 +1700,7 @@ void TemplateTable::if_nullcmp(Condition cc) { transition(atos, vtos); // assume branch is more often taken than not (loops use backward branches) Label not_taken; - __ testq(rax, rax); + __ testptr(rax, rax); __ jcc(j_not(cc), not_taken); branch(false, false); __ bind(not_taken); @@ -1710,7 +1712,7 @@ void TemplateTable::if_acmp(Condition cc) { // assume branch is more often taken than not (loops use backward branches) Label not_taken; __ pop_ptr(rdx); - __ cmpq(rdx, rax); + __ cmpptr(rdx, rax); __ jcc(j_not(cc), not_taken); branch(false, false); __ bind(not_taken); @@ -1720,23 +1722,23 @@ void TemplateTable::if_acmp(Condition cc) { void TemplateTable::ret() { transition(vtos, vtos); locals_index(rbx); - __ movq(rbx, aaddress(rbx)); // get return bci, compute return bcp + __ movslq(rbx, iaddress(rbx)); // get return bci, compute return bcp __ profile_ret(rbx, rcx); __ get_method(rax); - __ movq(r13, Address(rax, methodOopDesc::const_offset())); - __ leaq(r13, Address(r13, rbx, Address::times_1, - constMethodOopDesc::codes_offset())); + __ movptr(r13, Address(rax, methodOopDesc::const_offset())); + __ lea(r13, Address(r13, rbx, Address::times_1, + constMethodOopDesc::codes_offset())); __ dispatch_next(vtos); } void TemplateTable::wide_ret() { transition(vtos, vtos); locals_index_wide(rbx); - __ movq(rbx, aaddress(rbx)); // get return bci, compute return bcp + __ movptr(rbx, aaddress(rbx)); // get return bci, compute return bcp __ profile_ret(rbx, rcx); __ get_method(rax); - __ movq(r13, Address(rax, methodOopDesc::const_offset())); - __ leaq(r13, Address(r13, rbx, Address::times_1, constMethodOopDesc::codes_offset())); + __ movptr(r13, Address(rax, methodOopDesc::const_offset())); + __ lea(r13, Address(r13, rbx, Address::times_1, constMethodOopDesc::codes_offset())); __ dispatch_next(vtos); } @@ -1744,8 +1746,8 @@ void TemplateTable::tableswitch() { Label default_case, continue_execution; transition(itos, vtos); // align r13 - __ leaq(rbx, at_bcp(BytesPerInt)); - __ andq(rbx, -BytesPerInt); + __ lea(rbx, at_bcp(BytesPerInt)); + __ andptr(rbx, -BytesPerInt); // load lo & hi __ movl(rcx, Address(rbx, BytesPerInt)); __ movl(rdx, Address(rbx, 2 * BytesPerInt)); @@ -1763,9 +1765,9 @@ void TemplateTable::tableswitch() { // continue execution __ bind(continue_execution); __ bswapl(rdx); - __ movslq(rdx, rdx); + __ movl2ptr(rdx, rdx); __ load_unsigned_byte(rbx, Address(r13, rdx, Address::times_1)); - __ addq(r13, rdx); + __ addptr(r13, rdx); __ dispatch_only(vtos); // handle default __ bind(default_case); @@ -1785,10 +1787,10 @@ void TemplateTable::fast_linearswitch() { // bswap rax so we can avoid bswapping the table entries __ bswapl(rax); // align r13 - __ leaq(rbx, at_bcp(BytesPerInt)); // btw: should be able to get rid of - // this instruction (change offsets - // below) - __ andq(rbx, -BytesPerInt); + __ lea(rbx, at_bcp(BytesPerInt)); // btw: should be able to get rid of + // this instruction (change offsets + // below) + __ andptr(rbx, -BytesPerInt); // set counter __ movl(rcx, Address(rbx, BytesPerInt)); __ bswapl(rcx); @@ -1811,9 +1813,9 @@ void TemplateTable::fast_linearswitch() { // continue execution __ bind(continue_execution); __ bswapl(rdx); - __ movslq(rdx, rdx); + __ movl2ptr(rdx, rdx); __ load_unsigned_byte(rbx, Address(r13, rdx, Address::times_1)); - __ addq(r13, rdx); + __ addptr(r13, rdx); __ dispatch_only(vtos); } @@ -1853,11 +1855,11 @@ void TemplateTable::fast_binaryswitch() { const Register temp = rsi; // Find array start - __ leaq(array, at_bcp(3 * BytesPerInt)); // btw: should be able to - // get rid of this - // instruction (change - // offsets below) - __ andq(array, -BytesPerInt); + __ lea(array, at_bcp(3 * BytesPerInt)); // btw: should be able to + // get rid of this + // instruction (change + // offsets below) + __ andptr(array, -BytesPerInt); // Initialize i & j __ xorl(i, i); // i = 0; @@ -1909,9 +1911,9 @@ void TemplateTable::fast_binaryswitch() { __ movl(j , Address(array, i, Address::times_8, BytesPerInt)); __ profile_switch_case(i, key, array); __ bswapl(j); - __ movslq(j, j); + __ movl2ptr(j, j); __ load_unsigned_byte(rbx, Address(r13, j, Address::times_1)); - __ addq(r13, j); + __ addptr(r13, j); __ dispatch_only(vtos); // default case -> j = default offset @@ -1919,9 +1921,9 @@ void TemplateTable::fast_binaryswitch() { __ profile_switch_default(i); __ movl(j, Address(array, -2 * BytesPerInt)); __ bswapl(j); - __ movslq(j, j); + __ movl2ptr(j, j); __ load_unsigned_byte(rbx, Address(r13, j, Address::times_1)); - __ addq(r13, j); + __ addptr(r13, j); __ dispatch_only(vtos); } @@ -1933,7 +1935,7 @@ void TemplateTable::_return(TosState state) { if (_desc->bytecode() == Bytecodes::_return_register_finalizer) { assert(state == vtos, "only valid state"); - __ movq(c_rarg1, aaddress(0)); + __ movptr(c_rarg1, aaddress(0)); __ load_klass(rdi, c_rarg1); __ movl(rdi, Address(rdi, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc))); __ testl(rdi, JVM_ACC_HAS_FINALIZER); @@ -2044,9 +2046,9 @@ void TemplateTable::load_field_cp_cache_entry(Register obj, ByteSize cp_base_offset = constantPoolCacheOopDesc::base_offset(); // Field offset - __ movq(off, Address(cache, index, Address::times_8, - in_bytes(cp_base_offset + - ConstantPoolCacheEntry::f2_offset()))); + __ movptr(off, Address(cache, index, Address::times_8, + in_bytes(cp_base_offset + + ConstantPoolCacheEntry::f2_offset()))); // Flags __ movl(flags, Address(cache, index, Address::times_8, in_bytes(cp_base_offset + @@ -2054,9 +2056,9 @@ void TemplateTable::load_field_cp_cache_entry(Register obj, // klass overwrite register if (is_static) { - __ movq(obj, Address(cache, index, Address::times_8, - in_bytes(cp_base_offset + - ConstantPoolCacheEntry::f1_offset()))); + __ movptr(obj, Address(cache, index, Address::times_8, + in_bytes(cp_base_offset + + ConstantPoolCacheEntry::f1_offset()))); } } @@ -2088,9 +2090,9 @@ void TemplateTable::load_invoke_cp_cache_entry(int byte_no, resolve_cache_and_index(byte_no, cache, index); assert(wordSize == 8, "adjust code below"); - __ movq(method, Address(cache, index, Address::times_8, method_offset)); + __ movptr(method, Address(cache, index, Address::times_8, method_offset)); if (itable_index != noreg) { - __ movq(itable_index, + __ movptr(itable_index, Address(cache, index, Address::times_8, index_offset)); } __ movl(flags , Address(cache, index, Address::times_8, flags_offset)); @@ -2116,13 +2118,13 @@ void TemplateTable::jvmti_post_field_access(Register cache, Register index, __ get_cache_and_index_at_bcp(c_rarg2, c_rarg3, 1); // cache entry pointer - __ addq(c_rarg2, in_bytes(constantPoolCacheOopDesc::base_offset())); + __ addptr(c_rarg2, in_bytes(constantPoolCacheOopDesc::base_offset())); __ shll(c_rarg3, LogBytesPerWord); - __ addq(c_rarg2, c_rarg3); + __ addptr(c_rarg2, c_rarg3); if (is_static) { __ xorl(c_rarg1, c_rarg1); // NULL object reference } else { - __ movq(c_rarg1, at_tos()); // get object pointer without popping it + __ movptr(c_rarg1, at_tos()); // get object pointer without popping it __ verify_oop(c_rarg1); } // c_rarg1: object pointer or NULL @@ -2319,20 +2321,20 @@ void TemplateTable::jvmti_post_field_mod(Register cache, Register index, bool is // Make sure we don't need to mask rcx for tosBits after the // above shift ConstantPoolCacheEntry::verify_tosBits(); - __ movq(c_rarg1, at_tos_p1()); // initially assume a one word jvalue + __ movptr(c_rarg1, at_tos_p1()); // initially assume a one word jvalue __ cmpl(c_rarg3, ltos); - __ cmovq(Assembler::equal, - c_rarg1, at_tos_p2()); // ltos (two word jvalue) + __ cmovptr(Assembler::equal, + c_rarg1, at_tos_p2()); // ltos (two word jvalue) __ cmpl(c_rarg3, dtos); - __ cmovq(Assembler::equal, - c_rarg1, at_tos_p2()); // dtos (two word jvalue) + __ cmovptr(Assembler::equal, + c_rarg1, at_tos_p2()); // dtos (two word jvalue) } // cache entry pointer - __ addq(c_rarg2, in_bytes(cp_base_offset)); + __ addptr(c_rarg2, in_bytes(cp_base_offset)); __ shll(rscratch1, LogBytesPerWord); - __ addq(c_rarg2, rscratch1); + __ addptr(c_rarg2, rscratch1); // object (tos) - __ movq(c_rarg3, rsp); + __ mov(c_rarg3, rsp); // c_rarg1: object pointer set up above (NULL if static) // c_rarg2: cache entry pointer // c_rarg3: jvalue object on the stack @@ -2510,8 +2512,8 @@ void TemplateTable::jvmti_post_fast_field_mod() { __ pop_ptr(rbx); // copy the object pointer from tos __ verify_oop(rbx); __ push_ptr(rbx); // put the object pointer back on tos - __ subq(rsp, sizeof(jvalue)); // add space for a jvalue object - __ movq(c_rarg3, rsp); + __ subptr(rsp, sizeof(jvalue)); // add space for a jvalue object + __ mov(c_rarg3, rsp); const Address field(c_rarg3, 0); switch (bytecode()) { // load values into the jvalue object @@ -2529,7 +2531,7 @@ void TemplateTable::jvmti_post_fast_field_mod() { // Save rax because call_VM() will clobber it, then use it for // JVMTI purposes - __ pushq(rax); + __ push(rax); // access constant pool cache entry __ get_cache_entry_pointer_at_bcp(c_rarg2, rax, 1); __ verify_oop(rbx); @@ -2540,8 +2542,8 @@ void TemplateTable::jvmti_post_fast_field_mod() { CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_modification), rbx, c_rarg2, c_rarg3); - __ popq(rax); // restore lower value - __ addq(rsp, sizeof(jvalue)); // release jvalue object space + __ pop(rax); // restore lower value + __ addptr(rsp, sizeof(jvalue)); // release jvalue object space __ bind(L2); } } @@ -2562,8 +2564,8 @@ void TemplateTable::fast_storefield(TosState state) { ConstantPoolCacheEntry::flags_offset()))); // replace index with field offset from cache entry - __ movq(rbx, Address(rcx, rbx, Address::times_8, - in_bytes(base + ConstantPoolCacheEntry::f2_offset()))); + __ movptr(rbx, Address(rcx, rbx, Address::times_8, + in_bytes(base + ConstantPoolCacheEntry::f2_offset()))); // [jk] not needed currently // volatile_barrier(Assembler::Membar_mask_bits(Assembler::LoadStore | @@ -2632,15 +2634,15 @@ void TemplateTable::fast_accessfield(TosState state) { // access constant pool cache entry __ get_cache_entry_pointer_at_bcp(c_rarg2, rcx, 1); __ verify_oop(rax); - __ movq(r12, rax); // save object pointer before call_VM() clobbers it - __ movq(c_rarg1, rax); + __ mov(r12, rax); // save object pointer before call_VM() clobbers it + __ mov(c_rarg1, rax); // c_rarg1: object pointer copied above // c_rarg2: cache entry pointer __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_access), c_rarg1, c_rarg2); - __ movq(rax, r12); // restore object pointer + __ mov(rax, r12); // restore object pointer __ reinit_heapbase(); __ bind(L1); } @@ -2656,9 +2658,9 @@ void TemplateTable::fast_accessfield(TosState state) { // __ shrl(rdx, ConstantPoolCacheEntry::volatileField); // __ andl(rdx, 0x1); // } - __ movq(rbx, Address(rcx, rbx, Address::times_8, - in_bytes(constantPoolCacheOopDesc::base_offset() + - ConstantPoolCacheEntry::f2_offset()))); + __ movptr(rbx, Address(rcx, rbx, Address::times_8, + in_bytes(constantPoolCacheOopDesc::base_offset() + + ConstantPoolCacheEntry::f2_offset()))); // rax: object __ verify_oop(rax); @@ -2709,17 +2711,17 @@ void TemplateTable::fast_xaccess(TosState state) { transition(vtos, state); // get receiver - __ movq(rax, aaddress(0)); + __ movptr(rax, aaddress(0)); debug_only(__ verify_local_tag(frame::TagReference, 0)); // access constant pool cache __ get_cache_and_index_at_bcp(rcx, rdx, 2); - __ movq(rbx, - Address(rcx, rdx, Address::times_8, - in_bytes(constantPoolCacheOopDesc::base_offset() + - ConstantPoolCacheEntry::f2_offset()))); + __ movptr(rbx, + Address(rcx, rdx, Address::times_8, + in_bytes(constantPoolCacheOopDesc::base_offset() + + ConstantPoolCacheEntry::f2_offset()))); // make sure exception is reported in correct bcp range (getfield is // next instruction) - __ incrementq(r13); + __ increment(r13); __ null_check(rax); switch (state) { case itos: @@ -2749,7 +2751,7 @@ void TemplateTable::fast_xaccess(TosState state) { // __ bind(notVolatile); // } - __ decrementq(r13); + __ decrement(r13); } @@ -2788,7 +2790,7 @@ void TemplateTable::prepare_invoke(Register method, __ movl(recv, flags); __ andl(recv, 0xFF); if (TaggedStackInterpreter) __ shll(recv, 1); // index*2 - __ movq(recv, Address(rsp, recv, Address::times_8, + __ movptr(recv, Address(rsp, recv, Address::times_8, -Interpreter::expr_offset_in_bytes(1))); __ verify_oop(recv); } @@ -2811,11 +2813,11 @@ void TemplateTable::prepare_invoke(Register method, ExternalAddress return_5((address)Interpreter::return_5_addrs_by_index_table()); ExternalAddress return_3((address)Interpreter::return_3_addrs_by_index_table()); __ lea(rscratch1, (is_invokeinterface ? return_5 : return_3)); - __ movq(flags, Address(rscratch1, flags, Address::times_8)); + __ movptr(flags, Address(rscratch1, flags, Address::times_8)); } // push return address - __ pushq(flags); + __ push(flags); // Restore flag field from the constant pool cache, and restore esi // for later null checks. r13 is the bytecode pointer @@ -2867,10 +2869,10 @@ void TemplateTable::invokevirtual_helper(Register index, const int base = instanceKlass::vtable_start_offset() * wordSize; assert(vtableEntry::size() * wordSize == 8, "adjust the scaling in the code below"); - __ movq(method, Address(rax, index, + __ movptr(method, Address(rax, index, Address::times_8, base + vtableEntry::method_offset_in_bytes())); - __ movq(rdx, Address(method, methodOopDesc::interpreter_entry_offset())); + __ movptr(rdx, Address(method, methodOopDesc::interpreter_entry_offset())); __ jump_from_interpreted(method, rdx); } @@ -2940,7 +2942,7 @@ void TemplateTable::invokeinterface(int byte_no) { // profile this call __ profile_virtual_call(rdx, r13, r14); - __ movq(r14, rdx); // Save klassOop in r14 + __ mov(r14, rdx); // Save klassOop in r14 // Compute start of first itableOffsetEntry (which is at the end of // the vtable) @@ -2950,18 +2952,18 @@ void TemplateTable::invokeinterface(int byte_no) { "adjust the scaling in the code below"); __ movl(r13, Address(rdx, instanceKlass::vtable_length_offset() * wordSize)); - __ leaq(rdx, Address(rdx, r13, Address::times_8, base)); + __ lea(rdx, Address(rdx, r13, Address::times_8, base)); if (HeapWordsPerLong > 1) { // Round up to align_object_offset boundary - __ round_to_q(rdx, BytesPerLong); + __ round_to(rdx, BytesPerLong); } Label entry, search, interface_ok; __ jmpb(entry); __ bind(search); - __ addq(rdx, itableOffsetEntry::size() * wordSize); + __ addptr(rdx, itableOffsetEntry::size() * wordSize); __ bind(entry); @@ -2969,13 +2971,13 @@ void TemplateTable::invokeinterface(int byte_no) { // receiver class doesn't implement the interface, and wasn't the // same as the receiver class checked when the interface was // resolved. - __ pushq(rdx); - __ movq(rdx, Address(rdx, itableOffsetEntry::interface_offset_in_bytes())); - __ testq(rdx, rdx); + __ push(rdx); + __ movptr(rdx, Address(rdx, itableOffsetEntry::interface_offset_in_bytes())); + __ testptr(rdx, rdx); __ jcc(Assembler::notZero, interface_ok); // throw exception - __ popq(rdx); // pop saved register first. - __ popq(rbx); // pop return address (pushed by prepare_invoke) + __ pop(rdx); // pop saved register first. + __ pop(rbx); // pop return address (pushed by prepare_invoke) __ restore_bcp(); // r13 must be correct for exception handler (was // destroyed) __ restore_locals(); // make sure locals pointer is correct as well @@ -2986,17 +2988,17 @@ void TemplateTable::invokeinterface(int byte_no) { __ should_not_reach_here(); __ bind(interface_ok); - __ popq(rdx); + __ pop(rdx); - __ cmpq(rax, Address(rdx, itableOffsetEntry::interface_offset_in_bytes())); + __ cmpptr(rax, Address(rdx, itableOffsetEntry::interface_offset_in_bytes())); __ jcc(Assembler::notEqual, search); __ movl(rdx, Address(rdx, itableOffsetEntry::offset_offset_in_bytes())); - __ addq(rdx, r14); // Add offset to klassOop + __ addptr(rdx, r14); // Add offset to klassOop assert(itableMethodEntry::size() * wordSize == 8, "adjust the scaling in the code below"); - __ movq(rbx, Address(rdx, rbx, Address::times_8)); + __ movptr(rbx, Address(rdx, rbx, Address::times_8)); // rbx: methodOop to call // rcx: receiver // Check for abstract method error @@ -3005,12 +3007,12 @@ void TemplateTable::invokeinterface(int byte_no) { // conditional jump to it in case of a null method. { Label L; - __ testq(rbx, rbx); + __ testptr(rbx, rbx); __ jcc(Assembler::notZero, L); // throw exception // note: must restore interpreter registers to canonical // state for exception handling to work correctly! - __ popq(rbx); // pop return address (pushed by prepare_invoke) + __ pop(rbx); // pop return address (pushed by prepare_invoke) __ restore_bcp(); // r13 must be correct for exception handler // (was destroyed) __ restore_locals(); // make sure locals pointer is correct as @@ -3023,7 +3025,7 @@ void TemplateTable::invokeinterface(int byte_no) { __ bind(L); } - __ movq(rcx, Address(rbx, methodOopDesc::interpreter_entry_offset())); + __ movptr(rcx, Address(rbx, methodOopDesc::interpreter_entry_offset())); // do the call // rcx: receiver @@ -3047,8 +3049,8 @@ void TemplateTable::_new() { __ get_cpool_and_tags(rsi, rax); // get instanceKlass - __ movq(rsi, Address(rsi, rdx, - Address::times_8, sizeof(constantPoolOopDesc))); + __ movptr(rsi, Address(rsi, rdx, + Address::times_8, sizeof(constantPoolOopDesc))); // make sure the class we're about to instantiate has been // resolved. Note: slow_case does a pop of stack, which is why we @@ -3084,11 +3086,11 @@ void TemplateTable::_new() { Universe::heap()->supports_inline_contig_alloc() && !CMSIncrementalMode; if (UseTLAB) { - __ movq(rax, Address(r15_thread, in_bytes(JavaThread::tlab_top_offset()))); - __ leaq(rbx, Address(rax, rdx, Address::times_1)); - __ cmpq(rbx, Address(r15_thread, in_bytes(JavaThread::tlab_end_offset()))); + __ movptr(rax, Address(r15_thread, in_bytes(JavaThread::tlab_top_offset()))); + __ lea(rbx, Address(rax, rdx, Address::times_1)); + __ cmpptr(rbx, Address(r15_thread, in_bytes(JavaThread::tlab_end_offset()))); __ jcc(Assembler::above, allow_shared_alloc ? allocate_shared : slow_case); - __ movq(Address(r15_thread, in_bytes(JavaThread::tlab_top_offset())), rbx); + __ movptr(Address(r15_thread, in_bytes(JavaThread::tlab_top_offset())), rbx); if (ZeroTLAB) { // the fields have been already cleared __ jmp(initialize_header); @@ -3109,13 +3111,13 @@ void TemplateTable::_new() { __ lea(RtopAddr, top); __ lea(RendAddr, end); - __ movq(rax, Address(RtopAddr, 0)); + __ movptr(rax, Address(RtopAddr, 0)); // For retries rax gets set by cmpxchgq Label retry; __ bind(retry); - __ leaq(rbx, Address(rax, rdx, Address::times_1)); - __ cmpq(rbx, Address(RendAddr, 0)); + __ lea(rbx, Address(rax, rdx, Address::times_1)); + __ cmpptr(rbx, Address(RendAddr, 0)); __ jcc(Assembler::above, slow_case); // Compare rax with the top addr, and if still equal, store the new @@ -3128,7 +3130,7 @@ void TemplateTable::_new() { if (os::is_MP()) { __ lock(); } - __ cmpxchgq(rbx, Address(RtopAddr, 0)); + __ cmpxchgptr(rbx, Address(RtopAddr, 0)); // if someone beat us on the allocation, try again, otherwise continue __ jcc(Assembler::notEqual, retry); @@ -3157,8 +3159,8 @@ void TemplateTable::_new() { // initialize object header only. __ bind(initialize_header); if (UseBiasedLocking) { - __ movq(rscratch1, Address(rsi, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); - __ movq(Address(rax, oopDesc::mark_offset_in_bytes()), rscratch1); + __ movptr(rscratch1, Address(rsi, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + __ movptr(Address(rax, oopDesc::mark_offset_in_bytes()), rscratch1); } else { __ movptr(Address(rax, oopDesc::mark_offset_in_bytes()), (intptr_t) markOopDesc::prototype()); // header (address 0x1) @@ -3215,7 +3217,7 @@ void TemplateTable::arraylength() { void TemplateTable::checkcast() { transition(atos, atos); Label done, is_null, ok_is_subtype, quicked, resolved; - __ testq(rax, rax); // object is in rax + __ testptr(rax, rax); // object is in rax __ jcc(Assembler::zero, is_null); // Get cpool & tags index @@ -3228,7 +3230,7 @@ void TemplateTable::checkcast() { JVM_CONSTANT_Class); __ jcc(Assembler::equal, quicked); __ push(atos); // save receiver for result, and for GC - __ movq(r12, rcx); // save rcx XXX + __ mov(r12, rcx); // save rcx XXX call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc)); __ movq(rcx, r12); // restore rcx XXX __ reinit_heapbase(); @@ -3237,8 +3239,8 @@ void TemplateTable::checkcast() { // Get superklass in rax and subklass in rbx __ bind(quicked); - __ movq(rdx, rax); // Save object in rdx; rax needed for subtype check - __ movq(rax, Address(rcx, rbx, + __ mov(rdx, rax); // Save object in rdx; rax needed for subtype check + __ movptr(rax, Address(rcx, rbx, Address::times_8, sizeof(constantPoolOopDesc))); __ bind(resolved); @@ -3255,7 +3257,7 @@ void TemplateTable::checkcast() { // Come here on success __ bind(ok_is_subtype); - __ movq(rax, rdx); // Restore object in rdx + __ mov(rax, rdx); // Restore object in rdx // Collect counts on whether this check-cast sees NULLs a lot or not. if (ProfileInterpreter) { @@ -3271,7 +3273,7 @@ void TemplateTable::checkcast() { void TemplateTable::instanceof() { transition(atos, itos); Label done, is_null, ok_is_subtype, quicked, resolved; - __ testq(rax, rax); + __ testptr(rax, rax); __ jcc(Assembler::zero, is_null); // Get cpool & tags index @@ -3285,7 +3287,7 @@ void TemplateTable::instanceof() { __ jcc(Assembler::equal, quicked); __ push(atos); // save receiver for result, and for GC - __ movq(r12, rcx); // save rcx + __ mov(r12, rcx); // save rcx call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc)); __ movq(rcx, r12); // restore rcx __ reinit_heapbase(); @@ -3296,8 +3298,8 @@ void TemplateTable::instanceof() { // Get superklass in rax and subklass in rdx __ bind(quicked); __ load_klass(rdx, rax); - __ movq(rax, Address(rcx, rbx, - Address::times_8, sizeof(constantPoolOopDesc))); + __ movptr(rax, Address(rcx, rbx, + Address::times_8, sizeof(constantPoolOopDesc))); __ bind(resolved); @@ -3340,7 +3342,7 @@ void TemplateTable::_breakpoint() { CAST_FROM_FN_PTR(address, InterpreterRuntime::get_original_bytecode_at), c_rarg1, r13); - __ movq(rbx, rax); + __ mov(rbx, rax); // post the breakpoint event __ get_method(c_rarg1); @@ -3398,52 +3400,52 @@ void TemplateTable::monitorenter() { // find a free slot in the monitor block (result in c_rarg1) { Label entry, loop, exit; - __ movq(c_rarg3, monitor_block_top); // points to current entry, + __ movptr(c_rarg3, monitor_block_top); // points to current entry, // starting with top-most entry - __ leaq(c_rarg2, monitor_block_bot); // points to word before bottom + __ lea(c_rarg2, monitor_block_bot); // points to word before bottom // of monitor block __ jmpb(entry); __ bind(loop); // check if current entry is used - __ cmpq(Address(c_rarg3, BasicObjectLock::obj_offset_in_bytes()), (int) NULL); + __ cmpptr(Address(c_rarg3, BasicObjectLock::obj_offset_in_bytes()), (int32_t) NULL_WORD); // if not used then remember entry in c_rarg1 - __ cmovq(Assembler::equal, c_rarg1, c_rarg3); + __ cmov(Assembler::equal, c_rarg1, c_rarg3); // check if current entry is for same object - __ cmpq(rax, Address(c_rarg3, BasicObjectLock::obj_offset_in_bytes())); + __ cmpptr(rax, Address(c_rarg3, BasicObjectLock::obj_offset_in_bytes())); // if same object then stop searching __ jccb(Assembler::equal, exit); // otherwise advance to next entry - __ addq(c_rarg3, entry_size); + __ addptr(c_rarg3, entry_size); __ bind(entry); // check if bottom reached - __ cmpq(c_rarg3, c_rarg2); + __ cmpptr(c_rarg3, c_rarg2); // if not at bottom then check this entry __ jcc(Assembler::notEqual, loop); __ bind(exit); } - __ testq(c_rarg1, c_rarg1); // check if a slot has been found + __ testptr(c_rarg1, c_rarg1); // check if a slot has been found __ jcc(Assembler::notZero, allocated); // if found, continue with that one // allocate one if there's no free slot { Label entry, loop; - // 1. compute new pointers // rsp: old expression stack top - __ movq(c_rarg1, monitor_block_bot); // c_rarg1: old expression stack bottom - __ subq(rsp, entry_size); // move expression stack top - __ subq(c_rarg1, entry_size); // move expression stack bottom - __ movq(c_rarg3, rsp); // set start value for copy loop - __ movq(monitor_block_bot, c_rarg1); // set new monitor block bottom + // 1. compute new pointers // rsp: old expression stack top + __ movptr(c_rarg1, monitor_block_bot); // c_rarg1: old expression stack bottom + __ subptr(rsp, entry_size); // move expression stack top + __ subptr(c_rarg1, entry_size); // move expression stack bottom + __ mov(c_rarg3, rsp); // set start value for copy loop + __ movptr(monitor_block_bot, c_rarg1); // set new monitor block bottom __ jmp(entry); // 2. move expression stack contents __ bind(loop); - __ movq(c_rarg2, Address(c_rarg3, entry_size)); // load expression stack - // word from old location - __ movq(Address(c_rarg3, 0), c_rarg2); // and store it at new location - __ addq(c_rarg3, wordSize); // advance to next word + __ movptr(c_rarg2, Address(c_rarg3, entry_size)); // load expression stack + // word from old location + __ movptr(Address(c_rarg3, 0), c_rarg2); // and store it at new location + __ addptr(c_rarg3, wordSize); // advance to next word __ bind(entry); - __ cmpq(c_rarg3, c_rarg1); // check if bottom reached + __ cmpptr(c_rarg3, c_rarg1); // check if bottom reached __ jcc(Assembler::notEqual, loop); // if not at bottom then // copy next word } @@ -3456,10 +3458,10 @@ void TemplateTable::monitorenter() { // handling for async. exceptions work correctly. // The object has already been poped from the stack, so the // expression stack looks correct. - __ incrementq(r13); + __ increment(r13); // store object - __ movq(Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes()), rax); + __ movptr(Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes()), rax); __ lock_object(c_rarg1); // check to make sure this monitor doesn't cause stack overflow after locking @@ -3489,22 +3491,22 @@ void TemplateTable::monitorexit() { // find matching slot { Label entry, loop; - __ movq(c_rarg1, monitor_block_top); // points to current entry, + __ movptr(c_rarg1, monitor_block_top); // points to current entry, // starting with top-most entry - __ leaq(c_rarg2, monitor_block_bot); // points to word before bottom + __ lea(c_rarg2, monitor_block_bot); // points to word before bottom // of monitor block __ jmpb(entry); __ bind(loop); // check if current entry is for same object - __ cmpq(rax, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes())); + __ cmpptr(rax, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes())); // if same object then stop searching __ jcc(Assembler::equal, found); // otherwise advance to next entry - __ addq(c_rarg1, entry_size); + __ addptr(c_rarg1, entry_size); __ bind(entry); // check if bottom reached - __ cmpq(c_rarg1, c_rarg2); + __ cmpptr(c_rarg1, c_rarg2); // if not at bottom then check this entry __ jcc(Assembler::notEqual, loop); } @@ -3541,11 +3543,12 @@ void TemplateTable::multianewarray() { // last dim is on top of stack; we want address of first one: // first_addr = last_addr + (ndims - 1) * wordSize if (TaggedStackInterpreter) __ shll(rax, 1); // index*2 - __ leaq(c_rarg1, Address(rsp, rax, Address::times_8, -wordSize)); + __ lea(c_rarg1, Address(rsp, rax, Address::times_8, -wordSize)); call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::multianewarray), c_rarg1); __ load_unsigned_byte(rbx, at_bcp(3)); if (TaggedStackInterpreter) __ shll(rbx, 1); // index*2 - __ leaq(rsp, Address(rsp, rbx, Address::times_8)); + __ lea(rsp, Address(rsp, rbx, Address::times_8)); } +#endif // !CC_INTERP diff --git a/hotspot/src/cpu/x86/vm/vm_version_x86_32.cpp b/hotspot/src/cpu/x86/vm/vm_version_x86_32.cpp index d65cc0cc3e6..839a4cdaeda 100644 --- a/hotspot/src/cpu/x86/vm/vm_version_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/vm_version_x86_32.cpp @@ -67,23 +67,23 @@ class VM_Version_StubGenerator: public StubCodeGenerator { // // void getPsrInfo(VM_Version::CpuidInfo* cpuid_info); // - __ pushl(rbp); - __ movl(rbp, Address(rsp, 8)); // cpuid_info address - __ pushl(rbx); - __ pushl(rsi); - __ pushfd(); // preserve rbx, and flags - __ popl(rax); - __ pushl(rax); - __ movl(rcx, rax); + __ push(rbp); + __ movptr(rbp, Address(rsp, 8)); // cpuid_info address + __ push(rbx); + __ push(rsi); + __ pushf(); // preserve rbx, and flags + __ pop(rax); + __ push(rax); + __ mov(rcx, rax); // // if we are unable to change the AC flag, we have a 386 // __ xorl(rax, EFL_AC); - __ pushl(rax); - __ popfd(); - __ pushfd(); - __ popl(rax); - __ cmpl(rax, rcx); + __ push(rax); + __ popf(); + __ pushf(); + __ pop(rax); + __ cmpptr(rax, rcx); __ jccb(Assembler::notEqual, detect_486); __ movl(rax, CPU_FAMILY_386); @@ -95,13 +95,13 @@ class VM_Version_StubGenerator: public StubCodeGenerator { // not support the "cpuid" instruction. // __ bind(detect_486); - __ movl(rax, rcx); + __ mov(rax, rcx); __ xorl(rax, EFL_ID); - __ pushl(rax); - __ popfd(); - __ pushfd(); - __ popl(rax); - __ cmpl(rcx, rax); + __ push(rax); + __ popf(); + __ pushf(); + __ pop(rax); + __ cmpptr(rcx, rax); __ jccb(Assembler::notEqual, detect_586); __ bind(cpu486); @@ -113,13 +113,13 @@ class VM_Version_StubGenerator: public StubCodeGenerator { // at this point, we have a chip which supports the "cpuid" instruction // __ bind(detect_586); - __ xorl(rax, rax); + __ xorptr(rax, rax); __ cpuid(); - __ orl(rax, rax); + __ orptr(rax, rax); __ jcc(Assembler::equal, cpu486); // if cpuid doesn't support an input // value of at least 1, we give up and // assume a 486 - __ leal(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid0_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid0_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -134,13 +134,13 @@ class VM_Version_StubGenerator: public StubCodeGenerator { __ movl(rax, 4); // and rcx already set to 0x0 __ xorl(rcx, rcx); __ cpuid(); - __ pushl(rax); + __ push(rax); __ andl(rax, 0x1f); // Determine if valid cache parameters used __ orl(rax, rax); // rax,[4:0] == 0 indicates invalid cache - __ popl(rax); + __ pop(rax); __ jccb(Assembler::equal, std_cpuid1); - __ leal(rsi, Address(rbp, in_bytes(VM_Version::dcp_cpuid4_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::dcp_cpuid4_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -152,7 +152,7 @@ class VM_Version_StubGenerator: public StubCodeGenerator { __ bind(std_cpuid1); __ movl(rax, 1); __ cpuid(); - __ leal(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid1_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid1_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -171,7 +171,7 @@ class VM_Version_StubGenerator: public StubCodeGenerator { // __ movl(rax, 0x80000008); __ cpuid(); - __ leal(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid8_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid8_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -183,7 +183,7 @@ class VM_Version_StubGenerator: public StubCodeGenerator { __ bind(ext_cpuid5); __ movl(rax, 0x80000005); __ cpuid(); - __ leal(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid5_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid5_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -195,7 +195,7 @@ class VM_Version_StubGenerator: public StubCodeGenerator { __ bind(ext_cpuid1); __ movl(rax, 0x80000001); __ cpuid(); - __ leal(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid1_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid1_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -205,10 +205,10 @@ class VM_Version_StubGenerator: public StubCodeGenerator { // return // __ bind(done); - __ popfd(); - __ popl(rsi); - __ popl(rbx); - __ popl(rbp); + __ popf(); + __ pop(rsi); + __ pop(rbx); + __ pop(rbp); __ ret(0); # undef __ diff --git a/hotspot/src/cpu/x86/vm/vm_version_x86_64.cpp b/hotspot/src/cpu/x86/vm/vm_version_x86_64.cpp index 71be1f8a20e..709d82e6e68 100644 --- a/hotspot/src/cpu/x86/vm/vm_version_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/vm_version_x86_64.cpp @@ -60,17 +60,17 @@ class VM_Version_StubGenerator: public StubCodeGenerator { // // rcx and rdx are first and second argument registers on windows - __ pushq(rbp); - __ movq(rbp, c_rarg0); // cpuid_info address - __ pushq(rbx); - __ pushq(rsi); + __ push(rbp); + __ mov(rbp, c_rarg0); // cpuid_info address + __ push(rbx); + __ push(rsi); // // we have a chip which supports the "cpuid" instruction // __ xorl(rax, rax); __ cpuid(); - __ leaq(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid0_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid0_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -85,13 +85,13 @@ class VM_Version_StubGenerator: public StubCodeGenerator { __ movl(rax, 4); __ xorl(rcx, rcx); // L1 cache __ cpuid(); - __ pushq(rax); + __ push(rax); __ andl(rax, 0x1f); // Determine if valid cache parameters used __ orl(rax, rax); // eax[4:0] == 0 indicates invalid cache - __ popq(rax); + __ pop(rax); __ jccb(Assembler::equal, std_cpuid1); - __ leaq(rsi, Address(rbp, in_bytes(VM_Version::dcp_cpuid4_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::dcp_cpuid4_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -103,7 +103,7 @@ class VM_Version_StubGenerator: public StubCodeGenerator { __ bind(std_cpuid1); __ movl(rax, 1); __ cpuid(); - __ leaq(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid1_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid1_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -122,7 +122,7 @@ class VM_Version_StubGenerator: public StubCodeGenerator { // __ movl(rax, 0x80000008); __ cpuid(); - __ leaq(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid8_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid8_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -134,7 +134,7 @@ class VM_Version_StubGenerator: public StubCodeGenerator { __ bind(ext_cpuid5); __ movl(rax, 0x80000005); __ cpuid(); - __ leaq(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid5_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid5_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -146,7 +146,7 @@ class VM_Version_StubGenerator: public StubCodeGenerator { __ bind(ext_cpuid1); __ movl(rax, 0x80000001); __ cpuid(); - __ leaq(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid1_offset()))); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid1_offset()))); __ movl(Address(rsi, 0), rax); __ movl(Address(rsi, 4), rbx); __ movl(Address(rsi, 8), rcx); @@ -156,9 +156,9 @@ class VM_Version_StubGenerator: public StubCodeGenerator { // return // __ bind(done); - __ popq(rsi); - __ popq(rbx); - __ popq(rbp); + __ pop(rsi); + __ pop(rbx); + __ pop(rbp); __ ret(0); # undef __ diff --git a/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp b/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp index 09d37901e61..c077929db1a 100644 --- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,7 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { #ifndef PRODUCT if (CountCompiledCalls) { - __ increment(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr())); + __ incrementl(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr())); } #endif /* PRODUCT */ @@ -58,7 +58,7 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { // get receiver klass address npe_addr = __ pc(); - __ movl(rax, Address(rcx, oopDesc::klass_offset_in_bytes())); + __ movptr(rax, Address(rcx, oopDesc::klass_offset_in_bytes())); // compute entry offset (in words) int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size(); #ifndef PRODUCT @@ -76,12 +76,12 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { const Register method = rbx; // load methodOop and target address - __ movl(method, Address(rax, entry_offset*wordSize + vtableEntry::method_offset_in_bytes())); + __ movptr(method, Address(rax, entry_offset*wordSize + vtableEntry::method_offset_in_bytes())); if (DebugVtables) { Label L; - __ cmpl(method, NULL_WORD); + __ cmpptr(method, (int32_t)NULL_WORD); __ jcc(Assembler::equal, L); - __ cmpl(Address(method, methodOopDesc::from_compiled_offset()), NULL_WORD); + __ cmpptr(Address(method, methodOopDesc::from_compiled_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::notZero, L); __ stop("Vtable entry is NULL"); __ bind(L); @@ -114,7 +114,7 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { #ifndef PRODUCT if (CountCompiledCalls) { - __ increment(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr())); + __ incrementl(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr())); } #endif /* PRODUCT */ // get receiver (need to skip return address on top of stack) @@ -123,16 +123,16 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { // get receiver klass (also an implicit null-check) address npe_addr = __ pc(); - __ movl(rbx, Address(rcx, oopDesc::klass_offset_in_bytes())); + __ movptr(rbx, Address(rcx, oopDesc::klass_offset_in_bytes())); - __ movl(rsi, rbx); // Save klass in free register + __ mov(rsi, rbx); // Save klass in free register // Most registers are in use, so save a few - __ pushl(rdx); + __ push(rdx); // compute itable entry offset (in words) const int base = instanceKlass::vtable_start_offset() * wordSize; assert(vtableEntry::size() * wordSize == 4, "adjust the scaling in the code below"); __ movl(rdx, Address(rbx, instanceKlass::vtable_length_offset() * wordSize)); // Get length of vtable - __ leal(rbx, Address(rbx, rdx, Address::times_4, base)); + __ lea(rbx, Address(rbx, rdx, Address::times_ptr, base)); if (HeapWordsPerLong > 1) { // Round up to align_object_offset boundary __ round_to(rbx, BytesPerLong); @@ -143,16 +143,16 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { __ jmpb(entry); __ bind(next); - __ addl(rbx, itableOffsetEntry::size() * wordSize); + __ addptr(rbx, itableOffsetEntry::size() * wordSize); __ bind(entry); // If the entry is NULL then we've reached the end of the table // without finding the expected interface, so throw an exception - __ movl(rdx, Address(rbx, itableOffsetEntry::interface_offset_in_bytes())); - __ testl(rdx, rdx); + __ movptr(rdx, Address(rbx, itableOffsetEntry::interface_offset_in_bytes())); + __ testptr(rdx, rdx); __ jcc(Assembler::zero, throw_icce); - __ cmpl(rax, rdx); + __ cmpptr(rax, rdx); __ jcc(Assembler::notEqual, next); // We found a hit, move offset into rbx, @@ -163,10 +163,10 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { // Get methodOop and entrypoint for compiler const Register method = rbx; - __ movl(method, Address(rsi, rdx, Address::times_1, method_offset)); + __ movptr(method, Address(rsi, rdx, Address::times_1, method_offset)); // Restore saved register, before possible trap. - __ popl(rdx); + __ pop(rdx); // method (rbx): methodOop // rcx: receiver @@ -174,9 +174,9 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { #ifdef ASSERT if (DebugVtables) { Label L1; - __ cmpl(method, NULL_WORD); + __ cmpptr(method, (int32_t)NULL_WORD); __ jcc(Assembler::equal, L1); - __ cmpl(Address(method, methodOopDesc::from_compiled_offset()), NULL_WORD); + __ cmpptr(Address(method, methodOopDesc::from_compiled_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::notZero, L1); __ stop("methodOop is null"); __ bind(L1); @@ -188,7 +188,7 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { __ bind(throw_icce); // Restore saved register - __ popl(rdx); + __ pop(rdx); __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry())); masm->flush(); diff --git a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp index 931b3aa900a..7ae875b73cc 100644 --- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp @@ -79,14 +79,14 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { // load methodOop and target address const Register method = rbx; - __ movq(method, Address(rax, - entry_offset * wordSize + - vtableEntry::method_offset_in_bytes())); + __ movptr(method, Address(rax, + entry_offset * wordSize + + vtableEntry::method_offset_in_bytes())); if (DebugVtables) { Label L; - __ cmpq(method, (int)NULL); + __ cmpptr(method, (int32_t)NULL_WORD); __ jcc(Assembler::equal, L); - __ cmpq(Address(method, methodOopDesc::from_compiled_offset()), (int)NULL_WORD); + __ cmpptr(Address(method, methodOopDesc::from_compiled_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::notZero, L); __ stop("Vtable entry is NULL"); __ bind(L); @@ -138,7 +138,7 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { // when there are mistakes in this assembly code that could generate // a spurious fault. Ask me how I know... - __ pushq(j_rarg1); // Most registers are in use, so save one + __ push(j_rarg1); // Most registers are in use, so save one // compute itable entry offset (in words) const int base = instanceKlass::vtable_start_offset() * wordSize; @@ -147,27 +147,27 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { // Get length of vtable __ movl(j_rarg1, Address(rbx, instanceKlass::vtable_length_offset() * wordSize)); - __ leaq(rbx, Address(rbx, j_rarg1, Address::times_8, base)); + __ lea(rbx, Address(rbx, j_rarg1, Address::times_8, base)); if (HeapWordsPerLong > 1) { // Round up to align_object_offset boundary - __ round_to_q(rbx, BytesPerLong); + __ round_to(rbx, BytesPerLong); } Label hit, next, entry, throw_icce; __ jmpb(entry); __ bind(next); - __ addq(rbx, itableOffsetEntry::size() * wordSize); + __ addptr(rbx, itableOffsetEntry::size() * wordSize); __ bind(entry); // If the entry is NULL then we've reached the end of the table // without finding the expected interface, so throw an exception - __ movq(j_rarg1, Address(rbx, itableOffsetEntry::interface_offset_in_bytes())); - __ testq(j_rarg1, j_rarg1); + __ movptr(j_rarg1, Address(rbx, itableOffsetEntry::interface_offset_in_bytes())); + __ testptr(j_rarg1, j_rarg1); __ jcc(Assembler::zero, throw_icce); - __ cmpq(rax, j_rarg1); + __ cmpptr(rax, j_rarg1); __ jccb(Assembler::notEqual, next); // We found a hit, move offset into j_rarg1 @@ -184,10 +184,10 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { __ load_klass(rax, j_rarg0); const Register method = rbx; - __ movq(method, Address(rax, j_rarg1, Address::times_1, method_offset)); + __ movptr(method, Address(rax, j_rarg1, Address::times_1, method_offset)); // Restore saved register, before possible trap. - __ popq(j_rarg1); + __ pop(j_rarg1); // method (rbx): methodOop // j_rarg0: receiver @@ -196,9 +196,9 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { #ifdef ASSERT if (DebugVtables) { Label L2; - __ cmpq(method, (int)NULL); + __ cmpptr(method, (int32_t)NULL_WORD); __ jcc(Assembler::equal, L2); - __ cmpq(Address(method, methodOopDesc::from_compiled_offset()), (int)NULL_WORD); + __ cmpptr(Address(method, methodOopDesc::from_compiled_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::notZero, L2); __ stop("compiler entrypoint is null"); __ bind(L2); @@ -212,7 +212,7 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { __ bind(throw_icce); // Restore saved register - __ popq(j_rarg1); + __ pop(j_rarg1); __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry())); __ flush(); diff --git a/hotspot/src/cpu/x86/vm/x86_32.ad b/hotspot/src/cpu/x86/vm/x86_32.ad index 35db833e9ef..a4a4199312d 100644 --- a/hotspot/src/cpu/x86/vm/x86_32.ad +++ b/hotspot/src/cpu/x86/vm/x86_32.ad @@ -236,7 +236,7 @@ reg_class xdb_reg7( XMM7a,XMM7b ); // This is a block of C++ code which provides values, functions, and // definitions necessary in the rest of the architecture description source %{ -#define RELOC_IMM32 Assembler::imm32_operand +#define RELOC_IMM32 Assembler::imm_operand #define RELOC_DISP32 Assembler::disp32_operand #define __ _masm. @@ -593,11 +593,11 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { if (VerifyStackAtCalls) { Label L; MacroAssembler masm(&cbuf); - masm.pushl(rax); - masm.movl(rax, rsp); - masm.andl(rax, StackAlignmentInBytes-1); - masm.cmpl(rax, StackAlignmentInBytes-wordSize); - masm.popl(rax); + masm.push(rax); + masm.mov(rax, rsp); + masm.andptr(rax, StackAlignmentInBytes-1); + masm.cmpptr(rax, StackAlignmentInBytes-wordSize); + masm.pop(rax); masm.jcc(Assembler::equal, L); masm.stop("Stack is not properly aligned!"); masm.bind(L); @@ -1150,7 +1150,8 @@ void emit_java_to_interp(CodeBuffer &cbuf ) { __ relocate(static_stub_Relocation::spec(mark), RELOC_IMM32); // static stub relocation also tags the methodOop in the code-stream. __ movoop(rbx, (jobject)NULL); // method is zapped till fixup time - __ jump(RuntimeAddress((address)-1)); + // This is recognized as unresolved by relocs/nativeInst/ic code + __ jump(RuntimeAddress(__ pc())); __ end_a_stub(); // Update current stubs pointer and restore code_end. @@ -1181,7 +1182,7 @@ void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { #ifdef ASSERT uint code_size = cbuf.code_size(); #endif - masm.cmpl(rax, Address(rcx, oopDesc::klass_offset_in_bytes())); + masm.cmpptr(rax, Address(rcx, oopDesc::klass_offset_in_bytes())); masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); /* WARNING these NOPs are critical so that verified entry point is properly @@ -1687,20 +1688,20 @@ encode %{ // Compare super with sub directly, since super is not in its own SSA. // The compiler used to emit this test, but we fold it in here, // to allow platform-specific tweaking on sparc. - __ cmpl(Reax, Resi); + __ cmpptr(Reax, Resi); __ jcc(Assembler::equal, hit); #ifndef PRODUCT - __ increment(ExternalAddress((address)&SharedRuntime::_partial_subtype_ctr)); + __ incrementl(ExternalAddress((address)&SharedRuntime::_partial_subtype_ctr)); #endif //PRODUCT - __ movl(Redi,Address(Resi,sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())); + __ movptr(Redi,Address(Resi,sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())); __ movl(Recx,Address(Redi,arrayOopDesc::length_offset_in_bytes())); - __ addl(Redi,arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + __ addptr(Redi,arrayOopDesc::base_offset_in_bytes(T_OBJECT)); __ repne_scan(); __ jcc(Assembler::notEqual, miss); - __ movl(Address(Resi,sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()),Reax); + __ movptr(Address(Resi,sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()),Reax); __ bind(hit); if( $primary ) - __ xorl(Redi,Redi); + __ xorptr(Redi,Redi); __ bind(miss); %} @@ -1749,15 +1750,15 @@ encode %{ // optimizer if the C function is a pure function. __ ffree(0); } else if (rt == T_FLOAT) { - __ leal(rsp, Address(rsp, -4)); + __ lea(rsp, Address(rsp, -4)); __ fstp_s(Address(rsp, 0)); __ movflt(xmm0, Address(rsp, 0)); - __ leal(rsp, Address(rsp, 4)); + __ lea(rsp, Address(rsp, 4)); } else if (rt == T_DOUBLE) { - __ leal(rsp, Address(rsp, -8)); + __ lea(rsp, Address(rsp, -8)); __ fstp_d(Address(rsp, 0)); __ movdbl(xmm0, Address(rsp, 0)); - __ leal(rsp, Address(rsp, 8)); + __ lea(rsp, Address(rsp, 8)); } } %} @@ -2888,10 +2889,10 @@ encode %{ __ jccb(Assembler::equal, done); __ jccb(Assembler::above, inc); __ bind(nan); - __ decrement(as_Register($dst$$reg)); + __ decrement(as_Register($dst$$reg)); // NO L qqq __ jmpb(done); __ bind(inc); - __ increment(as_Register($dst$$reg)); + __ increment(as_Register($dst$$reg)); // NO L qqq __ bind(done); %} @@ -3158,7 +3159,7 @@ encode %{ enc_class mov_i2x(regXD dst, eRegI src) %{ MacroAssembler _masm(&cbuf); - __ movd(as_XMMRegister($dst$$reg), as_Register($src$$reg)); + __ movdl(as_XMMRegister($dst$$reg), as_Register($src$$reg)); %} @@ -3258,30 +3259,30 @@ encode %{ } if (EmitSync & 1) { // set box->dhw = unused_mark (3) - // Force all sync thru slow-path: slow_enter() and slow_exit() - masm.movl (Address(boxReg, 0), intptr_t(markOopDesc::unused_mark())) ; - masm.cmpl (rsp, 0) ; - } else - if (EmitSync & 2) { - Label DONE_LABEL ; + // Force all sync thru slow-path: slow_enter() and slow_exit() + masm.movptr (Address(boxReg, 0), int32_t(markOopDesc::unused_mark())) ; + masm.cmpptr (rsp, (int32_t)0) ; + } else + if (EmitSync & 2) { + Label DONE_LABEL ; if (UseBiasedLocking) { // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument. masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); } - masm.movl (tmpReg, Address(objReg, 0)) ; // fetch markword - masm.orl (tmpReg, 0x1); - masm.movl (Address(boxReg, 0), tmpReg); // Anticipate successful CAS + masm.movptr(tmpReg, Address(objReg, 0)) ; // fetch markword + masm.orptr (tmpReg, 0x1); + masm.movptr(Address(boxReg, 0), tmpReg); // Anticipate successful CAS if (os::is_MP()) { masm.lock(); } - masm.cmpxchg(boxReg, Address(objReg, 0)); // Updates tmpReg + masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg masm.jcc(Assembler::equal, DONE_LABEL); // Recursive locking - masm.subl(tmpReg, rsp); - masm.andl(tmpReg, 0xFFFFF003 ); - masm.movl(Address(boxReg, 0), tmpReg); - masm.bind(DONE_LABEL) ; - } else { - // Possible cases that we'll encounter in fast_lock + masm.subptr(tmpReg, rsp); + masm.andptr(tmpReg, (int32_t) 0xFFFFF003 ); + masm.movptr(Address(boxReg, 0), tmpReg); + masm.bind(DONE_LABEL) ; + } else { + // Possible cases that we'll encounter in fast_lock // ------------------------------------------------ // * Inflated // -- unlocked @@ -3310,15 +3311,15 @@ encode %{ masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); } - masm.movl (tmpReg, Address(objReg, 0)) ; // [FETCH] - masm.testl (tmpReg, 0x02) ; // Inflated v (Stack-locked or neutral) + masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] + masm.testptr(tmpReg, 0x02) ; // Inflated v (Stack-locked or neutral) masm.jccb (Assembler::notZero, IsInflated) ; // Attempt stack-locking ... - masm.orl (tmpReg, 0x1); - masm.movl (Address(boxReg, 0), tmpReg); // Anticipate successful CAS + masm.orptr (tmpReg, 0x1); + masm.movptr(Address(boxReg, 0), tmpReg); // Anticipate successful CAS if (os::is_MP()) { masm.lock(); } - masm.cmpxchg(boxReg, Address(objReg, 0)); // Updates tmpReg + masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg if (_counters != NULL) { masm.cond_inc32(Assembler::equal, ExternalAddress((address)_counters->fast_path_entry_count_addr())); @@ -3326,9 +3327,9 @@ encode %{ masm.jccb (Assembler::equal, DONE_LABEL); // Recursive locking - masm.subl(tmpReg, rsp); - masm.andl(tmpReg, 0xFFFFF003 ); - masm.movl(Address(boxReg, 0), tmpReg); + masm.subptr(tmpReg, rsp); + masm.andptr(tmpReg, 0xFFFFF003 ); + masm.movptr(Address(boxReg, 0), tmpReg); if (_counters != NULL) { masm.cond_inc32(Assembler::equal, ExternalAddress((address)_counters->fast_path_entry_count_addr())); @@ -3360,36 +3361,33 @@ encode %{ // This is convenient but results a ST-before-CAS penalty. The following CAS suffers // additional latency as we have another ST in the store buffer that must drain. - if (EmitSync & 8192) { - masm.movl (Address(boxReg, 0), 3) ; // results in ST-before-CAS penalty - masm.get_thread (scrReg) ; - masm.movl (boxReg, tmpReg); // consider: LEA box, [tmp-2] - masm.movl (tmpReg, 0); // consider: xor vs mov - if (os::is_MP()) { masm.lock(); } - masm.cmpxchg (scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; - } else + if (EmitSync & 8192) { + masm.movptr(Address(boxReg, 0), 3) ; // results in ST-before-CAS penalty + masm.get_thread (scrReg) ; + masm.movptr(boxReg, tmpReg); // consider: LEA box, [tmp-2] + masm.movptr(tmpReg, 0); // consider: xor vs mov + if (os::is_MP()) { masm.lock(); } + masm.cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; + } else if ((EmitSync & 128) == 0) { // avoid ST-before-CAS - masm.movl (scrReg, boxReg) ; - masm.movl (boxReg, tmpReg); // consider: LEA box, [tmp-2] + masm.movptr(scrReg, boxReg) ; + masm.movptr(boxReg, tmpReg); // consider: LEA box, [tmp-2] // Using a prefetchw helps avoid later RTS->RTO upgrades and cache probes if ((EmitSync & 2048) && VM_Version::supports_3dnow() && os::is_MP()) { // prefetchw [eax + Offset(_owner)-2] - masm.emit_raw (0x0F) ; - masm.emit_raw (0x0D) ; - masm.emit_raw (0x48) ; - masm.emit_raw (ObjectMonitor::owner_offset_in_bytes()-2) ; + masm.prefetchw(Address(rax, ObjectMonitor::owner_offset_in_bytes()-2)); } if ((EmitSync & 64) == 0) { // Optimistic form: consider XORL tmpReg,tmpReg - masm.movl (tmpReg, 0 ) ; - } else { + masm.movptr(tmpReg, 0 ) ; + } else { // Can suffer RTS->RTO upgrades on shared or cold $ lines // Test-And-CAS instead of CAS - masm.movl (tmpReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; // rax, = m->_owner - masm.testl (tmpReg, tmpReg) ; // Locked ? - masm.jccb (Assembler::notZero, DONE_LABEL) ; + masm.movptr(tmpReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; // rax, = m->_owner + masm.testptr(tmpReg, tmpReg) ; // Locked ? + masm.jccb (Assembler::notZero, DONE_LABEL) ; } // Appears unlocked - try to swing _owner from null to non-null. @@ -3401,41 +3399,38 @@ encode %{ // (rsp or the address of the box) into m->owner is harmless. // Invariant: tmpReg == 0. tmpReg is EAX which is the implicit cmpxchg comparand. if (os::is_MP()) { masm.lock(); } - masm.cmpxchg (scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; - masm.movl (Address(scrReg, 0), 3) ; // box->_displaced_header = 3 - masm.jccb (Assembler::notZero, DONE_LABEL) ; + masm.cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; + masm.movptr(Address(scrReg, 0), 3) ; // box->_displaced_header = 3 + masm.jccb (Assembler::notZero, DONE_LABEL) ; masm.get_thread (scrReg) ; // beware: clobbers ICCs - masm.movl (Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2), scrReg) ; - masm.xorl (boxReg, boxReg) ; // set icc.ZFlag = 1 to indicate success - - // If the CAS fails we can either retry or pass control to the slow-path. - // We use the latter tactic. + masm.movptr(Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2), scrReg) ; + masm.xorptr(boxReg, boxReg) ; // set icc.ZFlag = 1 to indicate success + + // If the CAS fails we can either retry or pass control to the slow-path. + // We use the latter tactic. // Pass the CAS result in the icc.ZFlag into DONE_LABEL // If the CAS was successful ... // Self has acquired the lock // Invariant: m->_recursions should already be 0, so we don't need to explicitly set it. // Intentional fall-through into DONE_LABEL ... } else { - masm.movl (Address(boxReg, 0), 3) ; // results in ST-before-CAS penalty - masm.movl (boxReg, tmpReg) ; + masm.movptr(Address(boxReg, 0), 3) ; // results in ST-before-CAS penalty + masm.movptr(boxReg, tmpReg) ; // Using a prefetchw helps avoid later RTS->RTO upgrades and cache probes if ((EmitSync & 2048) && VM_Version::supports_3dnow() && os::is_MP()) { // prefetchw [eax + Offset(_owner)-2] - masm.emit_raw (0x0F) ; - masm.emit_raw (0x0D) ; - masm.emit_raw (0x48) ; - masm.emit_raw (ObjectMonitor::owner_offset_in_bytes()-2) ; + masm.prefetchw(Address(rax, ObjectMonitor::owner_offset_in_bytes()-2)); } if ((EmitSync & 64) == 0) { // Optimistic form - masm.xorl (tmpReg, tmpReg) ; - } else { + masm.xorptr (tmpReg, tmpReg) ; + } else { // Can suffer RTS->RTO upgrades on shared or cold $ lines - masm.movl (tmpReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; // rax, = m->_owner - masm.testl (tmpReg, tmpReg) ; // Locked ? - masm.jccb (Assembler::notZero, DONE_LABEL) ; + masm.movptr(tmpReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; // rax, = m->_owner + masm.testptr(tmpReg, tmpReg) ; // Locked ? + masm.jccb (Assembler::notZero, DONE_LABEL) ; } // Appears unlocked - try to swing _owner from null to non-null. @@ -3443,7 +3438,7 @@ encode %{ // Invariant: tmpReg == 0. tmpReg is EAX which is the implicit cmpxchg comparand. masm.get_thread (scrReg) ; if (os::is_MP()) { masm.lock(); } - masm.cmpxchg (scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; + masm.cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; // If the CAS fails we can either retry or pass control to the slow-path. // We use the latter tactic. @@ -3514,19 +3509,19 @@ encode %{ if (EmitSync & 4) { // Disable - inhibit all inlining. Force control through the slow-path - masm.cmpl (rsp, 0) ; - } else + masm.cmpptr (rsp, 0) ; + } else if (EmitSync & 8) { Label DONE_LABEL ; if (UseBiasedLocking) { masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); } // classic stack-locking code ... - masm.movl (tmpReg, Address(boxReg, 0)) ; - masm.testl (tmpReg, tmpReg) ; + masm.movptr(tmpReg, Address(boxReg, 0)) ; + masm.testptr(tmpReg, tmpReg) ; masm.jcc (Assembler::zero, DONE_LABEL) ; if (os::is_MP()) { masm.lock(); } - masm.cmpxchg(tmpReg, Address(objReg, 0)); // Uses EAX which is box + masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses EAX which is box masm.bind(DONE_LABEL); } else { Label DONE_LABEL, Stacked, CheckSucc, Inflated ; @@ -3536,12 +3531,12 @@ encode %{ if (UseBiasedLocking) { masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); } - - masm.cmpl (Address(boxReg, 0), 0) ; // Examine the displaced header - masm.movl (tmpReg, Address(objReg, 0)) ; // Examine the object's markword + + masm.cmpptr(Address(boxReg, 0), 0) ; // Examine the displaced header + masm.movptr(tmpReg, Address(objReg, 0)) ; // Examine the object's markword masm.jccb (Assembler::zero, DONE_LABEL) ; // 0 indicates recursive stack-lock - masm.testl (tmpReg, 0x02) ; // Inflated? + masm.testptr(tmpReg, 0x02) ; // Inflated? masm.jccb (Assembler::zero, Stacked) ; masm.bind (Inflated) ; @@ -3571,11 +3566,8 @@ encode %{ masm.get_thread (boxReg) ; if ((EmitSync & 4096) && VM_Version::supports_3dnow() && os::is_MP()) { - // prefetchw [ebx + Offset(_owner)-2] - masm.emit_raw (0x0F) ; - masm.emit_raw (0x0D) ; - masm.emit_raw (0x4B) ; - masm.emit_raw (ObjectMonitor::owner_offset_in_bytes()-2) ; + // prefetchw [ebx + Offset(_owner)-2] + masm.prefetchw(Address(rbx, ObjectMonitor::owner_offset_in_bytes()-2)); } // Note that we could employ various encoding schemes to reduce @@ -3584,22 +3576,22 @@ encode %{ // In practice the chain of fetches doesn't seem to impact performance, however. if ((EmitSync & 65536) == 0 && (EmitSync & 256)) { // Attempt to reduce branch density - AMD's branch predictor. - masm.xorl (boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; - masm.orl (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; - masm.orl (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; - masm.orl (boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; - masm.jccb (Assembler::notZero, DONE_LABEL) ; - masm.movl (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), 0) ; - masm.jmpb (DONE_LABEL) ; - } else { - masm.xorl (boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; - masm.orl (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; - masm.jccb (Assembler::notZero, DONE_LABEL) ; - masm.movl (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; - masm.orl (boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; - masm.jccb (Assembler::notZero, CheckSucc) ; - masm.movl (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), 0) ; - masm.jmpb (DONE_LABEL) ; + masm.xorptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; + masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; + masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; + masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; + masm.jccb (Assembler::notZero, DONE_LABEL) ; + masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), 0) ; + masm.jmpb (DONE_LABEL) ; + } else { + masm.xorptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; + masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; + masm.jccb (Assembler::notZero, DONE_LABEL) ; + masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; + masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; + masm.jccb (Assembler::notZero, CheckSucc) ; + masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), 0) ; + masm.jmpb (DONE_LABEL) ; } // The Following code fragment (EmitSync & 65536) improves the performance of @@ -3615,9 +3607,9 @@ encode %{ masm.bind (CheckSucc) ; // Optional pre-test ... it's safe to elide this - if ((EmitSync & 16) == 0) { - masm.cmpl (Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), 0) ; - masm.jccb (Assembler::zero, LGoSlowPath) ; + if ((EmitSync & 16) == 0) { + masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), 0) ; + masm.jccb (Assembler::zero, LGoSlowPath) ; } // We have a classic Dekker-style idiom: @@ -3645,39 +3637,37 @@ encode %{ // // We currently use (3), although it's likely that switching to (2) // is correct for the future. - - masm.movl (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), 0) ; - if (os::is_MP()) { - if (VM_Version::supports_sse2() && 1 == FenceInstruction) { - masm.emit_raw (0x0F) ; // MFENCE ... - masm.emit_raw (0xAE) ; - masm.emit_raw (0xF0) ; - } else { - masm.lock () ; masm.addl (Address(rsp, 0), 0) ; + + masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), 0) ; + if (os::is_MP()) { + if (VM_Version::supports_sse2() && 1 == FenceInstruction) { + masm.mfence(); + } else { + masm.lock () ; masm.addptr(Address(rsp, 0), 0) ; } } // Ratify _succ remains non-null - masm.cmpl (Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), 0) ; - masm.jccb (Assembler::notZero, LSuccess) ; + masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), 0) ; + masm.jccb (Assembler::notZero, LSuccess) ; - masm.xorl (boxReg, boxReg) ; // box is really EAX + masm.xorptr(boxReg, boxReg) ; // box is really EAX if (os::is_MP()) { masm.lock(); } - masm.cmpxchg(rsp, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); + masm.cmpxchgptr(rsp, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); masm.jccb (Assembler::notEqual, LSuccess) ; // Since we're low on registers we installed rsp as a placeholding in _owner. // Now install Self over rsp. This is safe as we're transitioning from // non-null to non=null masm.get_thread (boxReg) ; - masm.movl (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), boxReg) ; + masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), boxReg) ; // Intentional fall-through into LGoSlowPath ... - masm.bind (LGoSlowPath) ; - masm.orl (boxReg, 1) ; // set ICC.ZF=0 to indicate failure - masm.jmpb (DONE_LABEL) ; + masm.bind (LGoSlowPath) ; + masm.orptr(boxReg, 1) ; // set ICC.ZF=0 to indicate failure + masm.jmpb (DONE_LABEL) ; - masm.bind (LSuccess) ; - masm.xorl (boxReg, boxReg) ; // set ICC.ZF=1 to indicate success - masm.jmpb (DONE_LABEL) ; + masm.bind (LSuccess) ; + masm.xorptr(boxReg, boxReg) ; // set ICC.ZF=1 to indicate success + masm.jmpb (DONE_LABEL) ; } masm.bind (Stacked) ; @@ -3686,9 +3676,9 @@ encode %{ // Try to reset the header to displaced header. // The "box" value on the stack is stable, so we can reload // and be assured we observe the same value as above. - masm.movl (tmpReg, Address(boxReg, 0)) ; + masm.movptr(tmpReg, Address(boxReg, 0)) ; if (os::is_MP()) { masm.lock(); } - masm.cmpxchg(tmpReg, Address(objReg, 0)); // Uses EAX which is box + masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses EAX which is box // Intention fall-thru into DONE_LABEL @@ -3720,12 +3710,12 @@ encode %{ int count_offset = java_lang_String::count_offset_in_bytes(); int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); - masm.movl(rax, Address(rsi, value_offset)); + masm.movptr(rax, Address(rsi, value_offset)); masm.movl(rcx, Address(rsi, offset_offset)); - masm.leal(rax, Address(rax, rcx, Address::times_2, base_offset)); - masm.movl(rbx, Address(rdi, value_offset)); + masm.lea(rax, Address(rax, rcx, Address::times_2, base_offset)); + masm.movptr(rbx, Address(rdi, value_offset)); masm.movl(rcx, Address(rdi, offset_offset)); - masm.leal(rbx, Address(rbx, rcx, Address::times_2, base_offset)); + masm.lea(rbx, Address(rbx, rcx, Address::times_2, base_offset)); // Compute the minimum of the string lengths(rsi) and the // difference of the string lengths (stack) @@ -3736,14 +3726,14 @@ encode %{ masm.movl(rsi, Address(rsi, count_offset)); masm.movl(rcx, rdi); masm.subl(rdi, rsi); - masm.pushl(rdi); + masm.push(rdi); masm.cmovl(Assembler::lessEqual, rsi, rcx); } else { masm.movl(rdi, Address(rdi, count_offset)); masm.movl(rcx, Address(rsi, count_offset)); masm.movl(rsi, rdi); masm.subl(rdi, rcx); - masm.pushl(rdi); + masm.push(rdi); masm.jcc(Assembler::lessEqual, ECX_GOOD_LABEL); masm.movl(rsi, rcx); // rsi holds min, rcx is unused @@ -3761,14 +3751,14 @@ encode %{ // Compare first characters masm.subl(rcx, rdi); masm.jcc(Assembler::notZero, POP_LABEL); - masm.decrement(rsi); + masm.decrementl(rsi); masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL); { // Check after comparing first character to see if strings are equivalent Label LSkip2; // Check if the strings start at same location - masm.cmpl(rbx,rax); + masm.cmpptr(rbx,rax); masm.jcc(Assembler::notEqual, LSkip2); // Check if the length difference is zero (from stack) @@ -3780,8 +3770,8 @@ encode %{ } // Shift rax, and rbx, to the end of the arrays, negate min - masm.leal(rax, Address(rax, rsi, Address::times_2, 2)); - masm.leal(rbx, Address(rbx, rsi, Address::times_2, 2)); + masm.lea(rax, Address(rax, rsi, Address::times_2, 2)); + masm.lea(rbx, Address(rbx, rsi, Address::times_2, 2)); masm.negl(rsi); // Compare the rest of the characters @@ -3790,18 +3780,18 @@ encode %{ masm.load_unsigned_word(rdi, Address(rax, rsi, Address::times_2, 0)); masm.subl(rcx, rdi); masm.jcc(Assembler::notZero, POP_LABEL); - masm.increment(rsi); + masm.incrementl(rsi); masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL); // Strings are equal up to min length. Return the length difference. masm.bind(LENGTH_DIFF_LABEL); - masm.popl(rcx); + masm.pop(rcx); masm.jmp(DONE_LABEL); // Discard the stored length difference masm.bind(POP_LABEL); - masm.addl(rsp, 4); - + masm.addptr(rsp, 4); + // That's it masm.bind(DONE_LABEL); %} @@ -4315,7 +4305,8 @@ encode %{ enc_class enc_membar_volatile %{ MacroAssembler masm(&cbuf); - masm.membar(); + masm.membar(Assembler::Membar_mask_bits(Assembler::StoreLoad | + Assembler::StoreStore)); %} // Atomically load the volatile long @@ -11151,7 +11142,7 @@ instruct convXI2XD_reg(regXD dst, eRegI src) format %{ "MOVD $dst,$src\n\t" "CVTDQ2PD $dst,$dst\t# i2d" %} ins_encode %{ - __ movd($dst$$XMMRegister, $src$$Register); + __ movdl($dst$$XMMRegister, $src$$Register); __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); %} ins_pipe(pipe_slow); // XXX @@ -11249,7 +11240,7 @@ instruct convI2X_reg(regX dst, eRegI src) %{ format %{ "MOVD $dst,$src\n\t" "CVTDQ2PS $dst,$dst\t# i2f" %} ins_encode %{ - __ movd($dst$$XMMRegister, $src$$Register); + __ movdl($dst$$XMMRegister, $src$$Register); __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); %} ins_pipe(pipe_slow); // XXX @@ -12262,7 +12253,7 @@ instruct cmpL3_reg_reg(eSIRegI dst, eRegL src1, eRegL src2, eFlagsReg flags ) %{ "done:" %} ins_encode %{ Label p_one, m_one, done; - __ xorl($dst$$Register, $dst$$Register); + __ xorptr($dst$$Register, $dst$$Register); __ cmpl(HIGH_FROM_LOW($src1$$Register), HIGH_FROM_LOW($src2$$Register)); __ jccb(Assembler::less, m_one); __ jccb(Assembler::greater, p_one); @@ -12270,10 +12261,10 @@ instruct cmpL3_reg_reg(eSIRegI dst, eRegL src1, eRegL src2, eFlagsReg flags ) %{ __ jccb(Assembler::below, m_one); __ jccb(Assembler::equal, done); __ bind(p_one); - __ increment($dst$$Register); + __ incrementl($dst$$Register); __ jmpb(done); __ bind(m_one); - __ decrement($dst$$Register); + __ decrementl($dst$$Register); __ bind(done); %} ins_pipe( pipe_slow ); diff --git a/hotspot/src/cpu/x86/vm/x86_64.ad b/hotspot/src/cpu/x86/vm/x86_64.ad index 302994148c0..62b46da14b0 100644 --- a/hotspot/src/cpu/x86/vm/x86_64.ad +++ b/hotspot/src/cpu/x86/vm/x86_64.ad @@ -478,7 +478,7 @@ reg_class int_no_rcx_reg(RAX, // Class for all int registers except RAX, RDX (and RSP) reg_class int_no_rax_rdx_reg(RBP, - RDI + RDI, RSI, RCX, RBX, @@ -552,7 +552,7 @@ reg_class double_reg(XMM0, XMM0_H, // This is a block of C++ code which provides values, functions, and // definitions necessary in the rest of the architecture description source %{ -#define RELOC_IMM64 Assembler::imm64_operand +#define RELOC_IMM64 Assembler::imm_operand #define RELOC_DISP32 Assembler::disp32_operand #define __ _masm. @@ -962,11 +962,11 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const if (VerifyStackAtCalls) { Label L; MacroAssembler masm(&cbuf); - masm.pushq(rax); - masm.movq(rax, rsp); - masm.andq(rax, StackAlignmentInBytes-1); - masm.cmpq(rax, StackAlignmentInBytes-wordSize); - masm.popq(rax); + masm.push(rax); + masm.mov(rax, rsp); + masm.andptr(rax, StackAlignmentInBytes-1); + masm.cmpptr(rax, StackAlignmentInBytes-wordSize); + masm.pop(rax); masm.jcc(Assembler::equal, L); masm.stop("Stack is not properly aligned!"); masm.bind(L); @@ -1817,6 +1817,7 @@ void emit_java_to_interp(CodeBuffer& cbuf) __ relocate(static_stub_Relocation::spec(mark), RELOC_IMM64); // static stub relocation also tags the methodOop in the code-stream. __ movoop(rbx, (jobject) NULL); // method is zapped till fixup time + // This is recognized as unresolved by relocs/nativeinst/ic code __ jump(RuntimeAddress(__ pc())); // Update current stubs pointer and restore code_end. @@ -1863,9 +1864,9 @@ void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const #endif if (UseCompressedOops) { masm.load_klass(rscratch1, j_rarg0); - masm.cmpq(rax, rscratch1); + masm.cmpptr(rax, rscratch1); } else { - masm.cmpq(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); + masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); } masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); @@ -1949,7 +1950,7 @@ int emit_deopt_handler(CodeBuffer& cbuf) __ call(next, relocInfo::none); // reloc none is fine since it is a disp32 __ bind(next); // adjust it so it matches "the_pc" - __ subq(Address(rsp, 0), __ offset() - offset); + __ subptr(Address(rsp, 0), __ offset() - offset); __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); __ end_a_stub(); @@ -2577,23 +2578,23 @@ encode %{ // Compare super with sub directly, since super is not in its own SSA. // The compiler used to emit this test, but we fold it in here, // to allow platform-specific tweaking on sparc. - __ cmpq(Rrax, Rrsi); + __ cmpptr(Rrax, Rrsi); __ jcc(Assembler::equal, hit); #ifndef PRODUCT __ lea(Rrcx, ExternalAddress((address)&SharedRuntime::_partial_subtype_ctr)); __ incrementl(Address(Rrcx, 0)); #endif //PRODUCT - __ movq(Rrdi, Address(Rrsi, - sizeof(oopDesc) + + __ movptr(Rrdi, Address(Rrsi, + sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())); __ movl(Rrcx, Address(Rrdi, arrayOopDesc::length_offset_in_bytes())); - __ addq(Rrdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + __ addptr(Rrdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); if (UseCompressedOops) { __ encode_heap_oop(Rrax); __ repne_scanl(); __ jcc(Assembler::notEqual, cmiss); __ decode_heap_oop(Rrax); - __ movq(Address(Rrsi, + __ movptr(Address(Rrsi, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()), Rrax); @@ -2602,16 +2603,16 @@ encode %{ __ decode_heap_oop(Rrax); __ jmp(miss); } else { - __ repne_scanq(); + __ repne_scan(); __ jcc(Assembler::notEqual, miss); - __ movq(Address(Rrsi, + __ movptr(Address(Rrsi, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()), Rrax); } __ bind(hit); if ($primary) { - __ xorq(Rrdi, Rrdi); + __ xorptr(Rrdi, Rrdi); } __ bind(miss); %} @@ -3527,8 +3528,9 @@ encode %{ masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr())); } if (EmitSync & 1) { - masm.movptr (Address(boxReg, 0), intptr_t(markOopDesc::unused_mark())) ; - masm.cmpq (rsp, 0) ; + // Without cast to int32_t a movptr will destroy r10 which is typically obj + masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; + masm.cmpptr(rsp, (int32_t)NULL_WORD) ; } else if (EmitSync & 2) { Label DONE_LABEL; @@ -3536,29 +3538,30 @@ encode %{ // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument. masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); } - masm.movl(tmpReg, 0x1); - masm.orq(tmpReg, Address(objReg, 0)); - masm.movq(Address(boxReg, 0), tmpReg); + // QQQ was movl... + masm.movptr(tmpReg, 0x1); + masm.orptr(tmpReg, Address(objReg, 0)); + masm.movptr(Address(boxReg, 0), tmpReg); if (os::is_MP()) { masm.lock(); } - masm.cmpxchgq(boxReg, Address(objReg, 0)); // Updates tmpReg + masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg masm.jcc(Assembler::equal, DONE_LABEL); // Recursive locking - masm.subq(tmpReg, rsp); - masm.andq(tmpReg, 7 - os::vm_page_size()); - masm.movq(Address(boxReg, 0), tmpReg); + masm.subptr(tmpReg, rsp); + masm.andptr(tmpReg, 7 - os::vm_page_size()); + masm.movptr(Address(boxReg, 0), tmpReg); masm.bind(DONE_LABEL); masm.nop(); // avoid branch to branch } else { Label DONE_LABEL, IsInflated, Egress; - masm.movq (tmpReg, Address(objReg, 0)) ; - masm.testq (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased - masm.jcc (Assembler::notZero, IsInflated) ; - + masm.movptr(tmpReg, Address(objReg, 0)) ; + masm.testl (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased + masm.jcc (Assembler::notZero, IsInflated) ; + // it's stack-locked, biased or neutral // TODO: optimize markword triage order to reduce the number of // conditional branches in the most common cases. @@ -3568,13 +3571,14 @@ encode %{ if (UseBiasedLocking) { masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters); - masm.movq (tmpReg, Address(objReg, 0)) ; // [FETCH] + masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] } - masm.orq (tmpReg, 1) ; - masm.movq (Address(boxReg, 0), tmpReg) ; - if (os::is_MP()) { masm.lock(); } - masm.cmpxchgq(boxReg, Address(objReg, 0)); // Updates tmpReg + // was q will it destroy high? + masm.orl (tmpReg, 1) ; + masm.movptr(Address(boxReg, 0), tmpReg) ; + if (os::is_MP()) { masm.lock(); } + masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg if (_counters != NULL) { masm.cond_inc32(Assembler::equal, ExternalAddress((address) _counters->fast_path_entry_count_addr())); @@ -3582,9 +3586,9 @@ encode %{ masm.jcc (Assembler::equal, DONE_LABEL); // Recursive locking - masm.subq (tmpReg, rsp); - masm.andq (tmpReg, 7 - os::vm_page_size()); - masm.movq (Address(boxReg, 0), tmpReg); + masm.subptr(tmpReg, rsp); + masm.andptr(tmpReg, 7 - os::vm_page_size()); + masm.movptr(Address(boxReg, 0), tmpReg); if (_counters != NULL) { masm.cond_inc32(Assembler::equal, ExternalAddress((address) _counters->fast_path_entry_count_addr())); @@ -3599,16 +3603,17 @@ encode %{ // We should also think about trying a CAS without having // fetched _owner. If the CAS is successful we may // avoid an RTO->RTS upgrade on the $line. - masm.movptr(Address(boxReg, 0), intptr_t(markOopDesc::unused_mark())) ; + // Without cast to int32_t a movptr will destroy r10 which is typically obj + masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; - masm.movq (boxReg, tmpReg) ; - masm.movq (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; - masm.testq (tmpReg, tmpReg) ; - masm.jcc (Assembler::notZero, DONE_LABEL) ; + masm.mov (boxReg, tmpReg) ; + masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; + masm.testptr(tmpReg, tmpReg) ; + masm.jcc (Assembler::notZero, DONE_LABEL) ; // It's inflated and appears unlocked - if (os::is_MP()) { masm.lock(); } - masm.cmpxchgq(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; + if (os::is_MP()) { masm.lock(); } + masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; // Intentional fall-through into DONE_LABEL ... masm.bind (DONE_LABEL) ; @@ -3627,8 +3632,8 @@ encode %{ Register tmpReg = as_Register($tmp$$reg); MacroAssembler masm(&cbuf); - if (EmitSync & 4) { - masm.cmpq (rsp, 0) ; + if (EmitSync & 4) { + masm.cmpptr(rsp, 0) ; } else if (EmitSync & 8) { Label DONE_LABEL; @@ -3638,15 +3643,15 @@ encode %{ // Check whether the displaced header is 0 //(=> recursive unlock) - masm.movq(tmpReg, Address(boxReg, 0)); - masm.testq(tmpReg, tmpReg); + masm.movptr(tmpReg, Address(boxReg, 0)); + masm.testptr(tmpReg, tmpReg); masm.jcc(Assembler::zero, DONE_LABEL); // If not recursive lock, reset the header to displaced header if (os::is_MP()) { masm.lock(); } - masm.cmpxchgq(tmpReg, Address(objReg, 0)); // Uses RAX which is box + masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box masm.bind(DONE_LABEL); masm.nop(); // avoid branch to branch } else { @@ -3655,44 +3660,44 @@ encode %{ if (UseBiasedLocking) { masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); } - - masm.movq (tmpReg, Address(objReg, 0)) ; - masm.cmpq (Address(boxReg, 0), (int)NULL_WORD) ; - masm.jcc (Assembler::zero, DONE_LABEL) ; - masm.testq (tmpReg, 0x02) ; - masm.jcc (Assembler::zero, Stacked) ; - + + masm.movptr(tmpReg, Address(objReg, 0)) ; + masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ; + masm.jcc (Assembler::zero, DONE_LABEL) ; + masm.testl (tmpReg, 0x02) ; + masm.jcc (Assembler::zero, Stacked) ; + // It's inflated - masm.movq (boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; - masm.xorq (boxReg, r15_thread) ; - masm.orq (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; - masm.jcc (Assembler::notZero, DONE_LABEL) ; - masm.movq (boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; - masm.orq (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; - masm.jcc (Assembler::notZero, CheckSucc) ; - masm.mov64 (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int)NULL_WORD) ; - masm.jmp (DONE_LABEL) ; - - if ((EmitSync & 65536) == 0) { + masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; + masm.xorptr(boxReg, r15_thread) ; + masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; + masm.jcc (Assembler::notZero, DONE_LABEL) ; + masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; + masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; + masm.jcc (Assembler::notZero, CheckSucc) ; + masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; + masm.jmp (DONE_LABEL) ; + + if ((EmitSync & 65536) == 0) { Label LSuccess, LGoSlowPath ; masm.bind (CheckSucc) ; - masm.cmpq (Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int)NULL_WORD) ; + masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; masm.jcc (Assembler::zero, LGoSlowPath) ; // I'd much rather use lock:andl m->_owner, 0 as it's faster than the // the explicit ST;MEMBAR combination, but masm doesn't currently support // "ANDQ M,IMM". Don't use MFENCE here. lock:add to TOS, xchg, etc // are all faster when the write buffer is populated. - masm.movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int)NULL_WORD) ; + masm.movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; if (os::is_MP()) { - masm.lock () ; masm.addq (Address(rsp, 0), 0) ; + masm.lock () ; masm.addl (Address(rsp, 0), 0) ; } - masm.cmpq (Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int)NULL_WORD) ; + masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; masm.jcc (Assembler::notZero, LSuccess) ; - masm.movptr (boxReg, (int)NULL_WORD) ; // box is really EAX + masm.movptr (boxReg, (int32_t)NULL_WORD) ; // box is really EAX if (os::is_MP()) { masm.lock(); } - masm.cmpxchgq (r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); + masm.cmpxchgptr(r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); masm.jcc (Assembler::notEqual, LSuccess) ; // Intentional fall-through into slow-path @@ -3705,10 +3710,10 @@ encode %{ masm.jmp (DONE_LABEL) ; } - masm.bind (Stacked) ; - masm.movq (tmpReg, Address (boxReg, 0)) ; // re-fetch - if (os::is_MP()) { masm.lock(); } - masm.cmpxchgq(tmpReg, Address(objReg, 0)); // Uses RAX which is box + masm.bind (Stacked) ; + masm.movptr(tmpReg, Address (boxReg, 0)) ; // re-fetch + if (os::is_MP()) { masm.lock(); } + masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box if (EmitSync & 65536) { masm.bind (CheckSucc) ; @@ -3736,10 +3741,10 @@ encode %{ masm.load_heap_oop(rax, Address(rsi, value_offset)); masm.movl(rcx, Address(rsi, offset_offset)); - masm.leaq(rax, Address(rax, rcx, Address::times_2, base_offset)); + masm.lea(rax, Address(rax, rcx, Address::times_2, base_offset)); masm.load_heap_oop(rbx, Address(rdi, value_offset)); masm.movl(rcx, Address(rdi, offset_offset)); - masm.leaq(rbx, Address(rbx, rcx, Address::times_2, base_offset)); + masm.lea(rbx, Address(rbx, rcx, Address::times_2, base_offset)); // Compute the minimum of the string lengths(rsi) and the // difference of the string lengths (stack) @@ -3748,8 +3753,8 @@ encode %{ masm.movl(rsi, Address(rsi, count_offset)); masm.movl(rcx, rdi); masm.subl(rdi, rsi); - masm.pushq(rdi); - masm.cmovl(Assembler::lessEqual, rsi, rcx); + masm.push(rdi); + masm.cmov(Assembler::lessEqual, rsi, rcx); // Is the minimum length zero? masm.bind(RCX_GOOD_LABEL); @@ -3770,7 +3775,7 @@ encode %{ // Check after comparing first character to see if strings are equivalent Label LSkip2; // Check if the strings start at same location - masm.cmpq(rbx, rax); + masm.cmpptr(rbx, rax); masm.jcc(Assembler::notEqual, LSkip2); // Check if the length difference is zero (from stack) @@ -3782,9 +3787,9 @@ encode %{ } // Shift RAX and RBX to the end of the arrays, negate min - masm.leaq(rax, Address(rax, rsi, Address::times_2, 2)); - masm.leaq(rbx, Address(rbx, rsi, Address::times_2, 2)); - masm.negq(rsi); + masm.lea(rax, Address(rax, rsi, Address::times_2, 2)); + masm.lea(rbx, Address(rbx, rsi, Address::times_2, 2)); + masm.negptr(rsi); // Compare the rest of the characters masm.bind(WHILE_HEAD_LABEL); @@ -3792,18 +3797,18 @@ encode %{ masm.load_unsigned_word(rdi, Address(rax, rsi, Address::times_2, 0)); masm.subl(rcx, rdi); masm.jcc(Assembler::notZero, POP_LABEL); - masm.incrementq(rsi); + masm.increment(rsi); masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL); // Strings are equal up to min length. Return the length difference. masm.bind(LENGTH_DIFF_LABEL); - masm.popq(rcx); + masm.pop(rcx); masm.jmp(DONE_LABEL); // Discard the stored length difference masm.bind(POP_LABEL); - masm.addq(rsp, 8); - + masm.addptr(rsp, 8); + // That's it masm.bind(DONE_LABEL); %} @@ -3893,7 +3898,7 @@ encode %{ enc_class absF_encoding(regF dst) %{ int dstenc = $dst$$reg; - address signmask_address = (address) StubRoutines::amd64::float_sign_mask(); + address signmask_address = (address) StubRoutines::x86::float_sign_mask(); cbuf.set_inst_mark(); if (dstenc >= 8) { @@ -3910,7 +3915,7 @@ encode %{ enc_class absD_encoding(regD dst) %{ int dstenc = $dst$$reg; - address signmask_address = (address) StubRoutines::amd64::double_sign_mask(); + address signmask_address = (address) StubRoutines::x86::double_sign_mask(); cbuf.set_inst_mark(); emit_opcode(cbuf, 0x66); @@ -3928,7 +3933,7 @@ encode %{ enc_class negF_encoding(regF dst) %{ int dstenc = $dst$$reg; - address signflip_address = (address) StubRoutines::amd64::float_sign_flip(); + address signflip_address = (address) StubRoutines::x86::float_sign_flip(); cbuf.set_inst_mark(); if (dstenc >= 8) { @@ -3945,7 +3950,7 @@ encode %{ enc_class negD_encoding(regD dst) %{ int dstenc = $dst$$reg; - address signflip_address = (address) StubRoutines::amd64::double_sign_flip(); + address signflip_address = (address) StubRoutines::x86::double_sign_flip(); cbuf.set_inst_mark(); emit_opcode(cbuf, 0x66); @@ -4003,7 +4008,7 @@ encode %{ emit_opcode(cbuf, 0xE8); emit_d32_reloc(cbuf, (int) - (StubRoutines::amd64::f2i_fixup() - cbuf.code_end() - 4), + (StubRoutines::x86::f2i_fixup() - cbuf.code_end() - 4), runtime_call_Relocation::spec(), RELOC_DISP32); @@ -4020,7 +4025,7 @@ encode %{ %{ int dstenc = $dst$$reg; int srcenc = $src$$reg; - address const_address = (address) StubRoutines::amd64::double_sign_flip(); + address const_address = (address) StubRoutines::x86::double_sign_flip(); // cmpq $dst, [0x8000000000000000] cbuf.set_inst_mark(); @@ -4061,7 +4066,7 @@ encode %{ emit_opcode(cbuf, 0xE8); emit_d32_reloc(cbuf, (int) - (StubRoutines::amd64::f2l_fixup() - cbuf.code_end() - 4), + (StubRoutines::x86::f2l_fixup() - cbuf.code_end() - 4), runtime_call_Relocation::spec(), RELOC_DISP32); @@ -4117,7 +4122,7 @@ encode %{ emit_opcode(cbuf, 0xE8); emit_d32_reloc(cbuf, (int) - (StubRoutines::amd64::d2i_fixup() - cbuf.code_end() - 4), + (StubRoutines::x86::d2i_fixup() - cbuf.code_end() - 4), runtime_call_Relocation::spec(), RELOC_DISP32); @@ -4134,7 +4139,7 @@ encode %{ %{ int dstenc = $dst$$reg; int srcenc = $src$$reg; - address const_address = (address) StubRoutines::amd64::double_sign_flip(); + address const_address = (address) StubRoutines::x86::double_sign_flip(); // cmpq $dst, [0x8000000000000000] cbuf.set_inst_mark(); @@ -4175,7 +4180,7 @@ encode %{ emit_opcode(cbuf, 0xE8); emit_d32_reloc(cbuf, (int) - (StubRoutines::amd64::d2l_fixup() - cbuf.code_end() - 4), + (StubRoutines::x86::d2l_fixup() - cbuf.code_end() - 4), runtime_call_Relocation::spec(), RELOC_DISP32); diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index bc5d9ebc69e..551857525cd 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -94,6 +94,9 @@ static pid_t _initial_pid = 0; static int SR_signum = SIGUSR2; sigset_t SR_sigset; +/* Used to protect dlsym() calls */ +static pthread_mutex_t dl_mutex; + //////////////////////////////////////////////////////////////////////////////// // utility functions @@ -1493,6 +1496,24 @@ const char* os::dll_file_extension() { return ".so"; } const char* os::get_temp_directory() { return "/tmp/"; } +void os::dll_build_name( + char* buffer, size_t buflen, const char* pname, const char* fname) { + // copied from libhpi + const size_t pnamelen = pname ? strlen(pname) : 0; + + /* Quietly truncate on buffer overflow. Should be an error. */ + if (pnamelen + strlen(fname) + 10 > (size_t) buflen) { + *buffer = '\0'; + return; + } + + if (pnamelen == 0) { + sprintf(buffer, "lib%s.so", fname); + } else { + sprintf(buffer, "%s/lib%s.so", pname, fname); + } +} + const char* os::get_current_directory(char *buf, int buflen) { return getcwd(buf, buflen); } @@ -1742,7 +1763,17 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) return NULL; } - +/* + * glibc-2.0 libdl is not MT safe. If you are building with any glibc, + * chances are you might want to run the generated bits against glibc-2.0 + * libdl.so, so always use locking for any version of glibc. + */ +void* os::dll_lookup(void* handle, const char* name) { + pthread_mutex_lock(&dl_mutex); + void* res = dlsym(handle, name); + pthread_mutex_unlock(&dl_mutex); + return res; +} bool _print_ascii_file(const char* filename, outputStream* st) { @@ -2278,7 +2309,7 @@ void os::Linux::libnuma_init() { dlsym(RTLD_DEFAULT, "sched_getcpu"))); if (sched_getcpu() != -1) { // Does it work? - void *handle = dlopen("libnuma.so", RTLD_LAZY); + void *handle = dlopen("libnuma.so.1", RTLD_LAZY); if (handle != NULL) { set_numa_node_to_cpus(CAST_TO_FN_PTR(numa_node_to_cpus_func_t, dlsym(handle, "numa_node_to_cpus"))); @@ -3581,6 +3612,7 @@ void os::init(void) { Linux::clock_init(); initial_time_count = os::elapsed_counter(); + pthread_mutex_init(&dl_mutex, NULL); } // To install functions for atexit system call diff --git a/hotspot/src/os/solaris/vm/osThread_solaris.cpp b/hotspot/src/os/solaris/vm/osThread_solaris.cpp index 702e6d4e2d5..14974271efe 100644 --- a/hotspot/src/os/solaris/vm/osThread_solaris.cpp +++ b/hotspot/src/os/solaris/vm/osThread_solaris.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,15 +69,15 @@ void OSThread::pd_destroy() { static intptr_t compare_and_exchange_current_callback ( intptr_t callback, intptr_t *addr, intptr_t compare_value, Mutex *sync) { if (VM_Version::supports_compare_and_exchange()) { - return Atomic::cmpxchg_ptr(callback, addr, compare_value); + return Atomic::cmpxchg_ptr(callback, addr, compare_value); } else { - MutexLockerEx(sync, Mutex::_no_safepoint_check_flag); - if (*addr == compare_value) { - *addr = callback; - return compare_value; - } else { - return callback; - } + MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag); + if (*addr == compare_value) { + *addr = callback; + return compare_value; + } else { + return callback; + } } } @@ -86,7 +86,7 @@ static intptr_t exchange_current_callback(intptr_t callback, intptr_t *addr, Mut if (VM_Version::supports_compare_and_exchange()) { return Atomic::xchg_ptr(callback, addr); } else { - MutexLockerEx(sync, Mutex::_no_safepoint_check_flag); + MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag); intptr_t cb = *addr; *addr = callback; return cb; diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp index b6ca2a6db90..0c533f06246 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.cpp +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp @@ -1783,6 +1783,24 @@ const char* os::dll_file_extension() { return ".so"; } const char* os::get_temp_directory() { return "/tmp/"; } +void os::dll_build_name( + char* buffer, size_t buflen, const char* pname, const char* fname) { + // copied from libhpi + const size_t pnamelen = pname ? strlen(pname) : 0; + + /* Quietly truncate on buffer overflow. Should be an error. */ + if (pnamelen + strlen(fname) + 10 > (size_t) buflen) { + *buffer = '\0'; + return; + } + + if (pnamelen == 0) { + sprintf(buffer, "lib%s.so", fname); + } else { + sprintf(buffer, "%s/lib%s.so", pname, fname); + } +} + const char* os::get_current_directory(char *buf, int buflen) { return getcwd(buf, buflen); } @@ -2034,6 +2052,9 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) return NULL; } +void* os::dll_lookup(void* handle, const char* name) { + return dlsym(handle, name); +} bool _print_ascii_file(const char* filename, outputStream* st) { @@ -2658,6 +2679,12 @@ size_t os::numa_get_leaf_groups(int *ids, size_t size) { top += r; cur++; } + if (bottom == 0) { + // Handle a situation, when the OS reports no memory available. + // Assume UMA architecture. + ids[0] = 0; + return 1; + } return bottom; } @@ -4581,7 +4608,7 @@ void os::Solaris::synchronization_init() { } void os::Solaris::liblgrp_init() { - void *handle = dlopen("liblgrp.so", RTLD_LAZY); + void *handle = dlopen("liblgrp.so.1", RTLD_LAZY); if (handle != NULL) { os::Solaris::set_lgrp_home(CAST_TO_FN_PTR(lgrp_home_func_t, dlsym(handle, "lgrp_home"))); os::Solaris::set_lgrp_init(CAST_TO_FN_PTR(lgrp_init_func_t, dlsym(handle, "lgrp_init"))); diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index 14b3141d27e..60e99f67f9d 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -985,6 +985,28 @@ const char * os::get_temp_directory() } } +void os::dll_build_name(char *holder, size_t holderlen, + const char* pname, const char* fname) +{ + // copied from libhpi + const size_t pnamelen = pname ? strlen(pname) : 0; + const char c = (pnamelen > 0) ? pname[pnamelen-1] : 0; + + /* Quietly truncates on buffer overflow. Should be an error. */ + if (pnamelen + strlen(fname) + 10 > holderlen) { + *holder = '\0'; + return; + } + + if (pnamelen == 0) { + sprintf(holder, "%s.dll", fname); + } else if (c == ':' || c == '\\') { + sprintf(holder, "%s%s.dll", pname, fname); + } else { + sprintf(holder, "%s\\%s.dll", pname, fname); + } +} + // Needs to be in os specific directory because windows requires another // header file const char* os::get_current_directory(char *buf, int buflen) { @@ -1248,6 +1270,10 @@ bool os::dll_address_to_function_name(address addr, char *buf, return false; } +void* os::dll_lookup(void* handle, const char* name) { + return GetProcAddress((HMODULE)handle, name); +} + // save the start and end address of jvm.dll into param[0] and param[1] static int _locate_jvm_dll(int pid, char* mod_fname, address base_addr, unsigned size, void * param) { @@ -1421,44 +1447,78 @@ void os::print_dll_info(outputStream *st) { enumerate_modules(pid, _print_module, (void *)st); } +// function pointer to Windows API "GetNativeSystemInfo". +typedef void (WINAPI *GetNativeSystemInfo_func_type)(LPSYSTEM_INFO); +static GetNativeSystemInfo_func_type _GetNativeSystemInfo; + void os::print_os_info(outputStream* st) { - st->print("OS:"); + st->print("OS:"); - OSVERSIONINFOEX osvi; - ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + OSVERSIONINFOEX osvi; + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - if (!GetVersionEx((OSVERSIONINFO *)&osvi)) { - st->print_cr("N/A"); - return; - } + if (!GetVersionEx((OSVERSIONINFO *)&osvi)) { + st->print_cr("N/A"); + return; + } - int os_vers = osvi.dwMajorVersion * 1000 + osvi.dwMinorVersion; - - if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) { - switch (os_vers) { - case 3051: st->print(" Windows NT 3.51"); break; - case 4000: st->print(" Windows NT 4.0"); break; - case 5000: st->print(" Windows 2000"); break; - case 5001: st->print(" Windows XP"); break; - case 5002: st->print(" Windows Server 2003 family"); break; - case 6000: st->print(" Windows Vista"); break; - default: // future windows, print out its major and minor versions - st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion); - } - } else { - switch (os_vers) { - case 4000: st->print(" Windows 95"); break; - case 4010: st->print(" Windows 98"); break; - case 4090: st->print(" Windows Me"); break; - default: // future windows, print out its major and minor versions - st->print(" Windows %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion); - } - } - - st->print(" Build %d", osvi.dwBuildNumber); - st->print(" %s", osvi.szCSDVersion); // service pack - st->cr(); + int os_vers = osvi.dwMajorVersion * 1000 + osvi.dwMinorVersion; + if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) { + switch (os_vers) { + case 3051: st->print(" Windows NT 3.51"); break; + case 4000: st->print(" Windows NT 4.0"); break; + case 5000: st->print(" Windows 2000"); break; + case 5001: st->print(" Windows XP"); break; + case 5002: + case 6000: { + // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could + // find out whether we are running on 64 bit processor or not. + SYSTEM_INFO si; + ZeroMemory(&si, sizeof(SYSTEM_INFO)); + // Check to see if _GetNativeSystemInfo has been initialized. + if (_GetNativeSystemInfo == NULL) { + HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32.dll")); + _GetNativeSystemInfo = + CAST_TO_FN_PTR(GetNativeSystemInfo_func_type, + GetProcAddress(hKernel32, + "GetNativeSystemInfo")); + if (_GetNativeSystemInfo == NULL) + GetSystemInfo(&si); + } else { + _GetNativeSystemInfo(&si); + } + if (os_vers == 5002) { + if (osvi.wProductType == VER_NT_WORKSTATION && + si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) + st->print(" Windows XP x64 Edition"); + else + st->print(" Windows Server 2003 family"); + } else { // os_vers == 6000 + if (osvi.wProductType == VER_NT_WORKSTATION) + st->print(" Windows Vista"); + else + st->print(" Windows Server 2008"); + if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) + st->print(" , 64 bit"); + } + break; + } + default: // future windows, print out its major and minor versions + st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion); + } + } else { + switch (os_vers) { + case 4000: st->print(" Windows 95"); break; + case 4010: st->print(" Windows 98"); break; + case 4090: st->print(" Windows Me"); break; + default: // future windows, print out its major and minor versions + st->print(" Windows %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion); + } + } + st->print(" Build %d", osvi.dwBuildNumber); + st->print(" %s", osvi.szCSDVersion); // service pack + st->cr(); } void os::print_memory_info(outputStream* st) { diff --git a/hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86_64.cpp b/hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86.cpp similarity index 63% rename from hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86_64.cpp rename to hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86.cpp index 24a4dce09e4..4211d36118b 100644 --- a/hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86_64.cpp +++ b/hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,24 @@ */ #include "incls/_precompiled.incl" -#include "incls/_assembler_linux_x86_64.cpp.incl" +#include "incls/_assembler_linux_x86.cpp.incl" +#ifndef _LP64 +void MacroAssembler::int3() { + call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); +} + +void MacroAssembler::get_thread(Register thread) { + movl(thread, rsp); + shrl(thread, PAGE_SHIFT); + + ExternalAddress tls_base((address)ThreadLocalStorage::sp_map_addr()); + Address index(noreg, thread, Address::times_4); + ArrayAddress tls(tls_base, index); + + movptr(thread, tls); +} +#else void MacroAssembler::int3() { call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); } @@ -33,35 +49,36 @@ void MacroAssembler::get_thread(Register thread) { // call pthread_getspecific // void * pthread_getspecific(pthread_key_t key); if (thread != rax) { - pushq(rax); + push(rax); } - pushq(rdi); - pushq(rsi); - pushq(rdx); - pushq(rcx); - pushq(r8); - pushq(r9); - pushq(r10); + push(rdi); + push(rsi); + push(rdx); + push(rcx); + push(r8); + push(r9); + push(r10); // XXX - movq(r10, rsp); + mov(r10, rsp); andq(rsp, -16); - pushq(r10); - pushq(r11); + push(r10); + push(r11); movl(rdi, ThreadLocalStorage::thread_index()); call(RuntimeAddress(CAST_FROM_FN_PTR(address, pthread_getspecific))); - popq(r11); - popq(rsp); - popq(r10); - popq(r9); - popq(r8); - popq(rcx); - popq(rdx); - popq(rsi); - popq(rdi); + pop(r11); + pop(rsp); + pop(r10); + pop(r9); + pop(r8); + pop(rcx); + pop(rdx); + pop(rsi); + pop(rdi); if (thread != rax) { - movq(thread, rax); - popq(rax); + mov(thread, rax); + pop(rax); } } +#endif diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/assembler_solaris_sparc.cpp b/hotspot/src/os_cpu/solaris_sparc/vm/assembler_solaris_sparc.cpp index caab18f5dcd..a1ddb4c3946 100644 --- a/hotspot/src/os_cpu/solaris_sparc/vm/assembler_solaris_sparc.cpp +++ b/hotspot/src/os_cpu/solaris_sparc/vm/assembler_solaris_sparc.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86_32.cpp b/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86.cpp similarity index 50% rename from hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86_32.cpp rename to hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86.cpp index bce611c1125..9fd017b41a6 100644 --- a/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86_32.cpp +++ b/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86.cpp @@ -23,59 +23,111 @@ */ #include "incls/_precompiled.incl" -#include "incls/_assembler_solaris_x86_32.cpp.incl" +#include "incls/_assembler_solaris_x86.cpp.incl" void MacroAssembler::int3() { - pushl(rax); - pushl(rdx); - pushl(rcx); + push(rax); + push(rdx); + push(rcx); call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); - popl(rcx); - popl(rdx); - popl(rax); + pop(rcx); + pop(rdx); + pop(rax); } -void MacroAssembler::get_thread(Register thread) { - - // Try to emit a Solaris-specific fast TSD/TLS accessor. - ThreadLocalStorage::pd_tlsAccessMode tlsMode = ThreadLocalStorage::pd_getTlsAccessMode () ; - if (tlsMode == ThreadLocalStorage::pd_tlsAccessIndirect) { // T1 - // Use thread as a temporary: mov r, gs:[0]; mov r, [r+tlsOffset] - emit_byte (Assembler::GS_segment) ; - // ExternalAddress doesn't work because it can't take NULL - AddressLiteral null(0, relocInfo::none); - movptr (thread, null); - movl (thread, Address(thread, ThreadLocalStorage::pd_getTlsOffset())) ; - return ; - } else - if (tlsMode == ThreadLocalStorage::pd_tlsAccessDirect) { // T2 - // mov r, gs:[tlsOffset] - emit_byte (Assembler::GS_segment) ; - AddressLiteral tls((address)ThreadLocalStorage::pd_getTlsOffset(), relocInfo::none); - movptr (thread, tls); - return ; - } +#define __ _masm-> +#ifndef _LP64 +static void slow_call_thr_specific(MacroAssembler* _masm, Register thread) { // slow call to of thr_getspecific // int thr_getspecific(thread_key_t key, void **value); // Consider using pthread_getspecific instead. - pushl(0); // allocate space for return value - if (thread != rax) pushl(rax); // save rax, if caller still wants it - pushl(rcx); // save caller save - pushl(rdx); // save caller save +__ push(0); // allocate space for return value + if (thread != rax) __ push(rax); // save rax, if caller still wants it +__ push(rcx); // save caller save +__ push(rdx); // save caller save if (thread != rax) { - leal(thread, Address(rsp, 3 * sizeof(int))); // address of return value +__ lea(thread, Address(rsp, 3 * sizeof(int))); // address of return value } else { - leal(thread, Address(rsp, 2 * sizeof(int))); // address of return value +__ lea(thread, Address(rsp, 2 * sizeof(int))); // address of return value } - pushl(thread); // and pass the address - pushl(ThreadLocalStorage::thread_index()); // the key - call(RuntimeAddress(CAST_FROM_FN_PTR(address, thr_getspecific))); - increment(rsp, 2 * wordSize); - popl(rdx); - popl(rcx); - if (thread != rax) popl(rax); - popl(thread); +__ push(thread); // and pass the address +__ push(ThreadLocalStorage::thread_index()); // the key +__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, thr_getspecific))); +__ increment(rsp, 2 * wordSize); +__ pop(rdx); +__ pop(rcx); + if (thread != rax) __ pop(rax); +__ pop(thread); + +} +#else +static void slow_call_thr_specific(MacroAssembler* _masm, Register thread) { + // slow call to of thr_getspecific + // int thr_getspecific(thread_key_t key, void **value); + // Consider using pthread_getspecific instead. + + if (thread != rax) { +__ push(rax); + } +__ push(0); // space for return value +__ push(rdi); +__ push(rsi); +__ lea(rsi, Address(rsp, 16)); // pass return value address +__ push(rdx); +__ push(rcx); +__ push(r8); +__ push(r9); +__ push(r10); + // XXX +__ mov(r10, rsp); +__ andptr(rsp, -16); +__ push(r10); +__ push(r11); + +__ movl(rdi, ThreadLocalStorage::thread_index()); +__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, thr_getspecific))); + +__ pop(r11); +__ pop(rsp); +__ pop(r10); +__ pop(r9); +__ pop(r8); +__ pop(rcx); +__ pop(rdx); +__ pop(rsi); +__ pop(rdi); +__ pop(thread); // load return value + if (thread != rax) { +__ pop(rax); + } +} +#endif //LP64 + +void MacroAssembler::get_thread(Register thread) { + + int segment = NOT_LP64(Assembler::GS_segment) LP64_ONLY(Assembler::FS_segment); + // Try to emit a Solaris-specific fast TSD/TLS accessor. + ThreadLocalStorage::pd_tlsAccessMode tlsMode = ThreadLocalStorage::pd_getTlsAccessMode (); + if (tlsMode == ThreadLocalStorage::pd_tlsAccessIndirect) { // T1 + // Use thread as a temporary: mov r, gs:[0]; mov r, [r+tlsOffset] + emit_byte (segment); + // ExternalAddress doesn't work because it can't take NULL + AddressLiteral null(0, relocInfo::none); + movptr (thread, null); + movptr(thread, Address(thread, ThreadLocalStorage::pd_getTlsOffset())) ; + return ; + } else + if (tlsMode == ThreadLocalStorage::pd_tlsAccessDirect) { // T2 + // mov r, gs:[tlsOffset] + emit_byte (segment); + AddressLiteral tls_off((address)ThreadLocalStorage::pd_getTlsOffset(), relocInfo::none); + movptr (thread, tls_off); + return ; + } + + slow_call_thr_specific(this, thread); + } diff --git a/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86_64.cpp b/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86_64.cpp deleted file mode 100644 index 2ccae8a683d..00000000000 --- a/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86_64.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -#include "incls/_precompiled.incl" -#include "incls/_assembler_solaris_x86_64.cpp.incl" - -void MacroAssembler::int3() { - call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); -} - -void MacroAssembler::get_thread(Register thread) { - // Try to emit a Solaris-specific fast TSD/TLS accessor. - ThreadLocalStorage::pd_tlsAccessMode tlsMode = ThreadLocalStorage::pd_getTlsAccessMode(); - if (tlsMode == ThreadLocalStorage::pd_tlsAccessIndirect) { // T1 - // Use thread as a temporary: mov r, fs:[0]; mov r, [r+tlsOffset] - emit_byte(Assembler::FS_segment); - movq(thread, Address(NULL, relocInfo::none)); - movq(thread, Address(thread, ThreadLocalStorage::pd_getTlsOffset())); - return; - } else if (tlsMode == ThreadLocalStorage::pd_tlsAccessDirect) { // T2 - // mov r, fs:[tlsOffset] - emit_byte(Assembler::FS_segment); - ExternalAddress tls_off((address) ThreadLocalStorage::pd_getTlsOffset()); - movptr(thread, tls_off); - return; - } - - // slow call to of thr_getspecific - // int thr_getspecific(thread_key_t key, void **value); - // Consider using pthread_getspecific instead. - - if (thread != rax) { - pushq(rax); - } - pushq(0); // space for return value - pushq(rdi); - pushq(rsi); - leaq(rsi, Address(rsp, 16)); // pass return value address - pushq(rdx); - pushq(rcx); - pushq(r8); - pushq(r9); - pushq(r10); - // XXX - movq(r10, rsp); - andq(rsp, -16); - pushq(r10); - pushq(r11); - - movl(rdi, ThreadLocalStorage::thread_index()); - call(RuntimeAddress(CAST_FROM_FN_PTR(address, thr_getspecific))); - - popq(r11); - popq(rsp); - popq(r10); - popq(r9); - popq(r8); - popq(rcx); - popq(rdx); - popq(rsi); - popq(rdi); - popq(thread); // load return value - if (thread != rax) { - popq(rax); - } -} diff --git a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.ad b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.ad index 0409fb55d8b..911a8ad7d13 100644 --- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.ad +++ b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.ad @@ -1,5 +1,5 @@ // -// Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. +// Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it @@ -62,13 +62,13 @@ encode %{ enc_class solaris_breakpoint %{ MacroAssembler* masm = new MacroAssembler(&cbuf); // Really need to fix this - masm->pushl(rax); - masm->pushl(rcx); - masm->pushl(rdx); + masm->push(rax); + masm->push(rcx); + masm->push(rdx); masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); - masm->popl(rdx); - masm->popl(rcx); - masm->popl(rax); + masm->pop(rdx); + masm->pop(rcx); + masm->pop(rax); %} enc_class call_epilog %{ diff --git a/hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86_32.cpp b/hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86.cpp similarity index 78% rename from hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86_32.cpp rename to hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86.cpp index 5e91ce654f8..4d4642143e8 100644 --- a/hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86_32.cpp +++ b/hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86.cpp @@ -23,13 +23,14 @@ */ #include "incls/_precompiled.incl" -#include "incls/_assembler_windows_x86_32.cpp.incl" +#include "incls/_assembler_windows_x86.cpp.incl" void MacroAssembler::int3() { emit_byte(0xCC); } +#ifndef _LP64 // The current scheme to accelerate access to the thread // pointer is to store the current thread in the os_exception_wrapper // and reference the current thread from stubs and compiled code @@ -58,3 +59,40 @@ void MacroAssembler::get_thread(Register thread) { "Thread Pointer Offset has not been initialized"); movl(thread, Address(thread, ThreadLocalStorage::get_thread_ptr_offset())); } +#else +// call (Thread*)TlsGetValue(thread_index()); +void MacroAssembler::get_thread(Register thread) { + if (thread != rax) { + push(rax); + } + push(rdi); + push(rsi); + push(rdx); + push(rcx); + push(r8); + push(r9); + push(r10); + // XXX + mov(r10, rsp); + andq(rsp, -16); + push(r10); + push(r11); + + movl(c_rarg0, ThreadLocalStorage::thread_index()); + call(RuntimeAddress((address)TlsGetValue)); + + pop(r11); + pop(rsp); + pop(r10); + pop(r9); + pop(r8); + pop(rcx); + pop(rdx); + pop(rsi); + pop(rdi); + if (thread != rax) { + mov(thread, rax); + pop(rax); + } +} +#endif diff --git a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp index a2504045915..27b6af946d6 100644 --- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp +++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -369,7 +369,7 @@ frame os::current_frame() { // apparently _asm not supported on windows amd64 typedef intptr_t* get_fp_func (); get_fp_func* func = CAST_TO_FN_PTR(get_fp_func*, - StubRoutines::amd64::get_previous_fp_entry()); + StubRoutines::x86::get_previous_fp_entry()); if (func == NULL) return frame(NULL, NULL, NULL); intptr_t* fp = (*func)(); #else diff --git a/hotspot/src/share/vm/adlc/formssel.cpp b/hotspot/src/share/vm/adlc/formssel.cpp index 47fe6ae04eb..b45de088afb 100644 --- a/hotspot/src/share/vm/adlc/formssel.cpp +++ b/hotspot/src/share/vm/adlc/formssel.cpp @@ -3825,6 +3825,8 @@ int MatchRule::is_expensive() const { strcmp(opType,"ConvL2D")==0 || strcmp(opType,"ConvL2F")==0 || strcmp(opType,"ConvL2I")==0 || + strcmp(opType,"DecodeN")==0 || + strcmp(opType,"EncodeP")==0 || strcmp(opType,"RoundDouble")==0 || strcmp(opType,"RoundFloat")==0 || strcmp(opType,"ReverseBytesI")==0 || diff --git a/hotspot/src/share/vm/adlc/output_h.cpp b/hotspot/src/share/vm/adlc/output_h.cpp index 78f16078381..04cddcd28c8 100644 --- a/hotspot/src/share/vm/adlc/output_h.cpp +++ b/hotspot/src/share/vm/adlc/output_h.cpp @@ -1848,6 +1848,19 @@ void ArchDesc::declareClasses(FILE *fp) { fprintf(fp," const Type *bottom_type() const { const Type *t = in(oper_input_base()+%d)->bottom_type(); return (req() <= oper_input_base()+%d) ? t : t->meet(in(oper_input_base()+%d)->bottom_type()); } // CMoveP\n", offset, offset+1, offset+1); } + else if( instr->_matrule && instr->_matrule->_rChild && !strcmp(instr->_matrule->_rChild->_opType,"CMoveN") ) { + int offset = 1; + // Special special hack to see if the Cmp? has been incorporated in the conditional move + MatchNode *rl = instr->_matrule->_rChild->_lChild; + if( rl && !strcmp(rl->_opType, "Binary") ) { + MatchNode *rlr = rl->_rChild; + if (rlr && strncmp(rlr->_opType, "Cmp", 3) == 0) + offset = 2; + } + // Special hack for ideal CMoveN; ideal type depends on inputs + fprintf(fp," const Type *bottom_type() const { const Type *t = in(oper_input_base()+%d)->bottom_type(); return (req() <= oper_input_base()+%d) ? t : t->meet(in(oper_input_base()+%d)->bottom_type()); } // CMoveN\n", + offset, offset+1, offset+1); + } else if( instr->needs_base_oop_edge(_globalNames) ) { // Special hack for ideal AddP. Bottom type is an oop IFF it has a // legal base-pointer input. Otherwise it is NOT an oop. diff --git a/hotspot/src/share/vm/asm/assembler.cpp b/hotspot/src/share/vm/asm/assembler.cpp index dcf1f0dcd94..34ae81ce1cd 100644 --- a/hotspot/src/share/vm/asm/assembler.cpp +++ b/hotspot/src/share/vm/asm/assembler.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/hotspot/src/share/vm/c1/c1_FrameMap.cpp b/hotspot/src/share/vm/c1/c1_FrameMap.cpp index 31e29bed07f..970dad4d9c6 100644 --- a/hotspot/src/share/vm/c1/c1_FrameMap.cpp +++ b/hotspot/src/share/vm/c1/c1_FrameMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -278,7 +278,7 @@ ByteSize FrameMap::sp_offset_for_spill(const int index) const { ByteSize FrameMap::sp_offset_for_monitor_base(const int index) const { int end_of_spills = round_to(first_available_sp_in_frame + _reserved_argument_area_size, sizeof(double)) + _num_spills * spill_slot_size_in_bytes; - int offset = round_to(end_of_spills, HeapWordSize) + index * sizeof(BasicObjectLock); + int offset = (int) round_to(end_of_spills, HeapWordSize) + index * sizeof(BasicObjectLock); return in_ByteSize(offset); } diff --git a/hotspot/src/share/vm/c1/c1_LIR.cpp b/hotspot/src/share/vm/c1/c1_LIR.cpp index 7335abb0731..0c0f1eda623 100644 --- a/hotspot/src/share/vm/c1/c1_LIR.cpp +++ b/hotspot/src/share/vm/c1/c1_LIR.cpp @@ -37,7 +37,7 @@ Register LIR_OprDesc::as_register_hi() const { return FrameMap::cpu_rnr2reg(cpu_regnrHi()); } -#ifdef IA32 +#if defined(X86) XMMRegister LIR_OprDesc::as_xmm_float_reg() const { return FrameMap::nr2xmmreg(xmm_regnr()); @@ -48,7 +48,7 @@ XMMRegister LIR_OprDesc::as_xmm_double_reg() const { return FrameMap::nr2xmmreg(xmm_regnrLo()); } -#endif +#endif // X86 #ifdef SPARC @@ -81,7 +81,7 @@ LIR_Opr LIR_OprFact::value_type(ValueType* type) { case floatTag : return LIR_OprFact::floatConst(type->as_FloatConstant()->value()); case longTag : return LIR_OprFact::longConst(type->as_LongConstant()->value()); case doubleTag : return LIR_OprFact::doubleConst(type->as_DoubleConstant()->value()); - default: ShouldNotReachHere(); + default: ShouldNotReachHere(); return LIR_OprFact::intConst(-1); } } @@ -94,7 +94,7 @@ LIR_Opr LIR_OprFact::dummy_value_type(ValueType* type) { case floatTag: return LIR_OprFact::floatConst(0.0); case longTag: return LIR_OprFact::longConst(0); case doubleTag: return LIR_OprFact::doubleConst(0.0); - default: ShouldNotReachHere(); + default: ShouldNotReachHere(); return LIR_OprFact::intConst(-1); } return illegalOpr; } @@ -162,6 +162,7 @@ char LIR_OprDesc::type_char(BasicType t) { default: ShouldNotReachHere(); + return '?'; } } @@ -1374,7 +1375,7 @@ void LIR_OprDesc::print(outputStream* out) const { } else if (is_double_cpu()) { out->print(as_register_hi()->name()); out->print(as_register_lo()->name()); -#ifdef IA32 +#if defined(X86) } else if (is_single_xmm()) { out->print(as_xmm_float_reg()->name()); } else if (is_double_xmm()) { diff --git a/hotspot/src/share/vm/c1/c1_LIR.hpp b/hotspot/src/share/vm/c1/c1_LIR.hpp index 6612604ca66..d263b4e6b8d 100644 --- a/hotspot/src/share/vm/c1/c1_LIR.hpp +++ b/hotspot/src/share/vm/c1/c1_LIR.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -135,6 +135,13 @@ class LIR_Const: public LIR_OprPtr { return as_jint_hi(); } } + jlong as_jlong_bits() const { + if (type() == T_DOUBLE) { + return jlong_cast(_value.get_jdouble()); + } else { + return as_jlong(); + } + } virtual void print_value_on(outputStream* out) const PRODUCT_RETURN; @@ -302,6 +309,7 @@ class LIR_OprDesc: public CompilationResourceObj { default: ShouldNotReachHere(); + return single_size; } } @@ -417,12 +425,12 @@ class LIR_OprDesc: public CompilationResourceObj { return as_register(); } -#ifdef IA32 +#ifdef X86 XMMRegister as_xmm_float_reg() const; XMMRegister as_xmm_double_reg() const; // for compatibility with RInfo int fpu () const { return lo_reg_half(); } -#endif +#endif // X86 #ifdef SPARC FloatRegister as_float_reg () const; @@ -503,14 +511,14 @@ class LIR_Address: public LIR_OprPtr { , _type(type) , _disp(disp) { verify(); } -#ifdef IA32 +#ifdef X86 LIR_Address(LIR_Opr base, LIR_Opr index, Scale scale, int disp, BasicType type): _base(base) , _index(index) , _scale(scale) , _type(type) , _disp(disp) { verify(); } -#endif +#endif // X86 LIR_Opr base() const { return _base; } LIR_Opr index() const { return _index; } @@ -535,31 +543,93 @@ class LIR_OprFact: public AllStatic { static LIR_Opr illegalOpr; - static LIR_Opr single_cpu(int reg) { return (LIR_Opr)((reg << LIR_OprDesc::reg1_shift) | LIR_OprDesc::int_type | LIR_OprDesc::cpu_register | LIR_OprDesc::single_size); } - static LIR_Opr single_cpu_oop(int reg) { return (LIR_Opr)((reg << LIR_OprDesc::reg1_shift) | LIR_OprDesc::object_type | LIR_OprDesc::cpu_register | LIR_OprDesc::single_size); } - static LIR_Opr double_cpu(int reg1, int reg2) { return (LIR_Opr)((reg1 << LIR_OprDesc::reg1_shift) | (reg2 << LIR_OprDesc::reg2_shift) | LIR_OprDesc::long_type | LIR_OprDesc::cpu_register | LIR_OprDesc::double_size); } + static LIR_Opr single_cpu(int reg) { return (LIR_Opr)(intptr_t)((reg << LIR_OprDesc::reg1_shift) | LIR_OprDesc::int_type | LIR_OprDesc::cpu_register | LIR_OprDesc::single_size); } + static LIR_Opr single_cpu_oop(int reg) { return (LIR_Opr)(intptr_t)((reg << LIR_OprDesc::reg1_shift) | LIR_OprDesc::object_type | LIR_OprDesc::cpu_register | LIR_OprDesc::single_size); } + static LIR_Opr double_cpu(int reg1, int reg2) { + LP64_ONLY(assert(reg1 == reg2, "must be identical")); + return (LIR_Opr)(intptr_t)((reg1 << LIR_OprDesc::reg1_shift) | + (reg2 << LIR_OprDesc::reg2_shift) | + LIR_OprDesc::long_type | + LIR_OprDesc::cpu_register | + LIR_OprDesc::double_size); + } - static LIR_Opr single_fpu(int reg) { return (LIR_Opr)((reg << LIR_OprDesc::reg1_shift) | LIR_OprDesc::float_type | LIR_OprDesc::fpu_register | LIR_OprDesc::single_size); } + static LIR_Opr single_fpu(int reg) { return (LIR_Opr)(intptr_t)((reg << LIR_OprDesc::reg1_shift) | + LIR_OprDesc::float_type | + LIR_OprDesc::fpu_register | + LIR_OprDesc::single_size); } #ifdef SPARC - static LIR_Opr double_fpu(int reg1, int reg2) { return (LIR_Opr)((reg1 << LIR_OprDesc::reg1_shift) | (reg2 << LIR_OprDesc::reg2_shift) | LIR_OprDesc::double_type | LIR_OprDesc::fpu_register | LIR_OprDesc::double_size); } -#endif -#ifdef IA32 - static LIR_Opr double_fpu(int reg) { return (LIR_Opr)((reg << LIR_OprDesc::reg1_shift) | (reg << LIR_OprDesc::reg2_shift) | LIR_OprDesc::double_type | LIR_OprDesc::fpu_register | LIR_OprDesc::double_size); } - static LIR_Opr single_xmm(int reg) { return (LIR_Opr)((reg << LIR_OprDesc::reg1_shift) | LIR_OprDesc::float_type | LIR_OprDesc::fpu_register | LIR_OprDesc::single_size | LIR_OprDesc::is_xmm_mask); } - static LIR_Opr double_xmm(int reg) { return (LIR_Opr)((reg << LIR_OprDesc::reg1_shift) | (reg << LIR_OprDesc::reg2_shift) | LIR_OprDesc::double_type | LIR_OprDesc::fpu_register | LIR_OprDesc::double_size | LIR_OprDesc::is_xmm_mask); } + static LIR_Opr double_fpu(int reg1, int reg2) { return (LIR_Opr)(intptr_t)((reg1 << LIR_OprDesc::reg1_shift) | + (reg2 << LIR_OprDesc::reg2_shift) | + LIR_OprDesc::double_type | + LIR_OprDesc::fpu_register | + LIR_OprDesc::double_size); } #endif +#ifdef X86 + static LIR_Opr double_fpu(int reg) { return (LIR_Opr)(intptr_t)((reg << LIR_OprDesc::reg1_shift) | + (reg << LIR_OprDesc::reg2_shift) | + LIR_OprDesc::double_type | + LIR_OprDesc::fpu_register | + LIR_OprDesc::double_size); } + + static LIR_Opr single_xmm(int reg) { return (LIR_Opr)(intptr_t)((reg << LIR_OprDesc::reg1_shift) | + LIR_OprDesc::float_type | + LIR_OprDesc::fpu_register | + LIR_OprDesc::single_size | + LIR_OprDesc::is_xmm_mask); } + static LIR_Opr double_xmm(int reg) { return (LIR_Opr)(intptr_t)((reg << LIR_OprDesc::reg1_shift) | + (reg << LIR_OprDesc::reg2_shift) | + LIR_OprDesc::double_type | + LIR_OprDesc::fpu_register | + LIR_OprDesc::double_size | + LIR_OprDesc::is_xmm_mask); } +#endif // X86 static LIR_Opr virtual_register(int index, BasicType type) { LIR_Opr res; switch (type) { case T_OBJECT: // fall through - case T_ARRAY: res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::object_type | LIR_OprDesc::cpu_register | LIR_OprDesc::single_size | LIR_OprDesc::virtual_mask); break; - case T_INT: res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::int_type | LIR_OprDesc::cpu_register | LIR_OprDesc::single_size | LIR_OprDesc::virtual_mask); break; - case T_LONG: res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::long_type | LIR_OprDesc::cpu_register | LIR_OprDesc::double_size | LIR_OprDesc::virtual_mask); break; - case T_FLOAT: res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::float_type | LIR_OprDesc::fpu_register | LIR_OprDesc::single_size | LIR_OprDesc::virtual_mask); break; - case T_DOUBLE: res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::double_type | LIR_OprDesc::fpu_register | LIR_OprDesc::double_size | LIR_OprDesc::virtual_mask); break; + case T_ARRAY: + res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::object_type | + LIR_OprDesc::cpu_register | + LIR_OprDesc::single_size | + LIR_OprDesc::virtual_mask); + break; + + case T_INT: + res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::int_type | + LIR_OprDesc::cpu_register | + LIR_OprDesc::single_size | + LIR_OprDesc::virtual_mask); + break; + + case T_LONG: + res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::long_type | + LIR_OprDesc::cpu_register | + LIR_OprDesc::double_size | + LIR_OprDesc::virtual_mask); + break; + + case T_FLOAT: + res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::float_type | + LIR_OprDesc::fpu_register | + LIR_OprDesc::single_size | + LIR_OprDesc::virtual_mask); + break; + + case + T_DOUBLE: res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::double_type | + LIR_OprDesc::fpu_register | + LIR_OprDesc::double_size | + LIR_OprDesc::virtual_mask); + break; default: ShouldNotReachHere(); res = illegalOpr; } @@ -572,8 +642,8 @@ class LIR_OprFact: public AllStatic { // old-style calculation; check if old and new method are equal LIR_OprDesc::OprType t = as_OprType(type); - LIR_Opr old_res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | t | - ((type == T_FLOAT || type == T_DOUBLE) ? LIR_OprDesc::fpu_register : LIR_OprDesc::cpu_register) | + LIR_Opr old_res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | t | + ((type == T_FLOAT || type == T_DOUBLE) ? LIR_OprDesc::fpu_register : LIR_OprDesc::cpu_register) | LIR_OprDesc::size_for(type) | LIR_OprDesc::virtual_mask); assert(res == old_res, "old and new method not equal"); #endif @@ -588,11 +658,39 @@ class LIR_OprFact: public AllStatic { LIR_Opr res; switch (type) { case T_OBJECT: // fall through - case T_ARRAY: res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::object_type | LIR_OprDesc::stack_value | LIR_OprDesc::single_size); break; - case T_INT: res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::int_type | LIR_OprDesc::stack_value | LIR_OprDesc::single_size); break; - case T_LONG: res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::long_type | LIR_OprDesc::stack_value | LIR_OprDesc::double_size); break; - case T_FLOAT: res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::float_type | LIR_OprDesc::stack_value | LIR_OprDesc::single_size); break; - case T_DOUBLE: res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::double_type | LIR_OprDesc::stack_value | LIR_OprDesc::double_size); break; + case T_ARRAY: + res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::object_type | + LIR_OprDesc::stack_value | + LIR_OprDesc::single_size); + break; + + case T_INT: + res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::int_type | + LIR_OprDesc::stack_value | + LIR_OprDesc::single_size); + break; + + case T_LONG: + res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::long_type | + LIR_OprDesc::stack_value | + LIR_OprDesc::double_size); + break; + + case T_FLOAT: + res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::float_type | + LIR_OprDesc::stack_value | + LIR_OprDesc::single_size); + break; + case T_DOUBLE: + res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::double_type | + LIR_OprDesc::stack_value | + LIR_OprDesc::double_size); + break; default: ShouldNotReachHere(); res = illegalOpr; } @@ -601,7 +699,10 @@ class LIR_OprFact: public AllStatic { assert(index >= 0, "index must be positive"); assert(index <= (max_jint >> LIR_OprDesc::data_shift), "index is too big"); - LIR_Opr old_res = (LIR_Opr)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::stack_value | as_OprType(type) | LIR_OprDesc::size_for(type)); + LIR_Opr old_res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::stack_value | + as_OprType(type) | + LIR_OprDesc::size_for(type)); assert(res == old_res, "old and new method not equal"); #endif diff --git a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp index a8ed3da18a7..48f76fd7767 100644 --- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -215,7 +215,7 @@ void LIR_Assembler::emit_block(BlockBegin* block) { #endif /* PRODUCT */ assert(block->lir() != NULL, "must have LIR"); - IA32_ONLY(assert(_masm->rsp_offset() == 0, "frame size should be fixed")); + X86_ONLY(assert(_masm->rsp_offset() == 0, "frame size should be fixed")); #ifndef PRODUCT if (CommentedAssembly) { @@ -227,7 +227,7 @@ void LIR_Assembler::emit_block(BlockBegin* block) { emit_lir_list(block->lir()); - IA32_ONLY(assert(_masm->rsp_offset() == 0, "frame size should be fixed")); + X86_ONLY(assert(_masm->rsp_offset() == 0, "frame size should be fixed")); } @@ -434,7 +434,7 @@ void LIR_Assembler::emit_call(LIR_OpJavaCall* op) { break; default: ShouldNotReachHere(); } -#if defined(IA32) && defined(TIERED) +#if defined(X86) && defined(TIERED) // C2 leave fpu stack dirty clean it if (UseSSE < 2) { int i; @@ -445,7 +445,7 @@ void LIR_Assembler::emit_call(LIR_OpJavaCall* op) { ffree(0); } } -#endif // IA32 && TIERED +#endif // X86 && TIERED } diff --git a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp index 3a64fe678fa..1cbf564288c 100644 --- a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,9 +75,9 @@ class LIR_Assembler: public CompilationResourceObj { void emit_stubs(CodeStubList* stub_list); // addresses - static Address as_Address(LIR_Address* addr); - static Address as_Address_lo(LIR_Address* addr); - static Address as_Address_hi(LIR_Address* addr); + Address as_Address(LIR_Address* addr); + Address as_Address_lo(LIR_Address* addr); + Address as_Address_hi(LIR_Address* addr); // debug information void add_call_info(int pc_offset, CodeEmitInfo* cinfo); diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp index eb90b3fd2bc..209899357d3 100644 --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1717,7 +1717,7 @@ void LIRGenerator::do_UnsafeGetRaw(UnsafeGetRaw* x) { assert(log2_scale == 0, "must not have a scale"); addr = new LIR_Address(base_op, index_op->as_jint(), dst_type); } else { -#ifdef IA32 +#ifdef X86 addr = new LIR_Address(base_op, index_op, LIR_Address::Scale(log2_scale), 0, dst_type); #else if (index_op->is_illegal() || log2_scale == 0) { diff --git a/hotspot/src/share/vm/c1/c1_LinearScan.cpp b/hotspot/src/share/vm/c1/c1_LinearScan.cpp index 0d733b7e660..328c2e1a016 100644 --- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp +++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,7 +80,7 @@ LinearScan::LinearScan(IR* ir, LIRGenerator* gen, FrameMap* frame_map) , _scope_value_cache(0) // initialized later with correct length , _interval_in_loop(0, 0) // initialized later with correct length , _cached_blocks(*ir->linear_scan_order()) -#ifdef IA32 +#ifdef X86 , _fpu_stack_allocator(NULL) #endif { @@ -116,7 +116,7 @@ int LinearScan::reg_num(LIR_Opr opr) { return opr->cpu_regnr(); } else if (opr->is_double_cpu()) { return opr->cpu_regnrLo(); -#ifdef IA32 +#ifdef X86 } else if (opr->is_single_xmm()) { return opr->fpu_regnr() + pd_first_xmm_reg; } else if (opr->is_double_xmm()) { @@ -128,6 +128,7 @@ int LinearScan::reg_num(LIR_Opr opr) { return opr->fpu_regnrLo() + pd_first_fpu_reg; } else { ShouldNotReachHere(); + return -1; } } @@ -140,7 +141,7 @@ int LinearScan::reg_numHi(LIR_Opr opr) { return -1; } else if (opr->is_double_cpu()) { return opr->cpu_regnrHi(); -#ifdef IA32 +#ifdef X86 } else if (opr->is_single_xmm()) { return -1; } else if (opr->is_double_xmm()) { @@ -152,6 +153,7 @@ int LinearScan::reg_numHi(LIR_Opr opr) { return opr->fpu_regnrHi() + pd_first_fpu_reg; } else { ShouldNotReachHere(); + return -1; } } @@ -1063,7 +1065,7 @@ IntervalUseKind LinearScan::use_kind_of_input_operand(LIR_Op* op, LIR_Opr opr) { } -#ifdef IA32 +#ifdef X86 if (op->code() == lir_cmove) { // conditional moves can handle stack operands assert(op->result_opr()->is_register(), "result must always be in a register"); @@ -1128,7 +1130,7 @@ IntervalUseKind LinearScan::use_kind_of_input_operand(LIR_Op* op, LIR_Opr opr) { } } } -#endif // IA32 +#endif // X86 // all other operands require a register return mustHaveRegister; @@ -1261,7 +1263,7 @@ void LinearScan::build_intervals() { // virtual fpu operands. Otherwise no allocation for fpu registers is // perfomed and so the temp ranges would be useless if (has_fpu_registers()) { -#ifdef IA32 +#ifdef X86 if (UseSSE < 2) { #endif for (i = 0; i < FrameMap::nof_caller_save_fpu_regs; i++) { @@ -1270,7 +1272,7 @@ void LinearScan::build_intervals() { assert(reg_numHi(opr) == -1, "missing addition of range for hi-register"); caller_save_registers[num_caller_save_registers++] = reg_num(opr); } -#ifdef IA32 +#ifdef X86 } if (UseSSE > 0) { for (i = 0; i < FrameMap::nof_caller_save_xmm_regs; i++) { @@ -1299,8 +1301,8 @@ void LinearScan::build_intervals() { // Update intervals for registers live at the end of this block; BitMap live = block->live_out(); - int size = live.size(); - for (int number = live.get_next_one_offset(0, size); number < size; number = live.get_next_one_offset(number + 1, size)) { + int size = (int)live.size(); + for (int number = (int)live.get_next_one_offset(0, size); number < size; number = (int)live.get_next_one_offset(number + 1, size)) { assert(live.at(number), "should not stop here otherwise"); assert(number >= LIR_OprDesc::vreg_base, "fixed intervals must not be live on block bounds"); TRACE_LINEAR_SCAN(2, tty->print_cr("live in %d to %d", number, block_to + 2)); @@ -1654,7 +1656,7 @@ void LinearScan::resolve_collect_mappings(BlockBegin* from_block, BlockBegin* to const BitMap live_at_edge = to_block->live_in(); // visit all registers where the live_at_edge bit is set - for (int r = live_at_edge.get_next_one_offset(0, size); r < size; r = live_at_edge.get_next_one_offset(r + 1, size)) { + for (int r = (int)live_at_edge.get_next_one_offset(0, size); r < size; r = (int)live_at_edge.get_next_one_offset(r + 1, size)) { assert(r < num_regs, "live information set for not exisiting interval"); assert(from_block->live_out().at(r) && to_block->live_in().at(r), "interval not live at this edge"); @@ -1824,7 +1826,7 @@ void LinearScan::resolve_exception_entry(BlockBegin* block, MoveResolver &move_r // visit all registers where the live_in bit is set int size = live_set_size(); - for (int r = block->live_in().get_next_one_offset(0, size); r < size; r = block->live_in().get_next_one_offset(r + 1, size)) { + for (int r = (int)block->live_in().get_next_one_offset(0, size); r < size; r = (int)block->live_in().get_next_one_offset(r + 1, size)) { resolve_exception_entry(block, r, move_resolver); } @@ -1898,7 +1900,7 @@ void LinearScan::resolve_exception_edge(XHandler* handler, int throwing_op_id, M // visit all registers where the live_in bit is set BlockBegin* block = handler->entry_block(); int size = live_set_size(); - for (int r = block->live_in().get_next_one_offset(0, size); r < size; r = block->live_in().get_next_one_offset(r + 1, size)) { + for (int r = (int)block->live_in().get_next_one_offset(0, size); r < size; r = (int)block->live_in().get_next_one_offset(r + 1, size)) { resolve_exception_edge(handler, throwing_op_id, r, NULL, move_resolver); } @@ -2032,19 +2034,19 @@ LIR_Opr LinearScan::calc_operand_for_interval(const Interval* interval) { assert(assigned_reg % 2 == 0 && assigned_reg + 1 == assigned_regHi, "must be sequential and even"); } -#ifdef SPARC #ifdef _LP64 return LIR_OprFact::double_cpu(assigned_reg, assigned_reg); #else +#ifdef SPARC return LIR_OprFact::double_cpu(assigned_regHi, assigned_reg); -#endif #else return LIR_OprFact::double_cpu(assigned_reg, assigned_regHi); -#endif +#endif // SPARC +#endif // LP64 } case T_FLOAT: { -#ifdef IA32 +#ifdef X86 if (UseSSE >= 1) { assert(assigned_reg >= pd_first_xmm_reg && assigned_reg <= pd_last_xmm_reg, "no xmm register"); assert(interval->assigned_regHi() == any_reg, "must not have hi register"); @@ -2058,7 +2060,7 @@ LIR_Opr LinearScan::calc_operand_for_interval(const Interval* interval) { } case T_DOUBLE: { -#ifdef IA32 +#ifdef X86 if (UseSSE >= 2) { assert(assigned_reg >= pd_first_xmm_reg && assigned_reg <= pd_last_xmm_reg, "no xmm register"); assert(interval->assigned_regHi() == any_reg, "must not have hi register (double xmm values are stored in one register)"); @@ -2122,7 +2124,7 @@ LIR_Opr LinearScan::color_lir_opr(LIR_Opr opr, int op_id, LIR_OpVisitState::OprM LIR_Opr res = operand_for_interval(interval); -#ifdef IA32 +#ifdef X86 // new semantic for is_last_use: not only set on definite end of interval, // but also before hole // This may still miss some cases (e.g. for dead values), but it is not necessary that the @@ -2475,6 +2477,7 @@ int LinearScan::append_scope_value_for_constant(LIR_Opr opr, GrowableArrayappend(sv); return 1; -#ifdef IA32 +#ifdef X86 } else if (opr->is_single_xmm()) { VMReg rname = opr->as_xmm_float_reg()->as_VMReg(); LocationValue* sv = new LocationValue(Location::new_reg_loc(Location::normal, rname)); @@ -2525,7 +2528,7 @@ int LinearScan::append_scope_value_for_operand(LIR_Opr opr, GrowableArrayis_single_fpu()) { -#ifdef IA32 +#ifdef X86 // the exact location of fpu stack values is only known // during fpu stack allocation, so the stack allocator object // must be present @@ -2548,12 +2551,23 @@ int LinearScan::append_scope_value_for_operand(LIR_Opr opr, GrowableArrayis_double_stack()) { +#ifdef _LP64 + Location loc1; + Location::Type loc_type = opr->type() == T_LONG ? Location::lng : Location::dbl; + if (!frame_map()->locations_for_slot(opr->double_stack_ix(), loc_type, &loc1, NULL)) { + bailout("too large frame"); + } + // Does this reverse on x86 vs. sparc? + first = new LocationValue(loc1); + second = &_int_0_scope_value; +#else Location loc1, loc2; if (!frame_map()->locations_for_slot(opr->double_stack_ix(), Location::normal, &loc1, &loc2)) { bailout("too large frame"); } first = new LocationValue(loc1); second = new LocationValue(loc2); +#endif // _LP64 } else if (opr->is_double_cpu()) { #ifdef _LP64 @@ -2573,9 +2587,10 @@ int LinearScan::append_scope_value_for_operand(LIR_Opr opr, GrowableArrayis_double_xmm()) { assert(opr->fpu_regnrLo() == opr->fpu_regnrHi(), "assumed in calculation"); VMReg rname_first = opr->as_xmm_double_reg()->as_VMReg(); @@ -2589,13 +2604,13 @@ int LinearScan::append_scope_value_for_operand(LIR_Opr opr, GrowableArrayis_double_fpu()) { // On SPARC, fpu_regnrLo/fpu_regnrHi represents the two halves of - // the double as float registers in the native ordering. On IA32, + // the double as float registers in the native ordering. On X86, // fpu_regnrLo is a FPU stack slot whose VMReg represents // the low-order word of the double and fpu_regnrLo + 1 is the // name for the other half. *first and *second must represent the // least and most significant words, respectively. -#ifdef IA32 +#ifdef X86 // the exact location of fpu stack values is only known // during fpu stack allocation, so the stack allocator object // must be present @@ -2865,7 +2880,6 @@ void LinearScan::assign_reg_num(LIR_OpList* instructions, IntervalWalker* iw) { op->verify(); #endif -#ifndef _LP64 // remove useless moves if (op->code() == lir_move) { assert(op->as_Op1() != NULL, "move must be LIR_Op1"); @@ -2879,7 +2893,6 @@ void LinearScan::assign_reg_num(LIR_OpList* instructions, IntervalWalker* iw) { has_dead = true; } } -#endif } if (has_dead) { @@ -3192,7 +3205,7 @@ void LinearScan::verify_constants() { BitMap live_at_edge = block->live_in(); // visit all registers where the live_at_edge bit is set - for (int r = live_at_edge.get_next_one_offset(0, size); r < size; r = live_at_edge.get_next_one_offset(r + 1, size)) { + for (int r = (int)live_at_edge.get_next_one_offset(0, size); r < size; r = (int)live_at_edge.get_next_one_offset(r + 1, size)) { TRACE_LINEAR_SCAN(4, tty->print("checking interval %d of block B%d", r, block->block_id())); Value value = gen()->instruction_for_vreg(r); @@ -3438,7 +3451,7 @@ void RegisterVerifier::process_operations(LIR_List* ops, IntervalList* input_sta state_put(input_state, reg_num(FrameMap::caller_save_fpu_reg_at(j)), NULL); } -#ifdef IA32 +#ifdef X86 for (j = 0; j < FrameMap::nof_caller_save_xmm_regs; j++) { state_put(input_state, reg_num(FrameMap::caller_save_xmm_reg_at(j)), NULL); } @@ -4357,7 +4370,7 @@ void Interval::print(outputStream* out) const { opr = LIR_OprFact::single_cpu(assigned_reg()); } else if (assigned_reg() >= pd_first_fpu_reg && assigned_reg() <= pd_last_fpu_reg) { opr = LIR_OprFact::single_fpu(assigned_reg() - pd_first_fpu_reg); -#ifdef IA32 +#ifdef X86 } else if (assigned_reg() >= pd_first_xmm_reg && assigned_reg() <= pd_last_xmm_reg) { opr = LIR_OprFact::single_xmm(assigned_reg() - pd_first_xmm_reg); #endif @@ -5435,7 +5448,7 @@ void LinearScanWalker::alloc_locked_reg(Interval* cur) { } bool LinearScanWalker::no_allocation_possible(Interval* cur) { -#ifdef IA32 +#ifdef X86 // fast calculation of intervals that can never get a register because the // the next instruction is a call that blocks all registers // Note: this does not work if callee-saved registers are available (e.g. on Sparc) diff --git a/hotspot/src/share/vm/c1/c1_LinearScan.hpp b/hotspot/src/share/vm/c1/c1_LinearScan.hpp index bc187fa75d1..40a42e7592f 100644 --- a/hotspot/src/share/vm/c1/c1_LinearScan.hpp +++ b/hotspot/src/share/vm/c1/c1_LinearScan.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -177,7 +177,7 @@ class LinearScan : public CompilationResourceObj { bool is_interval_in_loop(int interval, int loop) const { return _interval_in_loop.at(interval, loop); } // handling of fpu stack allocation (platform dependent, needed for debug information generation) -#ifdef IA32 +#ifdef X86 FpuStackAllocator* _fpu_stack_allocator; bool use_fpu_stack_allocation() const { return UseSSE < 2 && has_fpu_registers(); } #else diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.cpp b/hotspot/src/share/vm/c1/c1_Runtime1.cpp index e7321ccc351..4a4765099e5 100644 --- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp +++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp @@ -336,21 +336,6 @@ JRT_ENTRY(void, Runtime1::new_multi_array(JavaThread* thread, klassOopDesc* klas assert(oop(klass)->is_klass(), "not a class"); assert(rank >= 1, "rank must be nonzero"); -#ifdef _LP64 -// In 64 bit mode, the sizes are stored in the top 32 bits -// of each 64 bit stack entry. -// dims is actually an intptr_t * because the arguments -// are pushed onto a 64 bit stack. -// We must create an array of jints to pass to multi_allocate. -// We reuse the current stack because it will be popped -// after this bytecode is completed. - if ( rank > 1 ) { - int index; - for ( index = 1; index < rank; index++ ) { // First size is ok - dims[index] = dims[index*2]; - } - } -#endif oop obj = arrayKlass::cast(klass)->multi_allocate(rank, dims, CHECK); thread->set_vm_result(obj); JRT_END diff --git a/hotspot/src/share/vm/ci/ciMethodBlocks.cpp b/hotspot/src/share/vm/ci/ciMethodBlocks.cpp index 9bfba219b88..2810523f4fc 100644 --- a/hotspot/src/share/vm/ci/ciMethodBlocks.cpp +++ b/hotspot/src/share/vm/ci/ciMethodBlocks.cpp @@ -351,7 +351,7 @@ void ciBlock::set_exception_range(int start_bci, int limit_bci) { } #ifndef PRODUCT -static char *flagnames[] = { +static const char *flagnames[] = { "Processed", "Handler", "MayThrow", diff --git a/hotspot/src/share/vm/ci/ciTypeFlow.hpp b/hotspot/src/share/vm/ci/ciTypeFlow.hpp index 2235a90a1df..f095d662b99 100644 --- a/hotspot/src/share/vm/ci/ciTypeFlow.hpp +++ b/hotspot/src/share/vm/ci/ciTypeFlow.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -127,7 +127,7 @@ public: // Used as a combined index for locals and temps enum Cell { - Cell_0 + Cell_0, Cell_max = INT_MAX }; // A StateVector summarizes the type information at some diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp index 65a07231a72..ea68a366740 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.cpp +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp @@ -649,8 +649,8 @@ jlong java_lang_Thread::thread_id(oop java_thread) { } oop java_lang_Thread::park_blocker(oop java_thread) { - assert(JDK_Version::supports_thread_park_blocker() && _park_blocker_offset != 0, - "Must support parkBlocker field"); + assert(JDK_Version::current().supports_thread_park_blocker() && + _park_blocker_offset != 0, "Must support parkBlocker field"); if (_park_blocker_offset > 0) { return java_thread->obj_field(_park_blocker_offset); diff --git a/hotspot/src/share/vm/code/location.cpp b/hotspot/src/share/vm/code/location.cpp index a74bb87305e..f5b85a8f8c7 100644 --- a/hotspot/src/share/vm/code/location.cpp +++ b/hotspot/src/share/vm/code/location.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #include "incls/_location.cpp.incl" void Location::print_on(outputStream* st) const { - if(type() == invalid && !legal_offset_in_bytes(offset() * BytesPerInt)) { + if(type() == invalid) { // product of Location::invalid_loc() or Location::Location(). switch (where()) { case on_stack: st->print("empty"); break; @@ -42,6 +42,7 @@ void Location::print_on(outputStream* st) const { switch (type()) { case normal: break; case oop: st->print(",oop"); break; + case narrowoop: st->print(",narrowoop"); break; case int_in_long: st->print(",int"); break; case lng: st->print(",long"); break; case float_in_dbl: st->print(",float"); break; @@ -53,17 +54,17 @@ void Location::print_on(outputStream* st) const { Location::Location(DebugInfoReadStream* stream) { - _value = (uint16_t) stream->read_int(); + _value = (juint) stream->read_int(); } void Location::write_on(DebugInfoWriteStream* stream) { - stream->write_int(_value & 0x0000FFFF); + stream->write_int(_value); } // Valid argument to Location::new_stk_loc()? bool Location::legal_offset_in_bytes(int offset_in_bytes) { if ((offset_in_bytes % BytesPerInt) != 0) return false; - return (offset_in_bytes / BytesPerInt) < (OFFSET_MASK >> OFFSET_SHIFT); + return (juint)(offset_in_bytes / BytesPerInt) < (OFFSET_MASK >> OFFSET_SHIFT); } diff --git a/hotspot/src/share/vm/code/location.hpp b/hotspot/src/share/vm/code/location.hpp index 0a12b8707a4..e9416bedadb 100644 --- a/hotspot/src/share/vm/code/location.hpp +++ b/hotspot/src/share/vm/code/location.hpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,10 +28,10 @@ // // Encoding: // -// bits: -// Where: [15] -// Type: [14..12] -// Offset: [11..0] +// bits (use low bits for best compression): +// Type: [3..0] +// Where: [4] +// Offset: [31..5] class Location VALUE_OBJ_CLASS_SPEC { friend class VMStructs; @@ -42,6 +42,7 @@ class Location VALUE_OBJ_CLASS_SPEC { }; enum Type { + invalid, // Invalid location normal, // Ints, floats, double halves oop, // Oop (please GC me!) int_in_long, // Integer held in long register @@ -49,21 +50,21 @@ class Location VALUE_OBJ_CLASS_SPEC { float_in_dbl, // Float held in double register dbl, // Double held in one register addr, // JSR return address - invalid // Invalid location + narrowoop // Narrow Oop (please GC me!) }; private: enum { - OFFSET_MASK = (jchar) 0x0FFF, - OFFSET_SHIFT = 0, - TYPE_MASK = (jchar) 0x7000, - TYPE_SHIFT = 12, - WHERE_MASK = (jchar) 0x8000, - WHERE_SHIFT = 15 + TYPE_MASK = (juint) 0x0F, + TYPE_SHIFT = 0, + WHERE_MASK = (juint) 0x10, + WHERE_SHIFT = 4, + OFFSET_MASK = (juint) 0xFFFFFFE0, + OFFSET_SHIFT = 5 }; - uint16_t _value; + juint _value; // Create a bit-packed Location Location(Where where_, Type type_, unsigned offset_) { @@ -74,9 +75,9 @@ class Location VALUE_OBJ_CLASS_SPEC { } inline void set(Where where_, Type type_, unsigned offset_) { - _value = (uint16_t) ((where_ << WHERE_SHIFT) | - (type_ << TYPE_SHIFT) | - ((offset_ << OFFSET_SHIFT) & OFFSET_MASK)); + _value = (juint) ((where_ << WHERE_SHIFT) | + (type_ << TYPE_SHIFT) | + ((offset_ << OFFSET_SHIFT) & OFFSET_MASK)); } public: @@ -86,7 +87,7 @@ class Location VALUE_OBJ_CLASS_SPEC { // Register location Factory static Location new_reg_loc( Type t, VMReg reg ) { return Location(in_register, t, reg->value()); } // Default constructor - Location() { set(on_stack,invalid,(unsigned) -1); } + Location() { set(on_stack,invalid,0); } // Bit field accessors Where where() const { return (Where) ((_value & WHERE_MASK) >> WHERE_SHIFT);} diff --git a/hotspot/src/share/vm/code/relocInfo.hpp b/hotspot/src/share/vm/code/relocInfo.hpp index 8a2867dc00e..4cbdfd8856f 100644 --- a/hotspot/src/share/vm/code/relocInfo.hpp +++ b/hotspot/src/share/vm/code/relocInfo.hpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1200,11 +1200,13 @@ class section_word_Relocation : public internal_word_Relocation { class poll_Relocation : public Relocation { bool is_data() { return true; } relocInfo::relocType type() { return relocInfo::poll_type; } + void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest); }; class poll_return_Relocation : public Relocation { bool is_data() { return true; } relocInfo::relocType type() { return relocInfo::poll_return_type; } + void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest); }; diff --git a/hotspot/src/share/vm/compiler/oopMap.cpp b/hotspot/src/share/vm/compiler/oopMap.cpp index ccad14450d4..22b4b9438cd 100644 --- a/hotspot/src/share/vm/compiler/oopMap.cpp +++ b/hotspot/src/share/vm/compiler/oopMap.cpp @@ -188,10 +188,6 @@ void OopMap::set_derived_oop(VMReg reg, VMReg derived_from_local_register ) { } } -void OopMap::set_stack_obj(VMReg reg) { - set_xxx(reg, OopMapValue::stack_obj, VMRegImpl::Bad()); -} - // OopMapSet OopMapSet::OopMapSet() { @@ -399,8 +395,7 @@ void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map, if ( loc != NULL ) { if ( omv.type() == OopMapValue::oop_value ) { #ifdef ASSERT - if (COMPILER2_PRESENT(!DoEscapeAnalysis &&) - (((uintptr_t)loc & (sizeof(*loc)-1)) != 0) || + if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) || !Universe::heap()->is_in_or_null(*loc)) { tty->print_cr("# Found non oop pointer. Dumping state at failure"); // try to dump out some helpful debugging information @@ -431,17 +426,6 @@ void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map, } } } - -#ifdef COMPILER2 - if (DoEscapeAnalysis) { - for (OopMapStream oms(map, OopMapValue::stack_obj); !oms.is_done(); oms.next()) { - omv = oms.current(); - assert(omv.is_stack_loc(), "should refer to stack location"); - oop loc = (oop) fr->oopmapreg_to_location(omv.reg(),reg_map); - oop_fn->do_oop(&loc); - } - } -#endif // COMPILER2 } @@ -540,9 +524,6 @@ void print_register_type(OopMapValue::oop_types x, VMReg optional, st->print("Derived_oop_" ); optional->print_on(st); break; - case OopMapValue::stack_obj: - st->print("Stack"); - break; default: ShouldNotReachHere(); } diff --git a/hotspot/src/share/vm/compiler/oopMap.hpp b/hotspot/src/share/vm/compiler/oopMap.hpp index 5dc1046cd15..72f9a83a9c2 100644 --- a/hotspot/src/share/vm/compiler/oopMap.hpp +++ b/hotspot/src/share/vm/compiler/oopMap.hpp @@ -46,7 +46,7 @@ private: public: // Constants - enum { type_bits = 6, + enum { type_bits = 5, register_bits = BitsPerShort - type_bits }; enum { type_shift = 0, @@ -63,8 +63,7 @@ public: value_value = 2, narrowoop_value = 4, callee_saved_value = 8, - derived_oop_value= 16, - stack_obj = 32 }; + derived_oop_value= 16 }; // Constructors OopMapValue () { set_value(0); set_content_reg(VMRegImpl::Bad()); } @@ -93,14 +92,12 @@ public: bool is_narrowoop() { return mask_bits(value(), type_mask_in_place) == narrowoop_value; } bool is_callee_saved() { return mask_bits(value(), type_mask_in_place) == callee_saved_value; } bool is_derived_oop() { return mask_bits(value(), type_mask_in_place) == derived_oop_value; } - bool is_stack_obj() { return mask_bits(value(), type_mask_in_place) == stack_obj; } void set_oop() { set_value((value() & register_mask_in_place) | oop_value); } void set_value() { set_value((value() & register_mask_in_place) | value_value); } void set_narrowoop() { set_value((value() & register_mask_in_place) | narrowoop_value); } void set_callee_saved() { set_value((value() & register_mask_in_place) | callee_saved_value); } void set_derived_oop() { set_value((value() & register_mask_in_place) | derived_oop_value); } - void set_stack_obj() { set_value((value() & register_mask_in_place) | stack_obj); } VMReg reg() const { return VMRegImpl::as_VMReg(mask_bits(value(), register_mask_in_place) >> register_shift); } oop_types type() const { return (oop_types)mask_bits(value(), type_mask_in_place); } @@ -180,7 +177,6 @@ class OopMap: public ResourceObj { void set_dead ( VMReg local); void set_callee_saved( VMReg local, VMReg caller_machine_register ); void set_derived_oop ( VMReg local, VMReg derived_from_local_register ); - void set_stack_obj( VMReg local); void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional); int heap_size() const; diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp index 2bef9fe5a1f..eb1a1118d72 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp @@ -71,8 +71,15 @@ TreeList* TreeList::as_TreeList(TreeChunk* tc) { TreeList* TreeList::as_TreeList(HeapWord* addr, size_t size) { TreeChunk* tc = (TreeChunk*) addr; assert(size >= sizeof(TreeChunk), "Chunk is too small for a TreeChunk"); - assert(tc->size() == 0 && tc->prev() == NULL && tc->next() == NULL, - "Space should be clear"); + // The space in the heap will have been mangled initially but + // is not remangled when a free chunk is returned to the free list + // (since it is used to maintain the chunk on the free list). + assert((ZapUnusedHeapArea && + SpaceMangler::is_mangled((HeapWord*) tc->size_addr()) && + SpaceMangler::is_mangled((HeapWord*) tc->prev_addr()) && + SpaceMangler::is_mangled((HeapWord*) tc->next_addr())) || + (tc->size() == 0 && tc->prev() == NULL && tc->next() == NULL), + "Space should be clear or mangled"); tc->setSize(size); tc->linkPrev(NULL); tc->linkNext(NULL); diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp index 6bddefce163..af9a9ecf3dc 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp @@ -54,7 +54,7 @@ CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs, _collector(NULL) { _bt.set_space(this); - initialize(mr, true); + initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle); // We have all of "mr", all of which we place in the dictionary // as one big chunk. We'll need to decide here which of several // possible alternative dictionary implementations to use. For diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index 83854fe202c..697ce756825 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -3195,31 +3195,16 @@ ConcurrentMarkSweepGeneration::expand_and_allocate(size_t word_size, // YSR: All of this generation expansion/shrinking stuff is an exact copy of // OneContigSpaceCardGeneration, which makes me wonder if we should move this // to CardGeneration and share it... +bool ConcurrentMarkSweepGeneration::expand(size_t bytes, size_t expand_bytes) { + return CardGeneration::expand(bytes, expand_bytes); +} + void ConcurrentMarkSweepGeneration::expand(size_t bytes, size_t expand_bytes, CMSExpansionCause::Cause cause) { - assert_locked_or_safepoint(Heap_lock); - size_t aligned_bytes = ReservedSpace::page_align_size_up(bytes); - size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes); - bool success = false; - if (aligned_expand_bytes > aligned_bytes) { - success = grow_by(aligned_expand_bytes); - } - if (!success) { - success = grow_by(aligned_bytes); - } - if (!success) { - size_t remaining_bytes = _virtual_space.uncommitted_size(); - if (remaining_bytes > 0) { - success = grow_by(remaining_bytes); - } - } - if (GC_locker::is_active()) { - if (PrintGC && Verbose) { - gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead"); - } - } + bool success = expand(bytes, expand_bytes); + // remember why we expanded; this information is used // by shouldConcurrentCollect() when making decisions on whether to start // a new CMS cycle. @@ -6882,11 +6867,9 @@ void MarkFromRootsClosure::do_bit(size_t offset) { // during the preclean or remark phase. (CMSCleanOnEnter) if (CMSCleanOnEnter) { size_t sz = _collector->block_size_using_printezis_bits(addr); - HeapWord* start_card_addr = (HeapWord*)round_down( - (intptr_t)addr, CardTableModRefBS::card_size); HeapWord* end_card_addr = (HeapWord*)round_to( (intptr_t)(addr+sz), CardTableModRefBS::card_size); - MemRegion redirty_range = MemRegion(start_card_addr, end_card_addr); + MemRegion redirty_range = MemRegion(addr, end_card_addr); assert(!redirty_range.is_empty(), "Arithmetical tautology"); // Bump _threshold to end_card_addr; note that // _threshold cannot possibly exceed end_card_addr, anyhow. @@ -7475,12 +7458,25 @@ void PushAndMarkClosure::do_oop(oop obj) { ) if (simulate_overflow || !_mark_stack->push(obj)) { if (_concurrent_precleaning) { - // During precleaning we can just dirty the appropriate card + // During precleaning we can just dirty the appropriate card(s) // in the mod union table, thus ensuring that the object remains - // in the grey set and continue. Note that no one can be intefering - // with us in this action of dirtying the mod union table, so - // no locking is required. - _mod_union_table->mark(addr); + // in the grey set and continue. In the case of object arrays + // we need to dirty all of the cards that the object spans, + // since the rescan of object arrays will be limited to the + // dirty cards. + // Note that no one can be intefering with us in this action + // of dirtying the mod union table, so no locking or atomics + // are required. + if (obj->is_objArray()) { + size_t sz = obj->size(); + HeapWord* end_card_addr = (HeapWord*)round_to( + (intptr_t)(addr+sz), CardTableModRefBS::card_size); + MemRegion redirty_range = MemRegion(addr, end_card_addr); + assert(!redirty_range.is_empty(), "Arithmetical tautology"); + _mod_union_table->mark_range(redirty_range); + } else { + _mod_union_table->mark(addr); + } _collector->_ser_pmc_preclean_ovflw++; } else { // During the remark phase, we need to remember this oop diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp index dd8956cfd0b..672bb8a8da7 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp @@ -1048,10 +1048,6 @@ class ConcurrentMarkSweepGeneration: public CardGeneration { double _initiating_occupancy; protected: - // Grow generation by specified size (returns false if unable to grow) - bool grow_by(size_t bytes); - // Grow generation to reserved size. - bool grow_to_reserved(); // Shrink generation by specified size (returns false if unable to shrink) virtual void shrink_by(size_t bytes); @@ -1103,6 +1099,11 @@ class ConcurrentMarkSweepGeneration: public CardGeneration { // Override virtual void ref_processor_init(); + // Grow generation by specified size (returns false if unable to grow) + bool grow_by(size_t bytes); + // Grow generation to reserved size. + bool grow_to_reserved(); + void clear_expansion_cause() { _expansion_cause = CMSExpansionCause::_no_expansion; } // Space enquiries @@ -1193,6 +1194,7 @@ class ConcurrentMarkSweepGeneration: public CardGeneration { // Allocation failure void expand(size_t bytes, size_t expand_bytes, CMSExpansionCause::Cause cause); + virtual bool expand(size_t bytes, size_t expand_bytes); void shrink(size_t bytes); HeapWord* expand_and_par_lab_allocate(CMSParGCThreadState* ps, size_t word_sz); bool expand_and_ensure_spooling_space(PromotionInfo* promo); diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp index 309bc7a19c6..5f9c4f22632 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp @@ -22,7 +22,6 @@ * */ - // A FreeBlockDictionary is an abstract superclass that will allow // a number of alternative implementations in the future. class FreeBlockDictionary: public CHeapObj { diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp index 10112108386..768614d7e2b 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp @@ -85,6 +85,8 @@ class FreeChunk VALUE_OBJ_CLASS_SPEC { } debug_only(void* prev_addr() const { return (void*)&_prev; }) + debug_only(void* next_addr() const { return (void*)&_next; }) + debug_only(void* size_addr() const { return (void*)&_size; }) size_t size() const volatile { LP64_ONLY(if (UseCompressedOops) return mark()->get_size(); else ) diff --git a/hotspot/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep b/hotspot/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep index 580a83167fa..505db4ad490 100644 --- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep +++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep @@ -28,6 +28,7 @@ binaryTreeDictionary.cpp allocationStats.hpp binaryTreeDictionary.cpp binaryTreeDictionary.hpp binaryTreeDictionary.cpp globals.hpp binaryTreeDictionary.cpp ostream.hpp +binaryTreeDictionary.cpp spaceDecorator.hpp binaryTreeDictionary.hpp freeBlockDictionary.hpp binaryTreeDictionary.hpp freeList.hpp @@ -114,6 +115,7 @@ compactibleFreeListSpace.cpp java.hpp compactibleFreeListSpace.cpp liveRange.hpp compactibleFreeListSpace.cpp oop.inline.hpp compactibleFreeListSpace.cpp resourceArea.hpp +compactibleFreeListSpace.cpp spaceDecorator.hpp compactibleFreeListSpace.cpp universe.inline.hpp compactibleFreeListSpace.cpp vmThread.hpp diff --git a/hotspot/src/share/vm/gc_implementation/includeDB_gc_parNew b/hotspot/src/share/vm/gc_implementation/includeDB_gc_parNew index 7c926792262..e5e5bc17b7c 100644 --- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_parNew +++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_parNew @@ -22,16 +22,17 @@ // // -asParNewGeneration.hpp adaptiveSizePolicy.hpp -asParNewGeneration.hpp parNewGeneration.hpp +asParNewGeneration.hpp adaptiveSizePolicy.hpp +asParNewGeneration.hpp parNewGeneration.hpp -asParNewGeneration.cpp asParNewGeneration.hpp -asParNewGeneration.cpp cmsAdaptiveSizePolicy.hpp +asParNewGeneration.cpp asParNewGeneration.hpp +asParNewGeneration.cpp cmsAdaptiveSizePolicy.hpp asParNewGeneration.cpp cmsGCAdaptivePolicyCounters.hpp -asParNewGeneration.cpp defNewGeneration.inline.hpp -asParNewGeneration.cpp oop.pcgc.inline.hpp -asParNewGeneration.cpp parNewGeneration.hpp +asParNewGeneration.cpp defNewGeneration.inline.hpp +asParNewGeneration.cpp oop.pcgc.inline.hpp +asParNewGeneration.cpp parNewGeneration.hpp asParNewGeneration.cpp referencePolicy.hpp +asParNewGeneration.cpp spaceDecorator.hpp parCardTableModRefBS.cpp allocation.inline.hpp parCardTableModRefBS.cpp cardTableModRefBS.hpp @@ -75,6 +76,7 @@ parNewGeneration.cpp referencePolicy.hpp parNewGeneration.cpp resourceArea.hpp parNewGeneration.cpp sharedHeap.hpp parNewGeneration.cpp space.hpp +parNewGeneration.cpp spaceDecorator.hpp parNewGeneration.cpp workgroup.hpp parNewGeneration.hpp defNewGeneration.hpp diff --git a/hotspot/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge b/hotspot/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge index 98ce44ea95d..574f8dc3d7b 100644 --- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge +++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge @@ -53,14 +53,15 @@ asPSOldGen.cpp java.hpp asPSOldGen.cpp oop.inline.hpp asPSOldGen.cpp parallelScavengeHeap.hpp asPSOldGen.cpp psMarkSweepDecorator.hpp -asPSOldGen.cpp asPSOldGen.hpp +asPSOldGen.cpp asPSOldGen.hpp asPSYoungGen.hpp generationCounters.hpp asPSYoungGen.hpp mutableSpace.hpp asPSYoungGen.hpp objectStartArray.hpp asPSYoungGen.hpp spaceCounters.hpp asPSYoungGen.hpp psVirtualspace.hpp -asPSYoungGen.hpp psYoungGen.hpp +asPSYoungGen.hpp psYoungGen.hpp +asPSYoungGen.hpp spaceDecorator.hpp asPSYoungGen.cpp gcUtil.hpp asPSYoungGen.cpp java.hpp @@ -68,8 +69,9 @@ asPSYoungGen.cpp oop.inline.hpp asPSYoungGen.cpp parallelScavengeHeap.hpp asPSYoungGen.cpp psMarkSweepDecorator.hpp asPSYoungGen.cpp psScavenge.hpp -asPSYoungGen.cpp asPSYoungGen.hpp -asPSYoungGen.cpp psYoungGen.hpp +asPSYoungGen.cpp asPSYoungGen.hpp +asPSYoungGen.cpp psYoungGen.hpp +asPSYoungGen.cpp spaceDecorator.hpp cardTableExtension.cpp cardTableExtension.hpp cardTableExtension.cpp gcTaskManager.hpp @@ -225,6 +227,7 @@ psMarkSweep.cpp psYoungGen.hpp psMarkSweep.cpp referencePolicy.hpp psMarkSweep.cpp referenceProcessor.hpp psMarkSweep.cpp safepoint.hpp +psMarkSweep.cpp spaceDecorator.hpp psMarkSweep.cpp symbolTable.hpp psMarkSweep.cpp systemDictionary.hpp psMarkSweep.cpp vmThread.hpp @@ -239,6 +242,7 @@ psMarkSweepDecorator.cpp oop.inline.hpp psMarkSweepDecorator.cpp parallelScavengeHeap.hpp psMarkSweepDecorator.cpp psMarkSweep.hpp psMarkSweepDecorator.cpp psMarkSweepDecorator.hpp +psMarkSweepDecorator.cpp spaceDecorator.hpp psMarkSweepDecorator.cpp systemDictionary.hpp psMarkSweepDecorator.hpp mutableSpace.hpp @@ -290,6 +294,7 @@ psOldGen.cpp oop.inline.hpp psOldGen.cpp parallelScavengeHeap.hpp psOldGen.cpp psMarkSweepDecorator.hpp psOldGen.cpp psOldGen.hpp +psOldGen.cpp spaceDecorator.hpp psOldGen.hpp psGenerationCounters.hpp psOldGen.hpp mutableSpace.hpp @@ -351,6 +356,7 @@ psScavenge.cpp psTasks.hpp psScavenge.cpp referencePolicy.hpp psScavenge.cpp referenceProcessor.hpp psScavenge.cpp resourceArea.hpp +psScavenge.cpp spaceDecorator.hpp psScavenge.cpp threadCritical.hpp psScavenge.cpp vmThread.hpp psScavenge.cpp vm_operations.hpp @@ -409,8 +415,8 @@ psVirtualspace.hpp virtualspace.hpp psVirtualspace.cpp os.hpp psVirtualspace.cpp os_.inline.hpp -psVirtualspace.cpp psVirtualspace.hpp -psVirtualspace.cpp virtualspace.hpp +psVirtualspace.cpp psVirtualspace.hpp +psVirtualspace.cpp virtualspace.hpp psYoungGen.cpp gcUtil.hpp psYoungGen.cpp java.hpp @@ -419,7 +425,8 @@ psYoungGen.cpp parallelScavengeHeap.hpp psYoungGen.cpp psMarkSweepDecorator.hpp psYoungGen.cpp psScavenge.hpp psYoungGen.cpp psYoungGen.hpp -psYoungGen.cpp mutableNUMASpace.hpp +psYoungGen.cpp mutableNUMASpace.hpp +psYoungGen.cpp spaceDecorator.hpp psYoungGen.hpp psGenerationCounters.hpp psYoungGen.hpp mutableSpace.hpp diff --git a/hotspot/src/share/vm/gc_implementation/includeDB_gc_shared b/hotspot/src/share/vm/gc_implementation/includeDB_gc_shared index f1d70f8bbba..75a87ce7369 100644 --- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_shared +++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_shared @@ -56,6 +56,7 @@ markSweep.inline.hpp psParallelCompact.hpp mutableNUMASpace.cpp mutableNUMASpace.hpp mutableNUMASpace.cpp oop.inline.hpp mutableNUMASpace.cpp sharedHeap.hpp +mutableNUMASpace.cpp spaceDecorator.hpp mutableNUMASpace.cpp thread_.inline.hpp mutableNUMASpace.hpp mutableSpace.hpp @@ -64,6 +65,7 @@ mutableNUMASpace.hpp gcUtil.hpp mutableSpace.cpp mutableSpace.hpp mutableSpace.cpp oop.inline.hpp mutableSpace.cpp safepoint.hpp +mutableSpace.cpp spaceDecorator.hpp mutableSpace.cpp thread.hpp spaceCounters.cpp resourceArea.hpp diff --git a/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp b/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp index 203bd7ddc70..224e2dcefa7 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp @@ -162,10 +162,9 @@ bool ASParNewGeneration::resize_generation(size_t eden_size, // Grow the generation size_t change = desired_size - orig_size; assert(change % alignment == 0, "just checking"); - if (!virtual_space()->expand_by(change)) { + if (expand(change)) { return false; // Error if we fail to resize! } - size_changed = true; } else if (desired_size < orig_size) { size_t desired_change = orig_size - desired_size; @@ -222,7 +221,9 @@ void ASParNewGeneration::reset_survivors_after_shrink() { // Was there a shrink of the survivor space? if (new_end < to()->end()) { MemRegion mr(to()->bottom(), new_end); - to()->initialize(mr, false /* clear */); + to()->initialize(mr, + SpaceDecorator::DontClear, + SpaceDecorator::DontMangle); } } } @@ -322,9 +323,7 @@ void ASParNewGeneration::resize_spaces(size_t requested_eden_size, pointer_delta(from_start, eden_start, sizeof(char))); } -// tty->print_cr("eden_size before: " SIZE_FORMAT, eden_size); eden_size = align_size_down(eden_size, alignment); -// tty->print_cr("eden_size after: " SIZE_FORMAT, eden_size); eden_end = eden_start + eden_size; assert(eden_end >= eden_start, "addition overflowed") @@ -501,11 +500,31 @@ void ASParNewGeneration::resize_spaces(size_t requested_eden_size, size_t old_from = from()->capacity(); size_t old_to = to()->capacity(); + // If not clearing the spaces, do some checking to verify that + // the spaces are already mangled. + + // Must check mangling before the spaces are reshaped. Otherwise, + // the bottom or end of one space may have moved into another + // a failure of the check may not correctly indicate which space + // is not properly mangled. + if (ZapUnusedHeapArea) { + HeapWord* limit = (HeapWord*) virtual_space()->high(); + eden()->check_mangled_unused_area(limit); + from()->check_mangled_unused_area(limit); + to()->check_mangled_unused_area(limit); + } + // The call to initialize NULL's the next compaction space - eden()->initialize(edenMR, true); + eden()->initialize(edenMR, + SpaceDecorator::Clear, + SpaceDecorator::DontMangle); eden()->set_next_compaction_space(from()); - to()->initialize(toMR , true); - from()->initialize(fromMR, false); // Note, not cleared! + to()->initialize(toMR , + SpaceDecorator::Clear, + SpaceDecorator::DontMangle); + from()->initialize(fromMR, + SpaceDecorator::DontClear, + SpaceDecorator::DontMangle); assert(from()->top() == old_from_top, "from top changed!"); diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp b/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp index 94377a3beb4..d4c641bf028 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp @@ -229,7 +229,7 @@ void ParGCAllocBufferWithBOT::retire(bool end_of_gc, bool retain) { HeapWord* first_card_start = _bsa->address_for_index(first_card_index); if (first_card_start < pre_top) { HeapWord* second_card_start = - _bsa->address_for_index(first_card_index + 1); + _bsa->inc_by_region_size(first_card_start); // Ensure enough room to fill with the smallest block second_card_start = MAX2(second_card_start, pre_top + AlignmentReserve); diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp index ed990a463a1..7803f08b56a 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp @@ -727,7 +727,7 @@ void ParNewGeneration::collect(bool full, SpecializationStats::clear(); age_table()->clear(); - to()->clear(); + to()->clear(SpaceDecorator::Mangle); gch->save_marks(); assert(workers != NULL, "Need parallel worker threads."); @@ -793,8 +793,18 @@ void ParNewGeneration::collect(bool full, } if (!promotion_failed()) { // Swap the survivor spaces. - eden()->clear(); - from()->clear(); + eden()->clear(SpaceDecorator::Mangle); + from()->clear(SpaceDecorator::Mangle); + if (ZapUnusedHeapArea) { + // This is now done here because of the piece-meal mangling which + // can check for valid mangling at intermediate points in the + // collection(s). When a minor collection fails to collect + // sufficient space resizing of the young generation can occur + // an redistribute the spaces in the young generation. Mangle + // here so that unzapped regions don't get distributed to + // other spaces. + to()->mangle_unused_area(); + } swap_spaces(); assert(to()->is_empty(), "to space should be empty now"); diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp index c8555fdfcaa..f4740bf3f27 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp @@ -170,9 +170,20 @@ bool ASPSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) { if (desired_size > orig_size) { // Grow the generation size_t change = desired_size - orig_size; + HeapWord* prev_low = (HeapWord*) virtual_space()->low(); if (!virtual_space()->expand_by(change)) { return false; } + if (ZapUnusedHeapArea) { + // Mangle newly committed space immediately because it + // can be done here more simply that after the new + // spaces have been computed. + HeapWord* new_low = (HeapWord*) virtual_space()->low(); + assert(new_low < prev_low, "Did not grow"); + + MemRegion mangle_region(new_low, prev_low); + SpaceMangler::mangle_region(mangle_region); + } size_changed = true; } else if (desired_size < orig_size) { size_t desired_change = orig_size - desired_size; @@ -215,8 +226,10 @@ bool ASPSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) { // current implementation does not allow holes between the spaces // _young_generation_boundary has to be reset because it changes. // so additional verification + void ASPSYoungGen::resize_spaces(size_t requested_eden_size, size_t requested_survivor_size) { + assert(UseAdaptiveSizePolicy, "sanity check"); assert(requested_eden_size > 0 && requested_survivor_size > 0, "just checking"); @@ -276,22 +289,42 @@ void ASPSYoungGen::resize_spaces(size_t requested_eden_size, ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); const size_t alignment = heap->intra_heap_alignment(); + const bool maintain_minimum = + (requested_eden_size + 2 * requested_survivor_size) <= min_gen_size(); + bool eden_from_to_order = from_start < to_start; // Check whether from space is below to space - if (from_start < to_start) { + if (eden_from_to_order) { // Eden, from, to + if (PrintAdaptiveSizePolicy && Verbose) { gclog_or_tty->print_cr(" Eden, from, to:"); } // Set eden - // Compute how big eden can be, then adjust end. - // See comment in PSYoungGen::resize_spaces() on - // calculating eden_end. - const size_t eden_size = MIN2(requested_eden_size, - pointer_delta(from_start, - eden_start, - sizeof(char))); + // "requested_eden_size" is a goal for the size of eden + // and may not be attainable. "eden_size" below is + // calculated based on the location of from-space and + // the goal for the size of eden. from-space is + // fixed in place because it contains live data. + // The calculation is done this way to avoid 32bit + // overflow (i.e., eden_start + requested_eden_size + // may too large for representation in 32bits). + size_t eden_size; + if (maintain_minimum) { + // Only make eden larger than the requested size if + // the minimum size of the generation has to be maintained. + // This could be done in general but policy at a higher + // level is determining a requested size for eden and that + // should be honored unless there is a fundamental reason. + eden_size = pointer_delta(from_start, + eden_start, + sizeof(char)); + } else { + eden_size = MIN2(requested_eden_size, + pointer_delta(from_start, eden_start, sizeof(char))); + } + eden_end = eden_start + eden_size; assert(eden_end >= eden_start, "addition overflowed") @@ -371,12 +404,14 @@ void ASPSYoungGen::resize_spaces(size_t requested_eden_size, to_start = MAX2(to_start, eden_start + alignment); // Compute how big eden can be, then adjust end. - // See comment in PSYoungGen::resize_spaces() on - // calculating eden_end. - const size_t eden_size = MIN2(requested_eden_size, - pointer_delta(to_start, - eden_start, - sizeof(char))); + // See comments above on calculating eden_end. + size_t eden_size; + if (maintain_minimum) { + eden_size = pointer_delta(to_start, eden_start, sizeof(char)); + } else { + eden_size = MIN2(requested_eden_size, + pointer_delta(to_start, eden_start, sizeof(char))); + } eden_end = eden_start + eden_size; assert(eden_end >= eden_start, "addition overflowed") @@ -423,9 +458,47 @@ void ASPSYoungGen::resize_spaces(size_t requested_eden_size, size_t old_from = from_space()->capacity_in_bytes(); size_t old_to = to_space()->capacity_in_bytes(); - eden_space()->initialize(edenMR, true); - to_space()->initialize(toMR , true); - from_space()->initialize(fromMR, false); // Note, not cleared! + if (ZapUnusedHeapArea) { + // NUMA is a special case because a numa space is not mangled + // in order to not prematurely bind its address to memory to + // the wrong memory (i.e., don't want the GC thread to first + // touch the memory). The survivor spaces are not numa + // spaces and are mangled. + if (UseNUMA) { + if (eden_from_to_order) { + mangle_survivors(from_space(), fromMR, to_space(), toMR); + } else { + mangle_survivors(to_space(), toMR, from_space(), fromMR); + } + } + + // If not mangling the spaces, do some checking to verify that + // the spaces are already mangled. + // The spaces should be correctly mangled at this point so + // do some checking here. Note that they are not being mangled + // in the calls to initialize(). + // Must check mangling before the spaces are reshaped. Otherwise, + // the bottom or end of one space may have moved into an area + // covered by another space and a failure of the check may + // not correctly indicate which space is not properly mangled. + + HeapWord* limit = (HeapWord*) virtual_space()->high(); + eden_space()->check_mangled_unused_area(limit); + from_space()->check_mangled_unused_area(limit); + to_space()->check_mangled_unused_area(limit); + } + // When an existing space is being initialized, it is not + // mangled because the space has been previously mangled. + eden_space()->initialize(edenMR, + SpaceDecorator::Clear, + SpaceDecorator::DontMangle); + to_space()->initialize(toMR, + SpaceDecorator::Clear, + SpaceDecorator::DontMangle); + from_space()->initialize(fromMR, + SpaceDecorator::DontClear, + SpaceDecorator::DontMangle); + PSScavenge::set_young_generation_boundary(eden_space()->bottom()); assert(from_space()->top() == old_from_top, "from top changed!"); @@ -446,7 +519,6 @@ void ASPSYoungGen::resize_spaces(size_t requested_eden_size, } space_invariants(); } - void ASPSYoungGen::reset_after_change() { assert_locked_or_safepoint(Heap_lock); @@ -458,7 +530,9 @@ void ASPSYoungGen::reset_after_change() { HeapWord* eden_bottom = eden_space()->bottom(); if (new_eden_bottom != eden_bottom) { MemRegion eden_mr(new_eden_bottom, eden_space()->end()); - eden_space()->initialize(eden_mr, true); + eden_space()->initialize(eden_mr, + SpaceDecorator::Clear, + SpaceDecorator::Mangle); PSScavenge::set_young_generation_boundary(eden_space()->bottom()); } MemRegion cmr((HeapWord*)virtual_space()->low(), diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp index c0a4d5857bc..cd260de6c82 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp @@ -666,9 +666,9 @@ void CardTableExtension::resize_commit_uncommit(int changed_region, HeapWord* new_end_for_commit = MIN2(cur_committed.end(), _guard_region.start()); - MemRegion new_committed = - MemRegion(new_start_aligned, new_end_for_commit); - if(!new_committed.is_empty()) { + if(new_start_aligned < new_end_for_commit) { + MemRegion new_committed = + MemRegion(new_start_aligned, new_end_for_commit); if (!os::commit_memory((char*)new_committed.start(), new_committed.byte_size())) { vm_exit_out_of_memory(new_committed.byte_size(), diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp index 6814abf6b44..5936c776a47 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp @@ -938,3 +938,23 @@ void ParallelScavengeHeap::resize_old_gen(size_t desired_free_space) { // Delegate the resize to the generation. _old_gen->resize(desired_free_space); } + +#ifndef PRODUCT +void ParallelScavengeHeap::record_gen_tops_before_GC() { + if (ZapUnusedHeapArea) { + young_gen()->record_spaces_top(); + old_gen()->record_spaces_top(); + perm_gen()->record_spaces_top(); + } +} + +void ParallelScavengeHeap::gen_mangle_unused_area() { + if (ZapUnusedHeapArea) { + young_gen()->eden_space()->mangle_unused_area(); + young_gen()->to_space()->mangle_unused_area(); + young_gen()->from_space()->mangle_unused_area(); + old_gen()->object_space()->mangle_unused_area(); + perm_gen()->object_space()->mangle_unused_area(); + } +} +#endif diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp index 75c6830cdc1..0fb2cb217fc 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp @@ -213,6 +213,12 @@ class ParallelScavengeHeap : public CollectedHeap { // Resize the old generation. The reserved space for the // generation may be expanded in preparation for the resize. void resize_old_gen(size_t desired_free_space); + + // Save the tops of the spaces in all generations + void record_gen_tops_before_GC() PRODUCT_RETURN; + + // Mangle the unused parts of all spaces in the heap + void gen_mangle_unused_area() PRODUCT_RETURN; }; inline size_t ParallelScavengeHeap::set_alignment(size_t& var, size_t val) diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp index 3a817a2049e..40a1d9a6631 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -98,6 +98,9 @@ void PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) { // Increment the invocation count heap->increment_total_collections(true /* full */); + // Save information needed to minimize mangling + heap->record_gen_tops_before_GC(); + // We need to track unique mark sweep invocations as well. _total_invocations++; @@ -188,6 +191,12 @@ void PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) { deallocate_stacks(); + if (ZapUnusedHeapArea) { + // Do a complete mangle (top to end) because the usage for + // scratch does not maintain a top pointer. + young_gen->to_space()->mangle_unused_area_complete(); + } + eden_empty = young_gen->eden_space()->is_empty(); if (!eden_empty) { eden_empty = absorb_live_data_from_eden(size_policy, young_gen, old_gen); @@ -198,7 +207,7 @@ void PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) { Universe::update_heap_info_at_gc(); survivors_empty = young_gen->from_space()->is_empty() && - young_gen->to_space()->is_empty(); + young_gen->to_space()->is_empty(); young_gen_empty = eden_empty && survivors_empty; BarrierSet* bs = heap->barrier_set(); @@ -344,6 +353,11 @@ void PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) { perm_gen->verify_object_start_array(); } + if (ZapUnusedHeapArea) { + old_gen->object_space()->check_mangled_unused_area_complete(); + perm_gen->object_space()->check_mangled_unused_area_complete(); + } + NOT_PRODUCT(ref_processor()->verify_no_references_recorded()); if (PrintHeapAtGC) { diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp index 8c8bff54dff..489cdea7272 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp @@ -438,5 +438,7 @@ void PSMarkSweepDecorator::compact(bool mangle_free_space ) { "should point inside space"); space()->set_top(compaction_top()); - if (mangle_free_space) space()->mangle_unused_area(); + if (mangle_free_space) { + space()->mangle_unused_area(); + } } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp index f92d291cc4e..b5cf4d31c09 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,6 +87,15 @@ void PSOldGen::initialize_work(const char* perf_data_name, int level) { MemRegion cmr((HeapWord*)virtual_space()->low(), (HeapWord*)virtual_space()->high()); + if (ZapUnusedHeapArea) { + // Mangle newly committed space immediately rather than + // waiting for the initialization of the space even though + // mangling is related to spaces. Doing it here eliminates + // the need to carry along information that a complete mangling + // (bottom to end) needs to be done. + SpaceMangler::mangle_region(cmr); + } + Universe::heap()->barrier_set()->resize_covered_region(cmr); CardTableModRefBS* _ct = (CardTableModRefBS*)Universe::heap()->barrier_set(); @@ -112,7 +121,9 @@ void PSOldGen::initialize_work(const char* perf_data_name, int level) { if (_object_space == NULL) vm_exit_during_initialization("Could not allocate an old gen space"); - object_space()->initialize(cmr, true); + object_space()->initialize(cmr, + SpaceDecorator::Clear, + SpaceDecorator::Mangle); _object_mark_sweep = new PSMarkSweepDecorator(_object_space, start_array(), MarkSweepDeadRatio); @@ -204,10 +215,22 @@ HeapWord* PSOldGen::expand_and_cas_allocate(size_t word_size) { } void PSOldGen::expand(size_t bytes) { + if (bytes == 0) { + return; + } MutexLocker x(ExpandHeap_lock); const size_t alignment = virtual_space()->alignment(); size_t aligned_bytes = align_size_up(bytes, alignment); size_t aligned_expand_bytes = align_size_up(MinHeapDeltaBytes, alignment); + if (aligned_bytes == 0){ + // The alignment caused the number of bytes to wrap. An expand_by(0) will + // return true with the implication that and expansion was done when it + // was not. A call to expand implies a best effort to expand by "bytes" + // but not a guarantee. Align down to give a best effort. This is likely + // the most that the generation can expand since it has some capacity to + // start with. + aligned_bytes = align_size_down(bytes, alignment); + } bool success = false; if (aligned_expand_bytes > aligned_bytes) { @@ -220,8 +243,8 @@ void PSOldGen::expand(size_t bytes) { success = expand_to_reserved(); } - if (GC_locker::is_active()) { - if (PrintGC && Verbose) { + if (PrintGC && Verbose) { + if (success && GC_locker::is_active()) { gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead"); } } @@ -230,8 +253,24 @@ void PSOldGen::expand(size_t bytes) { bool PSOldGen::expand_by(size_t bytes) { assert_lock_strong(ExpandHeap_lock); assert_locked_or_safepoint(Heap_lock); + if (bytes == 0) { + return true; // That's what virtual_space()->expand_by(0) would return + } bool result = virtual_space()->expand_by(bytes); if (result) { + if (ZapUnusedHeapArea) { + // We need to mangle the newly expanded area. The memregion spans + // end -> new_end, we assume that top -> end is already mangled. + // Do the mangling before post_resize() is called because + // the space is available for allocation after post_resize(); + HeapWord* const virtual_space_high = (HeapWord*) virtual_space()->high(); + assert(object_space()->end() < virtual_space_high, + "Should be true before post_resize()"); + MemRegion mangle_region(object_space()->end(), virtual_space_high); + // Note that the object space has not yet been updated to + // coincede with the new underlying virtual space. + SpaceMangler::mangle_region(mangle_region); + } post_resize(); if (UsePerfData) { _space_counters->update_capacity(); @@ -348,16 +387,7 @@ void PSOldGen::post_resize() { start_array()->set_covered_region(new_memregion); Universe::heap()->barrier_set()->resize_covered_region(new_memregion); - // Did we expand? HeapWord* const virtual_space_high = (HeapWord*) virtual_space()->high(); - if (object_space()->end() < virtual_space_high) { - // We need to mangle the newly expanded area. The memregion spans - // end -> new_end, we assume that top -> end is already mangled. - // This cannot be safely tested for, as allocation may be taking - // place. - MemRegion mangle_region(object_space()->end(), virtual_space_high); - object_space()->mangle_region(mangle_region); - } // ALWAYS do this last!! object_space()->set_end(virtual_space_high); @@ -462,3 +492,10 @@ void PSOldGen::verify_object_start_array() { VerifyObjectStartArrayClosure check( this, &_start_array ); object_iterate(&check); } + +#ifndef PRODUCT +void PSOldGen::record_spaces_top() { + assert(ZapUnusedHeapArea, "Not mangling unused space"); + object_space()->set_top_for_allocations(); +} +#endif diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp index a7a68bdf68e..f7fadd78bd0 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -185,4 +185,8 @@ class PSOldGen : public CHeapObj { // Printing support virtual const char* name() const { return _name; } + + // Debugging support + // Save the tops of all spaces for later use during mangling. + void record_spaces_top() PRODUCT_RETURN; }; diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp index 7bfbdb53978..1abdd88ac65 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp @@ -200,8 +200,8 @@ void PSParallelCompact::print_chunk_ranges() for (unsigned int id = 0; id < last_space_id; ++id) { const MutableSpace* space = _space_info[id].space(); tty->print_cr("%u %s " - SIZE_FORMAT_W("10") " " SIZE_FORMAT_W("10") " " - SIZE_FORMAT_W("10") " " SIZE_FORMAT_W("10") " ", + SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " " + SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " ", id, space_names[id], summary_data().addr_to_chunk_idx(space->bottom()), summary_data().addr_to_chunk_idx(space->top()), @@ -213,8 +213,8 @@ void PSParallelCompact::print_chunk_ranges() void print_generic_summary_chunk(size_t i, const ParallelCompactData::ChunkData* c) { -#define CHUNK_IDX_FORMAT SIZE_FORMAT_W("7") -#define CHUNK_DATA_FORMAT SIZE_FORMAT_W("5") +#define CHUNK_IDX_FORMAT SIZE_FORMAT_W(7) +#define CHUNK_DATA_FORMAT SIZE_FORMAT_W(5) ParallelCompactData& sd = PSParallelCompact::summary_data(); size_t dci = c->destination() ? sd.addr_to_chunk_idx(c->destination()) : 0; @@ -269,9 +269,9 @@ print_initial_summary_chunk(size_t i, const ParallelCompactData::ChunkData* c, bool newline = true) { - tty->print(SIZE_FORMAT_W("5") " " PTR_FORMAT " " - SIZE_FORMAT_W("5") " " SIZE_FORMAT_W("5") " " - SIZE_FORMAT_W("5") " " SIZE_FORMAT_W("5") " %d", + tty->print(SIZE_FORMAT_W(5) " " PTR_FORMAT " " + SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " " + SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " %d", i, c->destination(), c->partial_obj_size(), c->live_obj_size(), c->data_size(), c->source_chunk(), c->destination_count()); @@ -326,7 +326,7 @@ print_initial_summary_data(ParallelCompactData& summary_data, } print_initial_summary_chunk(i, c, false); - tty->print_cr(" %12.10f " SIZE_FORMAT_W("10") " " SIZE_FORMAT_W("10"), + tty->print_cr(" %12.10f " SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10), reclaimed_ratio, dead_to_right, live_to_right); live_to_right -= c->data_size(); @@ -338,8 +338,8 @@ print_initial_summary_data(ParallelCompactData& summary_data, print_initial_summary_chunk(i, summary_data.chunk(i)); } - tty->print_cr("max: " SIZE_FORMAT_W("4") " d2r=" SIZE_FORMAT_W("10") " " - "l2r=" SIZE_FORMAT_W("10") " max_ratio=%14.12f", + tty->print_cr("max: " SIZE_FORMAT_W(4) " d2r=" SIZE_FORMAT_W(10) " " + "l2r=" SIZE_FORMAT_W(10) " max_ratio=%14.12f", max_reclaimed_ratio_chunk, max_dead_to_right, max_live_to_right, max_reclaimed_ratio); } @@ -1060,6 +1060,10 @@ void PSParallelCompact::post_compact() ref_processor()->enqueue_discovered_references(NULL); + if (ZapUnusedHeapArea) { + heap->gen_mangle_unused_area(); + } + // Update time of last GC reset_millis_since_last_gc(); } @@ -1119,8 +1123,8 @@ PSParallelCompact::compute_dense_prefix_via_density(const SpaceId id, HeapWord* chunk_destination = cp->destination(); const size_t cur_deadwood = pointer_delta(dense_prefix, chunk_destination); if (TraceParallelOldGCDensePrefix && Verbose) { - tty->print_cr("c#=" SIZE_FORMAT_W("04") " dst=" PTR_FORMAT " " - "dp=" SIZE_FORMAT_W("08") " " "cdw=" SIZE_FORMAT_W("08"), + tty->print_cr("c#=" SIZE_FORMAT_W(4) " dst=" PTR_FORMAT " " + "dp=" SIZE_FORMAT_W(8) " " "cdw=" SIZE_FORMAT_W(8), sd.chunk(cp), chunk_destination, dense_prefix, cur_deadwood); } @@ -1145,7 +1149,7 @@ PSParallelCompact::compute_dense_prefix_via_density(const SpaceId id, return dense_prefix; } if (TraceParallelOldGCDensePrefix && Verbose) { - tty->print_cr("backing up from c=" SIZE_FORMAT_W("4") " d2r=%10.8f " + tty->print_cr("backing up from c=" SIZE_FORMAT_W(4) " d2r=%10.8f " "pc_d2r=%10.8f", sd.chunk(cp), density_to_right, prev_chunk_density_to_right); } @@ -1182,7 +1186,7 @@ void PSParallelCompact::print_dense_prefix_stats(const char* const algorithm, const size_t live_to_right = new_top - cp->destination(); const size_t dead_to_right = space->top() - addr - live_to_right; - tty->print_cr("%s=" PTR_FORMAT " dpc=" SIZE_FORMAT_W("05") " " + tty->print_cr("%s=" PTR_FORMAT " dpc=" SIZE_FORMAT_W(5) " " "spl=" SIZE_FORMAT " " "d2l=" SIZE_FORMAT " d2l%%=%6.4f " "d2r=" SIZE_FORMAT " l2r=" SIZE_FORMAT @@ -1522,48 +1526,53 @@ void PSParallelCompact::summarize_space(SpaceId id, bool maximum_compaction) { assert(id < last_space_id, "id out of range"); + assert(_space_info[id].dense_prefix() == _space_info[id].space()->bottom(), + "should have been set in summarize_spaces_quick()"); const MutableSpace* space = _space_info[id].space(); - HeapWord** new_top_addr = _space_info[id].new_top_addr(); - - HeapWord* dense_prefix_end = compute_dense_prefix(id, maximum_compaction); - _space_info[id].set_dense_prefix(dense_prefix_end); + if (_space_info[id].new_top() != space->bottom()) { + HeapWord* dense_prefix_end = compute_dense_prefix(id, maximum_compaction); + _space_info[id].set_dense_prefix(dense_prefix_end); #ifndef PRODUCT - if (TraceParallelOldGCDensePrefix) { - print_dense_prefix_stats("ratio", id, maximum_compaction, dense_prefix_end); - HeapWord* addr = compute_dense_prefix_via_density(id, maximum_compaction); - print_dense_prefix_stats("density", id, maximum_compaction, addr); - } + if (TraceParallelOldGCDensePrefix) { + print_dense_prefix_stats("ratio", id, maximum_compaction, + dense_prefix_end); + HeapWord* addr = compute_dense_prefix_via_density(id, maximum_compaction); + print_dense_prefix_stats("density", id, maximum_compaction, addr); + } #endif // #ifndef PRODUCT - // If dead space crosses the dense prefix boundary, it is (at least partially) - // filled with a dummy object, marked live and added to the summary data. - // This simplifies the copy/update phase and must be done before the final - // locations of objects are determined, to prevent leaving a fragment of dead - // space that is too small to fill with an object. - if (!maximum_compaction && dense_prefix_end != space->bottom()) { - fill_dense_prefix_end(id); - } + // If dead space crosses the dense prefix boundary, it is (at least + // partially) filled with a dummy object, marked live and added to the + // summary data. This simplifies the copy/update phase and must be done + // before the final locations of objects are determined, to prevent leaving + // a fragment of dead space that is too small to fill with an object. + if (!maximum_compaction && dense_prefix_end != space->bottom()) { + fill_dense_prefix_end(id); + } - // Compute the destination of each Chunk, and thus each object. - _summary_data.summarize_dense_prefix(space->bottom(), dense_prefix_end); - _summary_data.summarize(dense_prefix_end, space->end(), - dense_prefix_end, space->top(), - new_top_addr); + // Compute the destination of each Chunk, and thus each object. + _summary_data.summarize_dense_prefix(space->bottom(), dense_prefix_end); + _summary_data.summarize(dense_prefix_end, space->end(), + dense_prefix_end, space->top(), + _space_info[id].new_top_addr()); + } if (TraceParallelOldGCSummaryPhase) { const size_t chunk_size = ParallelCompactData::ChunkSize; + HeapWord* const dense_prefix_end = _space_info[id].dense_prefix(); const size_t dp_chunk = _summary_data.addr_to_chunk_idx(dense_prefix_end); const size_t dp_words = pointer_delta(dense_prefix_end, space->bottom()); - const HeapWord* nt_aligned_up = _summary_data.chunk_align_up(*new_top_addr); + HeapWord* const new_top = _space_info[id].new_top(); + const HeapWord* nt_aligned_up = _summary_data.chunk_align_up(new_top); const size_t cr_words = pointer_delta(nt_aligned_up, dense_prefix_end); tty->print_cr("id=%d cap=" SIZE_FORMAT " dp=" PTR_FORMAT " " "dp_chunk=" SIZE_FORMAT " " "dp_count=" SIZE_FORMAT " " "cr_count=" SIZE_FORMAT " " "nt=" PTR_FORMAT, id, space->capacity_in_words(), dense_prefix_end, dp_chunk, dp_words / chunk_size, - cr_words / chunk_size, *new_top_addr); + cr_words / chunk_size, new_top); } } @@ -1632,7 +1641,7 @@ void PSParallelCompact::summary_phase(ParCompactionManager* cm, const size_t live = pointer_delta(_space_info[id].new_top(), space->bottom()); const size_t available = pointer_delta(target_space_end, *new_top_addr); - if (live <= available) { + if (live > 0 && live <= available) { // All the live data will fit. if (TraceParallelOldGCSummaryPhase) { tty->print_cr("summarizing %d into old_space @ " PTR_FORMAT, @@ -1642,16 +1651,18 @@ void PSParallelCompact::summary_phase(ParCompactionManager* cm, space->bottom(), space->top(), new_top_addr); - // Reset the new_top value for the space. - _space_info[id].set_new_top(space->bottom()); - // Clear the source_chunk field for each chunk in the space. + HeapWord* const new_top = _space_info[id].new_top(); + HeapWord* const clear_end = _summary_data.chunk_align_up(new_top); ChunkData* beg_chunk = _summary_data.addr_to_chunk_ptr(space->bottom()); - ChunkData* end_chunk = _summary_data.addr_to_chunk_ptr(space->top() - 1); - while (beg_chunk <= end_chunk) { + ChunkData* end_chunk = _summary_data.addr_to_chunk_ptr(clear_end); + while (beg_chunk < end_chunk) { beg_chunk->set_source_chunk(0); ++beg_chunk; } + + // Reset the new_top value for the space. + _space_info[id].set_new_top(space->bottom()); } } @@ -1961,6 +1972,11 @@ void PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { PSPermGen* perm_gen = heap->perm_gen(); PSAdaptiveSizePolicy* size_policy = heap->size_policy(); + if (ZapUnusedHeapArea) { + // Save information needed to minimize mangling + heap->record_gen_tops_before_GC(); + } + _print_phases = PrintGCDetails && PrintParallelOldGCPhaseTimes; // Make sure data structures are sane, make the heap parsable, and do other @@ -2129,17 +2145,19 @@ void PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { size_t max_eden_size = young_gen->max_size() - young_gen->from_space()->capacity_in_bytes() - young_gen->to_space()->capacity_in_bytes(); - size_policy->compute_generation_free_space(young_gen->used_in_bytes(), - young_gen->eden_space()->used_in_bytes(), - old_gen->used_in_bytes(), - perm_gen->used_in_bytes(), - young_gen->eden_space()->capacity_in_bytes(), - old_gen->max_gen_size(), - max_eden_size, - true /* full gc*/, - gc_cause); + size_policy->compute_generation_free_space( + young_gen->used_in_bytes(), + young_gen->eden_space()->used_in_bytes(), + old_gen->used_in_bytes(), + perm_gen->used_in_bytes(), + young_gen->eden_space()->capacity_in_bytes(), + old_gen->max_gen_size(), + max_eden_size, + true /* full gc*/, + gc_cause); - heap->resize_old_gen(size_policy->calculated_old_free_size_in_bytes()); + heap->resize_old_gen( + size_policy->calculated_old_free_size_in_bytes()); // Don't resize the young generation at an major collection. A // desired young generation size may have been calculated but @@ -2212,6 +2230,11 @@ void PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { perm_gen->verify_object_start_array(); } + if (ZapUnusedHeapArea) { + old_gen->object_space()->check_mangled_unused_area_complete(); + perm_gen->object_space()->check_mangled_unused_area_complete(); + } + NOT_PRODUCT(ref_processor()->verify_no_references_recorded()); collection_exit.update(); @@ -2499,7 +2522,7 @@ void PSParallelCompact::enqueue_chunk_draining_tasks(GCTaskQueue* q, if (TraceParallelOldGCCompactionPhase && Verbose) { const size_t count_mod_8 = fillable_chunks & 7; if (count_mod_8 == 0) gclog_or_tty->print("fillable: "); - gclog_or_tty->print(" " SIZE_FORMAT_W("7"), cur); + gclog_or_tty->print(" " SIZE_FORMAT_W(7), cur); if (count_mod_8 == 7) gclog_or_tty->cr(); } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp index e680a000919..c3f1619db75 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp @@ -716,6 +716,99 @@ class BitBlockUpdateClosure: public ParMarkBitMapClosure { virtual IterationStatus do_addr(HeapWord* addr, size_t words); }; +// The UseParallelOldGC collector is a stop-the-world garbage +// collector that does parts of the collection using parallel threads. +// The collection includes the tenured generation and the young +// generation. The permanent generation is collected at the same +// time as the other two generations but the permanent generation +// is collect by a single GC thread. The permanent generation is +// collected serially because of the requirement that during the +// processing of a klass AAA, any objects reference by AAA must +// already have been processed. This requirement is enforced by +// a left (lower address) to right (higher address) sliding compaction. +// +// There are four phases of the collection. +// +// - marking phase +// - summary phase +// - compacting phase +// - clean up phase +// +// Roughly speaking these phases correspond, respectively, to +// - mark all the live objects +// - calculate the destination of each object at the end of the collection +// - move the objects to their destination +// - update some references and reinitialize some variables +// +// These three phases are invoked in PSParallelCompact::invoke_no_policy(). +// The marking phase is implemented in PSParallelCompact::marking_phase() +// and does a complete marking of the heap. +// The summary phase is implemented in PSParallelCompact::summary_phase(). +// The move and update phase is implemented in PSParallelCompact::compact(). +// +// A space that is being collected is divided into chunks and with +// each chunk is associated an object of type ParallelCompactData. +// Each chunk is of a fixed size and typically will contain more than +// 1 object and may have parts of objects at the front and back of the +// chunk. +// +// chunk -----+---------------------+---------- +// objects covered [ AAA )[ BBB )[ CCC )[ DDD ) +// +// The marking phase does a complete marking of all live objects in the +// heap. The marking also compiles the size of the data for +// all live objects covered by the chunk. This size includes the +// part of any live object spanning onto the chunk (part of AAA +// if it is live) from the front, all live objects contained in the chunk +// (BBB and/or CCC if they are live), and the part of any live objects +// covered by the chunk that extends off the chunk (part of DDD if it is +// live). The marking phase uses multiple GC threads and marking is +// done in a bit array of type ParMarkBitMap. The marking of the +// bit map is done atomically as is the accumulation of the size of the +// live objects covered by a chunk. +// +// The summary phase calculates the total live data to the left of +// each chunk XXX. Based on that total and the bottom of the space, +// it can calculate the starting location of the live data in XXX. +// The summary phase calculates for each chunk XXX quantites such as +// +// - the amount of live data at the beginning of a chunk from an object +// entering the chunk. +// - the location of the first live data on the chunk +// - a count of the number of chunks receiving live data from XXX. +// +// See ParallelCompactData for precise details. The summary phase also +// calculates the dense prefix for the compaction. The dense prefix +// is a portion at the beginning of the space that is not moved. The +// objects in the dense prefix do need to have their object references +// updated. See method summarize_dense_prefix(). +// +// The summary phase is done using 1 GC thread. +// +// The compaction phase moves objects to their new location and updates +// all references in the object. +// +// A current exception is that objects that cross a chunk boundary +// are moved but do not have their references updated. References are +// not updated because it cannot easily be determined if the klass +// pointer KKK for the object AAA has been updated. KKK likely resides +// in a chunk to the left of the chunk containing AAA. These AAA's +// have there references updated at the end in a clean up phase. +// See the method PSParallelCompact::update_deferred_objects(). An +// alternate strategy is being investigated for this deferral of updating. +// +// Compaction is done on a chunk basis. A chunk that is ready to be +// filled is put on a ready list and GC threads take chunk off the list +// and fill them. A chunk is ready to be filled if it +// empty of live objects. Such a chunk may have been initially +// empty (only contained +// dead objects) or may have had all its live objects copied out already. +// A chunk that compacts into itself is also ready for filling. The +// ready list is initially filled with empty chunks and chunks compacting +// into themselves. There is always at least 1 chunk that can be put on +// the ready list. The chunks are atomically added and removed from +// the ready list. +// class PSParallelCompact : AllStatic { public: // Convenient access to type names. diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp index cd5652de3f1..090b15f64ba 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp @@ -265,6 +265,11 @@ bool PSScavenge::invoke_no_policy() { young_gen->eden_space()->accumulate_statistics(); } + if (ZapUnusedHeapArea) { + // Save information needed to minimize mangling + heap->record_gen_tops_before_GC(); + } + if (PrintHeapAtGC) { Universe::print_heap_before_gc(); } @@ -315,7 +320,7 @@ bool PSScavenge::invoke_no_policy() { if (!ScavengeWithObjectsInToSpace) { assert(young_gen->to_space()->is_empty(), "Attempt to scavenge with live objects in to_space"); - young_gen->to_space()->clear(); + young_gen->to_space()->clear(SpaceDecorator::Mangle); } else if (ZapUnusedHeapArea) { young_gen->to_space()->mangle_unused_area(); } @@ -437,8 +442,10 @@ bool PSScavenge::invoke_no_policy() { if (!promotion_failure_occurred) { // Swap the survivor spaces. - young_gen->eden_space()->clear(); - young_gen->from_space()->clear(); + + + young_gen->eden_space()->clear(SpaceDecorator::Mangle); + young_gen->from_space()->clear(SpaceDecorator::Mangle); young_gen->swap_spaces(); size_t survived = young_gen->from_space()->used_in_bytes(); @@ -600,6 +607,12 @@ bool PSScavenge::invoke_no_policy() { Universe::print_heap_after_gc(); } + if (ZapUnusedHeapArea) { + young_gen->eden_space()->check_mangled_unused_area_complete(); + young_gen->from_space()->check_mangled_unused_area_complete(); + young_gen->to_space()->check_mangled_unused_area_complete(); + } + scavenge_exit.update(); if (PrintGCTaskTimeStamps) { diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp index 001f579e5d2..523103f6c6f 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp index 26452649c6b..bfbffcba0dc 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp @@ -36,7 +36,7 @@ PSYoungGen::PSYoungGen(size_t initial_size, void PSYoungGen::initialize_virtual_space(ReservedSpace rs, size_t alignment) { assert(_init_gen_size != 0, "Should have a finite size"); _virtual_space = new PSVirtualSpace(rs, alignment); - if (!_virtual_space->expand_by(_init_gen_size)) { + if (!virtual_space()->expand_by(_init_gen_size)) { vm_exit_during_initialization("Could not reserve enough space for " "object heap"); } @@ -49,13 +49,20 @@ void PSYoungGen::initialize(ReservedSpace rs, size_t alignment) { void PSYoungGen::initialize_work() { - _reserved = MemRegion((HeapWord*)_virtual_space->low_boundary(), - (HeapWord*)_virtual_space->high_boundary()); + _reserved = MemRegion((HeapWord*)virtual_space()->low_boundary(), + (HeapWord*)virtual_space()->high_boundary()); - MemRegion cmr((HeapWord*)_virtual_space->low(), - (HeapWord*)_virtual_space->high()); + MemRegion cmr((HeapWord*)virtual_space()->low(), + (HeapWord*)virtual_space()->high()); Universe::heap()->barrier_set()->resize_covered_region(cmr); + if (ZapUnusedHeapArea) { + // Mangle newly committed space immediately because it + // can be done here more simply that after the new + // spaces have been computed. + SpaceMangler::mangle_region(cmr); + } + if (UseNUMA) { _eden_space = new MutableNUMASpace(); } else { @@ -89,7 +96,7 @@ void PSYoungGen::initialize_work() { // Compute maximum space sizes for performance counters ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); size_t alignment = heap->intra_heap_alignment(); - size_t size = _virtual_space->reserved_size(); + size_t size = virtual_space()->reserved_size(); size_t max_survivor_size; size_t max_eden_size; @@ -142,7 +149,7 @@ void PSYoungGen::compute_initial_space_boundaries() { // Compute sizes size_t alignment = heap->intra_heap_alignment(); - size_t size = _virtual_space->committed_size(); + size_t size = virtual_space()->committed_size(); size_t survivor_size = size / InitialSurvivorRatio; survivor_size = align_size_down(survivor_size, alignment); @@ -164,18 +171,18 @@ void PSYoungGen::compute_initial_space_boundaries() { } void PSYoungGen::set_space_boundaries(size_t eden_size, size_t survivor_size) { - assert(eden_size < _virtual_space->committed_size(), "just checking"); + assert(eden_size < virtual_space()->committed_size(), "just checking"); assert(eden_size > 0 && survivor_size > 0, "just checking"); // Initial layout is Eden, to, from. After swapping survivor spaces, // that leaves us with Eden, from, to, which is step one in our two // step resize-with-live-data procedure. - char *eden_start = _virtual_space->low(); + char *eden_start = virtual_space()->low(); char *to_start = eden_start + eden_size; char *from_start = to_start + survivor_size; char *from_end = from_start + survivor_size; - assert(from_end == _virtual_space->high(), "just checking"); + assert(from_end == virtual_space()->high(), "just checking"); assert(is_object_aligned((intptr_t)eden_start), "checking alignment"); assert(is_object_aligned((intptr_t)to_start), "checking alignment"); assert(is_object_aligned((intptr_t)from_start), "checking alignment"); @@ -184,9 +191,9 @@ void PSYoungGen::set_space_boundaries(size_t eden_size, size_t survivor_size) { MemRegion to_mr ((HeapWord*)to_start, (HeapWord*)from_start); MemRegion from_mr((HeapWord*)from_start, (HeapWord*)from_end); - eden_space()->initialize(eden_mr, true); - to_space()->initialize(to_mr , true); - from_space()->initialize(from_mr, true); + eden_space()->initialize(eden_mr, true, ZapUnusedHeapArea); + to_space()->initialize(to_mr , true, ZapUnusedHeapArea); + from_space()->initialize(from_mr, true, ZapUnusedHeapArea); } #ifndef PRODUCT @@ -207,7 +214,7 @@ void PSYoungGen::space_invariants() { char* to_start = (char*)to_space()->bottom(); char* to_end = (char*)to_space()->end(); - guarantee(eden_start >= _virtual_space->low(), "eden bottom"); + guarantee(eden_start >= virtual_space()->low(), "eden bottom"); guarantee(eden_start < eden_end, "eden space consistency"); guarantee(from_start < from_end, "from space consistency"); guarantee(to_start < to_end, "to space consistency"); @@ -217,29 +224,29 @@ void PSYoungGen::space_invariants() { // Eden, from, to guarantee(eden_end <= from_start, "eden/from boundary"); guarantee(from_end <= to_start, "from/to boundary"); - guarantee(to_end <= _virtual_space->high(), "to end"); + guarantee(to_end <= virtual_space()->high(), "to end"); } else { // Eden, to, from guarantee(eden_end <= to_start, "eden/to boundary"); guarantee(to_end <= from_start, "to/from boundary"); - guarantee(from_end <= _virtual_space->high(), "from end"); + guarantee(from_end <= virtual_space()->high(), "from end"); } // More checks that the virtual space is consistent with the spaces - assert(_virtual_space->committed_size() >= + assert(virtual_space()->committed_size() >= (eden_space()->capacity_in_bytes() + to_space()->capacity_in_bytes() + from_space()->capacity_in_bytes()), "Committed size is inconsistent"); - assert(_virtual_space->committed_size() <= _virtual_space->reserved_size(), + assert(virtual_space()->committed_size() <= virtual_space()->reserved_size(), "Space invariant"); char* eden_top = (char*)eden_space()->top(); char* from_top = (char*)from_space()->top(); char* to_top = (char*)to_space()->top(); - assert(eden_top <= _virtual_space->high(), "eden top"); - assert(from_top <= _virtual_space->high(), "from top"); - assert(to_top <= _virtual_space->high(), "to top"); + assert(eden_top <= virtual_space()->high(), "eden top"); + assert(from_top <= virtual_space()->high(), "from top"); + assert(to_top <= virtual_space()->high(), "to top"); - _virtual_space->verify(); + virtual_space()->verify(); } #endif @@ -265,8 +272,8 @@ void PSYoungGen::resize(size_t eden_size, size_t survivor_size) { bool PSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) { - const size_t alignment = _virtual_space->alignment(); - size_t orig_size = _virtual_space->committed_size(); + const size_t alignment = virtual_space()->alignment(); + size_t orig_size = virtual_space()->committed_size(); bool size_changed = false; // There used to be this guarantee there. @@ -288,10 +295,18 @@ bool PSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) { // Grow the generation size_t change = desired_size - orig_size; assert(change % alignment == 0, "just checking"); - if (!_virtual_space->expand_by(change)) { + HeapWord* prev_high = (HeapWord*) virtual_space()->high(); + if (!virtual_space()->expand_by(change)) { return false; // Error if we fail to resize! } - + if (ZapUnusedHeapArea) { + // Mangle newly committed space immediately because it + // can be done here more simply that after the new + // spaces have been computed. + HeapWord* new_high = (HeapWord*) virtual_space()->high(); + MemRegion mangle_region(prev_high, new_high); + SpaceMangler::mangle_region(mangle_region); + } size_changed = true; } else if (desired_size < orig_size) { size_t desired_change = orig_size - desired_size; @@ -321,19 +336,95 @@ bool PSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) { post_resize(); if (Verbose && PrintGC) { - size_t current_size = _virtual_space->committed_size(); + size_t current_size = virtual_space()->committed_size(); gclog_or_tty->print_cr("PSYoung generation size changed: " SIZE_FORMAT "K->" SIZE_FORMAT "K", orig_size/K, current_size/K); } } - guarantee(eden_plus_survivors <= _virtual_space->committed_size() || - _virtual_space->committed_size() == max_size(), "Sanity"); + guarantee(eden_plus_survivors <= virtual_space()->committed_size() || + virtual_space()->committed_size() == max_size(), "Sanity"); return true; } +#ifndef PRODUCT +// In the numa case eden is not mangled so a survivor space +// moving into a region previously occupied by a survivor +// may find an unmangled region. Also in the PS case eden +// to-space and from-space may not touch (i.e., there may be +// gaps between them due to movement while resizing the +// spaces). Those gaps must be mangled. +void PSYoungGen::mangle_survivors(MutableSpace* s1, + MemRegion s1MR, + MutableSpace* s2, + MemRegion s2MR) { + // Check eden and gap between eden and from-space, in deciding + // what to mangle in from-space. Check the gap between from-space + // and to-space when deciding what to mangle. + // + // +--------+ +----+ +---+ + // | eden | |s1 | |s2 | + // +--------+ +----+ +---+ + // +-------+ +-----+ + // |s1MR | |s2MR | + // +-------+ +-----+ + // All of survivor-space is properly mangled so find the + // upper bound on the mangling for any portion above current s1. + HeapWord* delta_end = MIN2(s1->bottom(), s1MR.end()); + MemRegion delta1_left; + if (s1MR.start() < delta_end) { + delta1_left = MemRegion(s1MR.start(), delta_end); + s1->mangle_region(delta1_left); + } + // Find any portion to the right of the current s1. + HeapWord* delta_start = MAX2(s1->end(), s1MR.start()); + MemRegion delta1_right; + if (delta_start < s1MR.end()) { + delta1_right = MemRegion(delta_start, s1MR.end()); + s1->mangle_region(delta1_right); + } + + // Similarly for the second survivor space except that + // any of the new region that overlaps with the current + // region of the first survivor space has already been + // mangled. + delta_end = MIN2(s2->bottom(), s2MR.end()); + delta_start = MAX2(s2MR.start(), s1->end()); + MemRegion delta2_left; + if (s2MR.start() < delta_end) { + delta2_left = MemRegion(s2MR.start(), delta_end); + s2->mangle_region(delta2_left); + } + delta_start = MAX2(s2->end(), s2MR.start()); + MemRegion delta2_right; + if (delta_start < s2MR.end()) { + s2->mangle_region(delta2_right); + } + + if (TraceZapUnusedHeapArea) { + // s1 + gclog_or_tty->print_cr("Current region: [" PTR_FORMAT ", " PTR_FORMAT ") " + "New region: [" PTR_FORMAT ", " PTR_FORMAT ")", + s1->bottom(), s1->end(), s1MR.start(), s1MR.end()); + gclog_or_tty->print_cr(" Mangle before: [" PTR_FORMAT ", " + PTR_FORMAT ") Mangle after: [" PTR_FORMAT ", " PTR_FORMAT ")", + delta1_left.start(), delta1_left.end(), delta1_right.start(), + delta1_right.end()); + + // s2 + gclog_or_tty->print_cr("Current region: [" PTR_FORMAT ", " PTR_FORMAT ") " + "New region: [" PTR_FORMAT ", " PTR_FORMAT ")", + s2->bottom(), s2->end(), s2MR.start(), s2MR.end()); + gclog_or_tty->print_cr(" Mangle before: [" PTR_FORMAT ", " + PTR_FORMAT ") Mangle after: [" PTR_FORMAT ", " PTR_FORMAT ")", + delta2_left.start(), delta2_left.end(), delta2_right.start(), + delta2_right.end()); + } + +} +#endif // NOT PRODUCT void PSYoungGen::resize_spaces(size_t requested_eden_size, size_t requested_survivor_size) { @@ -396,9 +487,11 @@ void PSYoungGen::resize_spaces(size_t requested_eden_size, const bool maintain_minimum = (requested_eden_size + 2 * requested_survivor_size) <= min_gen_size(); + bool eden_from_to_order = from_start < to_start; // Check whether from space is below to space - if (from_start < to_start) { + if (eden_from_to_order) { // Eden, from, to + eden_from_to_order = true; if (PrintAdaptiveSizePolicy && Verbose) { gclog_or_tty->print_cr(" Eden, from, to:"); } @@ -435,7 +528,7 @@ void PSYoungGen::resize_spaces(size_t requested_eden_size, // extra calculations. // First calculate an optimal to-space - to_end = (char*)_virtual_space->high(); + to_end = (char*)virtual_space()->high(); to_start = (char*)pointer_delta(to_end, (char*)requested_survivor_size, sizeof(char)); @@ -491,7 +584,7 @@ void PSYoungGen::resize_spaces(size_t requested_eden_size, // to space as if we were able to resize from space, even though from // space is not modified. // Giving eden priority was tried and gave poorer performance. - to_end = (char*)pointer_delta(_virtual_space->high(), + to_end = (char*)pointer_delta(virtual_space()->high(), (char*)requested_survivor_size, sizeof(char)); to_end = MIN2(to_end, from_start); @@ -560,9 +653,45 @@ void PSYoungGen::resize_spaces(size_t requested_eden_size, size_t old_from = from_space()->capacity_in_bytes(); size_t old_to = to_space()->capacity_in_bytes(); - eden_space()->initialize(edenMR, true); - to_space()->initialize(toMR , true); - from_space()->initialize(fromMR, false); // Note, not cleared! + if (ZapUnusedHeapArea) { + // NUMA is a special case because a numa space is not mangled + // in order to not prematurely bind its address to memory to + // the wrong memory (i.e., don't want the GC thread to first + // touch the memory). The survivor spaces are not numa + // spaces and are mangled. + if (UseNUMA) { + if (eden_from_to_order) { + mangle_survivors(from_space(), fromMR, to_space(), toMR); + } else { + mangle_survivors(to_space(), toMR, from_space(), fromMR); + } + } + + // If not mangling the spaces, do some checking to verify that + // the spaces are already mangled. + // The spaces should be correctly mangled at this point so + // do some checking here. Note that they are not being mangled + // in the calls to initialize(). + // Must check mangling before the spaces are reshaped. Otherwise, + // the bottom or end of one space may have moved into an area + // covered by another space and a failure of the check may + // not correctly indicate which space is not properly mangled. + HeapWord* limit = (HeapWord*) virtual_space()->high(); + eden_space()->check_mangled_unused_area(limit); + from_space()->check_mangled_unused_area(limit); + to_space()->check_mangled_unused_area(limit); + } + // When an existing space is being initialized, it is not + // mangled because the space has been previously mangled. + eden_space()->initialize(edenMR, + SpaceDecorator::Clear, + SpaceDecorator::DontMangle); + to_space()->initialize(toMR, + SpaceDecorator::Clear, + SpaceDecorator::DontMangle); + from_space()->initialize(fromMR, + SpaceDecorator::DontClear, + SpaceDecorator::DontMangle); assert(from_space()->top() == old_from_top, "from top changed!"); @@ -671,7 +800,7 @@ void PSYoungGen::print_on(outputStream* st) const { st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K", capacity_in_bytes()/K, used_in_bytes()/K); } - _virtual_space->print_space_boundaries_on(st); + virtual_space()->print_space_boundaries_on(st); st->print(" eden"); eden_space()->print_on(st); st->print(" from"); from_space()->print_on(st); st->print(" to "); to_space()->print_on(st); @@ -774,7 +903,9 @@ void PSYoungGen::reset_survivors_after_shrink() { // Was there a shrink of the survivor space? if (new_end < space_shrinking->end()) { MemRegion mr(space_shrinking->bottom(), new_end); - space_shrinking->initialize(mr, false /* clear */); + space_shrinking->initialize(mr, + SpaceDecorator::DontClear, + SpaceDecorator::Mangle); } } @@ -809,3 +940,12 @@ void PSYoungGen::verify(bool allow_dirty) { from_space()->verify(allow_dirty); to_space()->verify(allow_dirty); } + +#ifndef PRODUCT +void PSYoungGen::record_spaces_top() { + assert(ZapUnusedHeapArea, "Not mangling unused space"); + eden_space()->set_top_for_allocations(); + from_space()->set_top_for_allocations(); + to_space()->set_top_for_allocations(); +} +#endif diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp index 953d4309f20..7ff3e271ad2 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -179,4 +179,12 @@ class PSYoungGen : public CHeapObj { // Space boundary invariant checker void space_invariants() PRODUCT_RETURN; + + // Helper for mangling survivor spaces. + void mangle_survivors(MutableSpace* s1, + MemRegion s1MR, + MutableSpace* s2, + MemRegion s2MR) PRODUCT_RETURN; + + void record_spaces_top() PRODUCT_RETURN; }; diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp b/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp index 83fdf871de7..affc3e44597 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,6 +58,12 @@ class AdaptiveWeightedAverage : public CHeapObj { _average(0.0), _sample_count(0), _weight(weight), _last_sample(0.0) { } + void clear() { + _average = 0; + _sample_count = 0; + _last_sample = 0; + } + // Accessors float average() const { return _average; } unsigned weight() const { return _weight; } @@ -115,6 +121,12 @@ class AdaptivePaddedAverage : public AdaptiveWeightedAverage { float deviation() const { return _deviation; } unsigned padding() const { return _padding; } + void clear() { + AdaptiveWeightedAverage::clear(); + _padded_avg = 0; + _deviation = 0; + } + // Override void sample(float new_sample); }; diff --git a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp index 48bfea8b6ff..344c6add09a 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp @@ -42,19 +42,31 @@ MutableNUMASpace::~MutableNUMASpace() { delete lgrp_spaces(); } +#ifndef PRODUCT void MutableNUMASpace::mangle_unused_area() { - for (int i = 0; i < lgrp_spaces()->length(); i++) { - LGRPSpace *ls = lgrp_spaces()->at(i); - MutableSpace *s = ls->space(); - if (!os::numa_has_static_binding()) { - HeapWord *top = MAX2((HeapWord*)round_down((intptr_t)s->top(), page_size()), s->bottom()); - if (top < s->end()) { - ls->add_invalid_region(MemRegion(top, s->end())); - } - } - s->mangle_unused_area(); - } + // This method should do nothing. + // It can be called on a numa space during a full compaction. } +void MutableNUMASpace::mangle_unused_area_complete() { + // This method should do nothing. + // It can be called on a numa space during a full compaction. +} +void MutableNUMASpace::mangle_region(MemRegion mr) { + // This method should do nothing because numa spaces are not mangled. +} +void MutableNUMASpace::set_top_for_allocations(HeapWord* v) { + assert(false, "Do not mangle MutableNUMASpace's"); +} +void MutableNUMASpace::set_top_for_allocations() { + // This method should do nothing. +} +void MutableNUMASpace::check_mangled_unused_area(HeapWord* limit) { + // This method should do nothing. +} +void MutableNUMASpace::check_mangled_unused_area_complete() { + // This method should do nothing. +} +#endif // NOT_PRODUCT // There may be unallocated holes in the middle chunks // that should be filled with dead objects to ensure parseability. @@ -129,7 +141,20 @@ size_t MutableNUMASpace::free_in_words() const { size_t MutableNUMASpace::tlab_capacity(Thread *thr) const { guarantee(thr != NULL, "No thread"); int lgrp_id = thr->lgrp_id(); - assert(lgrp_id != -1, "No lgrp_id set"); + if (lgrp_id == -1) { + // This case can occur after the topology of the system has + // changed. Thread can change their location, the new home + // group will be determined during the first allocation + // attempt. For now we can safely assume that all spaces + // have equal size because the whole space will be reinitialized. + if (lgrp_spaces()->length() > 0) { + return capacity_in_bytes() / lgrp_spaces()->length(); + } else { + assert(false, "There should be at least one locality group"); + return 0; + } + } + // That's the normal case, where we know the locality group of the thread. int i = lgrp_spaces()->find(&lgrp_id, LGRPSpace::equals); if (i == -1) { return 0; @@ -138,9 +163,17 @@ size_t MutableNUMASpace::tlab_capacity(Thread *thr) const { } size_t MutableNUMASpace::unsafe_max_tlab_alloc(Thread *thr) const { + // Please see the comments for tlab_capacity(). guarantee(thr != NULL, "No thread"); int lgrp_id = thr->lgrp_id(); - assert(lgrp_id != -1, "No lgrp_id set"); + if (lgrp_id == -1) { + if (lgrp_spaces()->length() > 0) { + return free_in_bytes() / lgrp_spaces()->length(); + } else { + assert(false, "There should be at least one locality group"); + return 0; + } + } int i = lgrp_spaces()->find(&lgrp_id, LGRPSpace::equals); if (i == -1) { return 0; @@ -238,12 +271,20 @@ void MutableNUMASpace::free_region(MemRegion mr) { void MutableNUMASpace::update() { if (update_layout(false)) { // If the topology has changed, make all chunks zero-sized. + // And clear the alloc-rate statistics. + // In future we may want to handle this more gracefully in order + // to avoid the reallocation of the pages as much as possible. for (int i = 0; i < lgrp_spaces()->length(); i++) { - MutableSpace *s = lgrp_spaces()->at(i)->space(); + LGRPSpace *ls = lgrp_spaces()->at(i); + MutableSpace *s = ls->space(); s->set_end(s->bottom()); s->set_top(s->bottom()); + ls->clear_alloc_rate(); } - initialize(region(), true); + // A NUMA space is never mangled + initialize(region(), + SpaceDecorator::Clear, + SpaceDecorator::DontMangle); } else { bool should_initialize = false; if (!os::numa_has_static_binding()) { @@ -257,7 +298,10 @@ void MutableNUMASpace::update() { if (should_initialize || (UseAdaptiveNUMAChunkSizing && adaptation_cycles() < samples_count())) { - initialize(region(), true); + // A NUMA space is never mangled + initialize(region(), + SpaceDecorator::Clear, + SpaceDecorator::DontMangle); } } @@ -448,14 +492,17 @@ void MutableNUMASpace::merge_regions(MemRegion new_region, MemRegion* intersecti } } -void MutableNUMASpace::initialize(MemRegion mr, bool clear_space) { +void MutableNUMASpace::initialize(MemRegion mr, + bool clear_space, + bool mangle_space) { assert(clear_space, "Reallocation will destory data!"); assert(lgrp_spaces()->length() > 0, "There should be at least one space"); MemRegion old_region = region(), new_region; set_bottom(mr.start()); set_end(mr.end()); - MutableSpace::set_top(bottom()); + // Must always clear the space + clear(SpaceDecorator::DontMangle); // Compute chunk sizes size_t prev_page_size = page_size(); @@ -586,10 +633,8 @@ void MutableNUMASpace::initialize(MemRegion mr, bool clear_space) { bias_region(top_region, ls->lgrp_id()); } - // If we clear the region, we would mangle it in debug. That would cause page - // allocation in a different place. Hence setting the top directly. - s->initialize(new_region, false); - s->set_top(s->bottom()); + // Clear space (set top = bottom) but never mangle. + s->initialize(new_region, SpaceDecorator::Clear, SpaceDecorator::DontMangle); set_adaptation_cycles(samples_count()); } @@ -641,10 +686,12 @@ void MutableNUMASpace::set_top(HeapWord* value) { MutableSpace::set_top(value); } -void MutableNUMASpace::clear() { +void MutableNUMASpace::clear(bool mangle_space) { MutableSpace::set_top(bottom()); for (int i = 0; i < lgrp_spaces()->length(); i++) { - lgrp_spaces()->at(i)->space()->clear(); + // Never mangle NUMA spaces because the mangling will + // bind the memory to a possibly unwanted lgroup. + lgrp_spaces()->at(i)->space()->clear(SpaceDecorator::DontMangle); } } diff --git a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp index 2cde6413eda..e3d824481f4 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp @@ -112,6 +112,7 @@ class MutableNUMASpace : public MutableSpace { int lgrp_id() const { return _lgrp_id; } MutableSpace* space() const { return _space; } AdaptiveWeightedAverage* alloc_rate() const { return _alloc_rate; } + void clear_alloc_rate() { _alloc_rate->clear(); } SpaceStats* space_stats() { return &_space_stats; } void clear_space_stats() { _space_stats = SpaceStats(); } @@ -171,14 +172,21 @@ class MutableNUMASpace : public MutableSpace { MutableNUMASpace(); virtual ~MutableNUMASpace(); // Space initialization. - virtual void initialize(MemRegion mr, bool clear_space); + virtual void initialize(MemRegion mr, bool clear_space, bool mangle_space); // Update space layout if necessary. Do all adaptive resizing job. virtual void update(); // Update allocation rate averages. virtual void accumulate_statistics(); - virtual void clear(); - virtual void mangle_unused_area(); + virtual void clear(bool mangle_space); + virtual void mangle_unused_area() PRODUCT_RETURN; + virtual void mangle_unused_area_complete() PRODUCT_RETURN; + virtual void mangle_region(MemRegion mr) PRODUCT_RETURN; + virtual void check_mangled_unused_area(HeapWord* limit) PRODUCT_RETURN; + virtual void check_mangled_unused_area_complete() PRODUCT_RETURN; + virtual void set_top_for_allocations(HeapWord* v) PRODUCT_RETURN; + virtual void set_top_for_allocations() PRODUCT_RETURN; + virtual void ensure_parsability(); virtual size_t used_in_words() const; virtual size_t free_in_words() const; diff --git a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp index 26621da944e..65c6d34cde8 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp @@ -25,7 +25,17 @@ # include "incls/_precompiled.incl" # include "incls/_mutableSpace.cpp.incl" -void MutableSpace::initialize(MemRegion mr, bool clear_space) { +MutableSpace::MutableSpace(): ImmutableSpace(), _top(NULL) { + _mangler = new MutableSpaceMangler(this); +} + +MutableSpace::~MutableSpace() { + delete _mangler; +} + +void MutableSpace::initialize(MemRegion mr, + bool clear_space, + bool mangle_space) { HeapWord* bottom = mr.start(); HeapWord* end = mr.end(); @@ -34,14 +44,51 @@ void MutableSpace::initialize(MemRegion mr, bool clear_space) { set_bottom(bottom); set_end(end); - if (clear_space) clear(); + if (clear_space) { + clear(mangle_space); + } } -void MutableSpace::clear() { +void MutableSpace::clear(bool mangle_space) { set_top(bottom()); - if (ZapUnusedHeapArea) mangle_unused_area(); + if (ZapUnusedHeapArea && mangle_space) { + mangle_unused_area(); + } } +#ifndef PRODUCT +void MutableSpace::check_mangled_unused_area(HeapWord* limit) { + mangler()->check_mangled_unused_area(limit); +} + +void MutableSpace::check_mangled_unused_area_complete() { + mangler()->check_mangled_unused_area_complete(); +} + +// Mangle only the unused space that has not previously +// been mangled and that has not been allocated since being +// mangled. +void MutableSpace::mangle_unused_area() { + mangler()->mangle_unused_area(); +} + +void MutableSpace::mangle_unused_area_complete() { + mangler()->mangle_unused_area_complete(); +} + +void MutableSpace::mangle_region(MemRegion mr) { + SpaceMangler::mangle_region(mr); +} + +void MutableSpace::set_top_for_allocations(HeapWord* v) { + mangler()->set_top_for_allocations(v); +} + +void MutableSpace::set_top_for_allocations() { + mangler()->set_top_for_allocations(top()); +} +#endif + // This version requires locking. */ HeapWord* MutableSpace::allocate(size_t size) { assert(Heap_lock->owned_by_self() || diff --git a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp index 91586c5068f..b55da4c8459 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp @@ -30,14 +30,23 @@ // Invariant: (ImmutableSpace +) bottom() <= top() <= end() // top() is inclusive and end() is exclusive. +class MutableSpaceMangler; + class MutableSpace: public ImmutableSpace { friend class VMStructs; + + // Helper for mangling unused space in debug builds + MutableSpaceMangler* _mangler; + protected: HeapWord* _top; + MutableSpaceMangler* mangler() { return _mangler; } + public: - virtual ~MutableSpace() {} - MutableSpace() { _top = NULL; } + virtual ~MutableSpace(); + MutableSpace(); + // Accessors HeapWord* top() const { return _top; } virtual void set_top(HeapWord* value) { _top = value; } @@ -52,21 +61,30 @@ class MutableSpace: public ImmutableSpace { MemRegion used_region() { return MemRegion(bottom(), top()); } // Initialization - virtual void initialize(MemRegion mr, bool clear_space); - virtual void clear(); + virtual void initialize(MemRegion mr, + bool clear_space, + bool mangle_space); + virtual void clear(bool mangle_space); + // Does the usual initialization but optionally resets top to bottom. +#if 0 // MANGLE_SPACE + void initialize(MemRegion mr, bool clear_space, bool reset_top); +#endif virtual void update() { } virtual void accumulate_statistics() { } - // Overwrites the unused portion of this space. Note that some collectors - // may use this "scratch" space during collections. - virtual void mangle_unused_area() { - mangle_region(MemRegion(_top, _end)); - } + // Methods used in mangling. See descriptions under SpaceMangler. + virtual void mangle_unused_area() PRODUCT_RETURN; + virtual void mangle_unused_area_complete() PRODUCT_RETURN; + virtual void check_mangled_unused_area(HeapWord* limit) PRODUCT_RETURN; + virtual void check_mangled_unused_area_complete() PRODUCT_RETURN; + virtual void set_top_for_allocations(HeapWord* v) PRODUCT_RETURN; + + // Used to save the space's current top for later use during mangling. + virtual void set_top_for_allocations() PRODUCT_RETURN; + virtual void ensure_parsability() { } - void mangle_region(MemRegion mr) { - debug_only(Copy::fill_to_words(mr.start(), mr.word_size(), badHeapWord)); - } + virtual void mangle_region(MemRegion mr) PRODUCT_RETURN; // Boolean querries. bool is_empty() const { return used_in_words() == 0; } diff --git a/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp b/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp new file mode 100644 index 00000000000..4e5643bba6c --- /dev/null +++ b/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp @@ -0,0 +1,141 @@ +/* + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +# include "incls/_precompiled.incl" +# include "incls/_spaceDecorator.cpp.incl" + +// Catch-all file for utility classes + +#ifndef PRODUCT + +// Returns true is the location q matches the mangling +// pattern. +bool SpaceMangler::is_mangled(HeapWord* q) { + // This test loses precision but is good enough + return badHeapWord == (max_juint & (uintptr_t) q->value()); +} + + +void SpaceMangler::set_top_for_allocations(HeapWord* v) { + if (v < end()) { + assert(!CheckZapUnusedHeapArea || is_mangled(v), + "The high water mark is not mangled"); + } + _top_for_allocations = v; +} + +// Mangle only the unused space that has not previously +// been mangled and that has not been allocated since being +// mangled. +void SpaceMangler::mangle_unused_area() { + assert(ZapUnusedHeapArea, "Mangling should not be in use"); + // Mangle between top and the high water mark. Safeguard + // against the space changing since top_for_allocations was + // set. + HeapWord* mangled_end = MIN2(top_for_allocations(), end()); + if (top() < mangled_end) { + MemRegion mangle_mr(top(), mangled_end); + SpaceMangler::mangle_region(mangle_mr); + // Light weight check of mangling. + check_mangled_unused_area(end()); + } + // Complete check of unused area which is functional when + // DEBUG_MANGLING is defined. + check_mangled_unused_area_complete(); +} + +// A complete mangle is expected in the +// exceptional case where top_for_allocations is not +// properly tracking the high water mark for mangling. +// This can be the case when to-space is being used for +// scratch space during a mark-sweep-compact. See +// contribute_scratch() and PSMarkSweep::allocate_stacks(). +void SpaceMangler::mangle_unused_area_complete() { + assert(ZapUnusedHeapArea, "Mangling should not be in use"); + MemRegion mangle_mr(top(), end()); + SpaceMangler::mangle_region(mangle_mr); +} + +// Simply mangle the MemRegion mr. +void SpaceMangler::mangle_region(MemRegion mr) { + assert(ZapUnusedHeapArea, "Mangling should not be in use"); +#ifdef ASSERT + if(TraceZapUnusedHeapArea) { + gclog_or_tty->print("Mangling [0x%x to 0x%x)", mr.start(), mr.end()); + } + Copy::fill_to_words(mr.start(), mr.word_size(), badHeapWord); + if(TraceZapUnusedHeapArea) { + gclog_or_tty->print_cr(" done"); + } +#endif +} + +// Check that top, top_for_allocations and the last +// word of the space are mangled. In a tight memory +// situation even this light weight mangling could +// cause paging by touching the end of the space. +void SpaceMangler::check_mangled_unused_area(HeapWord* limit) { + if (CheckZapUnusedHeapArea) { + // This method can be called while the spaces are + // being reshaped so skip the test if the end of the + // space is beyond the specified limit; + if (end() > limit) return; + + assert(top() == end() || + (is_mangled(top())), "Top not mangled"); + assert((top_for_allocations() < top()) || + (top_for_allocations() >= end()) || + (is_mangled(top_for_allocations())), + "Older unused not mangled"); + assert(top() == end() || + (is_mangled(end() - 1)), "End not properly mangled"); + // Only does checking when DEBUG_MANGLING is defined. + check_mangled_unused_area_complete(); + } +} + +#undef DEBUG_MANGLING +// This should only be used while debugging the mangling +// because of the high cost of checking the completeness. +void SpaceMangler::check_mangled_unused_area_complete() { + if (CheckZapUnusedHeapArea) { + assert(ZapUnusedHeapArea, "Not mangling unused area"); +#ifdef DEBUG_MANGLING + HeapWord* q = top(); + HeapWord* limit = end(); + + bool passed = true; + while (q < limit) { + if (!is_mangled(q)) { + passed = false; + break; + } + q++; + } + assert(passed, "Mangling is not complete"); +#endif + } +} +#undef DEBUG_MANGLING +#endif // not PRODUCT diff --git a/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.hpp b/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.hpp new file mode 100644 index 00000000000..9566512cbaf --- /dev/null +++ b/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.hpp @@ -0,0 +1,141 @@ +/* + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +class SpaceDecorator: public AllStatic { + public: + // Initialization flags. + static const bool Clear = true; + static const bool DontClear = false; + static const bool Mangle = true; + static const bool DontMangle = false; +}; + +// Functionality for use with class Space and class MutableSpace. +// The approach taken with the mangling is to mangle all +// the space initially and then to mangle areas that have +// been allocated since the last collection. Mangling is +// done in the context of a generation and in the context +// of a space. +// The space in a generation is mangled when it is first +// initialized and when the generation grows. The spaces +// are not necessarily up-to-date when this mangling occurs +// and the method mangle_region() is used. +// After allocations have been done in a space, the space generally +// need to be remangled. Remangling is only done on the +// recently allocated regions in the space. Typically, that is +// the region between the new top and the top just before a +// garbage collection. +// An exception to the usual mangling in a space is done when the +// space is used for an extraordinary purpose. Specifically, when +// to-space is used as scratch space for a mark-sweep-compact +// collection. +// Spaces are mangled after a collection. If the generation +// grows after a collection, the added space is mangled as part of +// the growth of the generation. No additional mangling is needed when the +// spaces are resized after an expansion. +// The class SpaceMangler keeps a pointer to the top of the allocated +// area and provides the methods for doing the piece meal mangling. +// Methods for doing sparces and full checking of the mangling are +// included. The full checking is done if DEBUG_MANGLING is defined. +// GenSpaceMangler is used with the GenCollectedHeap collectors and +// MutableSpaceMangler is used with the ParallelScavengeHeap collectors. +// These subclasses abstract the differences in the types of spaces used +// by each heap. + +class SpaceMangler: public CHeapObj { + friend class VMStructs; + + // High water mark for allocations. Typically, the space above + // this point have been mangle previously and don't need to be + // touched again. Space belows this point has been allocated + // and remangling is needed between the current top and this + // high water mark. + HeapWord* _top_for_allocations; + HeapWord* top_for_allocations() { return _top_for_allocations; } + + public: + + // Setting _top_for_allocations to NULL at initialization + // makes it always below top so that mangling done as part + // of the initialize() call of a space does nothing (as it + // should since the mangling is done as part of the constructor + // for the space. + SpaceMangler() : _top_for_allocations(NULL) {} + + // Methods for top and end that delegate to the specific + // space type. + virtual HeapWord* top() const = 0; + virtual HeapWord* end() const = 0; + + // Return true if q matches the mangled pattern. + static bool is_mangled(HeapWord* q) PRODUCT_RETURN0; + + // Used to save the an address in a space for later use during mangling. + void set_top_for_allocations(HeapWord* v); + + // Overwrites the unused portion of this space. + // Mangle only the region not previously mangled [top, top_previously_mangled) + void mangle_unused_area(); + // Mangle all the unused region [top, end) + void mangle_unused_area_complete(); + // Do some sparse checking on the area that should have been mangled. + void check_mangled_unused_area(HeapWord* limit) PRODUCT_RETURN; + // Do a complete check of the area that should be mangled. + void check_mangled_unused_area_complete() PRODUCT_RETURN; + + // Mangle the MemRegion. This is a non-space specific mangler. It + // is used during the initial mangling of a space before the space + // is fully constructed. Also is used when a generation is expanded + // and possibly before the spaces have been reshaped to to the new + // size of the generation. + static void mangle_region(MemRegion mr); +}; + +class ContiguousSpace; + +// For use with GenCollectedHeap's +class GenSpaceMangler: public SpaceMangler { + ContiguousSpace* _sp; + + ContiguousSpace* sp() { return _sp; } + + HeapWord* top() const { return _sp->top(); } + HeapWord* end() const { return _sp->end(); } + + public: + GenSpaceMangler(ContiguousSpace* sp) : SpaceMangler(), _sp(sp) {} +}; + +// For use with ParallelScavengeHeap's. +class MutableSpaceMangler: public SpaceMangler { + MutableSpace* _sp; + + MutableSpace* sp() { return _sp; } + + HeapWord* top() const { return _sp->top(); } + HeapWord* end() const { return _sp->end(); } + + public: + MutableSpaceMangler(MutableSpace* sp) : SpaceMangler(), _sp(sp) {} +}; diff --git a/hotspot/src/share/vm/includeDB_compiler1 b/hotspot/src/share/vm/includeDB_compiler1 index 3509507f10b..d3006b094a0 100644 --- a/hotspot/src/share/vm/includeDB_compiler1 +++ b/hotspot/src/share/vm/includeDB_compiler1 @@ -258,6 +258,7 @@ c1_LIRGenerator_.cpp ciArray.hpp c1_LIRGenerator_.cpp ciObjArrayKlass.hpp c1_LIRGenerator_.cpp ciTypeArrayKlass.hpp c1_LIRGenerator_.cpp sharedRuntime.hpp +c1_LIRGenerator_.cpp vmreg_.inline.hpp c1_LinearScan.cpp c1_CFGPrinter.hpp c1_LinearScan.cpp c1_Compilation.hpp @@ -281,7 +282,7 @@ c1_LinearScan_.cpp c1_LinearScan.hpp c1_LinearScan_.hpp generate_platform_dependent_include c1_MacroAssembler.hpp assembler.hpp -c1_MacroAssembler.hpp assembler_.inline.hpp +c1_MacroAssembler.hpp assembler_.inline.hpp c1_MacroAssembler_.cpp arrayOop.hpp c1_MacroAssembler_.cpp biasedLocking.hpp diff --git a/hotspot/src/share/vm/includeDB_compiler2 b/hotspot/src/share/vm/includeDB_compiler2 index 1d2cb6d8b15..07ae8a87096 100644 --- a/hotspot/src/share/vm/includeDB_compiler2 +++ b/hotspot/src/share/vm/includeDB_compiler2 @@ -26,7 +26,7 @@ ad_.cpp adGlobals_.hpp ad_.cpp ad_.hpp ad_.cpp allocation.inline.hpp ad_.cpp assembler.hpp -ad_.cpp assembler_.inline.hpp +ad_.cpp assembler_.inline.hpp ad_.cpp biasedLocking.hpp ad_.cpp cfgnode.hpp ad_.cpp collectedHeap.inline.hpp @@ -957,7 +957,7 @@ runtime.hpp vframe.hpp runtime_.cpp adGlobals_.hpp runtime_.cpp ad_.hpp runtime_.cpp assembler.hpp -runtime_.cpp assembler_.inline.hpp +runtime_.cpp assembler_.inline.hpp runtime_.cpp globalDefinitions.hpp runtime_.cpp interfaceSupport.hpp runtime_.cpp interpreter.hpp diff --git a/hotspot/src/share/vm/includeDB_core b/hotspot/src/share/vm/includeDB_core index 0c53185fd0e..5b2045617d2 100644 --- a/hotspot/src/share/vm/includeDB_core +++ b/hotspot/src/share/vm/includeDB_core @@ -178,6 +178,7 @@ arguments.cpp os_.inline.hpp arguments.cpp universe.inline.hpp arguments.cpp vm_version_.hpp +arguments.hpp java.hpp arguments.hpp perfData.hpp arguments.hpp top.hpp @@ -227,7 +228,7 @@ arrayOop.hpp universe.inline.hpp assembler.cpp assembler.hpp assembler.cpp assembler.inline.hpp -assembler.cpp assembler_.inline.hpp +assembler.cpp assembler_.inline.hpp assembler.cpp codeBuffer.hpp assembler.cpp icache.hpp assembler.cpp os.hpp @@ -247,29 +248,29 @@ assembler.inline.hpp codeBuffer.hpp assembler.inline.hpp disassembler.hpp assembler.inline.hpp threadLocalStorage.hpp -assembler_.cpp assembler_.inline.hpp -assembler_.cpp biasedLocking.hpp -assembler_.cpp cardTableModRefBS.hpp -assembler_.cpp collectedHeap.inline.hpp -assembler_.cpp interfaceSupport.hpp -assembler_.cpp interpreter.hpp -assembler_.cpp objectMonitor.hpp -assembler_.cpp os.hpp -assembler_.cpp resourceArea.hpp -assembler_.cpp sharedRuntime.hpp -assembler_.cpp stubRoutines.hpp +assembler_.cpp assembler_.inline.hpp +assembler_.cpp biasedLocking.hpp +assembler_.cpp cardTableModRefBS.hpp +assembler_.cpp collectedHeap.inline.hpp +assembler_.cpp interfaceSupport.hpp +assembler_.cpp interpreter.hpp +assembler_.cpp objectMonitor.hpp +assembler_.cpp os.hpp +assembler_.cpp resourceArea.hpp +assembler_.cpp sharedRuntime.hpp +assembler_.cpp stubRoutines.hpp -assembler_.hpp generate_platform_dependent_include +assembler_.hpp generate_platform_dependent_include -assembler_.inline.hpp assembler.inline.hpp -assembler_.inline.hpp codeBuffer.hpp -assembler_.inline.hpp codeCache.hpp -assembler_.inline.hpp handles.inline.hpp +assembler_.inline.hpp assembler.inline.hpp +assembler_.inline.hpp codeBuffer.hpp +assembler_.inline.hpp codeCache.hpp +assembler_.inline.hpp handles.inline.hpp -assembler_.cpp assembler.hpp -assembler_.cpp assembler_.inline.hpp -assembler_.cpp os.hpp -assembler_.cpp threadLocalStorage.hpp +assembler_.cpp assembler.hpp +assembler_.cpp assembler_.inline.hpp +assembler_.cpp os.hpp +assembler_.cpp threadLocalStorage.hpp atomic.cpp atomic.hpp atomic.cpp atomic_.inline.hpp @@ -1405,6 +1406,7 @@ defNewGeneration.cpp java.hpp defNewGeneration.cpp oop.inline.hpp defNewGeneration.cpp referencePolicy.hpp defNewGeneration.cpp space.inline.hpp +defNewGeneration.cpp spaceDecorator.hpp defNewGeneration.cpp thread_.inline.hpp defNewGeneration.hpp ageTable.hpp @@ -1789,6 +1791,7 @@ generation.cpp generation.inline.hpp generation.cpp java.hpp generation.cpp oop.hpp generation.cpp oop.inline.hpp +generation.cpp spaceDecorator.hpp generation.cpp space.inline.hpp generation.hpp allocation.hpp @@ -1923,7 +1926,7 @@ hpi_.cpp os.hpp hpi_imported.h jni.h -icBuffer.cpp assembler_.inline.hpp +icBuffer.cpp assembler_.inline.hpp icBuffer.cpp collectedHeap.inline.hpp icBuffer.cpp compiledIC.hpp icBuffer.cpp icBuffer.hpp @@ -1944,7 +1947,7 @@ icBuffer.hpp bytecodes.hpp icBuffer.hpp stubs.hpp icBuffer_.cpp assembler.hpp -icBuffer_.cpp assembler_.inline.hpp +icBuffer_.cpp assembler_.inline.hpp icBuffer_.cpp bytecodes.hpp icBuffer_.cpp collectedHeap.inline.hpp icBuffer_.cpp icBuffer.hpp @@ -1959,7 +1962,7 @@ icache.cpp resourceArea.hpp icache.hpp allocation.hpp icache.hpp stubCodeGenerator.hpp -icache_.cpp assembler_.inline.hpp +icache_.cpp assembler_.inline.hpp icache_.cpp icache.hpp icache_.hpp generate_platform_dependent_include @@ -2092,7 +2095,7 @@ interp_masm_.cpp sharedRuntime.hpp interp_masm_.cpp synchronizer.hpp interp_masm_.cpp thread_.inline.hpp -interp_masm_.hpp assembler_.inline.hpp +interp_masm_.hpp assembler_.inline.hpp interp_masm_.hpp invocationCounter.hpp interpreter.cpp allocation.inline.hpp @@ -2399,7 +2402,7 @@ jniFastGetField.cpp jniFastGetField.hpp jniFastGetField.hpp allocation.hpp jniFastGetField.hpp jvm_misc.hpp -jniFastGetField_.cpp assembler_.inline.hpp +jniFastGetField_.cpp assembler_.inline.hpp jniFastGetField_.cpp jniFastGetField.hpp jniFastGetField_.cpp jvm_misc.hpp jniFastGetField_.cpp resourceArea.hpp @@ -2902,7 +2905,7 @@ mutex_.inline.hpp interfaceSupport.hpp mutex_.inline.hpp os_.inline.hpp mutex_.inline.hpp thread_.inline.hpp -nativeInst_.cpp assembler_.inline.hpp +nativeInst_.cpp assembler_.inline.hpp nativeInst_.cpp handles.hpp nativeInst_.cpp nativeInst_.hpp nativeInst_.cpp oop.hpp @@ -3171,7 +3174,7 @@ os.hpp top.hpp os_.cpp allocation.inline.hpp os_.cpp arguments.hpp -os_.cpp assembler_.inline.hpp +os_.cpp assembler_.inline.hpp os_.cpp classLoader.hpp os_.cpp events.hpp os_.cpp extendedPC.hpp @@ -3205,7 +3208,7 @@ os_.hpp generate_platform_dependent_include os_.cpp allocation.inline.hpp os_.cpp arguments.hpp -os_.cpp assembler_.inline.hpp +os_.cpp assembler_.inline.hpp os_.cpp attachListener.hpp os_.cpp classLoader.hpp os_.cpp compileBroker.hpp @@ -3264,7 +3267,7 @@ osThread.hpp javaFrameAnchor.hpp osThread.hpp objectMonitor.hpp osThread.hpp top.hpp -osThread_.cpp assembler_.inline.hpp +osThread_.cpp assembler_.inline.hpp osThread_.cpp atomic.hpp osThread_.cpp handles.inline.hpp osThread_.cpp mutexLocker.hpp @@ -3477,7 +3480,7 @@ register_definitions_.cpp interp_masm_.hpp register_definitions_.cpp register.hpp register_definitions_.cpp register_.hpp -relocInfo.cpp assembler_.inline.hpp +relocInfo.cpp assembler_.inline.hpp relocInfo.cpp compiledIC.hpp relocInfo.cpp copy.hpp relocInfo.cpp nativeInst_.hpp @@ -3490,7 +3493,7 @@ relocInfo.hpp allocation.hpp relocInfo.hpp top.hpp relocInfo_.cpp assembler.inline.hpp -relocInfo_.cpp assembler_.inline.hpp +relocInfo_.cpp assembler_.inline.hpp relocInfo_.cpp nativeInst_.hpp relocInfo_.cpp oop.inline.hpp relocInfo_.cpp relocInfo.hpp @@ -3673,7 +3676,7 @@ sharedRuntime.hpp resourceArea.hpp sharedRuntime.hpp threadLocalStorage.hpp sharedRuntime_.cpp assembler.hpp -sharedRuntime_.cpp assembler_.inline.hpp +sharedRuntime_.cpp assembler_.inline.hpp sharedRuntime_.cpp compiledICHolderOop.hpp sharedRuntime_.cpp debugInfoRec.hpp sharedRuntime_.cpp icBuffer.hpp @@ -3722,6 +3725,7 @@ space.cpp oop.inline2.hpp space.cpp safepoint.hpp space.cpp space.hpp space.cpp space.inline.hpp +space.cpp spaceDecorator.hpp space.cpp systemDictionary.hpp space.cpp universe.inline.hpp space.cpp vmSymbols.hpp @@ -3744,6 +3748,13 @@ space.inline.hpp safepoint.hpp space.inline.hpp space.hpp space.inline.hpp universe.hpp +spaceDecorator.hpp globalDefinitions.hpp +spaceDecorator.hpp mutableSpace.hpp +spaceDecorator.hpp space.hpp + +spaceDecorator.cpp copy.hpp +spaceDecorator.cpp spaceDecorator.hpp + specialized_oop_closures.cpp ostream.hpp specialized_oop_closures.cpp specialized_oop_closures.hpp @@ -3808,7 +3819,7 @@ statSampler.cpp vm_version_.hpp statSampler.hpp perfData.hpp statSampler.hpp task.hpp -stubCodeGenerator.cpp assembler_.inline.hpp +stubCodeGenerator.cpp assembler_.inline.hpp stubCodeGenerator.cpp disassembler.hpp stubCodeGenerator.cpp forte.hpp stubCodeGenerator.cpp oop.inline.hpp @@ -3819,7 +3830,7 @@ stubCodeGenerator.hpp allocation.hpp stubCodeGenerator.hpp assembler.hpp stubGenerator_.cpp assembler.hpp -stubGenerator_.cpp assembler_.inline.hpp +stubGenerator_.cpp assembler_.inline.hpp stubGenerator_.cpp frame.inline.hpp stubGenerator_.cpp handles.inline.hpp stubGenerator_.cpp instanceOop.hpp @@ -4551,7 +4562,7 @@ vm_version.cpp vm_version_.hpp vm_version.hpp allocation.hpp vm_version.hpp ostream.hpp -vm_version_.cpp assembler_.inline.hpp +vm_version_.cpp assembler_.inline.hpp vm_version_.cpp java.hpp vm_version_.cpp os_.inline.hpp vm_version_.cpp resourceArea.hpp @@ -4592,7 +4603,7 @@ vtableStubs.cpp vtune.hpp vtableStubs.hpp allocation.hpp vtableStubs_.cpp assembler.hpp -vtableStubs_.cpp assembler_.inline.hpp +vtableStubs_.cpp assembler_.inline.hpp vtableStubs_.cpp instanceKlass.hpp vtableStubs_.cpp interp_masm_.hpp vtableStubs_.cpp klassVtable.hpp diff --git a/hotspot/src/share/vm/includeDB_features b/hotspot/src/share/vm/includeDB_features index eec1c35259e..7db5dc0c26f 100644 --- a/hotspot/src/share/vm/includeDB_features +++ b/hotspot/src/share/vm/includeDB_features @@ -1,5 +1,5 @@ // -// Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. +// Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it @@ -51,12 +51,13 @@ dump.cpp oop.hpp dump.cpp oopFactory.hpp dump.cpp resourceArea.hpp dump.cpp signature.hpp +dump.cpp spaceDecorator.hpp dump.cpp symbolTable.hpp dump.cpp systemDictionary.hpp dump.cpp vmThread.hpp dump.cpp vm_operations.hpp -dump_.cpp assembler_.inline.hpp +dump_.cpp assembler_.inline.hpp dump_.cpp compactingPermGenGen.hpp forte.cpp collectedHeap.inline.hpp diff --git a/hotspot/src/share/vm/memory/blockOffsetTable.hpp b/hotspot/src/share/vm/memory/blockOffsetTable.hpp index fc76fc9208c..3d271aaf86e 100644 --- a/hotspot/src/share/vm/memory/blockOffsetTable.hpp +++ b/hotspot/src/share/vm/memory/blockOffsetTable.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -199,6 +199,12 @@ public: // "index" in "_offset_array". HeapWord* address_for_index(size_t index) const; + // Return the address "p" incremented by the size of + // a region. This method does not align the address + // returned to the start of a region. It is a simple + // primitive. + HeapWord* inc_by_region_size(HeapWord* p) const { return p + N_words; } + // Shared space support void serialize(SerializeOopClosure* soc, HeapWord* start, HeapWord* end); }; diff --git a/hotspot/src/share/vm/memory/compactingPermGenGen.cpp b/hotspot/src/share/vm/memory/compactingPermGenGen.cpp index 2ba5222cde1..e1de54e38e8 100644 --- a/hotspot/src/share/vm/memory/compactingPermGenGen.cpp +++ b/hotspot/src/share/vm/memory/compactingPermGenGen.cpp @@ -421,28 +421,6 @@ size_t CompactingPermGenGen::max_capacity() const { } - -bool CompactingPermGenGen::grow_by(size_t bytes) { - // Don't allow _virtual_size to expand into shared spaces. - size_t max_bytes = _virtual_space.uncommitted_size() - _shared_space_size; - if (bytes > _shared_space_size) { - bytes = _shared_space_size; - } - return OneContigSpaceCardGeneration::grow_by(bytes); -} - - -void CompactingPermGenGen::grow_to_reserved() { - // Don't allow _virtual_size to expand into shared spaces. - if (_virtual_space.uncommitted_size() > _shared_space_size) { - size_t remaining_bytes = - _virtual_space.uncommitted_size() - _shared_space_size; - bool success = OneContigSpaceCardGeneration::grow_by(remaining_bytes); - DEBUG_ONLY(if (!success) warning("grow to reserved failed");) - } -} - - // No young generation references, clear this generation's main space's // card table entries. Do NOT clear the card table entries for the // read-only space (always clear) or the read-write space (valuable diff --git a/hotspot/src/share/vm/memory/compactingPermGenGen.hpp b/hotspot/src/share/vm/memory/compactingPermGenGen.hpp index ea0bb185dab..913f1728f8c 100644 --- a/hotspot/src/share/vm/memory/compactingPermGenGen.hpp +++ b/hotspot/src/share/vm/memory/compactingPermGenGen.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -183,8 +183,6 @@ public: void compact(); void post_compact(); size_t contiguous_available() const; - bool grow_by(size_t bytes); - void grow_to_reserved(); void clear_remembered_set(); void invalidate_remembered_set(); diff --git a/hotspot/src/share/vm/memory/defNewGeneration.cpp b/hotspot/src/share/vm/memory/defNewGeneration.cpp index a18734ec673..63278cee703 100644 --- a/hotspot/src/share/vm/memory/defNewGeneration.cpp +++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp @@ -172,15 +172,25 @@ DefNewGeneration::DefNewGeneration(ReservedSpace rs, _to_counters = new CSpaceCounters("s1", 2, _max_survivor_size, _to_space, _gen_counters); - compute_space_boundaries(0); + compute_space_boundaries(0, SpaceDecorator::Clear, SpaceDecorator::Mangle); update_counters(); _next_gen = NULL; _tenuring_threshold = MaxTenuringThreshold; _pretenure_size_threshold_words = PretenureSizeThreshold >> LogHeapWordSize; } -void DefNewGeneration::compute_space_boundaries(uintx minimum_eden_size) { - uintx alignment = GenCollectedHeap::heap()->collector_policy()->min_alignment(); +void DefNewGeneration::compute_space_boundaries(uintx minimum_eden_size, + bool clear_space, + bool mangle_space) { + uintx alignment = + GenCollectedHeap::heap()->collector_policy()->min_alignment(); + + // If the spaces are being cleared (only done at heap initialization + // currently), the survivor spaces need not be empty. + // Otherwise, no care is taken for used areas in the survivor spaces + // so check. + assert(clear_space || (to()->is_empty() && from()->is_empty()), + "Initialization of the survivor spaces assumes these are empty"); // Compute sizes uintx size = _virtual_space.committed_size(); @@ -214,16 +224,41 @@ void DefNewGeneration::compute_space_boundaries(uintx minimum_eden_size) { MemRegion fromMR((HeapWord*)from_start, (HeapWord*)to_start); MemRegion toMR ((HeapWord*)to_start, (HeapWord*)to_end); - eden()->initialize(edenMR, (minimum_eden_size == 0)); - // If minumum_eden_size != 0, we will not have cleared any + // A minimum eden size implies that there is a part of eden that + // is being used and that affects the initialization of any + // newly formed eden. + bool live_in_eden = minimum_eden_size > 0; + + // If not clearing the spaces, do some checking to verify that + // the space are already mangled. + if (!clear_space) { + // Must check mangling before the spaces are reshaped. Otherwise, + // the bottom or end of one space may have moved into another + // a failure of the check may not correctly indicate which space + // is not properly mangled. + if (ZapUnusedHeapArea) { + HeapWord* limit = (HeapWord*) _virtual_space.high(); + eden()->check_mangled_unused_area(limit); + from()->check_mangled_unused_area(limit); + to()->check_mangled_unused_area(limit); + } + } + + // Reset the spaces for their new regions. + eden()->initialize(edenMR, + clear_space && !live_in_eden, + SpaceDecorator::Mangle); + // If clear_space and live_in_eden, we will not have cleared any // portion of eden above its top. This can cause newly // expanded space not to be mangled if using ZapUnusedHeapArea. // We explicitly do such mangling here. - if (ZapUnusedHeapArea && (minimum_eden_size != 0)) { + if (ZapUnusedHeapArea && clear_space && live_in_eden && mangle_space) { eden()->mangle_unused_area(); } - from()->initialize(fromMR, true); - to()->initialize(toMR , true); + from()->initialize(fromMR, clear_space, mangle_space); + to()->initialize(toMR, clear_space, mangle_space); + + // Set next compaction spaces. eden()->set_next_compaction_space(from()); // The to-space is normally empty before a compaction so need // not be considered. The exception is during promotion @@ -250,7 +285,16 @@ void DefNewGeneration::swap_spaces() { bool DefNewGeneration::expand(size_t bytes) { MutexLocker x(ExpandHeap_lock); + HeapWord* prev_high = (HeapWord*) _virtual_space.high(); bool success = _virtual_space.expand_by(bytes); + if (success && ZapUnusedHeapArea) { + // Mangle newly committed space immediately because it + // can be done here more simply that after the new + // spaces have been computed. + HeapWord* new_high = (HeapWord*) _virtual_space.high(); + MemRegion mangle_region(prev_high, new_high); + SpaceMangler::mangle_region(mangle_region); + } // Do not attempt an expand-to-the reserve size. The // request should properly observe the maximum size of @@ -262,7 +306,8 @@ bool DefNewGeneration::expand(size_t bytes) { // value. if (GC_locker::is_active()) { if (PrintGC && Verbose) { - gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead"); + gclog_or_tty->print_cr("Garbage collection disabled, " + "expanded heap instead"); } } @@ -326,16 +371,24 @@ void DefNewGeneration::compute_new_size() { changed = true; } if (changed) { - compute_space_boundaries(eden()->used()); - MemRegion cmr((HeapWord*)_virtual_space.low(), (HeapWord*)_virtual_space.high()); + // The spaces have already been mangled at this point but + // may not have been cleared (set top = bottom) and should be. + // Mangling was done when the heap was being expanded. + compute_space_boundaries(eden()->used(), + SpaceDecorator::Clear, + SpaceDecorator::DontMangle); + MemRegion cmr((HeapWord*)_virtual_space.low(), + (HeapWord*)_virtual_space.high()); Universe::heap()->barrier_set()->resize_covered_region(cmr); if (Verbose && PrintGC) { size_t new_size_after = _virtual_space.committed_size(); size_t eden_size_after = eden()->capacity(); size_t survivor_size_after = from()->capacity(); - gclog_or_tty->print("New generation size " SIZE_FORMAT "K->" SIZE_FORMAT "K [eden=" + gclog_or_tty->print("New generation size " SIZE_FORMAT "K->" + SIZE_FORMAT "K [eden=" SIZE_FORMAT "K,survivor=" SIZE_FORMAT "K]", - new_size_before/K, new_size_after/K, eden_size_after/K, survivor_size_after/K); + new_size_before/K, new_size_after/K, + eden_size_after/K, survivor_size_after/K); if (WizardMode) { gclog_or_tty->print("[allowed " SIZE_FORMAT "K extra for %d threads]", thread_increase_size/K, threads_count); @@ -480,7 +533,7 @@ void DefNewGeneration::collect(bool full, ScanWeakRefClosure scan_weak_ref(this); age_table()->clear(); - to()->clear(); + to()->clear(SpaceDecorator::Mangle); gch->rem_set()->prepare_for_younger_refs_iterate(false); @@ -525,8 +578,18 @@ void DefNewGeneration::collect(bool full, soft_ref_policy, &is_alive, &keep_alive, &evacuate_followers, NULL); if (!promotion_failed()) { // Swap the survivor spaces. - eden()->clear(); - from()->clear(); + eden()->clear(SpaceDecorator::Mangle); + from()->clear(SpaceDecorator::Mangle); + if (ZapUnusedHeapArea) { + // This is now done here because of the piece-meal mangling which + // can check for valid mangling at intermediate points in the + // collection(s). When a minor collection fails to collect + // sufficient space resizing of the young generation can occur + // an redistribute the spaces in the young generation. Mangle + // here so that unzapped regions don't get distributed to + // other spaces. + to()->mangle_unused_area(); + } swap_spaces(); assert(to()->is_empty(), "to space should be empty now"); @@ -753,6 +816,15 @@ void DefNewGeneration::contribute_scratch(ScratchBlock*& list, Generation* reque } } +void DefNewGeneration::reset_scratch() { + // If contributing scratch in to_space, mangle all of + // to_space if ZapUnusedHeapArea. This is needed because + // top is not maintained while using to-space as scratch. + if (ZapUnusedHeapArea) { + to()->mangle_unused_area_complete(); + } +} + bool DefNewGeneration::collection_attempt_is_safe() { if (!to()->is_empty()) { return false; @@ -806,11 +878,25 @@ void DefNewGeneration::gc_epilogue(bool full) { } } + if (ZapUnusedHeapArea) { + eden()->check_mangled_unused_area_complete(); + from()->check_mangled_unused_area_complete(); + to()->check_mangled_unused_area_complete(); + } + // update the generation and space performance counters update_counters(); gch->collector_policy()->counters()->update_counters(); } +void DefNewGeneration::record_spaces_top() { + assert(ZapUnusedHeapArea, "Not mangling unused space"); + eden()->set_top_for_allocations(); + to()->set_top_for_allocations(); + from()->set_top_for_allocations(); +} + + void DefNewGeneration::update_counters() { if (UsePerfData) { _eden_counters->update_all(); diff --git a/hotspot/src/share/vm/memory/defNewGeneration.hpp b/hotspot/src/share/vm/memory/defNewGeneration.hpp index 9f7d6329137..cd8257a32cd 100644 --- a/hotspot/src/share/vm/memory/defNewGeneration.hpp +++ b/hotspot/src/share/vm/memory/defNewGeneration.hpp @@ -279,6 +279,9 @@ protected: virtual void gc_prologue(bool full); virtual void gc_epilogue(bool full); + // Save the tops for eden, from, and to + virtual void record_spaces_top(); + // Doesn't require additional work during GC prologue and epilogue virtual bool performs_in_place_marking() const { return false; } @@ -299,9 +302,12 @@ protected: // For non-youngest collection, the DefNewGeneration can contribute // "to-space". - void contribute_scratch(ScratchBlock*& list, Generation* requestor, + virtual void contribute_scratch(ScratchBlock*& list, Generation* requestor, size_t max_alloc_words); + // Reset for contribution of "to-space". + virtual void reset_scratch(); + // GC support virtual void compute_new_size(); virtual void collect(bool full, @@ -331,7 +337,12 @@ protected: void verify(bool allow_dirty); protected: - void compute_space_boundaries(uintx minimum_eden_size); + // If clear_space is true, clear the survivor spaces. Eden is + // cleared if the minimum size of eden is 0. If mangle_space + // is true, also mangle the space in debug mode. + void compute_space_boundaries(uintx minimum_eden_size, + bool clear_space, + bool mangle_space); // Scavenge support void swap_spaces(); }; diff --git a/hotspot/src/share/vm/memory/dump.cpp b/hotspot/src/share/vm/memory/dump.cpp index 0b088528270..cfe22633d15 100644 --- a/hotspot/src/share/vm/memory/dump.cpp +++ b/hotspot/src/share/vm/memory/dump.cpp @@ -645,7 +645,7 @@ public: class ClearSpaceClosure : public SpaceClosure { public: void do_space(Space* s) { - s->clear(); + s->clear(SpaceDecorator::Mangle); } }; @@ -1200,10 +1200,12 @@ public: mapinfo->write_space(CompactingPermGenGen::rw, _rw_space, false); _rw_space->set_saved_mark(); mapinfo->write_region(CompactingPermGenGen::md, _md_vs->low(), - md_top - _md_vs->low(), SharedMiscDataSize, + pointer_delta(md_top, _md_vs->low(), sizeof(char)), + SharedMiscDataSize, false, false); mapinfo->write_region(CompactingPermGenGen::mc, _mc_vs->low(), - mc_top - _mc_vs->low(), SharedMiscCodeSize, + pointer_delta(mc_top, _mc_vs->low(), sizeof(char)), + SharedMiscCodeSize, true, true); // Pass 2 - write data. @@ -1212,10 +1214,12 @@ public: mapinfo->write_space(CompactingPermGenGen::ro, _ro_space, true); mapinfo->write_space(CompactingPermGenGen::rw, _rw_space, false); mapinfo->write_region(CompactingPermGenGen::md, _md_vs->low(), - md_top - _md_vs->low(), SharedMiscDataSize, + pointer_delta(md_top, _md_vs->low(), sizeof(char)), + SharedMiscDataSize, false, false); mapinfo->write_region(CompactingPermGenGen::mc, _mc_vs->low(), - mc_top - _mc_vs->low(), SharedMiscCodeSize, + pointer_delta(mc_top, _mc_vs->low(), sizeof(char)), + SharedMiscCodeSize, true, true); mapinfo->close(); diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.cpp b/hotspot/src/share/vm/memory/genCollectedHeap.cpp index e77e86a0096..0cfa60bd2b9 100644 --- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp +++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp @@ -465,6 +465,11 @@ void GenCollectedHeap::do_collection(bool full, _gens[i]->stat_record()->invocations++; _gens[i]->stat_record()->accumulated_time.start(); + // Must be done anew before each collection because + // a previous collection will do mangling and will + // change top of some spaces. + record_gen_tops_before_GC(); + if (PrintGC && Verbose) { gclog_or_tty->print("level=%d invoke=%d size=" SIZE_FORMAT, i, @@ -1058,6 +1063,12 @@ ScratchBlock* GenCollectedHeap::gather_scratch(Generation* requestor, return res; } +void GenCollectedHeap::release_scratch() { + for (int i = 0; i < _n_gens; i++) { + _gens[i]->reset_scratch(); + } +} + size_t GenCollectedHeap::large_typearray_limit() { return gen_policy()->large_typearray_limit(); } @@ -1285,6 +1296,24 @@ void GenCollectedHeap::gc_epilogue(bool full) { always_do_update_barrier = UseConcMarkSweepGC; }; +#ifndef PRODUCT +class GenGCSaveTopsBeforeGCClosure: public GenCollectedHeap::GenClosure { + private: + public: + void do_generation(Generation* gen) { + gen->record_spaces_top(); + } +}; + +void GenCollectedHeap::record_gen_tops_before_GC() { + if (ZapUnusedHeapArea) { + GenGCSaveTopsBeforeGCClosure blk; + generation_iterate(&blk, false); // not old-to-young. + perm_gen()->record_spaces_top(); + } +} +#endif // not PRODUCT + class GenEnsureParsabilityClosure: public GenCollectedHeap::GenClosure { public: void do_generation(Generation* gen) { diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.hpp b/hotspot/src/share/vm/memory/genCollectedHeap.hpp index c85a2a307a1..f6b0c408f20 100644 --- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp +++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp @@ -259,6 +259,9 @@ public: // be provided are returned as a list of ScratchBlocks, sorted by // decreasing size. ScratchBlock* gather_scratch(Generation* requestor, size_t max_alloc_words); + // Allow each generation to reset any scratch space that it has + // contributed as it needs. + void release_scratch(); size_t large_typearray_limit(); @@ -482,6 +485,9 @@ private: bool should_do_concurrent_full_gc(GCCause::Cause cause); void collect_mostly_concurrent(GCCause::Cause cause); + // Save the tops of the spaces in all generations + void record_gen_tops_before_GC() PRODUCT_RETURN; + protected: virtual void gc_prologue(bool full); virtual void gc_epilogue(bool full); diff --git a/hotspot/src/share/vm/memory/genMarkSweep.cpp b/hotspot/src/share/vm/memory/genMarkSweep.cpp index 6885a73c773..bc46afba59c 100644 --- a/hotspot/src/share/vm/memory/genMarkSweep.cpp +++ b/hotspot/src/share/vm/memory/genMarkSweep.cpp @@ -190,6 +190,10 @@ void GenMarkSweep::allocate_stacks() { void GenMarkSweep::deallocate_stacks() { + + GenCollectedHeap* gch = GenCollectedHeap::heap(); + gch->release_scratch(); + if (_preserved_oop_stack) { delete _preserved_mark_stack; _preserved_mark_stack = NULL; diff --git a/hotspot/src/share/vm/memory/generation.cpp b/hotspot/src/share/vm/memory/generation.cpp index 04cce2e59fe..5167db243b6 100644 --- a/hotspot/src/share/vm/memory/generation.cpp +++ b/hotspot/src/share/vm/memory/generation.cpp @@ -32,6 +32,12 @@ Generation::Generation(ReservedSpace rs, size_t initial_size, int level) : vm_exit_during_initialization("Could not reserve enough space for " "object heap"); } + // Mangle all of the the initial generation. + if (ZapUnusedHeapArea) { + MemRegion mangle_region((HeapWord*)_virtual_space.low(), + (HeapWord*)_virtual_space.high()); + SpaceMangler::mangle_region(mangle_region); + } _reserved = MemRegion((HeapWord*)_virtual_space.low_boundary(), (HeapWord*)_virtual_space.high_boundary()); } @@ -373,6 +379,41 @@ CardGeneration::CardGeneration(ReservedSpace rs, size_t initial_byte_size, } } +bool CardGeneration::expand(size_t bytes, size_t expand_bytes) { + assert_locked_or_safepoint(Heap_lock); + if (bytes == 0) { + return true; // That's what grow_by(0) would return + } + size_t aligned_bytes = ReservedSpace::page_align_size_up(bytes); + if (aligned_bytes == 0){ + // The alignment caused the number of bytes to wrap. An expand_by(0) will + // return true with the implication that an expansion was done when it + // was not. A call to expand implies a best effort to expand by "bytes" + // but not a guarantee. Align down to give a best effort. This is likely + // the most that the generation can expand since it has some capacity to + // start with. + aligned_bytes = ReservedSpace::page_align_size_down(bytes); + } + size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes); + bool success = false; + if (aligned_expand_bytes > aligned_bytes) { + success = grow_by(aligned_expand_bytes); + } + if (!success) { + success = grow_by(aligned_bytes); + } + if (!success) { + success = grow_to_reserved(); + } + if (PrintGC && Verbose) { + if (success && GC_locker::is_active()) { + gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead"); + } + } + + return success; +} + // No young generation references, clear this generation's cards. void CardGeneration::clear_remembered_set() { @@ -435,25 +476,9 @@ OneContigSpaceCardGeneration::expand_and_allocate(size_t word_size, } } -void OneContigSpaceCardGeneration::expand(size_t bytes, size_t expand_bytes) { +bool OneContigSpaceCardGeneration::expand(size_t bytes, size_t expand_bytes) { GCMutexLocker x(ExpandHeap_lock); - size_t aligned_bytes = ReservedSpace::page_align_size_up(bytes); - size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes); - bool success = false; - if (aligned_expand_bytes > aligned_bytes) { - success = grow_by(aligned_expand_bytes); - } - if (!success) { - success = grow_by(aligned_bytes); - } - if (!success) { - grow_to_reserved(); - } - if (GC_locker::is_active()) { - if (PrintGC && Verbose) { - gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead"); - } - } + return CardGeneration::expand(bytes, expand_bytes); } @@ -505,8 +530,11 @@ bool OneContigSpaceCardGeneration::grow_by(size_t bytes) { _bts->resize(new_word_size); // Fix for bug #4668531 - MemRegion mangle_region(_the_space->end(), (HeapWord*)_virtual_space.high()); - _the_space->mangle_region(mangle_region); + if (ZapUnusedHeapArea) { + MemRegion mangle_region(_the_space->end(), + (HeapWord*)_virtual_space.high()); + SpaceMangler::mangle_region(mangle_region); + } // Expand space -- also expands space's BOT // (which uses (part of) shared array above) @@ -622,6 +650,14 @@ void OneContigSpaceCardGeneration::gc_epilogue(bool full) { // update the generation and space performance counters update_counters(); + if (ZapUnusedHeapArea) { + the_space()->check_mangled_unused_area_complete(); + } +} + +void OneContigSpaceCardGeneration::record_spaces_top() { + assert(ZapUnusedHeapArea, "Not mangling unused space"); + the_space()->set_top_for_allocations(); } void OneContigSpaceCardGeneration::verify(bool allow_dirty) { diff --git a/hotspot/src/share/vm/memory/generation.hpp b/hotspot/src/share/vm/memory/generation.hpp index 4a4cecd3f41..0f0e74e4794 100644 --- a/hotspot/src/share/vm/memory/generation.hpp +++ b/hotspot/src/share/vm/memory/generation.hpp @@ -376,6 +376,9 @@ class Generation: public CHeapObj { // The default is to do nothing. virtual void gc_epilogue(bool full) {}; + // Save the high water marks for the used space in a generation. + virtual void record_spaces_top() {}; + // Some generations may need to be "fixed-up" after some allocation // activity to make them parsable again. The default is to do nothing. virtual void ensure_parsability() {}; @@ -476,6 +479,10 @@ class Generation: public CHeapObj { virtual void contribute_scratch(ScratchBlock*& list, Generation* requestor, size_t max_alloc_words) {} + // Give each generation an opportunity to do clean up for any + // contributed scratch. + virtual void reset_scratch() {}; + // When an older generation has been collected, and perhaps resized, // this method will be invoked on all younger generations (from older to // younger), allowing them to resize themselves as appropriate. @@ -599,11 +606,21 @@ class CardGeneration: public Generation { public: + // Attempt to expand the generation by "bytes". Expand by at a + // minimum "expand_bytes". Return true if some amount (not + // necessarily the full "bytes") was done. + virtual bool expand(size_t bytes, size_t expand_bytes); + virtual void clear_remembered_set(); virtual void invalidate_remembered_set(); virtual void prepare_for_verify(); + + // Grow generation with specified size (returns false if unable to grow) + virtual bool grow_by(size_t bytes) = 0; + // Grow generation to reserved size. + virtual bool grow_to_reserved() = 0; }; // OneContigSpaceCardGeneration models a heap of old objects contained in a single @@ -624,14 +641,14 @@ class OneContigSpaceCardGeneration: public CardGeneration { // and after last GC. // Grow generation with specified size (returns false if unable to grow) - bool grow_by(size_t bytes); + virtual bool grow_by(size_t bytes); // Grow generation to reserved size. - bool grow_to_reserved(); + virtual bool grow_to_reserved(); // Shrink generation with specified size (returns false if unable to shrink) void shrink_by(size_t bytes); // Allocation failure - void expand(size_t bytes, size_t expand_bytes); + virtual bool expand(size_t bytes, size_t expand_bytes); void shrink(size_t bytes); // Accessing spaces @@ -699,6 +716,8 @@ class OneContigSpaceCardGeneration: public CardGeneration { virtual void gc_epilogue(bool full); + virtual void record_spaces_top(); + virtual void verify(bool allow_dirty); virtual void print_on(outputStream* st) const; }; diff --git a/hotspot/src/share/vm/memory/space.cpp b/hotspot/src/share/vm/memory/space.cpp index 894bd57279f..59f42bbbd9c 100644 --- a/hotspot/src/share/vm/memory/space.cpp +++ b/hotspot/src/share/vm/memory/space.cpp @@ -232,30 +232,44 @@ ContiguousSpace::new_dcto_cl(OopClosure* cl, return new ContiguousSpaceDCTOC(this, cl, precision, boundary); } -void Space::initialize(MemRegion mr, bool clear_space) { +void Space::initialize(MemRegion mr, + bool clear_space, + bool mangle_space) { HeapWord* bottom = mr.start(); HeapWord* end = mr.end(); assert(Universe::on_page_boundary(bottom) && Universe::on_page_boundary(end), "invalid space boundaries"); set_bottom(bottom); set_end(end); - if (clear_space) clear(); + if (clear_space) clear(mangle_space); } -void Space::clear() { - if (ZapUnusedHeapArea) mangle_unused_area(); +void Space::clear(bool mangle_space) { + if (ZapUnusedHeapArea && mangle_space) { + mangle_unused_area(); + } } -void ContiguousSpace::initialize(MemRegion mr, bool clear_space) +ContiguousSpace::ContiguousSpace(): CompactibleSpace(), _top(NULL) { + _mangler = new GenSpaceMangler(this); +} + +ContiguousSpace::~ContiguousSpace() { + delete _mangler; +} + +void ContiguousSpace::initialize(MemRegion mr, + bool clear_space, + bool mangle_space) { - CompactibleSpace::initialize(mr, clear_space); + CompactibleSpace::initialize(mr, clear_space, mangle_space); _concurrent_iteration_safe_limit = top(); } -void ContiguousSpace::clear() { +void ContiguousSpace::clear(bool mangle_space) { set_top(bottom()); set_saved_mark(); - Space::clear(); + Space::clear(mangle_space); } bool Space::is_in(const void* p) const { @@ -271,8 +285,8 @@ bool ContiguousSpace::is_free_block(const HeapWord* p) const { return p >= _top; } -void OffsetTableContigSpace::clear() { - ContiguousSpace::clear(); +void OffsetTableContigSpace::clear(bool mangle_space) { + ContiguousSpace::clear(mangle_space); _offsets.initialize_threshold(); } @@ -288,17 +302,46 @@ void OffsetTableContigSpace::set_end(HeapWord* new_end) { Space::set_end(new_end); } +#ifndef PRODUCT + +void ContiguousSpace::set_top_for_allocations(HeapWord* v) { + mangler()->set_top_for_allocations(v); +} +void ContiguousSpace::set_top_for_allocations() { + mangler()->set_top_for_allocations(top()); +} +void ContiguousSpace::check_mangled_unused_area(HeapWord* limit) { + mangler()->check_mangled_unused_area(limit); +} + +void ContiguousSpace::check_mangled_unused_area_complete() { + mangler()->check_mangled_unused_area_complete(); +} + +// Mangled only the unused space that has not previously +// been mangled and that has not been allocated since being +// mangled. void ContiguousSpace::mangle_unused_area() { - // to-space is used for storing marks during mark-sweep - mangle_region(MemRegion(top(), end())); + mangler()->mangle_unused_area(); +} +void ContiguousSpace::mangle_unused_area_complete() { + mangler()->mangle_unused_area_complete(); } - void ContiguousSpace::mangle_region(MemRegion mr) { - debug_only(Copy::fill_to_words(mr.start(), mr.word_size(), badHeapWord)); + // Although this method uses SpaceMangler::mangle_region() which + // is not specific to a space, the when the ContiguousSpace version + // is called, it is always with regard to a space and this + // bounds checking is appropriate. + MemRegion space_mr(bottom(), end()); + assert(space_mr.contains(mr), "Mangling outside space"); + SpaceMangler::mangle_region(mr); } +#endif // NOT_PRODUCT -void CompactibleSpace::initialize(MemRegion mr, bool clear_space) { - Space::initialize(mr, clear_space); +void CompactibleSpace::initialize(MemRegion mr, + bool clear_space, + bool mangle_space) { + Space::initialize(mr, clear_space, mangle_space); _compaction_top = bottom(); _next_compaction_space = NULL; } @@ -820,8 +863,8 @@ void ContiguousSpace::allocate_temporary_filler(int factor) { } } -void EdenSpace::clear() { - ContiguousSpace::clear(); +void EdenSpace::clear(bool mangle_space) { + ContiguousSpace::clear(mangle_space); set_soft_end(end()); } @@ -878,7 +921,7 @@ OffsetTableContigSpace::OffsetTableContigSpace(BlockOffsetSharedArray* sharedOff _par_alloc_lock(Mutex::leaf, "OffsetTableContigSpace par alloc lock", true) { _offsets.set_contig_space(this); - initialize(mr, true); + initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle); } diff --git a/hotspot/src/share/vm/memory/space.hpp b/hotspot/src/share/vm/memory/space.hpp index b8af6e695c7..de28ba87a3c 100644 --- a/hotspot/src/share/vm/memory/space.hpp +++ b/hotspot/src/share/vm/memory/space.hpp @@ -131,15 +131,17 @@ class Space: public CHeapObj { return MemRegion(bottom(), saved_mark_word()); } - // Initialization - virtual void initialize(MemRegion mr, bool clear_space); - virtual void clear(); + // Initialization. These may be run to reset an existing + // Space. + virtual void initialize(MemRegion mr, bool clear_space, bool mangle_space); + virtual void clear(bool mangle_space); // For detecting GC bugs. Should only be called at GC boundaries, since // some unused space may be used as scratch space during GC's. // Default implementation does nothing. We also call this when expanding // a space to satisfy an allocation request. See bug #4668531 virtual void mangle_unused_area() {} + virtual void mangle_unused_area_complete() {} virtual void mangle_region(MemRegion mr) {} // Testers @@ -354,7 +356,7 @@ private: CompactibleSpace* _next_compaction_space; public: - virtual void initialize(MemRegion mr, bool clear_space); + virtual void initialize(MemRegion mr, bool clear_space, bool mangle_space); // Used temporarily during a compaction phase to hold the value // top should have when compaction is complete. @@ -724,12 +726,14 @@ protected: /* continuously, but those that weren't need to have their thresholds */ \ /* re-initialized. Also mangles unused area for debugging. */ \ if (is_empty()) { \ - clear(); \ + clear(SpaceDecorator::Mangle); \ } else { \ if (ZapUnusedHeapArea) mangle_unused_area(); \ } \ } +class GenSpaceMangler; + // A space in which the free area is contiguous. It therefore supports // faster allocation, and compaction. class ContiguousSpace: public CompactibleSpace { @@ -738,13 +742,21 @@ class ContiguousSpace: public CompactibleSpace { protected: HeapWord* _top; HeapWord* _concurrent_iteration_safe_limit; + // A helper for mangling the unused area of the space in debug builds. + GenSpaceMangler* _mangler; + + GenSpaceMangler* mangler() { return _mangler; } // Allocation helpers (return NULL if full). inline HeapWord* allocate_impl(size_t word_size, HeapWord* end_value); inline HeapWord* par_allocate_impl(size_t word_size, HeapWord* end_value); public: - virtual void initialize(MemRegion mr, bool clear_space); + + ContiguousSpace(); + ~ContiguousSpace(); + + virtual void initialize(MemRegion mr, bool clear_space, bool mangle_space); // Accessors HeapWord* top() const { return _top; } @@ -753,15 +765,34 @@ class ContiguousSpace: public CompactibleSpace { void set_saved_mark() { _saved_mark_word = top(); } void reset_saved_mark() { _saved_mark_word = bottom(); } - virtual void clear(); + virtual void clear(bool mangle_space); WaterMark bottom_mark() { return WaterMark(this, bottom()); } WaterMark top_mark() { return WaterMark(this, top()); } WaterMark saved_mark() { return WaterMark(this, saved_mark_word()); } bool saved_mark_at_top() const { return saved_mark_word() == top(); } - void mangle_unused_area(); - void mangle_region(MemRegion mr); + // In debug mode mangle (write it with a particular bit + // pattern) the unused part of a space. + + // Used to save the an address in a space for later use during mangling. + void set_top_for_allocations(HeapWord* v) PRODUCT_RETURN; + // Used to save the space's current top for later use during mangling. + void set_top_for_allocations() PRODUCT_RETURN; + + // Mangle regions in the space from the current top up to the + // previously mangled part of the space. + void mangle_unused_area() PRODUCT_RETURN; + // Mangle [top, end) + void mangle_unused_area_complete() PRODUCT_RETURN; + // Mangle the given MemRegion. + void mangle_region(MemRegion mr) PRODUCT_RETURN; + + // Do some sparse checking on the area that should have been mangled. + void check_mangled_unused_area(HeapWord* limit) PRODUCT_RETURN; + // Check the complete area that should have been mangled. + // This code may be NULL depending on the macro DEBUG_MANGLING. + void check_mangled_unused_area_complete() PRODUCT_RETURN; // Size computations: sizes in bytes. size_t capacity() const { return byte_size(bottom(), end()); } @@ -956,7 +987,7 @@ class EdenSpace : public ContiguousSpace { void set_soft_end(HeapWord* value) { _soft_end = value; } // Override. - void clear(); + void clear(bool mangle_space); // Set both the 'hard' and 'soft' limits (_end and _soft_end). void set_end(HeapWord* value) { @@ -1000,7 +1031,7 @@ class OffsetTableContigSpace: public ContiguousSpace { void set_bottom(HeapWord* value); void set_end(HeapWord* value); - void clear(); + void clear(bool mangle_space); inline HeapWord* block_start(const void* p) const; diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index bfa85393d49..c943f5749a7 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -367,26 +367,31 @@ void Universe::genesis(TRAPS) { // Only 1.3 or later has the java.lang.Shutdown class. // Only 1.4 or later has the java.lang.CharSequence interface. // Only 1.5 or later has the java.lang.management.MemoryUsage class. - if (JDK_Version::is_pre_jdk16_version()) { - klassOop k = SystemDictionary::resolve_or_null(vmSymbolHandles::java_lang_management_MemoryUsage(), THREAD); + if (JDK_Version::is_partially_initialized()) { + uint8_t jdk_version; + klassOop k = SystemDictionary::resolve_or_null( + vmSymbolHandles::java_lang_management_MemoryUsage(), THREAD); CLEAR_PENDING_EXCEPTION; // ignore exceptions if (k == NULL) { - k = SystemDictionary::resolve_or_null(vmSymbolHandles::java_lang_CharSequence(), THREAD); + k = SystemDictionary::resolve_or_null( + vmSymbolHandles::java_lang_CharSequence(), THREAD); CLEAR_PENDING_EXCEPTION; // ignore exceptions if (k == NULL) { - k = SystemDictionary::resolve_or_null(vmSymbolHandles::java_lang_Shutdown(), THREAD); + k = SystemDictionary::resolve_or_null( + vmSymbolHandles::java_lang_Shutdown(), THREAD); CLEAR_PENDING_EXCEPTION; // ignore exceptions if (k == NULL) { - JDK_Version::set_jdk12x_version(); + jdk_version = 2; } else { - JDK_Version::set_jdk13x_version(); + jdk_version = 3; } } else { - JDK_Version::set_jdk14x_version(); + jdk_version = 4; } } else { - JDK_Version::set_jdk15x_version(); + jdk_version = 5; } + JDK_Version::fully_initialize(jdk_version); } #ifdef ASSERT diff --git a/hotspot/src/share/vm/opto/addnode.cpp b/hotspot/src/share/vm/opto/addnode.cpp index e5cc05b6b1f..e207e65eaab 100644 --- a/hotspot/src/share/vm/opto/addnode.cpp +++ b/hotspot/src/share/vm/opto/addnode.cpp @@ -157,6 +157,7 @@ Node *AddNode::Ideal(PhaseGVN *phase, bool can_reshape) { Node *a12 = add1->in(2); const Type *t12 = phase->type( a12 ); if( t12->singleton() && t12 != Type::TOP && (add1 != add1->in(1)) ) { + assert(add1->in(1) != this, "dead loop in AddNode::Ideal"); add2 = add1->clone(); add2->set_req(2, in(2)); add2 = phase->transform(add2); @@ -173,6 +174,7 @@ Node *AddNode::Ideal(PhaseGVN *phase, bool can_reshape) { Node *a22 = add2->in(2); const Type *t22 = phase->type( a22 ); if( t22->singleton() && t22 != Type::TOP && (add2 != add2->in(1)) ) { + assert(add2->in(1) != this, "dead loop in AddNode::Ideal"); Node *addx = add2->clone(); addx->set_req(1, in(1)); addx->set_req(2, add2->in(1)); @@ -573,8 +575,6 @@ const Type *AddPNode::bottom_type() const { intptr_t txoffset = Type::OffsetBot; if (tx->is_con()) { // Left input is an add of a constant? txoffset = tx->get_con(); - if (txoffset != (int)txoffset) - txoffset = Type::OffsetBot; // oops: add_offset will choke on it } return tp->add_offset(txoffset); } @@ -595,8 +595,6 @@ const Type *AddPNode::Value( PhaseTransform *phase ) const { intptr_t p2offset = Type::OffsetBot; if (p2->is_con()) { // Left input is an add of a constant? p2offset = p2->get_con(); - if (p2offset != (int)p2offset) - p2offset = Type::OffsetBot; // oops: add_offset will choke on it } return p1->add_offset(p2offset); } @@ -675,7 +673,7 @@ const Type *AddPNode::mach_bottom_type( const MachNode* n) { // Check for any interesting operand info. // In particular, check for both memory and non-memory operands. // %%%%% Clean this up: use xadd_offset - int con = opnd->constant(); + intptr_t con = opnd->constant(); if ( con == TypePtr::OffsetBot ) goto bottom_out; offset += con; con = opnd->constant_disp(); @@ -695,6 +693,8 @@ const Type *AddPNode::mach_bottom_type( const MachNode* n) { guarantee(tptr == NULL, "must be only one pointer operand"); tptr = et->isa_oopptr(); guarantee(tptr != NULL, "non-int operand must be pointer"); + if (tptr->higher_equal(tp->add_offset(tptr->offset()))) + tp = tptr; // Set more precise type for bailout continue; } if ( eti->_hi != eti->_lo ) goto bottom_out; diff --git a/hotspot/src/share/vm/opto/block.cpp b/hotspot/src/share/vm/opto/block.cpp index c6b94a45af2..e74eca8d12c 100644 --- a/hotspot/src/share/vm/opto/block.cpp +++ b/hotspot/src/share/vm/opto/block.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -467,6 +467,10 @@ void PhaseCFG::insert_goto_at(uint block_no, uint succ_no) { // get successor block succ_no assert(succ_no < in->_num_succs, "illegal successor number"); Block* out = in->_succs[succ_no]; + // Compute frequency of the new block. Do this before inserting + // new block in case succ_prob() needs to infer the probability from + // surrounding blocks. + float freq = in->_freq * in->succ_prob(succ_no); // get ProjNode corresponding to the succ_no'th successor of the in block ProjNode* proj = in->_nodes[in->_nodes.size() - in->_num_succs + succ_no]->as_Proj(); // create region for basic block @@ -491,6 +495,8 @@ void PhaseCFG::insert_goto_at(uint block_no, uint succ_no) { } // remap predecessor's successor to new block in->_succs.map(succ_no, block); + // Set the frequency of the new block + block->_freq = freq; // add new basic block to basic block list _blocks.insert(block_no + 1, block); _num_blocks++; diff --git a/hotspot/src/share/vm/opto/bytecodeInfo.cpp b/hotspot/src/share/vm/opto/bytecodeInfo.cpp index 5a919b916d9..847988efe8d 100644 --- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp +++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp @@ -83,7 +83,7 @@ static bool is_init_with_ea(ciMethod* callee_method, ciMethod* caller_method, Compile* C) { // True when EA is ON and a java constructor is called or // a super constructor is called from an inlined java constructor. - return DoEscapeAnalysis && EliminateAllocations && + return C->do_escape_analysis() && EliminateAllocations && ( callee_method->is_initializer() || (caller_method->is_initializer() && caller_method != C->method() && diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp index 26b288e660e..affd56a86e2 100644 --- a/hotspot/src/share/vm/opto/c2_globals.hpp +++ b/hotspot/src/share/vm/opto/c2_globals.hpp @@ -388,6 +388,9 @@ product(intx, EliminateAllocationArraySizeLimit, 64, \ "Array size (number of elements) limit for scalar replacement") \ \ + product(intx, ValueSearchLimit, 1000, \ + "Recursion limit in PhaseMacroExpand::value_from_mem_phi") \ + \ product(intx, MaxLabelRootDepth, 1100, \ "Maximum times call Label_Root to prevent stack overflow") \ \ diff --git a/hotspot/src/share/vm/opto/callGenerator.cpp b/hotspot/src/share/vm/opto/callGenerator.cpp index 3131cf6b333..8ce7c0ce57d 100644 --- a/hotspot/src/share/vm/opto/callGenerator.cpp +++ b/hotspot/src/share/vm/opto/callGenerator.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -464,6 +464,12 @@ JVMState* PredictedCallGenerator::generate(JVMState* jvms) { } } + if (kit.stopped()) { + // Instance exactly does not matches the desired type. + kit.set_jvms(slow_jvms); + return kit.transfer_exceptions_into_jvms(); + } + // fall through if the instance exactly matches the desired type kit.replace_in_map(receiver, exact_receiver); diff --git a/hotspot/src/share/vm/opto/callnode.cpp b/hotspot/src/share/vm/opto/callnode.cpp index 84015b5335c..2e54ce71801 100644 --- a/hotspot/src/share/vm/opto/callnode.cpp +++ b/hotspot/src/share/vm/opto/callnode.cpp @@ -334,6 +334,9 @@ static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, c case Type::InstPtr: st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->isa_oopptr()->const_oop()); break; + case Type::NarrowOop: + st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->make_ptr()->isa_oopptr()->const_oop()); + break; case Type::RawPtr: st->print(" %s%d]=#Raw" INTPTR_FORMAT,msg,i,t->is_rawptr()); break; @@ -631,61 +634,13 @@ uint CallNode::match_edge(uint idx) const { bool CallNode::may_modify(const TypePtr *addr_t, PhaseTransform *phase) { const TypeOopPtr *adrInst_t = addr_t->isa_oopptr(); - // if not an InstPtr or not an instance type, assume the worst - if (adrInst_t == NULL || !adrInst_t->is_known_instance_field()) { + // If not an OopPtr or not an instance type, assume the worst. + // Note: currently this method is called only for instance types. + if (adrInst_t == NULL || !adrInst_t->is_known_instance()) { return true; } - Compile *C = phase->C; - int offset = adrInst_t->offset(); - assert(adrInst_t->klass_is_exact() && offset >= 0, "should be valid offset"); - ciKlass* adr_k = adrInst_t->klass(); - assert(adr_k->is_loaded() && - adr_k->is_java_klass() && - !adr_k->is_interface(), - "only non-abstract classes are expected"); - - int base_idx = C->get_alias_index(adrInst_t); - int size = BytesPerLong; // If we don't know the size, assume largest. - if (adrInst_t->isa_instptr()) { - ciField* field = C->alias_type(base_idx)->field(); - if (field != NULL) { - size = field->size_in_bytes(); - } - } else { - assert(adrInst_t->isa_aryptr(), "only arrays are expected"); - size = type2aelembytes(adr_k->as_array_klass()->element_type()->basic_type()); - } - - ciMethod * meth = is_CallStaticJava() ? as_CallStaticJava()->method() : NULL; - BCEscapeAnalyzer *bcea = (meth != NULL) ? meth->get_bcea() : NULL; - - const TypeTuple * d = tf()->domain(); - for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { - const Type* t = d->field_at(i); - Node *arg = in(i); - const Type *at = phase->type(arg); - if (at == TypePtr::NULL_PTR || at == Type::TOP) - continue; // null can't affect anything - - const TypeOopPtr *at_ptr = at->isa_oopptr(); - if (!arg->is_top() && (t->isa_oopptr() != NULL || - t->isa_ptr() && at_ptr != NULL)) { - assert(at_ptr != NULL, "expecting an OopPtr"); - ciKlass* at_k = at_ptr->klass(); - if ((adrInst_t->base() == at_ptr->base()) && - at_k->is_loaded() && - at_k->is_java_klass()) { - // If we have found an argument matching addr_t, check if the field - // at the specified offset is modified. - if ((at_k->is_interface() || adr_k == at_k || - adr_k->is_subclass_of(at_k) && !at_ptr->klass_is_exact()) && - (bcea == NULL || - bcea->is_arg_modified(i - TypeFunc::Parms, offset, size))) { - return true; - } - } - } - } + // The instance_id is set only for scalar-replaceable allocations which + // are not passed as arguments according to Escape Analysis. return false; } @@ -877,9 +832,7 @@ SafePointNode* SafePointNode::next_exception() const { //------------------------------Ideal------------------------------------------ // Skip over any collapsed Regions Node *SafePointNode::Ideal(PhaseGVN *phase, bool can_reshape) { - if (remove_dead_region(phase, can_reshape)) return this; - - return NULL; + return remove_dead_region(phase, can_reshape) ? this : NULL; } //------------------------------Identity--------------------------------------- diff --git a/hotspot/src/share/vm/opto/cfgnode.cpp b/hotspot/src/share/vm/opto/cfgnode.cpp index 6087c17e0dd..0e7b2845dbc 100644 --- a/hotspot/src/share/vm/opto/cfgnode.cpp +++ b/hotspot/src/share/vm/opto/cfgnode.cpp @@ -713,7 +713,9 @@ PhiNode* PhiNode::split_out_instance(const TypePtr* at, PhaseIterGVN *igvn) cons assert(type() == Type::MEMORY && (t == TypePtr::BOTTOM || t == TypeRawPtr::BOTTOM || t->isa_oopptr() && !t->is_oopptr()->is_known_instance() && - t->is_oopptr()->cast_to_instance_id(t_oop->instance_id()) == t_oop), + t->is_oopptr()->cast_to_exactness(true) + ->is_oopptr()->cast_to_ptr_type(t_oop->ptr()) + ->is_oopptr()->cast_to_instance_id(t_oop->instance_id()) == t_oop), "bottom or raw memory required"); // Check if an appropriate node already exists. @@ -1089,6 +1091,8 @@ Node* PhiNode::unique_input(PhaseTransform* phase) { if (rc == NULL || phase->type(rc) == Type::TOP) continue; // ignore unreachable control path Node* n = in(i); + if (n == NULL) + continue; Node* un = n->uncast(); if (un == NULL || un == this || phase->type(un) == Type::TOP) { continue; // ignore if top, or in(i) and "this" are in a data cycle diff --git a/hotspot/src/share/vm/opto/chaitin.cpp b/hotspot/src/share/vm/opto/chaitin.cpp index 5d7efdb7637..74a0fce9014 100644 --- a/hotspot/src/share/vm/opto/chaitin.cpp +++ b/hotspot/src/share/vm/opto/chaitin.cpp @@ -43,7 +43,7 @@ void LRG::dump( ) const { if( _degree_valid ) tty->print( "%d ", _eff_degree ); else tty->print("? "); - if( _def == NodeSentinel ) { + if( is_multidef() ) { tty->print("MultiDef "); if (_defs != NULL) { tty->print("("); @@ -765,7 +765,7 @@ void PhaseChaitin::gather_lrg_masks( bool after_aggressive ) { // if the LRG is an unaligned pair, we will have to spill // so clear the LRG's register mask if it is not already spilled if ( !n->is_SpillCopy() && - (lrg._def == NULL || lrg._def == NodeSentinel || !lrg._def->is_SpillCopy()) && + (lrg._def == NULL || lrg.is_multidef() || !lrg._def->is_SpillCopy()) && lrgmask.is_misaligned_Pair()) { lrg.Clear(); } @@ -1282,7 +1282,7 @@ uint PhaseChaitin::Select( ) { // Live range is live and no colors available else { assert( lrg->alive(), "" ); - assert( !lrg->_fat_proj || lrg->_def == NodeSentinel || + assert( !lrg->_fat_proj || lrg->is_multidef() || lrg->_def->outcnt() > 0, "fat_proj cannot spill"); assert( !orig_mask.is_AllStack(), "All Stack does not spill" ); diff --git a/hotspot/src/share/vm/opto/chaitin.hpp b/hotspot/src/share/vm/opto/chaitin.hpp index 273fb03206f..9c7cc593e40 100644 --- a/hotspot/src/share/vm/opto/chaitin.hpp +++ b/hotspot/src/share/vm/opto/chaitin.hpp @@ -156,6 +156,8 @@ public: // Alive if non-zero, dead if zero bool alive() const { return _def != NULL; } + bool is_multidef() const { return _def == NodeSentinel; } + bool is_singledef() const { return _def != NodeSentinel; } #ifndef PRODUCT void dump( ) const; @@ -320,7 +322,8 @@ class PhaseChaitin : public PhaseRegAlloc { uint split_DEF( Node *def, Block *b, int loc, uint max, Node **Reachblock, Node **debug_defs, GrowableArray splits, int slidx ); uint split_USE( Node *def, Block *b, Node *use, uint useidx, uint max, bool def_down, bool cisc_sp, GrowableArray splits, int slidx ); int clone_projs( Block *b, uint idx, Node *con, Node *copy, uint &maxlrg ); - Node *split_Rematerialize( Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray splits, int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru ); + Node *split_Rematerialize(Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray splits, + int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru); // True if lidx is used before any real register is def'd in the block bool prompt_use( Block *b, uint lidx ); Node *get_spillcopy_wide( Node *def, Node *use, uint uidx ); diff --git a/hotspot/src/share/vm/opto/coalesce.cpp b/hotspot/src/share/vm/opto/coalesce.cpp index 20e9bd17992..7d9ab008398 100644 --- a/hotspot/src/share/vm/opto/coalesce.cpp +++ b/hotspot/src/share/vm/opto/coalesce.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -604,8 +604,8 @@ void PhaseConservativeCoalesce::union_helper( Node *lr1_node, Node *lr2_node, ui // If both are single def, then src_def powers one live range // and def_copy powers the other. After merging, src_def powers // the combined live range. - lrgs(lr1)._def = (lrgs(lr1)._def == NodeSentinel || - lrgs(lr2)._def == NodeSentinel ) + lrgs(lr1)._def = (lrgs(lr1).is_multidef() || + lrgs(lr2).is_multidef() ) ? NodeSentinel : src_def; lrgs(lr2)._def = NULL; // No def for lrg 2 lrgs(lr2).Clear(); // Force empty mask for LRG 2 diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index 3904dd5155a..8f833042bf2 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -583,18 +583,32 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr NOT_PRODUCT( verify_graph_edges(); ) // Perform escape analysis - if (_do_escape_analysis) - _congraph = new ConnectionGraph(this); - if (_congraph != NULL) { - NOT_PRODUCT( TracePhase t2("escapeAnalysis", &_t_escapeAnalysis, TimeCompiler); ) - _congraph->compute_escape(); - if (failing()) return; + if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) { + TracePhase t2("escapeAnalysis", &_t_escapeAnalysis, true); + // Add ConP#NULL and ConN#NULL nodes before ConnectionGraph construction. + PhaseGVN* igvn = initial_gvn(); + Node* oop_null = igvn->zerocon(T_OBJECT); + Node* noop_null = igvn->zerocon(T_NARROWOOP); + + _congraph = new(comp_arena()) ConnectionGraph(this); + bool has_non_escaping_obj = _congraph->compute_escape(); #ifndef PRODUCT if (PrintEscapeAnalysis) { _congraph->dump(); } #endif + // Cleanup. + if (oop_null->outcnt() == 0) + igvn->hash_delete(oop_null); + if (noop_null->outcnt() == 0) + igvn->hash_delete(noop_null); + + if (!has_non_escaping_obj) { + _congraph = NULL; + } + + if (failing()) return; } // Now optimize Optimize(); @@ -995,9 +1009,14 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const { int offset = tj->offset(); TypePtr::PTR ptr = tj->ptr(); + // Known instance (scalarizable allocation) alias only with itself. + bool is_known_inst = tj->isa_oopptr() != NULL && + tj->is_oopptr()->is_known_instance(); + // Process weird unsafe references. if (offset == Type::OffsetBot && (tj->isa_instptr() /*|| tj->isa_klassptr()*/)) { assert(InlineUnsafeOps, "indeterminate pointers come only from unsafe ops"); + assert(!is_known_inst, "scalarizable allocation should not have unsafe references"); tj = TypeOopPtr::BOTTOM; ptr = tj->ptr(); offset = tj->offset(); @@ -1005,14 +1024,20 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const { // Array pointers need some flattening const TypeAryPtr *ta = tj->isa_aryptr(); - if( ta && _AliasLevel >= 2 ) { + if( ta && is_known_inst ) { + if ( offset != Type::OffsetBot && + offset > arrayOopDesc::length_offset_in_bytes() ) { + offset = Type::OffsetBot; // Flatten constant access into array body only + tj = ta = TypeAryPtr::make(ptr, ta->ary(), ta->klass(), true, offset, ta->instance_id()); + } + } else if( ta && _AliasLevel >= 2 ) { // For arrays indexed by constant indices, we flatten the alias // space to include all of the array body. Only the header, klass // and array length can be accessed un-aliased. if( offset != Type::OffsetBot ) { if( ta->const_oop() ) { // methodDataOop or methodOop offset = Type::OffsetBot; // Flatten constant access into array body - tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),ta->ary(),ta->klass(),false,Type::OffsetBot, ta->instance_id()); + tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),ta->ary(),ta->klass(),false,offset); } else if( offset == arrayOopDesc::length_offset_in_bytes() ) { // range is OK as-is. tj = ta = TypeAryPtr::RANGE; @@ -1026,29 +1051,29 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const { ptr = TypePtr::BotPTR; } else { // Random constant offset into array body offset = Type::OffsetBot; // Flatten constant access into array body - tj = ta = TypeAryPtr::make(ptr,ta->ary(),ta->klass(),false,Type::OffsetBot, ta->instance_id()); + tj = ta = TypeAryPtr::make(ptr,ta->ary(),ta->klass(),false,offset); } } // Arrays of fixed size alias with arrays of unknown size. if (ta->size() != TypeInt::POS) { const TypeAry *tary = TypeAry::make(ta->elem(), TypeInt::POS); - tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,ta->klass(),false,offset, ta->instance_id()); + tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,ta->klass(),false,offset); } // Arrays of known objects become arrays of unknown objects. if (ta->elem()->isa_narrowoop() && ta->elem() != TypeNarrowOop::BOTTOM) { const TypeAry *tary = TypeAry::make(TypeNarrowOop::BOTTOM, ta->size()); - tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset, ta->instance_id()); + tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset); } if (ta->elem()->isa_oopptr() && ta->elem() != TypeInstPtr::BOTTOM) { const TypeAry *tary = TypeAry::make(TypeInstPtr::BOTTOM, ta->size()); - tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset, ta->instance_id()); + tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset); } // Arrays of bytes and of booleans both use 'bastore' and 'baload' so // cannot be distinguished by bytecode alone. if (ta->elem() == TypeInt::BOOL) { const TypeAry *tary = TypeAry::make(TypeInt::BYTE, ta->size()); ciKlass* aklass = ciTypeArrayKlass::make(T_BYTE); - tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,aklass,false,offset, ta->instance_id()); + tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,aklass,false,offset); } // During the 2nd round of IterGVN, NotNull castings are removed. // Make sure the Bottom and NotNull variants alias the same. @@ -1068,21 +1093,24 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const { if( ptr == TypePtr::Constant ) { // No constant oop pointers (such as Strings); they alias with // unknown strings. + assert(!is_known_inst, "not scalarizable allocation"); tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset); - } else if( to->is_known_instance_field() ) { + } else if( is_known_inst ) { tj = to; // Keep NotNull and klass_is_exact for instance type } else if( ptr == TypePtr::NotNull || to->klass_is_exact() ) { // During the 2nd round of IterGVN, NotNull castings are removed. // Make sure the Bottom and NotNull variants alias the same. // Also, make sure exact and non-exact variants alias the same. - tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset, to->instance_id()); + tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset); } // Canonicalize the holder of this field ciInstanceKlass *k = to->klass()->as_instance_klass(); if (offset >= 0 && offset < instanceOopDesc::base_offset_in_bytes()) { // First handle header references such as a LoadKlassNode, even if the // object's klass is unloaded at compile time (4965979). - tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, offset, to->instance_id()); + if (!is_known_inst) { // Do it only for non-instance types + tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, offset); + } } else if (offset < 0 || offset >= k->size_helper() * wordSize) { to = NULL; tj = TypeOopPtr::BOTTOM; @@ -1090,7 +1118,11 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const { } else { ciInstanceKlass *canonical_holder = k->get_canonical_holder(offset); if (!k->equals(canonical_holder) || tj->offset() != offset) { - tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, false, NULL, offset, to->instance_id()); + if( is_known_inst ) { + tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, true, NULL, offset, to->instance_id()); + } else { + tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, false, NULL, offset); + } } } } @@ -1276,7 +1308,9 @@ Compile::AliasType* Compile::find_alias_type(const TypePtr* adr_type, bool no_cr assert(flat != TypePtr::BOTTOM, "cannot alias-analyze an untyped ptr"); if (flat->isa_oopptr() && !flat->isa_klassptr()) { const TypeOopPtr* foop = flat->is_oopptr(); - const TypePtr* xoop = foop->cast_to_exactness(!foop->klass_is_exact())->is_ptr(); + // Scalarizable allocations have exact klass always. + bool exact = !foop->klass_is_exact() || foop->is_known_instance(); + const TypePtr* xoop = foop->cast_to_exactness(exact)->is_ptr(); assert(foop == flatten_alias_type(xoop), "exactness must not affect alias type"); } assert(flat == flatten_alias_type(flat), "exact bit doesn't matter"); @@ -1933,6 +1967,7 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) { !n->is_Proj() && nop != Op_CreateEx && nop != Op_CheckCastPP && + nop != Op_DecodeN && !n->is_Mem() ) { Node *x = n->clone(); call->set_req( TypeFunc::Parms, x ); @@ -2041,20 +2076,27 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) { case Op_CmpP: // Do this transformation here to preserve CmpPNode::sub() and // other TypePtr related Ideal optimizations (for example, ptr nullness). - if( n->in(1)->is_DecodeN() ) { + if (n->in(1)->is_DecodeN() || n->in(2)->is_DecodeN()) { + Node* in1 = n->in(1); + Node* in2 = n->in(2); + if (!in1->is_DecodeN()) { + in2 = in1; + in1 = n->in(2); + } + assert(in1->is_DecodeN(), "sanity"); + Compile* C = Compile::current(); - Node* in2 = NULL; - if( n->in(2)->is_DecodeN() ) { - in2 = n->in(2)->in(1); - } else if ( n->in(2)->Opcode() == Op_ConP ) { - const Type* t = n->in(2)->bottom_type(); - if (t == TypePtr::NULL_PTR) { - Node *in1 = n->in(1); + Node* new_in2 = NULL; + if (in2->is_DecodeN()) { + new_in2 = in2->in(1); + } else if (in2->Opcode() == Op_ConP) { + const Type* t = in2->bottom_type(); + if (t == TypePtr::NULL_PTR && UseImplicitNullCheckForNarrowOop) { if (Matcher::clone_shift_expressions) { // x86, ARM and friends can handle 2 adds in addressing mode. // Decode a narrow oop and do implicit NULL check in address // [R12 + narrow_oop_reg<<3 + offset] - in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR); + new_in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR); } else { // Don't replace CmpP(o ,null) if 'o' is used in AddP // to generate implicit NULL check on Sparc where @@ -2065,18 +2107,25 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) { break; } if (i >= in1->outcnt()) { - in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR); + new_in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR); } } } else if (t->isa_oopptr()) { - in2 = ConNode::make(C, t->make_narrowoop()); + new_in2 = ConNode::make(C, t->make_narrowoop()); } } - if( in2 != NULL ) { - Node* cmpN = new (C, 3) CmpNNode(n->in(1)->in(1), in2); + if (new_in2 != NULL) { + Node* cmpN = new (C, 3) CmpNNode(in1->in(1), new_in2); n->subsume_by( cmpN ); + if (in1->outcnt() == 0) { + in1->disconnect_inputs(NULL); + } + if (in2->outcnt() == 0) { + in2->disconnect_inputs(NULL); + } } } + break; #endif case Op_ModI: @@ -2179,6 +2228,9 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) { // Replacing Opaque nodes with their input in final_graph_reshaping_impl(), // requires that the walk visits a node's inputs before visiting the node. static void final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_Reshape_Counts &fpu ) { + ResourceArea *area = Thread::current()->resource_area(); + Unique_Node_List sfpt(area); + fpu._visited.set(root->_idx); // first, mark node as visited uint cnt = root->req(); Node *n = root; @@ -2189,6 +2241,8 @@ static void final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_Re Node* m = n->in(i); ++i; if (m != NULL && !fpu._visited.test_set(m->_idx)) { + if (m->is_SafePoint() && m->as_SafePoint()->jvms() != NULL) + sfpt.push(m); cnt = m->req(); nstack.push(n, i); // put on stack parent and next input's index n = m; @@ -2205,6 +2259,41 @@ static void final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_Re nstack.pop(); // Shift to the next node on stack } } + + // Go over safepoints nodes to skip DecodeN nodes for debug edges. + // It could be done for an uncommon traps or any safepoints/calls + // if the DecodeN node is referenced only in a debug info. + while (sfpt.size() > 0) { + n = sfpt.pop(); + JVMState *jvms = n->as_SafePoint()->jvms(); + assert(jvms != NULL, "sanity"); + int start = jvms->debug_start(); + int end = n->req(); + bool is_uncommon = (n->is_CallStaticJava() && + n->as_CallStaticJava()->uncommon_trap_request() != 0); + for (int j = start; j < end; j++) { + Node* in = n->in(j); + if (in->is_DecodeN()) { + bool safe_to_skip = true; + if (!is_uncommon ) { + // Is it safe to skip? + for (uint i = 0; i < in->outcnt(); i++) { + Node* u = in->raw_out(i); + if (!u->is_SafePoint() || + u->is_Call() && u->as_Call()->has_non_debug_use(n)) { + safe_to_skip = false; + } + } + } + if (safe_to_skip) { + n->set_req(j, in->in(1)); + } + if (in->outcnt() == 0) { + in->disconnect_inputs(NULL); + } + } + } + } } //------------------------------final_graph_reshaping-------------------------- diff --git a/hotspot/src/share/vm/opto/connode.cpp b/hotspot/src/share/vm/opto/connode.cpp index 8b441c99439..ceebd76a6bb 100644 --- a/hotspot/src/share/vm/opto/connode.cpp +++ b/hotspot/src/share/vm/opto/connode.cpp @@ -101,6 +101,8 @@ matter ever). // Move constants to the right. Node *CMoveNode::Ideal(PhaseGVN *phase, bool can_reshape) { if( in(0) && remove_dead_region(phase, can_reshape) ) return this; + // Don't bother trying to transform a dead node + if( in(0) && in(0)->is_top() ) return NULL; assert( !phase->eqv(in(Condition), this) && !phase->eqv(in(IfFalse), this) && !phase->eqv(in(IfTrue), this), "dead loop in CMoveNode::Ideal" ); diff --git a/hotspot/src/share/vm/opto/divnode.cpp b/hotspot/src/share/vm/opto/divnode.cpp index 90e198d0763..c1c2b5df442 100644 --- a/hotspot/src/share/vm/opto/divnode.cpp +++ b/hotspot/src/share/vm/opto/divnode.cpp @@ -264,8 +264,14 @@ static Node *long_by_long_mulhi( PhaseGVN *phase, Node *dividend, jlong magic_co Node *t1 = phase->transform(new (phase->C, 3) URShiftLNode(lolo_product, phase->intcon(N / 2))); Node *t2 = phase->transform(new (phase->C, 3) AddLNode(hilo_product, t1)); - Node *t3 = phase->transform(new (phase->C, 3) RShiftLNode(t2, phase->intcon(N / 2))); - Node *t4 = phase->transform(new (phase->C, 3) AndLNode(t2, phase->longcon(0xFFFFFFFF))); + + // Construct both t3 and t4 before transforming so t2 doesn't go dead + // prematurely. + Node *t3 = new (phase->C, 3) RShiftLNode(t2, phase->intcon(N / 2)); + Node *t4 = new (phase->C, 3) AndLNode(t2, phase->longcon(0xFFFFFFFF)); + t3 = phase->transform(t3); + t4 = phase->transform(t4); + Node *t5 = phase->transform(new (phase->C, 3) AddLNode(t4, lohi_product)); Node *t6 = phase->transform(new (phase->C, 3) RShiftLNode(t5, phase->intcon(N / 2))); Node *t7 = phase->transform(new (phase->C, 3) AddLNode(t3, hihi_product)); @@ -396,6 +402,8 @@ Node *DivINode::Identity( PhaseTransform *phase ) { // Divides can be changed to multiplies and/or shifts Node *DivINode::Ideal(PhaseGVN *phase, bool can_reshape) { if (in(0) && remove_dead_region(phase, can_reshape)) return this; + // Don't bother trying to transform a dead node + if( in(0) && in(0)->is_top() ) return NULL; const Type *t = phase->type( in(2) ); if( t == TypeInt::ONE ) // Identity? @@ -493,6 +501,8 @@ Node *DivLNode::Identity( PhaseTransform *phase ) { // Dividing by a power of 2 is a shift. Node *DivLNode::Ideal( PhaseGVN *phase, bool can_reshape) { if (in(0) && remove_dead_region(phase, can_reshape)) return this; + // Don't bother trying to transform a dead node + if( in(0) && in(0)->is_top() ) return NULL; const Type *t = phase->type( in(2) ); if( t == TypeLong::ONE ) // Identity? @@ -634,6 +644,8 @@ Node *DivFNode::Identity( PhaseTransform *phase ) { //------------------------------Idealize--------------------------------------- Node *DivFNode::Ideal(PhaseGVN *phase, bool can_reshape) { if (in(0) && remove_dead_region(phase, can_reshape)) return this; + // Don't bother trying to transform a dead node + if( in(0) && in(0)->is_top() ) return NULL; const Type *t2 = phase->type( in(2) ); if( t2 == TypeF::ONE ) // Identity? @@ -719,6 +731,8 @@ Node *DivDNode::Identity( PhaseTransform *phase ) { //------------------------------Idealize--------------------------------------- Node *DivDNode::Ideal(PhaseGVN *phase, bool can_reshape) { if (in(0) && remove_dead_region(phase, can_reshape)) return this; + // Don't bother trying to transform a dead node + if( in(0) && in(0)->is_top() ) return NULL; const Type *t2 = phase->type( in(2) ); if( t2 == TypeD::ONE ) // Identity? @@ -754,7 +768,9 @@ Node *DivDNode::Ideal(PhaseGVN *phase, bool can_reshape) { //------------------------------Idealize--------------------------------------- Node *ModINode::Ideal(PhaseGVN *phase, bool can_reshape) { // Check for dead control input - if( remove_dead_region(phase, can_reshape) ) return this; + if( in(0) && remove_dead_region(phase, can_reshape) ) return this; + // Don't bother trying to transform a dead node + if( in(0) && in(0)->is_top() ) return NULL; // Get the modulus const Type *t = phase->type( in(2) ); @@ -923,7 +939,9 @@ const Type *ModINode::Value( PhaseTransform *phase ) const { //------------------------------Idealize--------------------------------------- Node *ModLNode::Ideal(PhaseGVN *phase, bool can_reshape) { // Check for dead control input - if( remove_dead_region(phase, can_reshape) ) return this; + if( in(0) && remove_dead_region(phase, can_reshape) ) return this; + // Don't bother trying to transform a dead node + if( in(0) && in(0)->is_top() ) return NULL; // Get the modulus const Type *t = phase->type( in(2) ); diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp index 5aa90ea1f3d..1c1d5d8223f 100644 --- a/hotspot/src/share/vm/opto/escape.cpp +++ b/hotspot/src/share/vm/opto/escape.cpp @@ -25,16 +25,6 @@ #include "incls/_precompiled.incl" #include "incls/_escape.cpp.incl" -uint PointsToNode::edge_target(uint e) const { - assert(_edges != NULL && e < (uint)_edges->length(), "valid edge index"); - return (_edges->at(e) >> EdgeShift); -} - -PointsToNode::EdgeType PointsToNode::edge_type(uint e) const { - assert(_edges != NULL && e < (uint)_edges->length(), "valid edge index"); - return (EdgeType) (_edges->at(e) & EdgeMask); -} - void PointsToNode::add_edge(uint targIdx, PointsToNode::EdgeType et) { uint v = (targIdx << EdgeShift) + ((uint) et); if (_edges == NULL) { @@ -72,10 +62,14 @@ static const char *edge_type_suffix[] = { "F" // FieldEdge }; -void PointsToNode::dump() const { +void PointsToNode::dump(bool print_state) const { NodeType nt = node_type(); - EscapeState es = escape_state(); - tty->print("%s %s %s [[", node_type_names[(int) nt], esc_names[(int) es], _scalar_replaceable ? "" : "NSR"); + tty->print("%s ", node_type_names[(int) nt]); + if (print_state) { + EscapeState es = escape_state(); + tty->print("%s %s ", esc_names[(int) es], _scalar_replaceable ? "":"NSR"); + } + tty->print("[["); for (uint i = 0; i < edge_count(); i++) { tty->print(" %d%s", edge_target(i), edge_type_suffix[(int) edge_type(i)]); } @@ -87,17 +81,29 @@ void PointsToNode::dump() const { } #endif -ConnectionGraph::ConnectionGraph(Compile * C) : _processed(C->comp_arena()), _node_map(C->comp_arena()) { - _collecting = true; - this->_compile = C; - const PointsToNode &dummy = PointsToNode(); - int sz = C->unique(); - _nodes = new(C->comp_arena()) GrowableArray(C->comp_arena(), sz, sz, dummy); - _phantom_object = C->top()->_idx; - PointsToNode *phn = ptnode_adr(_phantom_object); - phn->_node = C->top(); - phn->set_node_type(PointsToNode::JavaObject); - phn->set_escape_state(PointsToNode::GlobalEscape); +ConnectionGraph::ConnectionGraph(Compile * C) : + _nodes(C->comp_arena(), C->unique(), C->unique(), PointsToNode()), + _processed(C->comp_arena()), + _collecting(true), + _compile(C), + _node_map(C->comp_arena()) { + + _phantom_object = C->top()->_idx, + add_node(C->top(), PointsToNode::JavaObject, PointsToNode::GlobalEscape,true); + + // Add ConP(#NULL) and ConN(#NULL) nodes. + PhaseGVN* igvn = C->initial_gvn(); + Node* oop_null = igvn->zerocon(T_OBJECT); + _oop_null = oop_null->_idx; + assert(_oop_null < C->unique(), "should be created already"); + add_node(oop_null, PointsToNode::JavaObject, PointsToNode::NoEscape, true); + + if (UseCompressedOops) { + Node* noop_null = igvn->zerocon(T_NARROWOOP); + _noop_null = noop_null->_idx; + assert(_noop_null < C->unique(), "should be created already"); + add_node(noop_null, PointsToNode::JavaObject, PointsToNode::NoEscape, true); + } } void ConnectionGraph::add_pointsto_edge(uint from_i, uint to_i) { @@ -182,32 +188,36 @@ PointsToNode::EscapeState ConnectionGraph::escape_state(Node *n, PhaseTransform // If we are still collecting or there were no non-escaping allocations // we don't know the answer yet - if (_collecting || !_has_allocations) + if (_collecting) return PointsToNode::UnknownEscape; // if the node was created after the escape computation, return // UnknownEscape - if (idx >= (uint)_nodes->length()) + if (idx >= nodes_size()) return PointsToNode::UnknownEscape; - es = _nodes->at_grow(idx).escape_state(); + es = ptnode_adr(idx)->escape_state(); // if we have already computed a value, return it if (es != PointsToNode::UnknownEscape) return es; + // PointsTo() calls n->uncast() which can return a new ideal node. + if (n->uncast()->_idx >= nodes_size()) + return PointsToNode::UnknownEscape; + // compute max escape state of anything this node could point to VectorSet ptset(Thread::current()->resource_area()); PointsTo(ptset, n, phase); for(VectorSetI i(&ptset); i.test() && es != PointsToNode::GlobalEscape; ++i) { uint pt = i.elem; - PointsToNode::EscapeState pes = _nodes->adr_at(pt)->escape_state(); + PointsToNode::EscapeState pes = ptnode_adr(pt)->escape_state(); if (pes > es) es = pes; } // cache the computed escape state assert(es != PointsToNode::UnknownEscape, "should have computed an escape state"); - _nodes->adr_at(idx)->set_escape_state(es); + ptnode_adr(idx)->set_escape_state(es); return es; } @@ -220,49 +230,51 @@ void ConnectionGraph::PointsTo(VectorSet &ptset, Node * n, PhaseTransform *phase #endif n = n->uncast(); - PointsToNode npt = _nodes->at_grow(n->_idx); + PointsToNode* npt = ptnode_adr(n->_idx); // If we have a JavaObject, return just that object - if (npt.node_type() == PointsToNode::JavaObject) { + if (npt->node_type() == PointsToNode::JavaObject) { ptset.set(n->_idx); return; } #ifdef ASSERT - if (npt._node == NULL) { + if (npt->_node == NULL) { if (orig_n != n) orig_n->dump(); n->dump(); - assert(npt._node != NULL, "unregistered node"); + assert(npt->_node != NULL, "unregistered node"); } #endif worklist.push(n->_idx); while(worklist.length() > 0) { int ni = worklist.pop(); - PointsToNode pn = _nodes->at_grow(ni); - if (!visited.test_set(ni)) { - // ensure that all inputs of a Phi have been processed - assert(!_collecting || !pn._node->is_Phi() || _processed.test(ni),""); + if (visited.test_set(ni)) + continue; - int edges_processed = 0; - for (uint e = 0; e < pn.edge_count(); e++) { - uint etgt = pn.edge_target(e); - PointsToNode::EdgeType et = pn.edge_type(e); - if (et == PointsToNode::PointsToEdge) { - ptset.set(etgt); - edges_processed++; - } else if (et == PointsToNode::DeferredEdge) { - worklist.push(etgt); - edges_processed++; - } else { - assert(false,"neither PointsToEdge or DeferredEdge"); - } - } - if (edges_processed == 0) { - // no deferred or pointsto edges found. Assume the value was set - // outside this method. Add the phantom object to the pointsto set. - ptset.set(_phantom_object); + PointsToNode* pn = ptnode_adr(ni); + // ensure that all inputs of a Phi have been processed + assert(!_collecting || !pn->_node->is_Phi() || _processed.test(ni),""); + + int edges_processed = 0; + uint e_cnt = pn->edge_count(); + for (uint e = 0; e < e_cnt; e++) { + uint etgt = pn->edge_target(e); + PointsToNode::EdgeType et = pn->edge_type(e); + if (et == PointsToNode::PointsToEdge) { + ptset.set(etgt); + edges_processed++; + } else if (et == PointsToNode::DeferredEdge) { + worklist.push(etgt); + edges_processed++; + } else { + assert(false,"neither PointsToEdge or DeferredEdge"); } } + if (edges_processed == 0) { + // no deferred or pointsto edges found. Assume the value was set + // outside this method. Add the phantom object to the pointsto set. + ptset.set(_phantom_object); + } } } @@ -272,11 +284,11 @@ void ConnectionGraph::remove_deferred(uint ni, GrowableArray* deferred_edg deferred_edges->clear(); visited->Clear(); - uint i = 0; + visited->set(ni); PointsToNode *ptn = ptnode_adr(ni); // Mark current edges as visited and move deferred edges to separate array. - while (i < ptn->edge_count()) { + for (uint i = 0; i < ptn->edge_count(); ) { uint t = ptn->edge_target(i); #ifdef ASSERT assert(!visited->test_set(t), "expecting no duplications"); @@ -293,24 +305,23 @@ void ConnectionGraph::remove_deferred(uint ni, GrowableArray* deferred_edg for (int next = 0; next < deferred_edges->length(); ++next) { uint t = deferred_edges->at(next); PointsToNode *ptt = ptnode_adr(t); - for (uint j = 0; j < ptt->edge_count(); j++) { - uint n1 = ptt->edge_target(j); - if (visited->test_set(n1)) + uint e_cnt = ptt->edge_count(); + for (uint e = 0; e < e_cnt; e++) { + uint etgt = ptt->edge_target(e); + if (visited->test_set(etgt)) continue; - switch(ptt->edge_type(j)) { - case PointsToNode::PointsToEdge: - add_pointsto_edge(ni, n1); - if(n1 == _phantom_object) { - // Special case - field set outside (globally escaping). - ptn->set_escape_state(PointsToNode::GlobalEscape); - } - break; - case PointsToNode::DeferredEdge: - deferred_edges->append(n1); - break; - case PointsToNode::FieldEdge: - assert(false, "invalid connection graph"); - break; + + PointsToNode::EdgeType et = ptt->edge_type(e); + if (et == PointsToNode::PointsToEdge) { + add_pointsto_edge(ni, etgt); + if(etgt == _phantom_object) { + // Special case - field set outside (globally escaping). + ptn->set_escape_state(PointsToNode::GlobalEscape); + } + } else if (et == PointsToNode::DeferredEdge) { + deferred_edges->append(etgt); + } else { + assert(false,"invalid connection graph"); } } } @@ -322,15 +333,15 @@ void ConnectionGraph::remove_deferred(uint ni, GrowableArray* deferred_edg // a pointsto edge is added if it is a JavaObject void ConnectionGraph::add_edge_from_fields(uint adr_i, uint to_i, int offs) { - PointsToNode an = _nodes->at_grow(adr_i); - PointsToNode to = _nodes->at_grow(to_i); - bool deferred = (to.node_type() == PointsToNode::LocalVar); + PointsToNode* an = ptnode_adr(adr_i); + PointsToNode* to = ptnode_adr(to_i); + bool deferred = (to->node_type() == PointsToNode::LocalVar); - for (uint fe = 0; fe < an.edge_count(); fe++) { - assert(an.edge_type(fe) == PointsToNode::FieldEdge, "expecting a field edge"); - int fi = an.edge_target(fe); - PointsToNode pf = _nodes->at_grow(fi); - int po = pf.offset(); + for (uint fe = 0; fe < an->edge_count(); fe++) { + assert(an->edge_type(fe) == PointsToNode::FieldEdge, "expecting a field edge"); + int fi = an->edge_target(fe); + PointsToNode* pf = ptnode_adr(fi); + int po = pf->offset(); if (po == offs || po == Type::OffsetBot || offs == Type::OffsetBot) { if (deferred) add_deferred_edge(fi, to_i); @@ -343,13 +354,13 @@ void ConnectionGraph::add_edge_from_fields(uint adr_i, uint to_i, int offs) { // Add a deferred edge from node given by "from_i" to any field of adr_i // whose offset matches "offset". void ConnectionGraph::add_deferred_edge_to_fields(uint from_i, uint adr_i, int offs) { - PointsToNode an = _nodes->at_grow(adr_i); - for (uint fe = 0; fe < an.edge_count(); fe++) { - assert(an.edge_type(fe) == PointsToNode::FieldEdge, "expecting a field edge"); - int fi = an.edge_target(fe); - PointsToNode pf = _nodes->at_grow(fi); - int po = pf.offset(); - if (pf.edge_count() == 0) { + PointsToNode* an = ptnode_adr(adr_i); + for (uint fe = 0; fe < an->edge_count(); fe++) { + assert(an->edge_type(fe) == PointsToNode::FieldEdge, "expecting a field edge"); + int fi = an->edge_target(fe); + PointsToNode* pf = ptnode_adr(fi); + int po = pf->offset(); + if (pf->edge_count() == 0) { // we have not seen any stores to this field, assume it was set outside this method add_pointsto_edge(fi, _phantom_object); } @@ -481,22 +492,41 @@ static Node* find_second_addp(Node* addp, Node* n) { // Adjust the type and inputs of an AddP which computes the // address of a field of an instance // -void ConnectionGraph::split_AddP(Node *addp, Node *base, PhaseGVN *igvn) { +bool ConnectionGraph::split_AddP(Node *addp, Node *base, PhaseGVN *igvn) { const TypeOopPtr *base_t = igvn->type(base)->isa_oopptr(); assert(base_t != NULL && base_t->is_known_instance(), "expecting instance oopptr"); const TypeOopPtr *t = igvn->type(addp)->isa_oopptr(); if (t == NULL) { // We are computing a raw address for a store captured by an Initialize - // compute an appropriate address type. + // compute an appropriate address type (cases #3 and #5). assert(igvn->type(addp) == TypeRawPtr::NOTNULL, "must be raw pointer"); assert(addp->in(AddPNode::Address)->is_Proj(), "base of raw address must be result projection from allocation"); - int offs = (int)igvn->find_intptr_t_con(addp->in(AddPNode::Offset), Type::OffsetBot); + intptr_t offs = (int)igvn->find_intptr_t_con(addp->in(AddPNode::Offset), Type::OffsetBot); assert(offs != Type::OffsetBot, "offset must be a constant"); t = base_t->add_offset(offs)->is_oopptr(); } int inst_id = base_t->instance_id(); assert(!t->is_known_instance() || t->instance_id() == inst_id, "old type must be non-instance or match new type"); + + // The type 't' could be subclass of 'base_t'. + // As result t->offset() could be large then base_t's size and it will + // cause the failure in add_offset() with narrow oops since TypeOopPtr() + // constructor verifies correctness of the offset. + // + // It could happend on subclass's branch (from the type profiling + // inlining) which was not eliminated during parsing since the exactness + // of the allocation type was not propagated to the subclass type check. + // + // Do nothing for such AddP node and don't process its users since + // this code branch will go away. + // + if (!t->is_known_instance() && + !t->klass()->equals(base_t->klass()) && + t->klass()->is_subtype_of(base_t->klass())) { + return false; // bail out + } + const TypeOopPtr *tinst = base_t->add_offset(t->offset())->is_oopptr(); // Do NOT remove the next call: ensure an new alias index is allocated // for the instance type @@ -504,32 +534,34 @@ void ConnectionGraph::split_AddP(Node *addp, Node *base, PhaseGVN *igvn) { igvn->set_type(addp, tinst); // record the allocation in the node map set_map(addp->_idx, get_map(base->_idx)); - // if the Address input is not the appropriate instance type - // (due to intervening casts,) insert a cast - Node *adr = addp->in(AddPNode::Address); - const TypeOopPtr *atype = igvn->type(adr)->isa_oopptr(); - if (atype != NULL && atype->instance_id() != inst_id) { - assert(!atype->is_known_instance(), "no conflicting instances"); - const TypeOopPtr *new_atype = base_t->add_offset(atype->offset())->isa_oopptr(); - Node *acast = new (_compile, 2) CastPPNode(adr, new_atype); - acast->set_req(0, adr->in(0)); - igvn->set_type(acast, new_atype); - record_for_optimizer(acast); - Node *bcast = acast; - Node *abase = addp->in(AddPNode::Base); - if (abase != adr) { - bcast = new (_compile, 2) CastPPNode(abase, base_t); - bcast->set_req(0, abase->in(0)); - igvn->set_type(bcast, base_t); - record_for_optimizer(bcast); + + // Set addp's Base and Address to 'base'. + Node *abase = addp->in(AddPNode::Base); + Node *adr = addp->in(AddPNode::Address); + if (adr->is_Proj() && adr->in(0)->is_Allocate() && + adr->in(0)->_idx == (uint)inst_id) { + // Skip AddP cases #3 and #5. + } else { + assert(!abase->is_top(), "sanity"); // AddP case #3 + if (abase != base) { + igvn->hash_delete(addp); + addp->set_req(AddPNode::Base, base); + if (abase == adr) { + addp->set_req(AddPNode::Address, base); + } else { + // AddP case #4 (adr is array's element offset AddP node) +#ifdef ASSERT + const TypeOopPtr *atype = igvn->type(adr)->isa_oopptr(); + assert(adr->is_AddP() && atype != NULL && + atype->instance_id() == inst_id, "array's element offset should be processed first"); +#endif + } + igvn->hash_insert(addp); } - igvn->hash_delete(addp); - addp->set_req(AddPNode::Base, bcast); - addp->set_req(AddPNode::Address, acast); - igvn->hash_insert(addp); } // Put on IGVN worklist since at least addp's type was changed above. record_for_optimizer(addp); + return true; } // @@ -664,27 +696,31 @@ Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArra Compile* C = phase->C; const TypeOopPtr *tinst = C->get_adr_type(alias_idx)->isa_oopptr(); bool is_instance = (tinst != NULL) && tinst->is_known_instance(); + Node *start_mem = C->start()->proj_out(TypeFunc::Memory); Node *prev = NULL; Node *result = orig_mem; while (prev != result) { prev = result; + if (result == start_mem) + break; // hit one of our sentinals if (result->is_Mem()) { - MemNode *mem = result->as_Mem(); - const Type *at = phase->type(mem->in(MemNode::Address)); + const Type *at = phase->type(result->in(MemNode::Address)); if (at != Type::TOP) { assert (at->isa_ptr() != NULL, "pointer type required."); int idx = C->get_alias_index(at->is_ptr()); if (idx == alias_idx) break; } - result = mem->in(MemNode::Memory); + result = result->in(MemNode::Memory); } if (!is_instance) continue; // don't search further for non-instance types // skip over a call which does not affect this memory slice if (result->is_Proj() && result->as_Proj()->_con == TypeFunc::Memory) { Node *proj_in = result->in(0); - if (proj_in->is_Call()) { + if (proj_in->is_Allocate() && proj_in->_idx == (uint)tinst->instance_id()) { + break; // hit one of our sentinals + } else if (proj_in->is_Call()) { CallNode *call = proj_in->as_Call(); if (!call->may_modify(tinst, phase)) { result = call->in(TypeFunc::Memory); @@ -721,12 +757,17 @@ Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArra } } } - if (is_instance && result->is_Phi()) { + if (result->is_Phi()) { PhiNode *mphi = result->as_Phi(); assert(mphi->bottom_type() == Type::MEMORY, "memory phi required"); const TypePtr *t = mphi->adr_type(); if (C->get_alias_index(t) != alias_idx) { + // Create a new Phi with the specified alias index type. result = split_memory_phi(mphi, alias_idx, orig_phis, phase); + } else if (!is_instance) { + // Push all non-instance Phis on the orig_phis worklist to update inputs + // during Phase 4 if needed. + orig_phis.append_if_missing(mphi); } } // the result is either MemNode, PhiNode, InitializeNode. @@ -835,6 +876,11 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) // Phase 1: Process possible allocations from alloc_worklist. // Create instance types for the CheckCastPP for allocations where possible. + // + // (Note: don't forget to change the order of the second AddP node on + // the alloc_worklist if the order of the worklist processing is changed, + // see the comment in find_second_addp().) + // while (alloc_worklist.length() != 0) { Node *n = alloc_worklist.pop(); uint ni = n->_idx; @@ -842,7 +888,7 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) if (n->is_Call()) { CallNode *alloc = n->as_Call(); // copy escape information to call node - PointsToNode* ptn = _nodes->adr_at(alloc->_idx); + PointsToNode* ptn = ptnode_adr(alloc->_idx); PointsToNode::EscapeState es = escape_state(alloc, igvn); // We have an allocation or call which returns a Java object, // see if it is unescaped. @@ -858,10 +904,14 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) !n->is_CheckCastPP()) // not unique CheckCastPP. continue; // The inline code for Object.clone() casts the allocation result to - // java.lang.Object and then to the the actual type of the allocated + // java.lang.Object and then to the actual type of the allocated // object. Detect this case and use the second cast. + // Also detect j.l.reflect.Array.newInstance(jobject, jint) case when + // the allocation result is cast to java.lang.Object and then + // to the actual Array type. if (alloc->is_Allocate() && n->as_Type()->type() == TypeInstPtr::NOTNULL - && igvn->type(alloc->in(AllocateNode::KlassNode)) != TypeKlassPtr::OBJECT) { + && (alloc->is_AllocateArray() || + igvn->type(alloc->in(AllocateNode::KlassNode)) != TypeKlassPtr::OBJECT)) { Node *cast2 = NULL; for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { Node *use = n->fast_out(i); @@ -877,7 +927,7 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) } } set_escape_state(n->_idx, es); - // in order for an object to be stackallocatable, it must be: + // in order for an object to be scalar-replaceable, it must be: // - a direct allocation (not a call returning an object) // - non-escaping // - eligible to be a unique type @@ -887,7 +937,7 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) const TypeOopPtr *t = igvn->type(n)->isa_oopptr(); if (t == NULL) continue; // not a TypeInstPtr - tinst = t->cast_to_instance_id(ni); + tinst = t->cast_to_exactness(true)->is_oopptr()->cast_to_instance_id(ni); igvn->hash_delete(n); igvn->set_type(n, tinst); n->raise_bottom_type(tinst); @@ -899,7 +949,7 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) // First, put on the worklist all Field edges from Connection Graph // which is more accurate then putting immediate users from Ideal Graph. for (uint e = 0; e < ptn->edge_count(); e++) { - Node *use = _nodes->adr_at(ptn->edge_target(e))->_node; + Node *use = ptnode_adr(ptn->edge_target(e))->_node; assert(ptn->edge_type(e) == PointsToNode::FieldEdge && use->is_AddP(), "only AddP nodes are Field edges in CG"); if (use->outcnt() > 0) { // Don't process dead nodes @@ -939,7 +989,7 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) if (elem == _phantom_object) continue; // Assume the value was set outside this method. Node *base = get_map(elem); // CheckCastPP node - split_AddP(n, base, igvn); + if (!split_AddP(n, base, igvn)) continue; // wrong type tinst = igvn->type(base)->isa_oopptr(); } else if (n->is_Phi() || n->is_CheckCastPP() || @@ -982,6 +1032,8 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) tn->set_type(tn_type); igvn->hash_insert(tn); record_for_optimizer(n); + } else { + continue; // wrong type } } } else { @@ -996,12 +1048,12 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) memnode_worklist.append_if_missing(use); } else if (use->is_MergeMem()) { mergemem_worklist.append_if_missing(use); - } else if (use->is_Call() && tinst != NULL) { + } else if (use->is_SafePoint() && tinst != NULL) { // Look for MergeMem nodes for calls which reference unique allocation // (through CheckCastPP nodes) even for debug info. Node* m = use->in(TypeFunc::Memory); uint iid = tinst->instance_id(); - while (m->is_Proj() && m->in(0)->is_Call() && + while (m->is_Proj() && m->in(0)->is_SafePoint() && m->in(0) != use && !m->in(0)->_idx != iid) { m = m->in(0)->in(TypeFunc::Memory); } @@ -1062,7 +1114,7 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) } if (mem != n->in(MemNode::Memory)) { set_map(n->_idx, mem); - _nodes->adr_at(n->_idx)->_node = n; + ptnode_adr(n->_idx)->_node = n; } if (n->is_Load()) { continue; // don't push users @@ -1203,8 +1255,8 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) // to recursively process Phi's encounted on the input memory // chains as is done in split_memory_phi() since they will // also be processed here. - while (orig_phis.length() != 0) { - PhiNode *phi = orig_phis.pop(); + for (int j = 0; j < orig_phis.length(); j++) { + PhiNode *phi = orig_phis.at(j); int alias_idx = _compile->get_alias_index(phi->adr_type()); igvn->hash_delete(phi); for (uint i = 1; i < phi->req(); i++) { @@ -1223,10 +1275,10 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) // Update the memory inputs of MemNodes with the value we computed // in Phase 2. - for (int i = 0; i < _nodes->length(); i++) { + for (uint i = 0; i < nodes_size(); i++) { Node *nmem = get_map(i); if (nmem != NULL) { - Node *n = _nodes->adr_at(i)->_node; + Node *n = ptnode_adr(i)->_node; if (n != NULL && n->is_Mem()) { igvn->hash_delete(n); n->set_req(MemNode::Memory, nmem); @@ -1237,28 +1289,48 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) } } -void ConnectionGraph::compute_escape() { +bool ConnectionGraph::has_candidates(Compile *C) { + // EA brings benefits only when the code has allocations and/or locks which + // are represented by ideal Macro nodes. + int cnt = C->macro_count(); + for( int i=0; i < cnt; i++ ) { + Node *n = C->macro_node(i); + if ( n->is_Allocate() ) + return true; + if( n->is_Lock() ) { + Node* obj = n->as_Lock()->obj_node()->uncast(); + if( !(obj->is_Parm() || obj->is_Con()) ) + return true; + } + } + return false; +} + +bool ConnectionGraph::compute_escape() { + Compile* C = _compile; // 1. Populate Connection Graph (CG) with Ideal nodes. Unique_Node_List worklist_init; - worklist_init.map(_compile->unique(), NULL); // preallocate space + worklist_init.map(C->unique(), NULL); // preallocate space // Initialize worklist - if (_compile->root() != NULL) { - worklist_init.push(_compile->root()); + if (C->root() != NULL) { + worklist_init.push(C->root()); } GrowableArray cg_worklist; - PhaseGVN* igvn = _compile->initial_gvn(); + PhaseGVN* igvn = C->initial_gvn(); bool has_allocations = false; // Push all useful nodes onto CG list and set their type. for( uint next = 0; next < worklist_init.size(); ++next ) { Node* n = worklist_init.at(next); record_for_escape_analysis(n, igvn); - if (n->is_Call() && - _nodes->adr_at(n->_idx)->node_type() == PointsToNode::JavaObject) { + // Only allocations and java static calls results are checked + // for an escape status. See process_call_result() below. + if (n->is_Allocate() || n->is_CallStaticJava() && + ptnode_adr(n->_idx)->node_type() == PointsToNode::JavaObject) { has_allocations = true; } if(n->is_AddP()) @@ -1269,24 +1341,23 @@ void ConnectionGraph::compute_escape() { } } - if (has_allocations) { - _has_allocations = true; - } else { - _has_allocations = false; + if (!has_allocations) { _collecting = false; - return; // Nothing to do. + return false; // Nothing to do. } // 2. First pass to create simple CG edges (doesn't require to walk CG). - for( uint next = 0; next < _delayed_worklist.size(); ++next ) { + uint delayed_size = _delayed_worklist.size(); + for( uint next = 0; next < delayed_size; ++next ) { Node* n = _delayed_worklist.at(next); build_connection_graph(n, igvn); } // 3. Pass to create fields edges (Allocate -F-> AddP). - for( int next = 0; next < cg_worklist.length(); ++next ) { + uint cg_length = cg_worklist.length(); + for( uint next = 0; next < cg_length; ++next ) { int ni = cg_worklist.at(next); - build_connection_graph(_nodes->adr_at(ni)->_node, igvn); + build_connection_graph(ptnode_adr(ni)->_node, igvn); } cg_worklist.clear(); @@ -1294,8 +1365,8 @@ void ConnectionGraph::compute_escape() { // 4. Build Connection Graph which need // to walk the connection graph. - for (uint ni = 0; ni < (uint)_nodes->length(); ni++) { - PointsToNode* ptn = _nodes->adr_at(ni); + for (uint ni = 0; ni < nodes_size(); ni++) { + PointsToNode* ptn = ptnode_adr(ni); Node *n = ptn->_node; if (n != NULL) { // Call, AddP, LoadP, StoreP build_connection_graph(n, igvn); @@ -1305,140 +1376,226 @@ void ConnectionGraph::compute_escape() { } VectorSet ptset(Thread::current()->resource_area()); - GrowableArray alloc_worklist; - GrowableArray worklist; GrowableArray deferred_edges; VectorSet visited(Thread::current()->resource_area()); - // remove deferred edges from the graph and collect - // information we will need for type splitting - for( int next = 0; next < cg_worklist.length(); ++next ) { + // 5. Remove deferred edges from the graph and collect + // information needed for type splitting. + cg_length = cg_worklist.length(); + for( uint next = 0; next < cg_length; ++next ) { int ni = cg_worklist.at(next); - PointsToNode* ptn = _nodes->adr_at(ni); + PointsToNode* ptn = ptnode_adr(ni); PointsToNode::NodeType nt = ptn->node_type(); - Node *n = ptn->_node; if (nt == PointsToNode::LocalVar || nt == PointsToNode::Field) { remove_deferred(ni, &deferred_edges, &visited); + Node *n = ptn->_node; if (n->is_AddP()) { - // If this AddP computes an address which may point to more that one - // object or more then one field (array's element), nothing the address - // points to can be scalar replaceable. + // Search for objects which are not scalar replaceable. + // Mark their escape state as ArgEscape to propagate the state + // to referenced objects. + // Note: currently there are no difference in compiler optimizations + // for ArgEscape objects and NoEscape objects which are not + // scalar replaceable. + + int offset = ptn->offset(); Node *base = get_addp_base(n); ptset.Clear(); PointsTo(ptset, base, igvn); - if (ptset.Size() > 1 || - (ptset.Size() != 0 && ptn->offset() == Type::OffsetBot)) { + int ptset_size = ptset.Size(); + + // Check if a field's initializing value is recorded and add + // a corresponding NULL field's value if it is not recorded. + // Connection Graph does not record a default initialization by NULL + // captured by Initialize node. + // + // Note: it will disable scalar replacement in some cases: + // + // Point p[] = new Point[1]; + // p[0] = new Point(); // Will be not scalar replaced + // + // but it will save us from incorrect optimizations in next cases: + // + // Point p[] = new Point[1]; + // if ( x ) p[0] = new Point(); // Will be not scalar replaced + // + // Without a control flow analysis we can't distinguish above cases. + // + if (offset != Type::OffsetBot && ptset_size == 1) { + uint elem = ptset.getelem(); // Allocation node's index + // It does not matter if it is not Allocation node since + // only non-escaping allocations are scalar replaced. + if (ptnode_adr(elem)->_node->is_Allocate() && + ptnode_adr(elem)->escape_state() == PointsToNode::NoEscape) { + AllocateNode* alloc = ptnode_adr(elem)->_node->as_Allocate(); + InitializeNode* ini = alloc->initialization(); + Node* value = NULL; + if (ini != NULL) { + BasicType ft = UseCompressedOops ? T_NARROWOOP : T_OBJECT; + Node* store = ini->find_captured_store(offset, type2aelembytes(ft), igvn); + if (store != NULL && store->is_Store()) + value = store->in(MemNode::ValueIn); + } + if (value == NULL || value != ptnode_adr(value->_idx)->_node) { + // A field's initializing value was not recorded. Add NULL. + uint null_idx = UseCompressedOops ? _noop_null : _oop_null; + add_pointsto_edge(ni, null_idx); + } + } + } + + // An object is not scalar replaceable if the field which may point + // to it has unknown offset (unknown element of an array of objects). + // + if (offset == Type::OffsetBot) { + uint e_cnt = ptn->edge_count(); + for (uint ei = 0; ei < e_cnt; ei++) { + uint npi = ptn->edge_target(ei); + set_escape_state(npi, PointsToNode::ArgEscape); + ptnode_adr(npi)->_scalar_replaceable = false; + } + } + + // Currently an object is not scalar replaceable if a LoadStore node + // access its field since the field value is unknown after it. + // + bool has_LoadStore = false; + for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { + Node *use = n->fast_out(i); + if (use->is_LoadStore()) { + has_LoadStore = true; + break; + } + } + // An object is not scalar replaceable if the address points + // to unknown field (unknown element for arrays, offset is OffsetBot). + // + // Or the address may point to more then one object. This may produce + // the false positive result (set scalar_replaceable to false) + // since the flow-insensitive escape analysis can't separate + // the case when stores overwrite the field's value from the case + // when stores happened on different control branches. + // + if (ptset_size > 1 || ptset_size != 0 && + (has_LoadStore || offset == Type::OffsetBot)) { for( VectorSetI j(&ptset); j.test(); ++j ) { - uint pt = j.elem; - ptnode_adr(pt)->_scalar_replaceable = false; + set_escape_state(j.elem, PointsToNode::ArgEscape); + ptnode_adr(j.elem)->_scalar_replaceable = false; } } } - } else if (nt == PointsToNode::JavaObject && n->is_Call()) { - // Push call on alloc_worlist (alocations are calls) - // for processing by split_unique_types(). - alloc_worklist.append(n); } } + // 6. Propagate escape states. + GrowableArray worklist; + bool has_non_escaping_obj = false; + // push all GlobalEscape nodes on the worklist - for( int next = 0; next < cg_worklist.length(); ++next ) { + for( uint next = 0; next < cg_length; ++next ) { int nk = cg_worklist.at(next); - if (_nodes->adr_at(nk)->escape_state() == PointsToNode::GlobalEscape) - worklist.append(nk); + if (ptnode_adr(nk)->escape_state() == PointsToNode::GlobalEscape) + worklist.push(nk); } - // mark all node reachable from GlobalEscape nodes + // mark all nodes reachable from GlobalEscape nodes while(worklist.length() > 0) { - PointsToNode n = _nodes->at(worklist.pop()); - for (uint ei = 0; ei < n.edge_count(); ei++) { - uint npi = n.edge_target(ei); + PointsToNode* ptn = ptnode_adr(worklist.pop()); + uint e_cnt = ptn->edge_count(); + for (uint ei = 0; ei < e_cnt; ei++) { + uint npi = ptn->edge_target(ei); PointsToNode *np = ptnode_adr(npi); if (np->escape_state() < PointsToNode::GlobalEscape) { np->set_escape_state(PointsToNode::GlobalEscape); - worklist.append_if_missing(npi); + worklist.push(npi); } } } // push all ArgEscape nodes on the worklist - for( int next = 0; next < cg_worklist.length(); ++next ) { + for( uint next = 0; next < cg_length; ++next ) { int nk = cg_worklist.at(next); - if (_nodes->adr_at(nk)->escape_state() == PointsToNode::ArgEscape) + if (ptnode_adr(nk)->escape_state() == PointsToNode::ArgEscape) worklist.push(nk); } - // mark all node reachable from ArgEscape nodes + // mark all nodes reachable from ArgEscape nodes while(worklist.length() > 0) { - PointsToNode n = _nodes->at(worklist.pop()); - for (uint ei = 0; ei < n.edge_count(); ei++) { - uint npi = n.edge_target(ei); + PointsToNode* ptn = ptnode_adr(worklist.pop()); + if (ptn->node_type() == PointsToNode::JavaObject) + has_non_escaping_obj = true; // Non GlobalEscape + uint e_cnt = ptn->edge_count(); + for (uint ei = 0; ei < e_cnt; ei++) { + uint npi = ptn->edge_target(ei); PointsToNode *np = ptnode_adr(npi); if (np->escape_state() < PointsToNode::ArgEscape) { np->set_escape_state(PointsToNode::ArgEscape); - worklist.append_if_missing(npi); + worklist.push(npi); } } } + GrowableArray alloc_worklist; + // push all NoEscape nodes on the worklist - for( int next = 0; next < cg_worklist.length(); ++next ) { + for( uint next = 0; next < cg_length; ++next ) { int nk = cg_worklist.at(next); - if (_nodes->adr_at(nk)->escape_state() == PointsToNode::NoEscape) + if (ptnode_adr(nk)->escape_state() == PointsToNode::NoEscape) worklist.push(nk); } - // mark all node reachable from NoEscape nodes + // mark all nodes reachable from NoEscape nodes while(worklist.length() > 0) { - PointsToNode n = _nodes->at(worklist.pop()); - for (uint ei = 0; ei < n.edge_count(); ei++) { - uint npi = n.edge_target(ei); + PointsToNode* ptn = ptnode_adr(worklist.pop()); + if (ptn->node_type() == PointsToNode::JavaObject) + has_non_escaping_obj = true; // Non GlobalEscape + Node* n = ptn->_node; + if (n->is_Allocate() && ptn->_scalar_replaceable ) { + // Push scalar replaceable alocations on alloc_worklist + // for processing in split_unique_types(). + alloc_worklist.append(n); + } + uint e_cnt = ptn->edge_count(); + for (uint ei = 0; ei < e_cnt; ei++) { + uint npi = ptn->edge_target(ei); PointsToNode *np = ptnode_adr(npi); if (np->escape_state() < PointsToNode::NoEscape) { np->set_escape_state(PointsToNode::NoEscape); - worklist.append_if_missing(npi); + worklist.push(npi); } } } _collecting = false; + assert(C->unique() == nodes_size(), "there should be no new ideal nodes during ConnectionGraph build"); - has_allocations = false; // Are there scalar replaceable allocations? + bool has_scalar_replaceable_candidates = alloc_worklist.length() > 0; + if ( has_scalar_replaceable_candidates && + C->AliasLevel() >= 3 && EliminateAllocations ) { - for( int next = 0; next < alloc_worklist.length(); ++next ) { - Node* n = alloc_worklist.at(next); - uint ni = n->_idx; - PointsToNode* ptn = _nodes->adr_at(ni); - PointsToNode::EscapeState es = ptn->escape_state(); - if (ptn->escape_state() == PointsToNode::NoEscape && - ptn->_scalar_replaceable) { - has_allocations = true; - break; - } - } - if (!has_allocations) { - return; // Nothing to do. - } - - if(_compile->AliasLevel() >= 3 && EliminateAllocations) { // Now use the escape information to create unique types for - // unescaped objects + // scalar replaceable objects. split_unique_types(alloc_worklist); - if (_compile->failing()) return; + + if (C->failing()) return false; // Clean up after split unique types. ResourceMark rm; - PhaseRemoveUseless pru(_compile->initial_gvn(), _compile->for_igvn()); + PhaseRemoveUseless pru(C->initial_gvn(), C->for_igvn()); + + C->print_method("After Escape Analysis", 2); #ifdef ASSERT - } else if (PrintEscapeAnalysis || PrintEliminateAllocations) { + } else if (Verbose && (PrintEscapeAnalysis || PrintEliminateAllocations)) { tty->print("=== No allocations eliminated for "); - C()->method()->print_short_name(); + C->method()->print_short_name(); if(!EliminateAllocations) { tty->print(" since EliminateAllocations is off ==="); - } else if(_compile->AliasLevel() < 3) { + } else if(!has_scalar_replaceable_candidates) { + tty->print(" since there are no scalar replaceable candidates ==="); + } else if(C->AliasLevel() < 3) { tty->print(" since AliasLevel < 3 ==="); } tty->cr(); #endif } + return has_non_escaping_obj; } void ConnectionGraph::process_call_arguments(CallNode *call, PhaseTransform *phase) { @@ -1538,7 +1695,7 @@ void ConnectionGraph::process_call_arguments(CallNode *call, PhaseTransform *pha } } if (copy_dependencies) - call_analyzer->copy_dependencies(C()->dependencies()); + call_analyzer->copy_dependencies(_compile->dependencies()); break; } } @@ -1561,7 +1718,6 @@ void ConnectionGraph::process_call_arguments(CallNode *call, PhaseTransform *pha for( VectorSetI j(&ptset); j.test(); ++j ) { uint pt = j.elem; set_escape_state(pt, PointsToNode::GlobalEscape); - PointsToNode *ptadr = ptnode_adr(pt); } } } @@ -1569,9 +1725,10 @@ void ConnectionGraph::process_call_arguments(CallNode *call, PhaseTransform *pha } } void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *phase) { - PointsToNode *ptadr = ptnode_adr(resproj->_idx); + CallNode *call = resproj->in(0)->as_Call(); + uint call_idx = call->_idx; + uint resproj_idx = resproj->_idx; - CallNode *call = resproj->in(0)->as_Call(); switch (call->Opcode()) { case Op_Allocate: { @@ -1587,7 +1744,6 @@ void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *pha ciKlass* cik = kt->klass(); ciInstanceKlass* ciik = cik->as_instance_klass(); - PointsToNode *ptadr = ptnode_adr(call->_idx); PointsToNode::EscapeState es; uint edge_to; if (cik->is_subclass_of(_compile->env()->Thread_klass()) || ciik->has_finalizer()) { @@ -1595,25 +1751,24 @@ void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *pha edge_to = _phantom_object; // Could not be worse } else { es = PointsToNode::NoEscape; - edge_to = call->_idx; + edge_to = call_idx; } - set_escape_state(call->_idx, es); - add_pointsto_edge(resproj->_idx, edge_to); - _processed.set(resproj->_idx); + set_escape_state(call_idx, es); + add_pointsto_edge(resproj_idx, edge_to); + _processed.set(resproj_idx); break; } case Op_AllocateArray: { - PointsToNode *ptadr = ptnode_adr(call->_idx); int length = call->in(AllocateNode::ALength)->find_int_con(-1); if (length < 0 || length > EliminateAllocationArraySizeLimit) { // Not scalar replaceable if the length is not constant or too big. - ptadr->_scalar_replaceable = false; + ptnode_adr(call_idx)->_scalar_replaceable = false; } - set_escape_state(call->_idx, PointsToNode::NoEscape); - add_pointsto_edge(resproj->_idx, call->_idx); - _processed.set(resproj->_idx); + set_escape_state(call_idx, PointsToNode::NoEscape); + add_pointsto_edge(resproj_idx, call_idx); + _processed.set(resproj_idx); break; } @@ -1631,19 +1786,17 @@ void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *pha // Note: we use isa_ptr() instead of isa_oopptr() here because the // _multianewarray functions return a TypeRawPtr. if (ret_type == NULL || ret_type->isa_ptr() == NULL) { - _processed.set(resproj->_idx); + _processed.set(resproj_idx); break; // doesn't return a pointer type } ciMethod *meth = call->as_CallJava()->method(); const TypeTuple * d = call->tf()->domain(); if (meth == NULL) { // not a Java method, assume global escape - set_escape_state(call->_idx, PointsToNode::GlobalEscape); - if (resproj != NULL) - add_pointsto_edge(resproj->_idx, _phantom_object); + set_escape_state(call_idx, PointsToNode::GlobalEscape); + add_pointsto_edge(resproj_idx, _phantom_object); } else { BCEscapeAnalyzer *call_analyzer = meth->get_bcea(); - VectorSet ptset(Thread::current()->resource_area()); bool copy_dependencies = false; if (call_analyzer->is_return_allocated()) { @@ -1651,13 +1804,13 @@ void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *pha // update dependency information. // Mark it as NoEscape so that objects referenced by // it's fields will be marked as NoEscape at least. - set_escape_state(call->_idx, PointsToNode::NoEscape); - if (resproj != NULL) - add_pointsto_edge(resproj->_idx, call->_idx); + set_escape_state(call_idx, PointsToNode::NoEscape); + add_pointsto_edge(resproj_idx, call_idx); copy_dependencies = true; - } else if (call_analyzer->is_return_local() && resproj != NULL) { + } else if (call_analyzer->is_return_local()) { // determine whether any arguments are returned - set_escape_state(call->_idx, PointsToNode::NoEscape); + set_escape_state(call_idx, PointsToNode::NoEscape); + bool ret_arg = false; for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { const Type* at = d->field_at(i); @@ -1665,36 +1818,41 @@ void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *pha Node *arg = call->in(i)->uncast(); if (call_analyzer->is_arg_returned(i - TypeFunc::Parms)) { - PointsToNode *arg_esp = _nodes->adr_at(arg->_idx); + ret_arg = true; + PointsToNode *arg_esp = ptnode_adr(arg->_idx); if (arg_esp->node_type() == PointsToNode::UnknownType) done = false; else if (arg_esp->node_type() == PointsToNode::JavaObject) - add_pointsto_edge(resproj->_idx, arg->_idx); + add_pointsto_edge(resproj_idx, arg->_idx); else - add_deferred_edge(resproj->_idx, arg->_idx); + add_deferred_edge(resproj_idx, arg->_idx); arg_esp->_hidden_alias = true; } } } + if (done && !ret_arg) { + // Returns unknown object. + set_escape_state(call_idx, PointsToNode::GlobalEscape); + add_pointsto_edge(resproj_idx, _phantom_object); + } copy_dependencies = true; } else { - set_escape_state(call->_idx, PointsToNode::GlobalEscape); - if (resproj != NULL) - add_pointsto_edge(resproj->_idx, _phantom_object); + set_escape_state(call_idx, PointsToNode::GlobalEscape); + add_pointsto_edge(resproj_idx, _phantom_object); for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { const Type* at = d->field_at(i); if (at->isa_oopptr() != NULL) { Node *arg = call->in(i)->uncast(); - PointsToNode *arg_esp = _nodes->adr_at(arg->_idx); + PointsToNode *arg_esp = ptnode_adr(arg->_idx); arg_esp->_hidden_alias = true; } } } if (copy_dependencies) - call_analyzer->copy_dependencies(C()->dependencies()); + call_analyzer->copy_dependencies(_compile->dependencies()); } if (done) - _processed.set(resproj->_idx); + _processed.set(resproj_idx); break; } @@ -1709,13 +1867,11 @@ void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *pha // Note: we use isa_ptr() instead of isa_oopptr() here because the // _multianewarray functions return a TypeRawPtr. if (ret_type->isa_ptr() != NULL) { - PointsToNode *ptadr = ptnode_adr(call->_idx); - set_escape_state(call->_idx, PointsToNode::GlobalEscape); - if (resproj != NULL) - add_pointsto_edge(resproj->_idx, _phantom_object); + set_escape_state(call_idx, PointsToNode::GlobalEscape); + add_pointsto_edge(resproj_idx, _phantom_object); } } - _processed.set(resproj->_idx); + _processed.set(resproj_idx); } } } @@ -1743,7 +1899,7 @@ void ConnectionGraph::record_for_escape_analysis(Node *n, PhaseTransform *phase) // Check if a call returns an object. const TypeTuple *r = n->as_Call()->tf()->range(); - if (r->cnt() > TypeFunc::Parms && + if (n->is_CallStaticJava() && r->cnt() > TypeFunc::Parms && n->as_Call()->proj_out(TypeFunc::Parms) != NULL) { // Note: use isa_ptr() instead of isa_oopptr() here because // the _multianewarray functions return a TypeRawPtr. @@ -1776,7 +1932,7 @@ void ConnectionGraph::record_for_escape_analysis(Node *n, PhaseTransform *phase) { add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false); int ti = n->in(1)->_idx; - PointsToNode::NodeType nt = _nodes->adr_at(ti)->node_type(); + PointsToNode::NodeType nt = ptnode_adr(ti)->node_type(); if (nt == PointsToNode::UnknownType) { _delayed_worklist.push(n); // Process it later. break; @@ -1828,7 +1984,7 @@ void ConnectionGraph::record_for_escape_analysis(Node *n, PhaseTransform *phase) case Op_LoadN: { const Type *t = phase->type(n); - if (!t->isa_narrowoop() && t->isa_ptr() == NULL) { + if (t->make_ptr() == NULL) { _processed.set(n->_idx); return; } @@ -1851,8 +2007,9 @@ void ConnectionGraph::record_for_escape_analysis(Node *n, PhaseTransform *phase) } case Op_Phi: { - if (n->as_Phi()->type()->isa_ptr() == NULL) { - // nothing to do if not an oop + const Type *t = n->as_Phi()->type(); + if (t->make_ptr() == NULL) { + // nothing to do if not an oop or narrow oop _processed.set(n->_idx); return; } @@ -1866,7 +2023,7 @@ void ConnectionGraph::record_for_escape_analysis(Node *n, PhaseTransform *phase) if (in->is_top() || in == n) continue; // ignore top or inputs which go back this node int ti = in->_idx; - PointsToNode::NodeType nt = _nodes->adr_at(ti)->node_type(); + PointsToNode::NodeType nt = ptnode_adr(ti)->node_type(); if (nt == PointsToNode::UnknownType) { break; } else if (nt == PointsToNode::JavaObject) { @@ -1904,7 +2061,7 @@ void ConnectionGraph::record_for_escape_analysis(Node *n, PhaseTransform *phase) // Treat Return value as LocalVar with GlobalEscape escape state. add_node(n, PointsToNode::LocalVar, PointsToNode::GlobalEscape, false); int ti = n->in(TypeFunc::Parms)->_idx; - PointsToNode::NodeType nt = _nodes->adr_at(ti)->node_type(); + PointsToNode::NodeType nt = ptnode_adr(ti)->node_type(); if (nt == PointsToNode::UnknownType) { _delayed_worklist.push(n); // Process it later. break; @@ -1968,17 +2125,17 @@ void ConnectionGraph::record_for_escape_analysis(Node *n, PhaseTransform *phase) } void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) { + uint n_idx = n->_idx; + // Don't set processed bit for AddP, LoadP, StoreP since // they may need more then one pass to process. - if (_processed.test(n->_idx)) + if (_processed.test(n_idx)) return; // No need to redefine node's state. - PointsToNode *ptadr = ptnode_adr(n->_idx); - if (n->is_Call()) { CallNode *call = n->as_Call(); process_call_arguments(call, phase); - _processed.set(n->_idx); + _processed.set(n_idx); return; } @@ -1991,7 +2148,7 @@ void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) { PointsTo(ptset, base, phase); for( VectorSetI i(&ptset); i.test(); ++i ) { uint pt = i.elem; - add_field_edge(pt, n->_idx, address_offset(n, phase)); + add_field_edge(pt, n_idx, address_offset(n, phase)); } break; } @@ -2006,12 +2163,12 @@ void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) { case Op_DecodeN: { int ti = n->in(1)->_idx; - if (_nodes->adr_at(ti)->node_type() == PointsToNode::JavaObject) { - add_pointsto_edge(n->_idx, ti); + if (ptnode_adr(ti)->node_type() == PointsToNode::JavaObject) { + add_pointsto_edge(n_idx, ti); } else { - add_deferred_edge(n->_idx, ti); + add_deferred_edge(n_idx, ti); } - _processed.set(n->_idx); + _processed.set(n_idx); break; } case Op_ConP: @@ -2040,7 +2197,7 @@ void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) { { const Type *t = phase->type(n); #ifdef ASSERT - if (!t->isa_narrowoop() && t->isa_ptr() == NULL) + if (t->make_ptr() == NULL) assert(false, "Op_LoadP"); #endif @@ -2060,7 +2217,7 @@ void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) { int offset = address_offset(adr, phase); for( VectorSetI i(&ptset); i.test(); ++i ) { uint pt = i.elem; - add_deferred_edge_to_fields(n->_idx, pt, offset); + add_deferred_edge_to_fields(n_idx, pt, offset); } break; } @@ -2072,7 +2229,8 @@ void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) { case Op_Phi: { #ifdef ASSERT - if (n->as_Phi()->type()->isa_ptr() == NULL) + const Type *t = n->as_Phi()->type(); + if (t->make_ptr() == NULL) assert(false, "Op_Phi"); #endif for (uint i = 1; i < n->req() ; i++) { @@ -2083,13 +2241,15 @@ void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) { if (in->is_top() || in == n) continue; // ignore top or inputs which go back this node int ti = in->_idx; - if (_nodes->adr_at(in->_idx)->node_type() == PointsToNode::JavaObject) { - add_pointsto_edge(n->_idx, ti); + PointsToNode::NodeType nt = ptnode_adr(ti)->node_type(); + assert(nt != PointsToNode::UnknownType, "all nodes should be known"); + if (nt == PointsToNode::JavaObject) { + add_pointsto_edge(n_idx, ti); } else { - add_deferred_edge(n->_idx, ti); + add_deferred_edge(n_idx, ti); } } - _processed.set(n->_idx); + _processed.set(n_idx); break; } case Op_Proj: @@ -2097,7 +2257,7 @@ void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) { // we are only interested in the result projection from a call if (n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->is_Call() ) { process_call_result(n->as_Proj(), phase); - assert(_processed.test(n->_idx), "all call results should be processed"); + assert(_processed.test(n_idx), "all call results should be processed"); } else { assert(false, "Op_Proj"); } @@ -2112,12 +2272,12 @@ void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) { } #endif int ti = n->in(TypeFunc::Parms)->_idx; - if (_nodes->adr_at(ti)->node_type() == PointsToNode::JavaObject) { - add_pointsto_edge(n->_idx, ti); + if (ptnode_adr(ti)->node_type() == PointsToNode::JavaObject) { + add_pointsto_edge(n_idx, ti); } else { - add_deferred_edge(n->_idx, ti); + add_deferred_edge(n_idx, ti); } - _processed.set(n->_idx); + _processed.set(n_idx); break; } case Op_StoreP: @@ -2162,9 +2322,9 @@ void ConnectionGraph::dump() { PhaseGVN *igvn = _compile->initial_gvn(); bool first = true; - uint size = (uint)_nodes->length(); + uint size = nodes_size(); for (uint ni = 0; ni < size; ni++) { - PointsToNode *ptn = _nodes->adr_at(ni); + PointsToNode *ptn = ptnode_adr(ni); PointsToNode::NodeType ptn_type = ptn->node_type(); if (ptn_type != PointsToNode::JavaObject || ptn->_node == NULL) @@ -2174,7 +2334,7 @@ void ConnectionGraph::dump() { if (first) { tty->cr(); tty->print("======== Connection graph for "); - C()->method()->print_short_name(); + _compile->method()->print_short_name(); tty->cr(); first = false; } @@ -2182,20 +2342,18 @@ void ConnectionGraph::dump() { ptn->dump(); // Print all locals which reference this allocation for (uint li = ni; li < size; li++) { - PointsToNode *ptn_loc = _nodes->adr_at(li); + PointsToNode *ptn_loc = ptnode_adr(li); PointsToNode::NodeType ptn_loc_type = ptn_loc->node_type(); if ( ptn_loc_type == PointsToNode::LocalVar && ptn_loc->_node != NULL && ptn_loc->edge_count() == 1 && ptn_loc->edge_target(0) == ni ) { - tty->print("%6d LocalVar [[%d]]", li, ni); - _nodes->adr_at(li)->_node->dump(); + ptnode_adr(li)->dump(false); } } if (Verbose) { // Print all fields which reference this allocation for (uint i = 0; i < ptn->edge_count(); i++) { uint ei = ptn->edge_target(i); - tty->print("%6d Field [[%d]]", ei, ni); - _nodes->adr_at(ei)->_node->dump(); + ptnode_adr(ei)->dump(false); } } tty->cr(); diff --git a/hotspot/src/share/vm/opto/escape.hpp b/hotspot/src/share/vm/opto/escape.hpp index c969f0dcd6c..1ce0cc9cf29 100644 --- a/hotspot/src/share/vm/opto/escape.hpp +++ b/hotspot/src/share/vm/opto/escape.hpp @@ -178,23 +178,33 @@ public: // count of outgoing edges uint edge_count() const { return (_edges == NULL) ? 0 : _edges->length(); } + // node index of target of outgoing edge "e" - uint edge_target(uint e) const; + uint edge_target(uint e) const { + assert(_edges != NULL, "valid edge index"); + return (_edges->at(e) >> EdgeShift); + } // type of outgoing edge "e" - EdgeType edge_type(uint e) const; + EdgeType edge_type(uint e) const { + assert(_edges != NULL, "valid edge index"); + return (EdgeType) (_edges->at(e) & EdgeMask); + } + // add a edge of the specified type pointing to the specified target void add_edge(uint targIdx, EdgeType et); + // remove an edge of the specified type pointing to the specified target void remove_edge(uint targIdx, EdgeType et); + #ifndef PRODUCT - void dump() const; + void dump(bool print_state=true) const; #endif }; class ConnectionGraph: public ResourceObj { private: - GrowableArray* _nodes; // Connection graph nodes indexed + GrowableArray _nodes; // Connection graph nodes indexed // by ideal node index. Unique_Node_List _delayed_worklist; // Nodes to be processed before @@ -207,24 +217,22 @@ private: // is still being collected. If false, // no new nodes will be processed. - bool _has_allocations; // Indicates whether method has any - // non-escaping allocations. - uint _phantom_object; // Index of globally escaping object // that pointer values loaded from // a field which has not been set // are assumed to point to. + uint _oop_null; // ConP(#NULL) + uint _noop_null; // ConN(#NULL) Compile * _compile; // Compile object for current compilation - // address of an element in _nodes. Used when the element is to be modified - PointsToNode *ptnode_adr(uint idx) { - if ((uint)_nodes->length() <= idx) { - // expand _nodes array - PointsToNode dummy = _nodes->at_grow(idx); - } - return _nodes->adr_at(idx); + // Address of an element in _nodes. Used when the element is to be modified + PointsToNode *ptnode_adr(uint idx) const { + // There should be no new ideal nodes during ConnectionGraph build, + // growableArray::adr_at() will throw assert otherwise. + return _nodes.adr_at(idx); } + uint nodes_size() const { return _nodes.length(); } // Add node to ConnectionGraph. void add_node(Node *n, PointsToNode::NodeType nt, PointsToNode::EscapeState es, bool done); @@ -278,7 +286,7 @@ private: // MemNode - new memory input for this node // ChecCastPP - allocation that this is a cast of // allocation - CheckCastPP of the allocation - void split_AddP(Node *addp, Node *base, PhaseGVN *igvn); + bool split_AddP(Node *addp, Node *base, PhaseGVN *igvn); PhiNode *create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray &orig_phi_worklist, PhaseGVN *igvn, bool &new_created); PhiNode *split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray &orig_phi_worklist, PhaseGVN *igvn); Node *find_mem(Node *mem, int alias_idx, PhaseGVN *igvn); @@ -307,30 +315,30 @@ private: // Set the escape state of a node void set_escape_state(uint ni, PointsToNode::EscapeState es); - // Get Compile object for current compilation. - Compile *C() const { return _compile; } - public: ConnectionGraph(Compile *C); + // Check for non-escaping candidates + static bool has_candidates(Compile *C); + // Compute the escape information - void compute_escape(); + bool compute_escape(); // escape state of a node PointsToNode::EscapeState escape_state(Node *n, PhaseTransform *phase); // other information we have collected bool is_scalar_replaceable(Node *n) { - if (_collecting) + if (_collecting || (n->_idx >= nodes_size())) return false; - PointsToNode ptn = _nodes->at_grow(n->_idx); - return ptn.escape_state() == PointsToNode::NoEscape && ptn._scalar_replaceable; + PointsToNode* ptn = ptnode_adr(n->_idx); + return ptn->escape_state() == PointsToNode::NoEscape && ptn->_scalar_replaceable; } bool hidden_alias(Node *n) { - if (_collecting) + if (_collecting || (n->_idx >= nodes_size())) return true; - PointsToNode ptn = _nodes->at_grow(n->_idx); - return (ptn.escape_state() != PointsToNode::NoEscape) || ptn._hidden_alias; + PointsToNode* ptn = ptnode_adr(n->_idx); + return (ptn->escape_state() != PointsToNode::NoEscape) || ptn->_hidden_alias; } #ifndef PRODUCT diff --git a/hotspot/src/share/vm/opto/gcm.cpp b/hotspot/src/share/vm/opto/gcm.cpp index 0627e50505b..b65101197cb 100644 --- a/hotspot/src/share/vm/opto/gcm.cpp +++ b/hotspot/src/share/vm/opto/gcm.cpp @@ -1609,7 +1609,30 @@ void CFGLoop::compute_freq() { float Block::succ_prob(uint i) { int eidx = end_idx(); Node *n = _nodes[eidx]; // Get ending Node - int op = n->is_Mach() ? n->as_Mach()->ideal_Opcode() : n->Opcode(); + + int op = n->Opcode(); + if (n->is_Mach()) { + if (n->is_MachNullCheck()) { + // Can only reach here if called after lcm. The original Op_If is gone, + // so we attempt to infer the probability from one or both of the + // successor blocks. + assert(_num_succs == 2, "expecting 2 successors of a null check"); + // If either successor has only one predecessor, then the + // probabiltity estimate can be derived using the + // relative frequency of the successor and this block. + if (_succs[i]->num_preds() == 2) { + return _succs[i]->_freq / _freq; + } else if (_succs[1-i]->num_preds() == 2) { + return 1 - (_succs[1-i]->_freq / _freq); + } else { + // Estimate using both successor frequencies + float freq = _succs[i]->_freq; + return freq / (freq + _succs[1-i]->_freq); + } + } + op = n->as_Mach()->ideal_Opcode(); + } + // Switch on branch type switch( op ) { diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp index ebd0d051cb8..2fcb90f4e45 100644 --- a/hotspot/src/share/vm/opto/graphKit.cpp +++ b/hotspot/src/share/vm/opto/graphKit.cpp @@ -1212,6 +1212,7 @@ Node* GraphKit::null_check_common(Node* value, BasicType type, Deoptimization::Action_make_not_entrant, NULL, "assert_null"); } else { + replace_in_map(value, zerocon(type)); builtin_throw(reason); } } @@ -1960,6 +1961,7 @@ Node* GraphKit::null_check_oop(Node* value, Node* *null_control, // method will be compiled to handle NULLs. PreserveJVMState pjvms(this); set_control(*null_control); + replace_in_map(value, null()); uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_make_not_entrant); (*null_control) = top(); // NULL path is dead diff --git a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp index 114a7ea17c7..6dfc5fc9c8a 100644 --- a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp +++ b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -473,10 +473,12 @@ void IdealGraphPrinter::visit_node(Node *n, void *param) { print_prop("is_dontcare", "false"); } +#ifdef ASSERT Node* old = C->matcher()->find_old_node(node); if (old != NULL) { print_prop("old_node_idx", old->_idx); } +#endif } if (node->is_Proj()) { diff --git a/hotspot/src/share/vm/opto/ifg.cpp b/hotspot/src/share/vm/opto/ifg.cpp index 2c6cd665fea..4b65eabcb8e 100644 --- a/hotspot/src/share/vm/opto/ifg.cpp +++ b/hotspot/src/share/vm/opto/ifg.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -594,7 +594,7 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) { // Insure high score for immediate-use spill copies so they get a color if( n->is_SpillCopy() - && lrgs(r)._def != NodeSentinel // MultiDef live range can still split + && lrgs(r).is_singledef() // MultiDef live range can still split && n->outcnt() == 1 // and use must be in this block && _cfg._bbs[n->unique_out()->_idx] == b ) { // All single-use MachSpillCopy(s) that immediately precede their diff --git a/hotspot/src/share/vm/opto/ifnode.cpp b/hotspot/src/share/vm/opto/ifnode.cpp index 073d4202f68..4f230765ab8 100644 --- a/hotspot/src/share/vm/opto/ifnode.cpp +++ b/hotspot/src/share/vm/opto/ifnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -725,6 +725,11 @@ static Node *remove_useless_bool(IfNode *iff, PhaseGVN *phase) { int true_path = phi->is_diamond_phi(); if( true_path == 0 ) return NULL; + // Make sure that iff and the control of the phi are different. This + // should really only happen for dead control flow since it requires + // an illegal cycle. + if (phi->in(0)->in(1)->in(0) == iff) return NULL; + // phi->region->if_proj->ifnode->bool->cmp BoolNode *bol2 = phi->in(0)->in(1)->in(0)->in(1)->as_Bool(); @@ -751,6 +756,7 @@ static Node *remove_useless_bool(IfNode *iff, PhaseGVN *phase) { } Node* new_bol = (flip ? phase->transform( bol2->negate(phase) ) : bol2); + assert(new_bol != iff->in(1), "must make progress"); iff->set_req(1, new_bol); // Intervening diamond probably goes dead phase->C->set_major_progress(); diff --git a/hotspot/src/share/vm/opto/lcm.cpp b/hotspot/src/share/vm/opto/lcm.cpp index 9be6e270faa..d80e8f0b055 100644 --- a/hotspot/src/share/vm/opto/lcm.cpp +++ b/hotspot/src/share/vm/opto/lcm.cpp @@ -58,6 +58,9 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe not_null_block = _succs[0]; null_block = _succs[1]; } + while (null_block->is_Empty() == Block::empty_with_goto) { + null_block = null_block->_succs[0]; + } // Search the exception block for an uncommon trap. // (See Parse::do_if and Parse::do_ifnull for the reason @@ -149,6 +152,10 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe const TypePtr *adr_type = NULL; // Do not need this return value here const Node* base = mach->get_base_and_disp(offset, adr_type); if (base == NULL || base == NodeSentinel) { + // Narrow oop address doesn't have base, only index + if( val->bottom_type()->isa_narrowoop() && + MacroAssembler::needs_explicit_null_check(offset) ) + continue; // Give up if offset is beyond page size // cannot reason about it; is probably not implicit null exception } else { const TypePtr* tptr = base->bottom_type()->is_ptr(); @@ -322,7 +329,7 @@ Node *Block::select(PhaseCFG *cfg, Node_List &worklist, int *ready_cnt, VectorSe uint choice = 0; // Bigger is most important uint latency = 0; // Bigger is scheduled first uint score = 0; // Bigger is better - uint idx; // Index in worklist + int idx = -1; // Index in worklist for( uint i=0; i= 0, "index should be set"); + Node *n = worklist[(uint)idx]; // Get the winner - worklist.map(idx,worklist.pop()); // Compress worklist + worklist.map((uint)idx, worklist.pop()); // Compress worklist return n; } @@ -599,7 +607,14 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, int *ready_cnt, Vect assert(cfg->_bbs[oop_store->_idx]->_dom_depth <= this->_dom_depth, "oop_store must dominate card-mark"); } } - if( n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_MemBarAcquire ) { + if( n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_MemBarAcquire && + n->req() > TypeFunc::Parms ) { + // MemBarAcquire could be created without Precedent edge. + // del_req() replaces the specified edge with the last input edge + // and then removes the last edge. If the specified edge > number of + // edges the last edge will be moved outside of the input edges array + // and the edge will be lost. This is why this code should be + // executed only when Precedent (== TypeFunc::Parms) edge is present. Node *x = n->in(TypeFunc::Parms); n->del_req(TypeFunc::Parms); n->add_prec(x); diff --git a/hotspot/src/share/vm/opto/loopnode.cpp b/hotspot/src/share/vm/opto/loopnode.cpp index c411cdc3451..7e853e6a1f8 100644 --- a/hotspot/src/share/vm/opto/loopnode.cpp +++ b/hotspot/src/share/vm/opto/loopnode.cpp @@ -2625,9 +2625,11 @@ void PhaseIdealLoop::build_loop_late_post( Node *n, const PhaseIdealLoop *verify case Op_LoadF: case Op_LoadI: case Op_LoadKlass: + case Op_LoadNKlass: case Op_LoadL: case Op_LoadS: case Op_LoadP: + case Op_LoadN: case Op_LoadRange: case Op_LoadD_unaligned: case Op_LoadL_unaligned: diff --git a/hotspot/src/share/vm/opto/loopopts.cpp b/hotspot/src/share/vm/opto/loopopts.cpp index f7fa3f21b2c..36ceb61a351 100644 --- a/hotspot/src/share/vm/opto/loopopts.cpp +++ b/hotspot/src/share/vm/opto/loopopts.cpp @@ -96,6 +96,10 @@ Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) { // our new node, even though we may throw the node away. // (Note: This tweaking with igvn only works because x is a new node.) _igvn.set_type(x, t); + // If x is a TypeNode, capture any more-precise type permanently into Node + // othewise it will be not updated during igvn->transform since + // igvn->type(x) is set to x->Value() already. + x->raise_bottom_type(t); Node *y = x->Identity(&_igvn); if( y != x ) { wins++; @@ -464,11 +468,11 @@ Node *PhaseIdealLoop::conditional_move( Node *region ) { case T_FLOAT: case T_DOUBLE: case T_ADDRESS: // (RawPtr) - case T_NARROWOOP: cost++; break; + case T_NARROWOOP: // Fall through case T_OBJECT: { // Base oops are OK, but not derived oops - const TypeOopPtr *tp = phi->type()->isa_oopptr(); + const TypeOopPtr *tp = phi->type()->make_ptr()->isa_oopptr(); // Derived pointers are Bad (tm): what's the Base (for GC purposes) of a // CMOVE'd derived pointer? It's a CMOVE'd derived base. Thus // CMOVE'ing a derived pointer requires we also CMOVE the base. If we @@ -499,11 +503,11 @@ Node *PhaseIdealLoop::conditional_move( Node *region ) { return NULL; // Too much speculative goo } } - // See if the Phi is used by a Cmp. This will likely Split-If, a - // higher-payoff operation. + // See if the Phi is used by a Cmp or Narrow oop Decode/Encode. + // This will likely Split-If, a higher-payoff operation. for (DUIterator_Fast kmax, k = phi->fast_outs(kmax); k < kmax; k++) { Node* use = phi->fast_out(k); - if( use->is_Cmp() ) + if( use->is_Cmp() || use->is_DecodeN() || use->is_EncodeP() ) return NULL; } } @@ -578,7 +582,8 @@ Node *PhaseIdealLoop::split_if_with_blocks_pre( Node *n ) { Node *cmov = conditional_move( n ); if( cmov ) return cmov; } - if( n->is_CFG() || n_op == Op_StorePConditional || n_op == Op_StoreLConditional || n_op == Op_CompareAndSwapI || n_op == Op_CompareAndSwapL ||n_op == Op_CompareAndSwapP) return n; + if( n->is_CFG() || n->is_LoadStore() ) + return n; if( n_op == Op_Opaque1 || // Opaque nodes cannot be mod'd n_op == Op_Opaque2 ) { if( !C->major_progress() ) // If chance of no more loop opts... @@ -927,7 +932,7 @@ void PhaseIdealLoop::split_if_with_blocks_post( Node *n ) { // to fold a StoreP and an AddP together (as part of an // address expression) and the AddP and StoreP have // different controls. - if( !x->is_Load() ) _igvn._worklist.yank(x); + if( !x->is_Load() && !x->is_DecodeN() ) _igvn._worklist.yank(x); } _igvn.remove_dead_node(n); } @@ -1891,18 +1896,19 @@ void PhaseIdealLoop::clone_for_use_outside_loop( IdealLoopTree *loop, Node* n, N _igvn.hash_delete(use); use->set_req(j, n_clone); _igvn._worklist.push(use); + Node* use_c; if (!use->is_Phi()) { - Node* use_c = has_ctrl(use) ? get_ctrl(use) : use->in(0); - set_ctrl(n_clone, use_c); - assert(!loop->is_member(get_loop(use_c)), "should be outside loop"); - get_loop(use_c)->_body.push(n_clone); + use_c = has_ctrl(use) ? get_ctrl(use) : use->in(0); } else { // Use in a phi is considered a use in the associated predecessor block - Node *prevbb = use->in(0)->in(j); - set_ctrl(n_clone, prevbb); - assert(!loop->is_member(get_loop(prevbb)), "should be outside loop"); - get_loop(prevbb)->_body.push(n_clone); + use_c = use->in(0)->in(j); } + if (use_c->is_CountedLoop()) { + use_c = use_c->in(LoopNode::EntryControl); + } + set_ctrl(n_clone, use_c); + assert(!loop->is_member(get_loop(use_c)), "should be outside loop"); + get_loop(use_c)->_body.push(n_clone); _igvn.register_new_node_with_optimizer(n_clone); #if !defined(PRODUCT) if (TracePartialPeeling) { diff --git a/hotspot/src/share/vm/opto/macro.cpp b/hotspot/src/share/vm/opto/macro.cpp index cd38a4be324..f8aea8e36aa 100644 --- a/hotspot/src/share/vm/opto/macro.cpp +++ b/hotspot/src/share/vm/opto/macro.cpp @@ -194,9 +194,10 @@ void PhaseMacroExpand::eliminate_card_mark(Node *p2x) { } // Search for a memory operation for the specified memory slice. -static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_mem, Node *alloc) { +static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_mem, Node *alloc, PhaseGVN *phase) { Node *orig_mem = mem; Node *alloc_mem = alloc->in(TypeFunc::Memory); + const TypeOopPtr *tinst = phase->C->get_adr_type(alias_idx)->isa_oopptr(); while (true) { if (mem == alloc_mem || mem == start_mem ) { return mem; // hit one of our sentinals @@ -208,7 +209,13 @@ static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_me // already know that the object is safe to eliminate. if (in->is_Initialize() && in->as_Initialize()->allocation() == alloc) { return in; - } else if (in->is_Call() || in->is_MemBar()) { + } else if (in->is_Call()) { + CallNode *call = in->as_Call(); + if (!call->may_modify(tinst, phase)) { + mem = call->in(TypeFunc::Memory); + } + mem = in->in(TypeFunc::Memory); + } else if (in->is_MemBar()) { mem = in->in(TypeFunc::Memory); } else { assert(false, "unexpected projection"); @@ -231,8 +238,7 @@ static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_me } else { return mem; } - if (mem == orig_mem) - return mem; + assert(mem != orig_mem, "dead memory loop"); } } @@ -241,27 +247,50 @@ static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_me // on the input paths. // Note: this function is recursive, its depth is limied by the "level" argument // Returns the computed Phi, or NULL if it cannot compute it. -Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type *phi_type, const TypeOopPtr *adr_t, Node *alloc, int level) { - - if (level <= 0) { - return NULL; - } +Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type *phi_type, const TypeOopPtr *adr_t, Node *alloc, Node_Stack *value_phis, int level) { + assert(mem->is_Phi(), "sanity"); int alias_idx = C->get_alias_index(adr_t); int offset = adr_t->offset(); int instance_id = adr_t->instance_id(); + // Check if an appropriate value phi already exists. + Node* region = mem->in(0); + for (DUIterator_Fast kmax, k = region->fast_outs(kmax); k < kmax; k++) { + Node* phi = region->fast_out(k); + if (phi->is_Phi() && phi != mem && + phi->as_Phi()->is_same_inst_field(phi_type, instance_id, alias_idx, offset)) { + return phi; + } + } + // Check if an appropriate new value phi already exists. + Node* new_phi = NULL; + uint size = value_phis->size(); + for (uint i=0; i < size; i++) { + if ( mem->_idx == value_phis->index_at(i) ) { + return value_phis->node_at(i); + } + } + + if (level <= 0) { + return NULL; // Give up: phi tree too deep + } Node *start_mem = C->start()->proj_out(TypeFunc::Memory); Node *alloc_mem = alloc->in(TypeFunc::Memory); uint length = mem->req(); GrowableArray values(length, length, NULL); + // create a new Phi for the value + PhiNode *phi = new (C, length) PhiNode(mem->in(0), phi_type, NULL, instance_id, alias_idx, offset); + transform_later(phi); + value_phis->push(phi, mem->_idx); + for (uint j = 1; j < length; j++) { Node *in = mem->in(j); if (in == NULL || in->is_top()) { values.at_put(j, in); } else { - Node *val = scan_mem_chain(in, alias_idx, offset, start_mem, alloc); + Node *val = scan_mem_chain(in, alias_idx, offset, start_mem, alloc, &_igvn); if (val == start_mem || val == alloc_mem) { // hit a sentinel, return appropriate 0 value values.at_put(j, _igvn.zerocon(ft)); @@ -280,33 +309,18 @@ Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type * } else if(val->is_Proj() && val->in(0) == alloc) { values.at_put(j, _igvn.zerocon(ft)); } else if (val->is_Phi()) { - // Check if an appropriate node already exists. - Node* region = val->in(0); - Node* old_phi = NULL; - for (DUIterator_Fast kmax, k = region->fast_outs(kmax); k < kmax; k++) { - Node* phi = region->fast_out(k); - if (phi->is_Phi() && phi != val && - phi->as_Phi()->is_same_inst_field(phi_type, instance_id, alias_idx, offset)) { - old_phi = phi; - break; - } - } - if (old_phi == NULL) { - val = value_from_mem_phi(val, ft, phi_type, adr_t, alloc, level-1); - if (val == NULL) { - return NULL; - } - values.at_put(j, val); - } else { - values.at_put(j, old_phi); + val = value_from_mem_phi(val, ft, phi_type, adr_t, alloc, value_phis, level-1); + if (val == NULL) { + return NULL; } + values.at_put(j, val); } else { - return NULL; // unknown node on this path + assert(false, "unknown node on this path"); + return NULL; // unknown node on this path } } } - // create a new Phi for the value - PhiNode *phi = new (C, length) PhiNode(mem->in(0), phi_type, NULL, instance_id, alias_idx, offset); + // Set Phi's inputs for (uint j = 1; j < length; j++) { if (values.at(j) == mem) { phi->init_req(j, phi); @@ -314,7 +328,6 @@ Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type * phi->init_req(j, values.at(j)); } } - transform_later(phi); return phi; } @@ -329,7 +342,8 @@ Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, BasicType ft, const Type Node *start_mem = C->start()->proj_out(TypeFunc::Memory); Node *alloc_ctrl = alloc->in(TypeFunc::Control); Node *alloc_mem = alloc->in(TypeFunc::Memory); - VectorSet visited(Thread::current()->resource_area()); + Arena *a = Thread::current()->resource_area(); + VectorSet visited(a); bool done = sfpt_mem == alloc_mem; @@ -338,7 +352,7 @@ Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, BasicType ft, const Type if (visited.test_set(mem->_idx)) { return NULL; // found a loop, give up } - mem = scan_mem_chain(mem, alias_idx, offset, start_mem, alloc); + mem = scan_mem_chain(mem, alias_idx, offset, start_mem, alloc, &_igvn); if (mem == start_mem || mem == alloc_mem) { done = true; // hit a sentinel, return appropriate 0 value } else if (mem->is_Initialize()) { @@ -362,7 +376,7 @@ Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, BasicType ft, const Type Node *unique_input = NULL; Node *top = C->top(); for (uint i = 1; i < mem->req(); i++) { - Node *n = scan_mem_chain(mem->in(i), alias_idx, offset, start_mem, alloc); + Node *n = scan_mem_chain(mem->in(i), alias_idx, offset, start_mem, alloc, &_igvn); if (n == NULL || n == top || n == mem) { continue; } else if (unique_input == NULL) { @@ -389,9 +403,18 @@ Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, BasicType ft, const Type return mem->in(MemNode::ValueIn); } else if (mem->is_Phi()) { // attempt to produce a Phi reflecting the values on the input paths of the Phi - Node * phi = value_from_mem_phi(mem, ft, ftype, adr_t, alloc, 8); + Node_Stack value_phis(a, 8); + Node * phi = value_from_mem_phi(mem, ft, ftype, adr_t, alloc, &value_phis, ValueSearchLimit); if (phi != NULL) { return phi; + } else { + // Kill all new Phis + while(value_phis.is_nonempty()) { + Node* n = value_phis.node(); + _igvn.hash_delete(n); + _igvn.subsume_node(n, C->top()); + value_phis.pop(); + } } } } @@ -448,7 +471,7 @@ bool PhaseMacroExpand::can_eliminate_allocation(AllocateNode *alloc, GrowableArr Node* n = use->fast_out(k); if (!n->is_Store() && n->Opcode() != Op_CastP2X) { DEBUG_ONLY(disq_node = n;) - if (n->is_Load()) { + if (n->is_Load() || n->is_LoadStore()) { NOT_PRODUCT(fail_eliminate = "Field load";) } else { NOT_PRODUCT(fail_eliminate = "Not store field referrence";) @@ -571,7 +594,7 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray nonstatic_field_at(j); @@ -579,7 +602,7 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray type(); basic_elem_type = field->layout_type(); } else { - offset = array_base + j * element_size; + offset = array_base + j * (intptr_t)element_size; } const Type *field_type; diff --git a/hotspot/src/share/vm/opto/macro.hpp b/hotspot/src/share/vm/opto/macro.hpp index 0f784aafc02..89ed2bd2f47 100644 --- a/hotspot/src/share/vm/opto/macro.hpp +++ b/hotspot/src/share/vm/opto/macro.hpp @@ -79,7 +79,7 @@ private: const TypeFunc* slow_call_type, address slow_call_address); Node *value_from_mem(Node *mem, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, Node *alloc); - Node *value_from_mem_phi(Node *mem, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, Node *alloc, int level); + Node *value_from_mem_phi(Node *mem, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, Node *alloc, Node_Stack *value_phis, int level); bool eliminate_allocate_node(AllocateNode *alloc); bool can_eliminate_allocation(AllocateNode *alloc, GrowableArray & safepoints); diff --git a/hotspot/src/share/vm/opto/matcher.cpp b/hotspot/src/share/vm/opto/matcher.cpp index 1640b28e3cc..f8ff59632ae 100644 --- a/hotspot/src/share/vm/opto/matcher.cpp +++ b/hotspot/src/share/vm/opto/matcher.cpp @@ -1450,6 +1450,8 @@ MachNode *Matcher::ReduceInst( State *s, int rule, Node *&mem ) { Node *leaf = s->_leaf; // Check for instruction or instruction chain rule if( rule >= _END_INST_CHAIN_RULE || rule < _BEGIN_INST_CHAIN_RULE ) { + assert(C->node_arena()->contains(s->_leaf) || !has_new_node(s->_leaf), + "duplicating node that's already been matched"); // Instruction mach->add_req( leaf->in(0) ); // Set initial control // Reduce interior of complex instruction @@ -1872,6 +1874,12 @@ void Matcher::find_shared( Node *n ) { // Clone addressing expressions as they are "free" in most instructions if( mem_op && i == MemNode::Address && mop == Op_AddP ) { + if (m->in(AddPNode::Base)->Opcode() == Op_DecodeN) { + // Bases used in addresses must be shared but since + // they are shared through a DecodeN they may appear + // to have a single use so force sharing here. + set_shared(m->in(AddPNode::Base)->in(1)); + } Node *off = m->in(AddPNode::Offset); if( off->is_Con() ) { set_visited(m); // Flag as visited now diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp index 5015d99c483..56f7ef736c9 100644 --- a/hotspot/src/share/vm/opto/memnode.cpp +++ b/hotspot/src/share/vm/opto/memnode.cpp @@ -94,14 +94,19 @@ Node *MemNode::optimize_simple_memory_chain(Node *mchain, const TypePtr *t_adr, if (tinst == NULL || !tinst->is_known_instance_field()) return mchain; // don't try to optimize non-instance types uint instance_id = tinst->instance_id(); + Node *start_mem = phase->C->start()->proj_out(TypeFunc::Memory); Node *prev = NULL; Node *result = mchain; while (prev != result) { prev = result; + if (result == start_mem) + break; // hit one of our sentinals // skip over a call which does not affect this memory slice if (result->is_Proj() && result->as_Proj()->_con == TypeFunc::Memory) { Node *proj_in = result->in(0); - if (proj_in->is_Call()) { + if (proj_in->is_Allocate() && proj_in->_idx == instance_id) { + break; // hit one of our sentinals + } else if (proj_in->is_Call()) { CallNode *call = proj_in->as_Call(); if (!call->may_modify(t_adr, phase)) { result = call->in(TypeFunc::Memory); @@ -115,6 +120,8 @@ Node *MemNode::optimize_simple_memory_chain(Node *mchain, const TypePtr *t_adr, } } else if (proj_in->is_MemBar()) { result = proj_in->in(TypeFunc::Memory); + } else { + assert(false, "unexpected projection"); } } else if (result->is_MergeMem()) { result = step_through_mergemem(phase, result->as_MergeMem(), t_adr, NULL, tty); @@ -135,7 +142,9 @@ Node *MemNode::optimize_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGV const TypePtr *t = mphi->adr_type(); if (t == TypePtr::BOTTOM || t == TypeRawPtr::BOTTOM || t->isa_oopptr() && !t->is_oopptr()->is_known_instance() && - t->is_oopptr()->cast_to_instance_id(t_oop->instance_id()) == t_oop) { + t->is_oopptr()->cast_to_exactness(true) + ->is_oopptr()->cast_to_ptr_type(t_oop->ptr()) + ->is_oopptr()->cast_to_instance_id(t_oop->instance_id()) == t_oop) { // clone the Phi with our address type result = mphi->split_out_instance(t_adr, igvn); } else { @@ -205,6 +214,9 @@ Node *MemNode::Ideal_common(PhaseGVN *phase, bool can_reshape) { Node *ctl = in(MemNode::Control); if (ctl && remove_dead_region(phase, can_reshape)) return this; + ctl = in(MemNode::Control); + // Don't bother trying to transform a dead node + if( ctl && ctl->is_top() ) return NodeSentinel; // Ignore if memory is dead, or self-loop Node *mem = in(MemNode::Memory); @@ -235,6 +247,7 @@ Node *MemNode::Ideal_common(PhaseGVN *phase, bool can_reshape) { if (mem != old_mem) { set_req(MemNode::Memory, mem); + if (phase->type( mem ) == Type::TOP) return NodeSentinel; return this; } @@ -1222,6 +1235,10 @@ Node *LoadNode::split_through_phi(PhaseGVN *phase) { // our new node, even though we may throw the node away. // (This tweaking with igvn only works because x is a new node.) igvn->set_type(x, t); + // If x is a TypeNode, capture any more-precise type permanently into Node + // othewise it will be not updated during igvn->transform since + // igvn->type(x) is set to x->Value() already. + x->raise_bottom_type(t); Node *y = x->Identity(igvn); if( y != x ) { wins++; @@ -1303,6 +1320,7 @@ Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) { Node* opt_mem = MemNode::optimize_memory_chain(mem, addr_t, phase); if (opt_mem != mem) { set_req(MemNode::Memory, opt_mem); + if (phase->type( opt_mem ) == Type::TOP) return NULL; return this; } const TypeOopPtr *t_oop = addr_t->isa_oopptr(); @@ -1400,7 +1418,7 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const { // had an original form like p1:(AddP x x (LShiftL quux 3)), where the // expression (LShiftL quux 3) independently optimized to the constant 8. if ((t->isa_int() == NULL) && (t->isa_long() == NULL) - && Opcode() != Op_LoadKlass) { + && Opcode() != Op_LoadKlass && Opcode() != Op_LoadNKlass) { // t might actually be lower than _type, if _type is a unique // concrete subclass of abstract class t. // Make sure the reference is not into the header, by comparing @@ -2434,8 +2452,7 @@ MemBarNode* MemBarNode::make(Compile* C, int opcode, int atp, Node* pn) { // Return a node which is more "ideal" than the current node. Strip out // control copies Node *MemBarNode::Ideal(PhaseGVN *phase, bool can_reshape) { - if (remove_dead_region(phase, can_reshape)) return this; - return NULL; + return remove_dead_region(phase, can_reshape) ? this : NULL; } //------------------------------Value------------------------------------------ diff --git a/hotspot/src/share/vm/opto/memnode.hpp b/hotspot/src/share/vm/opto/memnode.hpp index 891b9f64a87..dff9dad102e 100644 --- a/hotspot/src/share/vm/opto/memnode.hpp +++ b/hotspot/src/share/vm/opto/memnode.hpp @@ -607,6 +607,7 @@ public: }; //------------------------------LoadStoreNode--------------------------- +// Note: is_Mem() method returns 'true' for this class. class LoadStoreNode : public Node { public: enum { diff --git a/hotspot/src/share/vm/opto/node.cpp b/hotspot/src/share/vm/opto/node.cpp index df3e56c2dc7..9130403ed9d 100644 --- a/hotspot/src/share/vm/opto/node.cpp +++ b/hotspot/src/share/vm/opto/node.cpp @@ -1166,16 +1166,15 @@ bool Node::dominates(Node* sub, Node_List &nlist) { // using it dead as well. This will happen normally via the usual IterGVN // worklist but this call is more efficient. Do not update use-def info // inside the dead region, just at the borders. -static bool kill_dead_code( Node *dead, PhaseIterGVN *igvn ) { +static void kill_dead_code( Node *dead, PhaseIterGVN *igvn ) { // Con's are a popular node to re-hit in the hash table again. - if( dead->is_Con() ) return false; + if( dead->is_Con() ) return; // Can't put ResourceMark here since igvn->_worklist uses the same arena // for verify pass with +VerifyOpto and we add/remove elements in it here. Node_List nstack(Thread::current()->resource_area()); Node *top = igvn->C->top(); - bool progress = false; nstack.push(dead); while (nstack.size() > 0) { @@ -1214,7 +1213,6 @@ static bool kill_dead_code( Node *dead, PhaseIterGVN *igvn ) { for (uint i=0; i < dead->req(); i++) { Node *n = dead->in(i); // Get input to dead guy if (n != NULL && !n->is_top()) { // Input is valid? - progress = true; dead->set_req(i, top); // Smash input away if (n->outcnt() == 0) { // Input also goes dead? if (!n->is_Con()) @@ -1233,7 +1231,7 @@ static bool kill_dead_code( Node *dead, PhaseIterGVN *igvn ) { } } // (dead->outcnt() == 0) } // while (nstack.size() > 0) for outputs - return progress; + return; } //------------------------------remove_dead_region----------------------------- @@ -1243,7 +1241,8 @@ bool Node::remove_dead_region(PhaseGVN *phase, bool can_reshape) { // Lost control into this guy? I.e., it became unreachable? // Aggressively kill all unreachable code. if (can_reshape && n->is_top()) { - return kill_dead_code(this, phase->is_IterGVN()); + kill_dead_code(this, phase->is_IterGVN()); + return false; // Node is dead. } if( n->is_Region() && n->as_Region()->is_copy() ) { diff --git a/hotspot/src/share/vm/opto/node.hpp b/hotspot/src/share/vm/opto/node.hpp index 7f78b426b1c..e027265bf67 100644 --- a/hotspot/src/share/vm/opto/node.hpp +++ b/hotspot/src/share/vm/opto/node.hpp @@ -1399,6 +1399,10 @@ public: uint index() const { return _inode_top->indx; } + uint index_at(uint i) const { + assert(_inodes + i <= _inode_top, "in range"); + return _inodes[i].indx; + } void set_node(Node *n) { _inode_top->node = n; } diff --git a/hotspot/src/share/vm/opto/output.cpp b/hotspot/src/share/vm/opto/output.cpp index 64bf38f5d1a..a3c877077b5 100644 --- a/hotspot/src/share/vm/opto/output.cpp +++ b/hotspot/src/share/vm/opto/output.cpp @@ -685,6 +685,8 @@ void Compile::FillLocArray( int idx, MachSafePointNode* sfpt, Node *local, } else if( t->base() == Type::Int && OptoReg::is_reg(regnum) ) { array->append(new_loc_value( _regalloc, regnum, Matcher::int_in_long ? Location::int_in_long : Location::normal )); + } else if( t->base() == Type::NarrowOop ) { + array->append(new_loc_value( _regalloc, regnum, Location::narrowoop )); } else { array->append(new_loc_value( _regalloc, regnum, _regalloc->is_oop(local) ? Location::oop : Location::normal )); } @@ -704,6 +706,13 @@ void Compile::FillLocArray( int idx, MachSafePointNode* sfpt, Node *local, case Type::KlassPtr: // fall through array->append(new ConstantOopWriteValue(t->isa_oopptr()->const_oop()->encoding())); break; + case Type::NarrowOop: + if (t == TypeNarrowOop::NULL_PTR) { + array->append(new ConstantOopWriteValue(NULL)); + } else { + array->append(new ConstantOopWriteValue(t->make_ptr()->isa_oopptr()->const_oop()->encoding())); + } + break; case Type::Int: array->append(new ConstantIntValue(t->is_int()->get_con())); break; @@ -878,9 +887,14 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) { } } else if( !obj_node->is_Con() ) { OptoReg::Name obj_reg = _regalloc->get_reg_first(obj_node); - scval = new_loc_value( _regalloc, obj_reg, Location::oop ); + if( obj_node->bottom_type()->base() == Type::NarrowOop ) { + scval = new_loc_value( _regalloc, obj_reg, Location::narrowoop ); + } else { + scval = new_loc_value( _regalloc, obj_reg, Location::oop ); + } } else { - scval = new ConstantOopWriteValue(obj_node->bottom_type()->is_instptr()->const_oop()->encoding()); + const TypePtr *tp = obj_node->bottom_type()->make_ptr(); + scval = new ConstantOopWriteValue(tp->is_instptr()->const_oop()->encoding()); } OptoReg::Name box_reg = BoxLockNode::stack_slot(box_node); diff --git a/hotspot/src/share/vm/opto/parse.hpp b/hotspot/src/share/vm/opto/parse.hpp index 10b3fe2ca14..bf344cb6f5f 100644 --- a/hotspot/src/share/vm/opto/parse.hpp +++ b/hotspot/src/share/vm/opto/parse.hpp @@ -479,7 +479,7 @@ class Parse : public GraphKit { float branch_prediction(float &cnt, BoolTest::mask btest, int target_bci); bool seems_never_taken(float prob); - void do_ifnull(BoolTest::mask btest); + void do_ifnull(BoolTest::mask btest, Node* c); void do_if(BoolTest::mask btest, Node* c); void repush_if_args(); void adjust_map_after_if(BoolTest::mask btest, Node* c, float prob, diff --git a/hotspot/src/share/vm/opto/parse2.cpp b/hotspot/src/share/vm/opto/parse2.cpp index b3e0a9aff10..cc1d6b3e430 100644 --- a/hotspot/src/share/vm/opto/parse2.cpp +++ b/hotspot/src/share/vm/opto/parse2.cpp @@ -875,6 +875,8 @@ bool Parse::seems_never_taken(float prob) { return prob < PROB_MIN; } +//-------------------------------repush_if_args-------------------------------- +// Push arguments of an "if" bytecode back onto the stack by adjusting _sp. inline void Parse::repush_if_args() { #ifndef PRODUCT if (PrintOpto && WizardMode) { @@ -892,7 +894,7 @@ inline void Parse::repush_if_args() { } //----------------------------------do_ifnull---------------------------------- -void Parse::do_ifnull(BoolTest::mask btest) { +void Parse::do_ifnull(BoolTest::mask btest, Node *c) { int target_bci = iter().get_dest(); Block* branch_block = successor_for_bci(target_bci); @@ -904,7 +906,7 @@ void Parse::do_ifnull(BoolTest::mask btest) { // (An earlier version of do_ifnull omitted this trap for OSR methods.) #ifndef PRODUCT if (PrintOpto && Verbose) - tty->print_cr("Never-taken backedge stops compilation at bci %d",bci()); + tty->print_cr("Never-taken edge stops compilation at bci %d",bci()); #endif repush_if_args(); // to gather stats on loop // We need to mark this branch as taken so that if we recompile we will @@ -923,18 +925,7 @@ void Parse::do_ifnull(BoolTest::mask btest) { return; } - // If this is a backwards branch in the bytecodes, add Safepoint - maybe_add_safepoint(target_bci); - explicit_null_checks_inserted++; - Node* a = null(); - Node* b = pop(); - Node* c = _gvn.transform( new (C, 3) CmpPNode(b, a) ); - - // Make a cast-away-nullness that is control dependent on the test - const Type *t = _gvn.type(b); - const Type *t_not_null = t->join(TypePtr::NOTNULL); - Node *cast = new (C, 2) CastPPNode(b,t_not_null); // Generate real control flow Node *tst = _gvn.transform( new (C, 2) BoolNode( c, btest ) ); @@ -996,7 +987,7 @@ void Parse::do_if(BoolTest::mask btest, Node* c) { if (prob == PROB_UNKNOWN) { #ifndef PRODUCT if (PrintOpto && Verbose) - tty->print_cr("Never-taken backedge stops compilation at bci %d",bci()); + tty->print_cr("Never-taken edge stops compilation at bci %d",bci()); #endif repush_if_args(); // to gather stats on loop // We need to mark this branch as taken so that if we recompile we will @@ -2100,11 +2091,15 @@ void Parse::do_one_bytecode() { break; } - case Bytecodes::_ifnull: - do_ifnull(BoolTest::eq); - break; - case Bytecodes::_ifnonnull: - do_ifnull(BoolTest::ne); + case Bytecodes::_ifnull: btest = BoolTest::eq; goto handle_if_null; + case Bytecodes::_ifnonnull: btest = BoolTest::ne; goto handle_if_null; + handle_if_null: + // If this is a backwards branch in the bytecodes, add Safepoint + maybe_add_safepoint(iter().get_dest()); + a = null(); + b = pop(); + c = _gvn.transform( new (C, 3) CmpPNode(b, a) ); + do_ifnull(btest, c); break; case Bytecodes::_if_acmpeq: btest = BoolTest::eq; goto handle_if_acmp; diff --git a/hotspot/src/share/vm/opto/phaseX.cpp b/hotspot/src/share/vm/opto/phaseX.cpp index 45690469d92..484629a90ce 100644 --- a/hotspot/src/share/vm/opto/phaseX.cpp +++ b/hotspot/src/share/vm/opto/phaseX.cpp @@ -986,7 +986,9 @@ Node *PhaseIterGVN::transform_old( Node *n ) { // Apply the Ideal call in a loop until it no longer applies Node *k = n; DEBUG_ONLY(dead_loop_check(k);) + DEBUG_ONLY(bool is_new = (k->outcnt() == 0);) Node *i = k->Ideal(this, /*can_reshape=*/true); + assert(i != k || is_new || i->outcnt() > 0, "don't return dead nodes"); #ifndef PRODUCT if( VerifyIterativeGVN ) verify_step(k); @@ -1024,7 +1026,9 @@ Node *PhaseIterGVN::transform_old( Node *n ) { } DEBUG_ONLY(dead_loop_check(k);) // Try idealizing again + DEBUG_ONLY(is_new = (k->outcnt() == 0);) i = k->Ideal(this, /*can_reshape=*/true); + assert(i != k || is_new || i->outcnt() > 0, "don't return dead nodes"); #ifndef PRODUCT if( VerifyIterativeGVN ) verify_step(k); diff --git a/hotspot/src/share/vm/opto/reg_split.cpp b/hotspot/src/share/vm/opto/reg_split.cpp index 5101eb2e75a..6db3a76d5f7 100644 --- a/hotspot/src/share/vm/opto/reg_split.cpp +++ b/hotspot/src/share/vm/opto/reg_split.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -284,7 +284,7 @@ Node *PhaseChaitin::split_Rematerialize( Node *def, Block *b, uint insidx, uint // Check for single-def (LRG cannot redefined) uint lidx = n2lidx(in); if( lidx >= _maxlrg ) continue; // Value is a recent spill-copy - if( lrgs(lidx)._def != NodeSentinel ) continue; + if (lrgs(lidx).is_singledef()) continue; Block *b_def = _cfg._bbs[def->_idx]; int idx_def = b_def->find_node(def); @@ -311,12 +311,20 @@ Node *PhaseChaitin::split_Rematerialize( Node *def, Block *b, uint insidx, uint uint lidx = Find_id(in); // Walk backwards thru spill copy node intermediates - if( walkThru ) + if (walkThru) { while ( in->is_SpillCopy() && lidx >= _maxlrg ) { in = in->in(1); lidx = Find_id(in); } + if (lidx < _maxlrg && lrgs(lidx).is_multidef()) { + // walkThru found a multidef LRG, which is unsafe to use, so + // just keep the original def used in the clone. + in = spill->in(i); + lidx = Find_id(in); + } + } + if( lidx < _maxlrg && lrgs(lidx).reg() >= LRG::SPILL_REG ) { Node *rdef = Reachblock[lrg2reach[lidx]]; if( rdef ) spill->set_req(i,rdef); @@ -505,7 +513,7 @@ uint PhaseChaitin::Split( uint maxlrg ) { // Do not bother splitting or putting in Phis for single-def // rematerialized live ranges. This happens alot to constants // with long live ranges. - if( lrgs(lidx)._def != NodeSentinel && + if( lrgs(lidx).is_singledef() && lrgs(lidx)._def->rematerialize() ) { // reset the Reaches & UP entries Reachblock[slidx] = lrgs(lidx)._def; @@ -519,6 +527,7 @@ uint PhaseChaitin::Split( uint maxlrg ) { // Initialize needs_phi and needs_split bool needs_phi = false; bool needs_split = false; + bool has_phi = false; // Walk the predecessor blocks to check inputs for that live range // Grab predecessor block header n1 = b->pred(1); @@ -562,28 +571,30 @@ uint PhaseChaitin::Split( uint maxlrg ) { } } // End for all potential Phi inputs - // If a phi is needed, check for it - if( needs_phi ) { - // check block for appropriate phinode & update edges - for( insidx = 1; insidx <= b->end_idx(); insidx++ ) { - n1 = b->_nodes[insidx]; - // bail if this is not a phi - phi = n1->is_Phi() ? n1->as_Phi() : NULL; - if( phi == NULL ) { - // Keep track of index of first non-PhiNode instruction in block - non_phi = insidx; - // break out of the for loop as we have handled all phi nodes - break; - } - // must be looking at a phi - if( Find_id(n1) == lidxs.at(slidx) ) { - // found the necessary phi - needs_phi = false; - // initialize the Reaches entry for this LRG - Reachblock[slidx] = phi; - break; - } // end if found correct phi - } // end for all phi's + // check block for appropriate phinode & update edges + for( insidx = 1; insidx <= b->end_idx(); insidx++ ) { + n1 = b->_nodes[insidx]; + // bail if this is not a phi + phi = n1->is_Phi() ? n1->as_Phi() : NULL; + if( phi == NULL ) { + // Keep track of index of first non-PhiNode instruction in block + non_phi = insidx; + // break out of the for loop as we have handled all phi nodes + break; + } + // must be looking at a phi + if( Find_id(n1) == lidxs.at(slidx) ) { + // found the necessary phi + needs_phi = false; + has_phi = true; + // initialize the Reaches entry for this LRG + Reachblock[slidx] = phi; + break; + } // end if found correct phi + } // end for all phi's + + // If a phi is needed or exist, check for it + if( needs_phi || has_phi ) { // add new phinode if one not already found if( needs_phi ) { // create a new phi node and insert it into the block @@ -687,7 +698,8 @@ uint PhaseChaitin::Split( uint maxlrg ) { } } assert( u, "at least 1 valid input expected" ); - if( i >= cnt ) { // Didn't find 2+ unique inputs? + if( i >= cnt ) { // Found one unique input + assert(Find_id(n) == Find_id(u), "should be the same lrg"); n->replace_by(u); // Then replace with unique input n->disconnect_inputs(NULL); b->_nodes.remove(insidx); diff --git a/hotspot/src/share/vm/opto/subnode.cpp b/hotspot/src/share/vm/opto/subnode.cpp index 90ad08700c3..774aff9f430 100644 --- a/hotspot/src/share/vm/opto/subnode.cpp +++ b/hotspot/src/share/vm/opto/subnode.cpp @@ -633,20 +633,31 @@ const Type *CmpPNode::sub( const Type *t1, const Type *t2 ) const { kps != 1 && // both or neither are klass pointers !klass0->is_interface() && // do not trust interfaces !klass1->is_interface()) { + bool unrelated_classes = false; // See if neither subclasses the other, or if the class on top - // is precise. In either of these cases, the compare must fail. + // is precise. In either of these cases, the compare is known + // to fail if at least one of the pointers is provably not null. if (klass0->equals(klass1) || // if types are unequal but klasses are !klass0->is_java_klass() || // types not part of Java language? !klass1->is_java_klass()) { // types not part of Java language? // Do nothing; we know nothing for imprecise types } else if (klass0->is_subtype_of(klass1)) { - // If klass1's type is PRECISE, then we can fail. - if (xklass1) return TypeInt::CC_GT; + // If klass1's type is PRECISE, then classes are unrelated. + unrelated_classes = xklass1; } else if (klass1->is_subtype_of(klass0)) { - // If klass0's type is PRECISE, then we can fail. - if (xklass0) return TypeInt::CC_GT; + // If klass0's type is PRECISE, then classes are unrelated. + unrelated_classes = xklass0; } else { // Neither subtypes the other - return TypeInt::CC_GT; // ...so always fail + unrelated_classes = true; + } + if (unrelated_classes) { + // The oops classes are known to be unrelated. If the joined PTRs of + // two oops is not Null and not Bottom, then we are sure that one + // of the two oops is non-null, and the comparison will always fail. + TypePtr::PTR jp = r0->join_ptr(r1->_ptr); + if (jp != TypePtr::Null && jp != TypePtr::BotPTR) { + return TypeInt::CC_GT; + } } } } @@ -681,7 +692,11 @@ Node *CmpPNode::Ideal( PhaseGVN *phase, bool can_reshape ) { // Now check for LoadKlass on left. Node* ldk1 = in(1); - if (ldk1->Opcode() != Op_LoadKlass) + if (ldk1->is_DecodeN()) { + ldk1 = ldk1->in(1); + if (ldk1->Opcode() != Op_LoadNKlass ) + return NULL; + } else if (ldk1->Opcode() != Op_LoadKlass ) return NULL; // Take apart the address of the LoadKlass: Node* adr1 = ldk1->in(MemNode::Address); @@ -702,7 +717,11 @@ Node *CmpPNode::Ideal( PhaseGVN *phase, bool can_reshape ) { // Check for a LoadKlass from primary supertype array. // Any nested loadklass from loadklass+con must be from the p.s. array. - if (ldk2->Opcode() != Op_LoadKlass) + if (ldk2->is_DecodeN()) { + // Keep ldk2 as DecodeN since it could be used in CmpP below. + if (ldk2->in(1)->Opcode() != Op_LoadNKlass ) + return NULL; + } else if (ldk2->Opcode() != Op_LoadKlass) return NULL; // Verify that we understand the situation @@ -769,20 +788,31 @@ const Type *CmpNNode::sub( const Type *t1, const Type *t2 ) const { kps != 1 && // both or neither are klass pointers !klass0->is_interface() && // do not trust interfaces !klass1->is_interface()) { + bool unrelated_classes = false; // See if neither subclasses the other, or if the class on top - // is precise. In either of these cases, the compare must fail. + // is precise. In either of these cases, the compare is known + // to fail if at least one of the pointers is provably not null. if (klass0->equals(klass1) || // if types are unequal but klasses are !klass0->is_java_klass() || // types not part of Java language? !klass1->is_java_klass()) { // types not part of Java language? // Do nothing; we know nothing for imprecise types } else if (klass0->is_subtype_of(klass1)) { - // If klass1's type is PRECISE, then we can fail. - if (xklass1) return TypeInt::CC_GT; + // If klass1's type is PRECISE, then classes are unrelated. + unrelated_classes = xklass1; } else if (klass1->is_subtype_of(klass0)) { - // If klass0's type is PRECISE, then we can fail. - if (xklass0) return TypeInt::CC_GT; + // If klass0's type is PRECISE, then classes are unrelated. + unrelated_classes = xklass0; } else { // Neither subtypes the other - return TypeInt::CC_GT; // ...so always fail + unrelated_classes = true; + } + if (unrelated_classes) { + // The oops classes are known to be unrelated. If the joined PTRs of + // two oops is not Null and not Bottom, then we are sure that one + // of the two oops is non-null, and the comparison will always fail. + TypePtr::PTR jp = r0->join_ptr(r1->_ptr); + if (jp != TypePtr::Null && jp != TypePtr::BotPTR) { + return TypeInt::CC_GT; + } } } } diff --git a/hotspot/src/share/vm/opto/superword.cpp b/hotspot/src/share/vm/opto/superword.cpp index 593d5dd2dd0..acc8248500d 100644 --- a/hotspot/src/share/vm/opto/superword.cpp +++ b/hotspot/src/share/vm/opto/superword.cpp @@ -1196,8 +1196,10 @@ void SuperWord::construct_bb() { Node *n = lp()->fast_out(i); if (in_bb(n) && (n->is_Phi() && n->bottom_type() == Type::MEMORY)) { Node* n_tail = n->in(LoopNode::LoopBackControl); - _mem_slice_head.push(n); - _mem_slice_tail.push(n_tail); + if (n_tail != n->in(LoopNode::EntryControl)) { + _mem_slice_head.push(n); + _mem_slice_tail.push(n_tail); + } } } diff --git a/hotspot/src/share/vm/opto/type.cpp b/hotspot/src/share/vm/opto/type.cpp index bb6c959388f..243b44c4263 100644 --- a/hotspot/src/share/vm/opto/type.cpp +++ b/hotspot/src/share/vm/opto/type.cpp @@ -804,6 +804,7 @@ const Type *TypeF::xmeet( const Type *t ) const { case InstPtr: case KlassPtr: case AryPtr: + case NarrowOop: case Int: case Long: case DoubleTop: @@ -1955,14 +1956,25 @@ const Type *TypePtr::xdual() const { return new TypePtr( AnyPtr, dual_ptr(), dual_offset() ); } +//------------------------------xadd_offset------------------------------------ +int TypePtr::xadd_offset( intptr_t offset ) const { + // Adding to 'TOP' offset? Return 'TOP'! + if( _offset == OffsetTop || offset == OffsetTop ) return OffsetTop; + // Adding to 'BOTTOM' offset? Return 'BOTTOM'! + if( _offset == OffsetBot || offset == OffsetBot ) return OffsetBot; + // Addition overflows or "accidentally" equals to OffsetTop? Return 'BOTTOM'! + offset += (intptr_t)_offset; + if (offset != (int)offset || offset == OffsetTop) return OffsetBot; + + // assert( _offset >= 0 && _offset+offset >= 0, "" ); + // It is possible to construct a negative offset during PhaseCCP + + return (int)offset; // Sum valid offsets +} + //------------------------------add_offset------------------------------------- -const TypePtr *TypePtr::add_offset( int offset ) const { - if( offset == 0 ) return this; // No change - if( _offset == OffsetBot ) return this; - if( offset == OffsetBot ) offset = OffsetBot; - else if( _offset == OffsetTop || offset == OffsetTop ) offset = OffsetTop; - else offset += _offset; - return make( AnyPtr, _ptr, offset ); +const TypePtr *TypePtr::add_offset( intptr_t offset ) const { + return make( AnyPtr, _ptr, xadd_offset(offset) ); } //------------------------------eq--------------------------------------------- @@ -2095,7 +2107,7 @@ const Type *TypeRawPtr::xdual() const { } //------------------------------add_offset------------------------------------- -const TypePtr *TypeRawPtr::add_offset( int offset ) const { +const TypePtr *TypeRawPtr::add_offset( intptr_t offset ) const { if( offset == OffsetTop ) return BOTTOM; // Undefined offset-> undefined pointer if( offset == OffsetBot ) return BOTTOM; // Unknown offset-> unknown pointer if( offset == 0 ) return this; // No change @@ -2218,7 +2230,7 @@ const Type *TypeOopPtr::cast_to_ptr_type(PTR ptr) const { return make(ptr, _offset); } -//-----------------------------cast_to_instance------------------------------- +//-----------------------------cast_to_instance_id---------------------------- const TypeOopPtr *TypeOopPtr::cast_to_instance_id(int instance_id) const { // There are no instances of a general oop. // Return self unchanged. @@ -2263,6 +2275,7 @@ const Type *TypeOopPtr::xmeet( const Type *t ) const { case DoubleTop: case DoubleCon: case DoubleBot: + case NarrowOop: case Bottom: // Ye Olde Default return Type::BOTTOM; case Top: @@ -2543,21 +2556,8 @@ bool TypeOopPtr::singleton(void) const { return (_offset == 0) && !below_centerline(_ptr); } -//------------------------------xadd_offset------------------------------------ -int TypeOopPtr::xadd_offset( int offset ) const { - // Adding to 'TOP' offset? Return 'TOP'! - if( _offset == OffsetTop || offset == OffsetTop ) return OffsetTop; - // Adding to 'BOTTOM' offset? Return 'BOTTOM'! - if( _offset == OffsetBot || offset == OffsetBot ) return OffsetBot; - - // assert( _offset >= 0 && _offset+offset >= 0, "" ); - // It is possible to construct a negative offset during PhaseCCP - - return _offset+offset; // Sum valid offsets -} - //------------------------------add_offset------------------------------------- -const TypePtr *TypeOopPtr::add_offset( int offset ) const { +const TypePtr *TypeOopPtr::add_offset( intptr_t offset ) const { return make( _ptr, xadd_offset(offset) ); } @@ -2610,8 +2610,7 @@ const TypeInstPtr *TypeInstPtr::make(PTR ptr, // Ptr is never Null assert( ptr != Null, "NULL pointers are not typed" ); - if ( instance_id > 0 ) - xk = true; // instances are always exactly typed + assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed"); if (!UseExactTypes) xk = false; if (ptr == Constant) { // Note: This case includes meta-object constants, such as methods. @@ -2650,16 +2649,10 @@ const Type *TypeInstPtr::cast_to_exactness(bool klass_is_exact) const { return make(ptr(), klass(), klass_is_exact, const_oop(), _offset, _instance_id); } -//-----------------------------cast_to_instance------------------------------- +//-----------------------------cast_to_instance_id---------------------------- const TypeOopPtr *TypeInstPtr::cast_to_instance_id(int instance_id) const { if( instance_id == _instance_id ) return this; - bool exact = _klass_is_exact; - PTR ptr_t = _ptr; - if ( instance_id > 0 ) { // instances are always exactly typed - if (UseExactTypes) exact = true; - ptr_t = NotNull; - } - return make(ptr_t, klass(), exact, const_oop(), _offset, instance_id); + return make(_ptr, klass(), _klass_is_exact, const_oop(), _offset, instance_id); } //------------------------------xmeet_unloaded--------------------------------- @@ -2899,6 +2892,7 @@ const Type *TypeInstPtr::xmeet( const Type *t ) const { xk = above_centerline(ptr) ? tinst_xk : false; // Watch out for Constant vs. AnyNull interface. if (ptr == Constant) ptr = NotNull; // forget it was a constant + instance_id = InstanceBot; } ciObject* o = NULL; // the Constant value, if any if (ptr == Constant) { @@ -2989,6 +2983,7 @@ const Type *TypeInstPtr::xmeet( const Type *t ) const { // class hierarchy - which means we have to fall to at least NotNull. if( ptr == TopPTR || ptr == AnyNull || ptr == Constant ) ptr = NotNull; + instance_id = InstanceBot; // Now we find the LCA of Java classes ciKlass* k = this_klass->least_common_ancestor(tinst_klass); @@ -3079,7 +3074,7 @@ void TypeInstPtr::dump2( Dict &d, uint depth, outputStream *st ) const { #endif //------------------------------add_offset------------------------------------- -const TypePtr *TypeInstPtr::add_offset( int offset ) const { +const TypePtr *TypeInstPtr::add_offset( intptr_t offset ) const { return make( _ptr, klass(), klass_is_exact(), const_oop(), xadd_offset(offset), _instance_id ); } @@ -3101,8 +3096,7 @@ const TypeAryPtr *TypeAryPtr::make( PTR ptr, const TypeAry *ary, ciKlass* k, boo assert(!(k == NULL && ary->_elem->isa_int()), "integral arrays must be pre-equipped with a class"); if (!xk) xk = ary->ary_must_be_exact(); - if ( instance_id > 0 ) - xk = true; // instances are always exactly typed + assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed"); if (!UseExactTypes) xk = (ptr == Constant); return (TypeAryPtr*)(new TypeAryPtr(ptr, NULL, ary, k, xk, offset, instance_id))->hashcons(); } @@ -3113,8 +3107,7 @@ const TypeAryPtr *TypeAryPtr::make( PTR ptr, ciObject* o, const TypeAry *ary, ci "integral arrays must be pre-equipped with a class"); assert( (ptr==Constant && o) || (ptr!=Constant && !o), "" ); if (!xk) xk = (o != NULL) || ary->ary_must_be_exact(); - if ( instance_id > 0 ) - xk = true; // instances are always exactly typed + assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed"); if (!UseExactTypes) xk = (ptr == Constant); return (TypeAryPtr*)(new TypeAryPtr(ptr, o, ary, k, xk, offset, instance_id))->hashcons(); } @@ -3134,16 +3127,10 @@ const Type *TypeAryPtr::cast_to_exactness(bool klass_is_exact) const { return make(ptr(), const_oop(), _ary, klass(), klass_is_exact, _offset, _instance_id); } -//-----------------------------cast_to_instance------------------------------- +//-----------------------------cast_to_instance_id---------------------------- const TypeOopPtr *TypeAryPtr::cast_to_instance_id(int instance_id) const { if( instance_id == _instance_id ) return this; - bool exact = _klass_is_exact; - PTR ptr_t = _ptr; - if ( instance_id > 0 ) { // instances are always exactly typed - if (UseExactTypes) exact = true; - ptr_t = NotNull; - } - return make(ptr_t, const_oop(), _ary, klass(), exact, _offset, instance_id); + return make(_ptr, const_oop(), _ary, klass(), _klass_is_exact, _offset, instance_id); } //-----------------------------narrow_size_type------------------------------- @@ -3300,6 +3287,7 @@ const Type *TypeAryPtr::xmeet( const Type *t ) const { } else { // Something like byte[int+] meets char[int+]. // This must fall to bottom, not (int[-128..65535])[int+]. + instance_id = InstanceBot; tary = TypeAry::make(Type::BOTTOM, tary->_size); } } @@ -3316,6 +3304,7 @@ const Type *TypeAryPtr::xmeet( const Type *t ) const { if( tap->const_oop() != NULL && !o->equals(tap->const_oop()) ) { ptr = NotNull; o = NULL; + instance_id = InstanceBot; } } else if( above_centerline(_ptr) ) { o = tap->const_oop(); @@ -3436,7 +3425,7 @@ bool TypeAryPtr::empty(void) const { } //------------------------------add_offset------------------------------------- -const TypePtr *TypeAryPtr::add_offset( int offset ) const { +const TypePtr *TypeAryPtr::add_offset( intptr_t offset ) const { return make( _ptr, _const_oop, _ary, _klass, _klass_is_exact, xadd_offset(offset), _instance_id ); } @@ -3476,7 +3465,7 @@ bool TypeNarrowOop::empty(void) const { return _ooptype->empty(); } -//------------------------------meet------------------------------------------- +//------------------------------xmeet------------------------------------------ // Compute the MEET of two types. It returns a new Type object. const Type *TypeNarrowOop::xmeet( const Type *t ) const { // Perform a fast test for common case; meeting the same types together. @@ -3494,6 +3483,13 @@ const Type *TypeNarrowOop::xmeet( const Type *t ) const { case DoubleTop: case DoubleCon: case DoubleBot: + case AnyPtr: + case RawPtr: + case OopPtr: + case InstPtr: + case KlassPtr: + case AryPtr: + case Bottom: // Ye Olde Default return Type::BOTTOM; case Top: @@ -3510,16 +3506,9 @@ const Type *TypeNarrowOop::xmeet( const Type *t ) const { default: // All else is a mistake typerr(t); - case RawPtr: - case AnyPtr: - case OopPtr: - case InstPtr: - case KlassPtr: - case AryPtr: - typerr(t); - return Type::BOTTOM; - } // End of switch + + return this; } const Type *TypeNarrowOop::xdual() const { // Compute dual right now. @@ -3663,7 +3652,7 @@ ciKlass* TypeAryPtr::klass() const { //------------------------------add_offset------------------------------------- // Access internals of klass object -const TypePtr *TypeKlassPtr::add_offset( int offset ) const { +const TypePtr *TypeKlassPtr::add_offset( intptr_t offset ) const { return make( _ptr, klass(), xadd_offset(offset) ); } @@ -3713,6 +3702,7 @@ const Type *TypeKlassPtr::xmeet( const Type *t ) const { case DoubleTop: case DoubleCon: case DoubleBot: + case NarrowOop: case Bottom: // Ye Olde Default return Type::BOTTOM; case Top: diff --git a/hotspot/src/share/vm/opto/type.hpp b/hotspot/src/share/vm/opto/type.hpp index 7dbcf096277..68366edca9b 100644 --- a/hotspot/src/share/vm/opto/type.hpp +++ b/hotspot/src/share/vm/opto/type.hpp @@ -581,7 +581,8 @@ public: virtual intptr_t get_con() const; - virtual const TypePtr *add_offset( int offset ) const; + int xadd_offset( intptr_t offset ) const; + virtual const TypePtr *add_offset( intptr_t offset ) const; virtual bool singleton(void) const; // TRUE if type is a singleton virtual bool empty(void) const; // TRUE if type is vacuous @@ -632,7 +633,7 @@ public: virtual intptr_t get_con() const; - virtual const TypePtr *add_offset( int offset ) const; + virtual const TypePtr *add_offset( intptr_t offset ) const; virtual const Type *xmeet( const Type *t ) const; virtual const Type *xdual() const; // Compute dual right now. @@ -659,7 +660,6 @@ public: }; protected: - int xadd_offset( int offset ) const; // Oop is NULL, unless this is a constant oop. ciObject* _const_oop; // Constant oop // If _klass is NULL, then so is _sig. This is an unloaded klass. @@ -724,7 +724,7 @@ public: // corresponding pointer to klass, for a given instance const TypeKlassPtr* as_klass_type() const; - virtual const TypePtr *add_offset( int offset ) const; + virtual const TypePtr *add_offset( intptr_t offset ) const; virtual const Type *xmeet( const Type *t ) const; virtual const Type *xdual() const; // Compute dual right now. @@ -793,7 +793,7 @@ class TypeInstPtr : public TypeOopPtr { virtual const TypeOopPtr *cast_to_instance_id(int instance_id) const; - virtual const TypePtr *add_offset( int offset ) const; + virtual const TypePtr *add_offset( intptr_t offset ) const; virtual const Type *xmeet( const Type *t ) const; virtual const TypeInstPtr *xmeet_unloaded( const TypeInstPtr *t ) const; @@ -842,7 +842,7 @@ public: virtual const TypeAryPtr* cast_to_size(const TypeInt* size) const; virtual bool empty(void) const; // TRUE if type is vacuous - virtual const TypePtr *add_offset( int offset ) const; + virtual const TypePtr *add_offset( intptr_t offset ) const; virtual const Type *xmeet( const Type *t ) const; virtual const Type *xdual() const; // Compute dual right now. @@ -896,7 +896,7 @@ public: // corresponding pointer to instance, for a given class const TypeOopPtr* as_instance_type() const; - virtual const TypePtr *add_offset( int offset ) const; + virtual const TypePtr *add_offset( intptr_t offset ) const; virtual const Type *xmeet( const Type *t ) const; virtual const Type *xdual() const; // Compute dual right now. diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 882e92b337d..62e764d1a7a 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -153,37 +153,56 @@ void Arguments::init_system_properties() { os::init_system_properties_values(); } -// String containing commands that will be ignored and cause a -// warning to be issued. These commands should be accepted -// for 1.6 but not 1.7. The string should be cleared at the -// beginning of 1.7. -static const char* obsolete_jvm_flags_1_5_0[] = { - "UseTrainGC", - "UseSpecialLargeObjectHandling", - "UseOversizedCarHandling", - "TraceCarAllocation", - "PrintTrainGCProcessingStats", - "LogOfCarSpaceSize", - "OversizedCarThreshold", - "MinTickInterval", - "DefaultTickInterval", - "MaxTickInterval", - "DelayTickAdjustment", - "ProcessingToTenuringRatio", - "MinTrainLength", - 0}; +/** + * Provide a slightly more user-friendly way of eliminating -XX flags. + * When a flag is eliminated, it can be added to this list in order to + * continue accepting this flag on the command-line, while issuing a warning + * and ignoring the value. Once the JDK version reaches the 'accept_until' + * limit, we flatly refuse to admit the existence of the flag. This allows + * a flag to die correctly over JDK releases using HSX. + */ +typedef struct { + const char* name; + JDK_Version obsoleted_in; // when the flag went away + JDK_Version accept_until; // which version to start denying the existence +} ObsoleteFlag; -bool Arguments::made_obsolete_in_1_5_0(const char *s) { +static ObsoleteFlag obsolete_jvm_flags[] = { + { "UseTrainGC", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "UseSpecialLargeObjectHandling", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "UseOversizedCarHandling", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "TraceCarAllocation", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "PrintTrainGCProcessingStats", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "LogOfCarSpaceSize", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "OversizedCarThreshold", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "MinTickInterval", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "DefaultTickInterval", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "MaxTickInterval", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "DelayTickAdjustment", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "ProcessingToTenuringRatio", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "MinTrainLength", JDK_Version::jdk(5), JDK_Version::jdk(7) }, + { "AppendRatio", JDK_Version::jdk_update(6,10), JDK_Version::jdk(7) }, + { NULL, JDK_Version(0), JDK_Version(0) } +}; + +// Returns true if the flag is obsolete and fits into the range specified +// for being ignored. In the case that the flag is ignored, the 'version' +// value is filled in with the version number when the flag became +// obsolete so that that value can be displayed to the user. +bool Arguments::is_newly_obsolete(const char *s, JDK_Version* version) { int i = 0; - while (obsolete_jvm_flags_1_5_0[i] != NULL) { + assert(version != NULL, "Must provide a version buffer"); + while (obsolete_jvm_flags[i].name != NULL) { + const ObsoleteFlag& flag_status = obsolete_jvm_flags[i]; // =xxx form // [-|+] form - if ((strncmp(obsolete_jvm_flags_1_5_0[i], s, - strlen(obsolete_jvm_flags_1_5_0[i])) == 0) || + if ((strncmp(flag_status.name, s, strlen(flag_status.name)) == 0) || ((s[0] == '+' || s[0] == '-') && - (strncmp(obsolete_jvm_flags_1_5_0[i], &s[1], - strlen(obsolete_jvm_flags_1_5_0[i])) == 0))) { - return true; + (strncmp(flag_status.name, &s[1], strlen(flag_status.name)) == 0))) { + if (JDK_Version::current().compare(flag_status.accept_until) == -1) { + *version = flag_status.obsoleted_in; + return true; + } } i++; } @@ -705,14 +724,20 @@ void Arguments::print_jvm_args_on(outputStream* st) { } } -bool Arguments::process_argument(const char* arg, jboolean ignore_unrecognized, FlagValueOrigin origin) { +bool Arguments::process_argument(const char* arg, + jboolean ignore_unrecognized, FlagValueOrigin origin) { + + JDK_Version since = JDK_Version(); if (parse_argument(arg, origin)) { // do nothing - } else if (made_obsolete_in_1_5_0(arg)) { + } else if (is_newly_obsolete(arg, &since)) { + enum { bufsize = 256 }; + char buffer[bufsize]; + since.to_string(buffer, bufsize); jio_fprintf(defaultStream::error_stream(), - "Warning: The flag %s has been EOL'd as of 1.5.0 and will" - " be ignored\n", arg); + "Warning: The flag %s has been EOL'd as of %s and will" + " be ignored\n", arg, buffer); } else { if (!ignore_unrecognized) { jio_fprintf(defaultStream::error_stream(), @@ -1179,15 +1204,17 @@ void Arguments::set_ergonomics_flags() { // Turn off until bug is fixed. // FLAG_SET_ERGO(bool, UseCompressedOops, true); } +#ifdef _WIN64 + if (UseLargePages && UseCompressedOops) { + // Cannot allocate guard pages for implicit checks in indexed addressing + // mode, when large pages are specified on windows. + FLAG_SET_DEFAULT(UseImplicitNullCheckForNarrowOop, false); + } +#endif // _WIN64 } else { if (UseCompressedOops && !FLAG_IS_DEFAULT(UseCompressedOops)) { // If specified, give a warning - if (UseConcMarkSweepGC){ - warning("Compressed Oops does not work with CMS"); - } else { - warning( - "Max heap size too large for Compressed Oops"); - } + warning( "Max heap size too large for Compressed Oops"); FLAG_SET_DEFAULT(UseCompressedOops, false); } } @@ -2471,6 +2498,9 @@ jint Arguments::parse(const JavaVMInitArgs* args) { if (match_option(option, "-XX:+PrintVMOptions", &tail)) { PrintVMOptions = true; } + if (match_option(option, "-XX:-PrintVMOptions", &tail)) { + PrintVMOptions = false; + } } // Parse default .hotspotrc settings file diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp index bbc91c89c95..1a7e3849fe4 100644 --- a/hotspot/src/share/vm/runtime/arguments.hpp +++ b/hotspot/src/share/vm/runtime/arguments.hpp @@ -357,9 +357,11 @@ class Arguments : AllStatic { short* methodsNum, short* methodsMax, char*** methods, bool** allClasses ); - // Returns true if the string s is in the list of - // flags made obsolete in 1.5.0. - static bool made_obsolete_in_1_5_0(const char* s); + // Returns true if the string s is in the list of flags that have recently + // been made obsolete. If we detect one of these flags on the command + // line, instead of failing we print a warning message and ignore the + // flag. This gives the user a release or so to stop using the flag. + static bool is_newly_obsolete(const char* s, JDK_Version* buffer); static short CompileOnlyClassesNum; static short CompileOnlyClassesMax; diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 8d797953cd5..4f4b9b54bcd 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -294,6 +294,9 @@ class CommandLineFlags { lp64_product(bool, CheckCompressedOops, trueInDebug, \ "generate checks in encoding/decoding code") \ \ + product(bool, UseImplicitNullCheckForNarrowOop, true, \ + "generate implicit null check in indexed addressing mode.") \ + \ /* UseMembar is theoretically a temp flag used for memory barrier \ * removal testing. It was supposed to be removed before FCS but has \ * been re-added (see 6401008) */ \ @@ -589,9 +592,15 @@ class CommandLineFlags { develop(bool, ZapJNIHandleArea, trueInDebug, \ "Zap freed JNI handle space with 0xFEFEFEFE") \ \ - develop(bool, ZapUnusedHeapArea, false, \ + develop(bool, ZapUnusedHeapArea, trueInDebug, \ "Zap unused heap space with 0xBAADBABE") \ \ + develop(bool, TraceZapUnusedHeapArea, false, \ + "Trace zapping of unused heap space") \ + \ + develop(bool, CheckZapUnusedHeapArea, false, \ + "Check zapping of unused heap space") \ + \ develop(bool, PrintVMMessages, true, \ "Print vm messages on console") \ \ @@ -1437,7 +1446,7 @@ class CommandLineFlags { "CMSPrecleanNumerator:CMSPrecleanDenominator yields convergence" \ " ratio") \ \ - product(bool, CMSPrecleanRefLists1, true, \ + product(bool, CMSPrecleanRefLists1, false, \ "Preclean ref lists during (initial) preclean phase") \ \ product(bool, CMSPrecleanRefLists2, false, \ diff --git a/hotspot/src/share/vm/runtime/init.cpp b/hotspot/src/share/vm/runtime/init.cpp index 4851d19a15a..3f470e3ed9a 100644 --- a/hotspot/src/share/vm/runtime/init.cpp +++ b/hotspot/src/share/vm/runtime/init.cpp @@ -39,7 +39,6 @@ void bytecodes_init(); void classLoader_init(); void codeCache_init(); void VM_Version_init(); -void JDK_Version_init(); void stubRoutines_init1(); jint universe_init(); // dependent on codeCache_init and stubRoutines_init void interpreter_init(); // before any methods loaded @@ -88,7 +87,6 @@ jint init_globals() { classLoader_init(); codeCache_init(); VM_Version_init(); - JDK_Version_init(); stubRoutines_init1(); jint status = universe_init(); // dependent on codeCache_init and stubRoutines_init if (status != JNI_OK) diff --git a/hotspot/src/share/vm/runtime/java.cpp b/hotspot/src/share/vm/runtime/java.cpp index 4e0ba39e629..ad992664a97 100644 --- a/hotspot/src/share/vm/runtime/java.cpp +++ b/hotspot/src/share/vm/runtime/java.cpp @@ -563,32 +563,104 @@ void vm_shutdown_during_initialization(const char* error, const char* message) { vm_shutdown(); } -jdk_version_info JDK_Version::_version_info = {0}; -bool JDK_Version::_pre_jdk16_version = false; -int JDK_Version::_jdk_version = 0; +JDK_Version JDK_Version::_current; void JDK_Version::initialize() { + jdk_version_info info; + assert(!_current.is_valid(), "Don't initialize twice"); + void *lib_handle = os::native_java_library(); - jdk_version_info_fn_t func = - CAST_TO_FN_PTR(jdk_version_info_fn_t, hpi::dll_lookup(lib_handle, "JDK_GetVersionInfo0")); + jdk_version_info_fn_t func = CAST_TO_FN_PTR(jdk_version_info_fn_t, + os::dll_lookup(lib_handle, "JDK_GetVersionInfo0")); if (func == NULL) { // JDK older than 1.6 - _pre_jdk16_version = true; - return; - } - - if (func != NULL) { - (*func)(&_version_info, sizeof(_version_info)); - } - if (jdk_major_version() == 1) { - _jdk_version = jdk_minor_version(); + _current._partially_initialized = true; } else { - // If the release version string is changed to n.x.x (e.g. 7.0.0) in a future release - _jdk_version = jdk_major_version(); + (*func)(&info, sizeof(info)); + + int major = JDK_VERSION_MAJOR(info.jdk_version); + int minor = JDK_VERSION_MINOR(info.jdk_version); + int micro = JDK_VERSION_MICRO(info.jdk_version); + int build = JDK_VERSION_BUILD(info.jdk_version); + if (major == 1 && minor > 4) { + // We represent "1.5.0" as "5.0", but 1.4.2 as itself. + major = minor; + minor = micro; + micro = 0; + } + _current = JDK_Version(major, minor, micro, info.update_version, + info.special_update_version, build, + info.thread_park_blocker == 1); } } +void JDK_Version::fully_initialize( + uint8_t major, uint8_t minor, uint8_t micro, uint8_t update) { + // This is only called when current is less than 1.6 and we've gotten + // far enough in the initialization to determine the exact version. + assert(major < 6, "not needed for JDK version >= 6"); + assert(is_partially_initialized(), "must not initialize"); + if (major < 5) { + // JDK verison sequence: 1.2.x, 1.3.x, 1.4.x, 5.0.x, 6.0.x, etc. + micro = minor; + minor = major; + major = 1; + } + _current = JDK_Version(major, minor, micro, update); +} + void JDK_Version_init() { JDK_Version::initialize(); } + +static int64_t encode_jdk_version(const JDK_Version& v) { + return + ((int64_t)v.major_version() << (BitsPerByte * 5)) | + ((int64_t)v.minor_version() << (BitsPerByte * 4)) | + ((int64_t)v.micro_version() << (BitsPerByte * 3)) | + ((int64_t)v.update_version() << (BitsPerByte * 2)) | + ((int64_t)v.special_update_version() << (BitsPerByte * 1)) | + ((int64_t)v.build_number() << (BitsPerByte * 0)); +} + +int JDK_Version::compare(const JDK_Version& other) const { + assert(is_valid() && other.is_valid(), "Invalid version (uninitialized?)"); + if (!is_partially_initialized() && other.is_partially_initialized()) { + return -(other.compare(*this)); // flip the comparators + } + assert(!other.is_partially_initialized(), "Not initialized yet"); + if (is_partially_initialized()) { + assert(other.major_version() >= 6, + "Invalid JDK version comparison during initialization"); + return -1; + } else { + uint64_t e = encode_jdk_version(*this); + uint64_t o = encode_jdk_version(other); + return (e > o) ? 1 : ((e == o) ? 0 : -1); + } +} + +void JDK_Version::to_string(char* buffer, size_t buflen) const { + size_t index = 0; + if (!is_valid()) { + jio_snprintf(buffer, buflen, "%s", "(uninitialized)"); + } else if (is_partially_initialized()) { + jio_snprintf(buffer, buflen, "%s", "(uninitialized) pre-1.6.0"); + } else { + index += jio_snprintf( + &buffer[index], buflen - index, "%d.%d", _major, _minor); + if (_micro > 0) { + index += jio_snprintf(&buffer[index], buflen - index, ".%d", _micro); + } + if (_update > 0) { + index += jio_snprintf(&buffer[index], buflen - index, "_%02d", _update); + } + if (_special > 0) { + index += jio_snprintf(&buffer[index], buflen - index, "%c", _special); + } + if (_build > 0) { + index += jio_snprintf(&buffer[index], buflen - index, "-b%02d", _build); + } + } +} diff --git a/hotspot/src/share/vm/runtime/java.hpp b/hotspot/src/share/vm/runtime/java.hpp index 160c62bb26a..0a557751619 100644 --- a/hotspot/src/share/vm/runtime/java.hpp +++ b/hotspot/src/share/vm/runtime/java.hpp @@ -48,100 +48,163 @@ extern void vm_exit_during_initialization(symbolHandle exception_name, const cha extern void vm_exit_during_initialization(const char* error, const char* message = NULL); extern void vm_shutdown_during_initialization(const char* error, const char* message = NULL); -class JDK_Version : AllStatic { +/** + * Discovering the JDK_Version during initialization is tricky when the + * running JDK is less than JDK6. For JDK6 and greater, a "GetVersion" + * function exists in libjava.so and we simply call it during the + * 'initialize()' call to find the version. For JDKs with version < 6, no + * such call exists and we have to probe the JDK in order to determine + * the exact version. This probing cannot happen during late in + * the VM initialization process so there's a period of time during + * initialization when we don't know anything about the JDK version other than + * that it less than version 6. This is the "partially initialized" time, + * when we can answer only certain version queries (such as, is the JDK + * version greater than 5? Answer: no). Once the JDK probing occurs, we + * know the version and are considered fully initialized. + */ +class JDK_Version VALUE_OBJ_CLASS_SPEC { friend class VMStructs; + friend class Universe; + friend void JDK_Version_init(); private: - static jdk_version_info _version_info; - static bool _pre_jdk16_version; - static int _jdk_version; // JDK version number representing the release - // i.e. n in 1.n.x (= jdk_minor_version()) + + static JDK_Version _current; + + // In this class, we promote the minor version of release to be the + // major version for releases >= 5 in anticipation of the JDK doing the + // same thing. For example, we represent "1.5.0" as major version 5 (we + // drop the leading 1 and use 5 as the 'major'). + + uint8_t _major; + uint8_t _minor; + uint8_t _micro; + uint8_t _update; + uint8_t _special; + uint8_t _build; + + // If partially initialized, the above fields are invalid and we know + // that we're less than major version 6. + bool _partially_initialized; + + bool _thread_park_blocker; + + bool is_valid() const { + return (_major != 0 || _partially_initialized); + } + + // initializes or partially initializes the _current static field + static void initialize(); + + // Completes initialization for a pre-JDK6 version. + static void fully_initialize(uint8_t major, uint8_t minor = 0, + uint8_t micro = 0, uint8_t update = 0); public: - static void initialize(); - static int jdk_major_version() { return JDK_VERSION_MAJOR(_version_info.jdk_version); } - static int jdk_minor_version() { return JDK_VERSION_MINOR(_version_info.jdk_version); } - static int jdk_micro_version() { return JDK_VERSION_MICRO(_version_info.jdk_version); } - static int jdk_build_number() { return JDK_VERSION_BUILD(_version_info.jdk_version); } - static bool is_pre_jdk16_version() { return _pre_jdk16_version; } - static bool is_jdk12x_version() { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 2; } - static bool is_jdk13x_version() { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 3; } - static bool is_jdk14x_version() { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 4; } - static bool is_jdk15x_version() { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 5; } + // Returns true if the the current version has only been partially initialized + static bool is_partially_initialized() { + return _current._partially_initialized; + } + + JDK_Version() : _major(0), _minor(0), _micro(0), _update(0), + _special(0), _build(0), _partially_initialized(false), + _thread_park_blocker(false) {} + + JDK_Version(uint8_t major, uint8_t minor = 0, uint8_t micro = 0, + uint8_t update = 0, uint8_t special = 0, uint8_t build = 0, + bool thread_park_blocker = false) : + _major(major), _minor(minor), _micro(micro), _update(update), + _special(special), _build(build), _partially_initialized(false), + _thread_park_blocker(thread_park_blocker) {} + + // Returns the current running JDK version + static JDK_Version current() { return _current; } + + // Factory methods for convenience + static JDK_Version jdk(uint8_t m) { + return JDK_Version(m); + } + + static JDK_Version jdk_update(uint8_t major, uint8_t update_number) { + return JDK_Version(major, 0, 0, update_number); + } + + uint8_t major_version() const { return _major; } + uint8_t minor_version() const { return _minor; } + uint8_t micro_version() const { return _micro; } + uint8_t update_version() const { return _update; } + uint8_t special_update_version() const { return _special; } + uint8_t build_number() const { return _build; } + + bool supports_thread_park_blocker() const { + return _thread_park_blocker; + } + + // Performs a full ordering comparison using all fields (update, build, etc.) + int compare(const JDK_Version& other) const; + + /** + * Performs comparison using only the major version, returning negative + * if the major version of 'this' is less than the parameter, 0 if it is + * equal, and a positive value if it is greater. + */ + int compare_major(int version) const { + if (_partially_initialized) { + if (version >= 6) { + return -1; + } else { + assert(false, "Can't make this comparison during init time"); + return -1; // conservative + } + } else { + return major_version() - version; + } + } + + void to_string(char* buffer, size_t buflen) const; + + // Convenience methods for queries on the current major/minor version + static bool is_jdk12x_version() { + return current().compare_major(2) == 0; + } + + static bool is_jdk13x_version() { + return current().compare_major(3) == 0; + } + + static bool is_jdk14x_version() { + return current().compare_major(4) == 0; + } + + static bool is_jdk15x_version() { + return current().compare_major(5) == 0; + } static bool is_jdk16x_version() { - if (is_jdk_version_initialized()) { - return _jdk_version == 6; - } else { - assert(is_pre_jdk16_version(), "must have been initialized"); - return false; - } + return current().compare_major(6) == 0; } static bool is_jdk17x_version() { - if (is_jdk_version_initialized()) { - return _jdk_version == 7; - } else { - assert(is_pre_jdk16_version(), "must have been initialized"); - return false; - } + return current().compare_major(7) == 0; } - static bool supports_thread_park_blocker() { return _version_info.thread_park_blocker; } + static bool is_gte_jdk13x_version() { + return current().compare_major(3) >= 0; + } static bool is_gte_jdk14x_version() { - // Keep the semantics of this that the version number is >= 1.4 - assert(is_jdk_version_initialized(), "Not initialized"); - return _jdk_version >= 4; + return current().compare_major(4) >= 0; } + static bool is_gte_jdk15x_version() { - // Keep the semantics of this that the version number is >= 1.5 - assert(is_jdk_version_initialized(), "Not initialized"); - return _jdk_version >= 5; + return current().compare_major(5) >= 0; } + static bool is_gte_jdk16x_version() { - // Keep the semantics of this that the version number is >= 1.6 - if (is_jdk_version_initialized()) { - return _jdk_version >= 6; - } else { - assert(is_pre_jdk16_version(), "Not initialized"); - return false; - } + return current().compare_major(6) >= 0; } static bool is_gte_jdk17x_version() { - // Keep the semantics of this that the version number is >= 1.7 - if (is_jdk_version_initialized()) { - return _jdk_version >= 7; - } else { - assert(is_pre_jdk16_version(), "Not initialized"); - return false; - } - } - - static bool is_jdk_version_initialized() { - return _jdk_version > 0; - } - - // These methods are defined to deal with pre JDK 1.6 versions - static void set_jdk12x_version() { - assert(_pre_jdk16_version && !is_jdk_version_initialized(), "must not initialize"); - _jdk_version = 2; - _version_info.jdk_version = (1 << 24) | (2 << 16); - } - static void set_jdk13x_version() { - assert(_pre_jdk16_version && !is_jdk_version_initialized(), "must not initialize"); - _jdk_version = 3; - _version_info.jdk_version = (1 << 24) | (3 << 16); - } - static void set_jdk14x_version() { - assert(_pre_jdk16_version && !is_jdk_version_initialized(), "must not initialize"); - _jdk_version = 4; - _version_info.jdk_version = (1 << 24) | (4 << 16); - } - static void set_jdk15x_version() { - assert(_pre_jdk16_version && !is_jdk_version_initialized(), "must not initialize"); - _jdk_version = 5; - _version_info.jdk_version = (1 << 24) | (5 << 16); + return current().compare_major(7) >= 0; } }; diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp index f276e7e7250..088a07ff45e 100644 --- a/hotspot/src/share/vm/runtime/os.cpp +++ b/hotspot/src/share/vm/runtime/os.cpp @@ -336,29 +336,38 @@ void* os::native_java_library() { char buffer[JVM_MAXPATHLEN]; char ebuf[1024]; - // Try to load verify dll first. In 1.3 java dll depends on it and is not always - // able to find it when the loading executable is outside the JDK. + // Try to load verify dll first. In 1.3 java dll depends on it and is not + // always able to find it when the loading executable is outside the JDK. // In order to keep working with 1.2 we ignore any loading errors. - hpi::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "verify"); - hpi::dll_load(buffer, ebuf, sizeof(ebuf)); + dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "verify"); + dll_load(buffer, ebuf, sizeof(ebuf)); // Load java dll - hpi::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "java"); - _native_java_library = hpi::dll_load(buffer, ebuf, sizeof(ebuf)); + dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "java"); + _native_java_library = dll_load(buffer, ebuf, sizeof(ebuf)); if (_native_java_library == NULL) { vm_exit_during_initialization("Unable to load native library", ebuf); } - // The JNI_OnLoad handling is normally done by method load in java.lang.ClassLoader$NativeLibrary, - // but the VM loads the base library explicitly so we have to check for JNI_OnLoad as well - const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS; - JNI_OnLoad_t JNI_OnLoad = CAST_TO_FN_PTR(JNI_OnLoad_t, hpi::dll_lookup(_native_java_library, onLoadSymbols[0])); - if (JNI_OnLoad != NULL) { - JavaThread* thread = JavaThread::current(); - ThreadToNativeFromVM ttn(thread); - HandleMark hm(thread); - jint ver = (*JNI_OnLoad)(&main_vm, NULL); - if (!Threads::is_supported_jni_version_including_1_1(ver)) { - vm_exit_during_initialization("Unsupported JNI version"); + } + static jboolean onLoaded = JNI_FALSE; + if (onLoaded) { + // We may have to wait to fire OnLoad until TLS is initialized. + if (ThreadLocalStorage::is_initialized()) { + // The JNI_OnLoad handling is normally done by method load in + // java.lang.ClassLoader$NativeLibrary, but the VM loads the base library + // explicitly so we have to check for JNI_OnLoad as well + const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS; + JNI_OnLoad_t JNI_OnLoad = CAST_TO_FN_PTR( + JNI_OnLoad_t, dll_lookup(_native_java_library, onLoadSymbols[0])); + if (JNI_OnLoad != NULL) { + JavaThread* thread = JavaThread::current(); + ThreadToNativeFromVM ttn(thread); + HandleMark hm(thread); + jint ver = (*JNI_OnLoad)(&main_vm, NULL); + onLoaded = JNI_TRUE; + if (!Threads::is_supported_jni_version_including_1_1(ver)) { + vm_exit_during_initialization("Unsupported JNI version"); + } } } } diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp index 0b8cea57884..8111d3937e4 100644 --- a/hotspot/src/share/vm/runtime/os.hpp +++ b/hotspot/src/share/vm/runtime/os.hpp @@ -390,6 +390,10 @@ class os: AllStatic { static const char* get_temp_directory(); static const char* get_current_directory(char *buf, int buflen); + // Builds a platform-specific full library path given a ld path and lib name + static void dll_build_name(char* buffer, size_t size, + const char* pathname, const char* fname); + // Symbol lookup, find nearest function name; basically it implements // dladdr() for all platforms. Name of the nearest function is copied // to buf. Distance from its base address is returned as offset. @@ -413,6 +417,9 @@ class os: AllStatic { // same architecture as Hotspot is running on static void* dll_load(const char *name, char *ebuf, int ebuflen); + // lookup symbol in a shared library + static void* dll_lookup(void* handle, const char* name); + // Print out system information; they are called by fatal error handler. // Output format may be different on different platforms. static void print_os_info(outputStream* st); diff --git a/hotspot/src/share/vm/runtime/stackValue.cpp b/hotspot/src/share/vm/runtime/stackValue.cpp index 65387af23a9..b6b2e359acf 100644 --- a/hotspot/src/share/vm/runtime/stackValue.cpp +++ b/hotspot/src/share/vm/runtime/stackValue.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -86,6 +86,22 @@ StackValue* StackValue::create_stack_value(const frame* fr, const RegisterMap* r case Location::lng: // Long value in an aligned adjacent pair return new StackValue(*(intptr_t*)value_addr); + case Location::narrowoop: { + union { intptr_t p; narrowOop noop;} value; + value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF); + if (loc.is_register()) { + // The callee has no clue whether the register holds an int, + // long or is unused. He always saves a long. Here we know + // a long was saved, but we only want an int back. Narrow the + // saved long to the int that the JVM wants. + value.noop = (narrowOop) *(julong*) value_addr; + } else { + value.noop = *(narrowOop*) value_addr; + } + // Decode narrowoop and wrap a handle around the oop + Handle h(oopDesc::decode_heap_oop(value.noop)); + return new StackValue(h); + } #endif case Location::oop: { Handle h(*(oop *)value_addr); // Wrap a handle around the oop diff --git a/hotspot/src/share/vm/runtime/statSampler.cpp b/hotspot/src/share/vm/runtime/statSampler.cpp index f7205b9e189..17b62fa970a 100644 --- a/hotspot/src/share/vm/runtime/statSampler.cpp +++ b/hotspot/src/share/vm/runtime/statSampler.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -217,6 +217,7 @@ static const char* property_counters_ss[] = { "java.class.path", "java.endorsed.dirs", "java.ext.dirs", + "java.version", "java.home", NULL }; diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index c488b3f2c52..1de74558377 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -2578,7 +2578,8 @@ void JavaThread::prepare(jobject jni_thread, ThreadPriority prio) { oop JavaThread::current_park_blocker() { // Support for JSR-166 locks oop thread_oop = threadObj(); - if (thread_oop != NULL && JDK_Version::supports_thread_park_blocker()) { + if (thread_oop != NULL && + JDK_Version::current().supports_thread_park_blocker()) { return java_lang_Thread::park_blocker(thread_oop); } return NULL; @@ -2755,12 +2756,24 @@ void Threads::threads_do(ThreadClosure* tc) { // For now, just manually iterate through them. tc->do_thread(VMThread::vm_thread()); Universe::heap()->gc_threads_do(tc); - tc->do_thread(WatcherThread::watcher_thread()); + WatcherThread *wt = WatcherThread::watcher_thread(); + // Strictly speaking, the following NULL check isn't sufficient to make sure + // the data for WatcherThread is still valid upon being examined. However, + // considering that WatchThread terminates when the VM is on the way to + // exit at safepoint, the chance of the above is extremely small. The right + // way to prevent termination of WatcherThread would be to acquire + // Terminator_lock, but we can't do that without violating the lock rank + // checking in some cases. + if (wt != NULL) + tc->do_thread(wt); + // If CompilerThreads ever become non-JavaThreads, add them here } jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { + extern void JDK_Version_init(); + // Check version if (!is_supported_jni_version(args->version)) return JNI_EVERSION; @@ -2776,6 +2789,9 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { // Initialize system properties. Arguments::init_system_properties(); + // So that JDK version can be used as a discrimintor when parsing arguments + JDK_Version_init(); + // Parse arguments jint parse_result = Arguments::parse(args); if (parse_result != JNI_OK) return parse_result; diff --git a/hotspot/src/share/vm/runtime/threadLocalStorage.cpp b/hotspot/src/share/vm/runtime/threadLocalStorage.cpp index e00c7fe257b..1718ae4309f 100644 --- a/hotspot/src/share/vm/runtime/threadLocalStorage.cpp +++ b/hotspot/src/share/vm/runtime/threadLocalStorage.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,8 +42,13 @@ void ThreadLocalStorage::set_thread(Thread* thread) { } void ThreadLocalStorage::init() { - assert(ThreadLocalStorage::thread_index() == -1, "More than one attempt to initialize threadLocalStorage"); + assert(!is_initialized(), + "More than one attempt to initialize threadLocalStorage"); pd_init(); set_thread_index(os::allocate_thread_local_storage()); generate_code_for_get_thread(); } + +bool ThreadLocalStorage::is_initialized() { + return (thread_index() != -1); +} diff --git a/hotspot/src/share/vm/runtime/threadLocalStorage.hpp b/hotspot/src/share/vm/runtime/threadLocalStorage.hpp index e522d2791ab..4be9c9ec85b 100644 --- a/hotspot/src/share/vm/runtime/threadLocalStorage.hpp +++ b/hotspot/src/share/vm/runtime/threadLocalStorage.hpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,7 @@ class ThreadLocalStorage : AllStatic { // Initialization // Called explicitly from VMThread::activate_system instead of init_globals. static void init(); + static bool is_initialized(); private: static int _thread_index; diff --git a/hotspot/src/share/vm/runtime/virtualspace.cpp b/hotspot/src/share/vm/runtime/virtualspace.cpp index 44471632df6..cbcc3520e37 100644 --- a/hotspot/src/share/vm/runtime/virtualspace.cpp +++ b/hotspot/src/share/vm/runtime/virtualspace.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -380,7 +380,8 @@ ReservedHeapSpace::ReservedHeapSpace(size_t size, size_t alignment, bool large, char* requested_address) : ReservedSpace(size, alignment, large, requested_address, - UseCompressedOops ? lcm(os::vm_page_size(), alignment) : 0) { + UseCompressedOops && UseImplicitNullCheckForNarrowOop ? + lcm(os::vm_page_size(), alignment) : 0) { // Only reserved space for the java heap should have a noaccess_prefix // if using compressed oops. protect_noaccess_prefix(size); @@ -391,7 +392,8 @@ ReservedHeapSpace::ReservedHeapSpace(const size_t prefix_size, const size_t suffix_size, const size_t suffix_align) : ReservedSpace(prefix_size, prefix_align, suffix_size, suffix_align, - UseCompressedOops ? lcm(os::vm_page_size(), prefix_align) : 0) { + UseCompressedOops && UseImplicitNullCheckForNarrowOop ? + lcm(os::vm_page_size(), prefix_align) : 0) { protect_noaccess_prefix(prefix_size+suffix_size); } diff --git a/hotspot/src/share/vm/runtime/virtualspace.hpp b/hotspot/src/share/vm/runtime/virtualspace.hpp index 556b4c92bb6..fa65035fde0 100644 --- a/hotspot/src/share/vm/runtime/virtualspace.hpp +++ b/hotspot/src/share/vm/runtime/virtualspace.hpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index eeda67501aa..e557d853db1 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -583,7 +583,7 @@ static inline uint64_t cast_uint64_t(size_t x) /***********************************/ \ \ static_field(StubRoutines, _call_stub_return_address, address) \ - IA32_ONLY(static_field(StubRoutines::i486,_call_stub_compiled_return, address)) \ + IA32_ONLY(static_field(StubRoutines::x86,_call_stub_compiled_return, address)) \ \ /***************************************/ \ /* PcDesc and other compiled code info */ \ @@ -761,8 +761,9 @@ static inline uint64_t cast_uint64_t(size_t x) static_field(Abstract_VM_Version, _vm_minor_version, int) \ static_field(Abstract_VM_Version, _vm_build_number, int) \ \ - static_field(JDK_Version, _pre_jdk16_version, bool) \ - static_field(JDK_Version, _jdk_version, int) \ + static_field(JDK_Version, _current, JDK_Version) \ + nonstatic_field(JDK_Version, _partially_initialized, bool) \ + nonstatic_field(JDK_Version, _major, unsigned char) \ \ \ \ @@ -1106,7 +1107,7 @@ static inline uint64_t cast_uint64_t(size_t x) \ declare_toplevel_type(StubQueue) \ declare_toplevel_type(StubRoutines) \ - IA32_ONLY(declare_toplevel_type(StubRoutines::i486)) \ + IA32_ONLY(declare_toplevel_type(StubRoutines::x86)) \ declare_toplevel_type(Stub) \ declare_type(InterpreterCodelet, Stub) \ \ @@ -1576,6 +1577,7 @@ static inline uint64_t cast_uint64_t(size_t x) \ declare_constant(Location::normal) \ declare_constant(Location::oop) \ + declare_constant(Location::narrowoop) \ declare_constant(Location::int_in_long) \ declare_constant(Location::lng) \ declare_constant(Location::float_in_dbl) \ diff --git a/hotspot/src/share/vm/services/threadService.cpp b/hotspot/src/share/vm/services/threadService.cpp index 5084dbf0b4e..ee56b62f70a 100644 --- a/hotspot/src/share/vm/services/threadService.cpp +++ b/hotspot/src/share/vm/services/threadService.cpp @@ -744,7 +744,7 @@ ThreadSnapshot::ThreadSnapshot(JavaThread* thread) { } // Support for JSR-166 locks - if (JDK_Version::supports_thread_park_blocker() && + if (JDK_Version::current().supports_thread_park_blocker() && (_thread_status == java_lang_Thread::PARKED || _thread_status == java_lang_Thread::PARKED_TIMED)) { diff --git a/hotspot/src/share/vm/utilities/globalDefinitions.hpp b/hotspot/src/share/vm/utilities/globalDefinitions.hpp index 0eeb5dbe3d4..258a70f0154 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp @@ -97,8 +97,12 @@ const int SerializePageShiftCount = 3; // object size. class HeapWord { friend class VMStructs; -private: + private: char* i; +#ifdef ASSERT + public: + char* value() { return i; } +#endif }; // HeapWordSize must be 2^LogHeapWordSize. diff --git a/hotspot/src/share/vm/utilities/macros.hpp b/hotspot/src/share/vm/utilities/macros.hpp index 2f495efac67..770ac0b3876 100644 --- a/hotspot/src/share/vm/utilities/macros.hpp +++ b/hotspot/src/share/vm/utilities/macros.hpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -144,6 +144,14 @@ #define NOT_WINDOWS(code) code #endif +#if defined(IA32) || defined(AMD64) +#define X86 +#define X86_ONLY(code) code +#else +#undef X86 +#define X86_ONLY(code) +#endif + #ifdef IA32 #define IA32_ONLY(code) code #define NOT_IA32(code) diff --git a/hotspot/test/Makefile b/hotspot/test/Makefile index 26fdb59a0fa..2596d851229 100644 --- a/hotspot/test/Makefile +++ b/hotspot/test/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -19,17 +19,18 @@ # Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, # CA 95054 USA or visit www.sun.com if you need additional information or # have any questions. -# +# # # -# Makefile to run jtreg +# Makefile to run various jdk tests # +# Get OS/ARCH specifics OSNAME = $(shell uname -s) +SLASH_JAVA = /java ifeq ($(OSNAME), SunOS) PLATFORM = solaris - JCT_PLATFORM = solaris ARCH = $(shell uname -p) ifeq ($(ARCH), i386) ARCH=i586 @@ -37,203 +38,165 @@ ifeq ($(OSNAME), SunOS) endif ifeq ($(OSNAME), Linux) PLATFORM = linux - JCT_PLATFORM = linux ARCH = $(shell uname -m) ifeq ($(ARCH), i386) - ARCH=i586 + ARCH = i586 endif endif ifeq ($(OSNAME), Windows_NT) PLATFORM = windows - JCT_PLATFORM = win32 + SLASH_JAVA = J: ifeq ($(word 1, $(PROCESSOR_IDENTIFIER)),ia64) - ARCH=ia64 + ARCH = ia64 else ifeq ($(word 1, $(PROCESSOR_IDENTIFIER)),AMD64) - ARCH=x64 + ARCH = x64 else ifeq ($(word 1, $(PROCESSOR_IDENTIFIER)),EM64T) - ARCH=x64 + ARCH = x64 else - ARCH=i586 + ARCH = i586 endif endif endif + EXESUFFIX = .exe endif -# Default bundle of all test results (passed or not) -JPRT_ARCHIVE_BUNDLE=$(TEST_ROOT)/JPRT_ARCHIVE_BUNDLE.zip +# Utilities used +CD = cd +CP = cp +ECHO = echo +MKDIR = mkdir +ZIP = zip -# Default home for JTREG -ifeq ($(PLATFORM), windows) - JT_HOME = J:/svc/jct-tools3.2.2_01 -else - JT_HOME = /java/svc/jct-tools3.2.2_01 -endif - -# Default JTREG to run -JTREG = $(JT_HOME)/$(JCT_PLATFORM)/bin/jtreg - -# Root of this test area +# Root of this test area (important to use full paths in some places) TEST_ROOT := $(shell pwd) -# Default JDK to test -JAVA_HOME = $(TEST_ROOT)/../build/$(PLATFORM)-$(ARCH) - -# The test directories to run -DEFAULT_TESTDIRS = serviceability -TESTDIRS = $(DEFAULT_TESTDIRS) - -# Files that hold total passed and failed counts (passed==0 is bad) -JTREG_TOTALS_DIR = $(TEST_ROOT)/JTREG_TOTALS_$(PLATFORM)_$(ARCH) -JTREG_FAILED = $(JTREG_TOTALS_DIR)/failed_count -JTREG_PASSED = $(JTREG_TOTALS_DIR)/passed_count - # Root of all test results -JTREG_ALL_OUTPUT_DIRNAME = JTREG_OUTPUT_$(PLATFORM)_$(ARCH) -JTREG_ALL_OUTPUT_DIR = $(TEST_ROOT)/$(JTREG_ALL_OUTPUT_DIRNAME) +ABS_BUILD_ROOT = $(TEST_ROOT)/../build/$(PLATFORM)-$(ARCH) +ABS_TEST_OUTPUT_DIR = $(ABS_BUILD_ROOT)/testoutput -# Test results for one test directory -JTREG_TEST_OUTPUT_DIR = $(JTREG_ALL_OUTPUT_DIR)/$@ -JTREG_TEST_REPORT_DIR = $(JTREG_TEST_OUTPUT_DIR)/JTreport -JTREG_TEST_WORK_DIR = $(JTREG_TEST_OUTPUT_DIR)/JTwork -JTREG_TEST_SUMMARY = $(JTREG_TEST_REPORT_DIR)/summary.txt +# Expect JPRT to set PRODUCT_HOME (the product or jdk in this case to test) +ifndef PRODUCT_HOME + # Try to use j2sdk-image if it exists + ABS_JDK_IMAGE = $(ABS_BUILD_ROOT)/j2sdk-image + PRODUCT_HOME := \ + $(shell \ + if [ -d $(ABS_JDK_IMAGE) ] ; then \ + $(ECHO) "$(ABS_JDK_IMAGE)"; \ + else \ + $(ECHO) "$(ABS_BUILD_ROOT)" ; \ + fi) +endif -# Temp files used by this Makefile -JTREG_TEST_TEMP_DIR = $(JTREG_ALL_OUTPUT_DIR)/$@/temp -JTREG_TEMP_PASSED = $(JTREG_TEST_TEMP_DIR)/passed -JTREG_TEMP_FAILED = $(JTREG_TEST_TEMP_DIR)/failed -JTREG_TEMP_OUTPUT = $(JTREG_TEST_TEMP_DIR)/output -JTREG_TEMP_RESULTS = $(JTREG_TEST_TEMP_DIR)/results +# Expect JPRT to set JAVA_ARGS (e.g. -server etc.) +JAVA_OPTIONS = +ifdef JAVA_ARGS + JAVA_OPTIONS = $(JAVA_ARGS) +endif -# JTREG options (different for 2.1.6 and 3.2.2_01) -JTREG_COMMON_OPTIONS = -r:$(JTREG_TEST_REPORT_DIR) \ - -w:$(JTREG_TEST_WORK_DIR) \ - -testjdk:$(JAVA_HOME) \ - -automatic \ - -verbose:all -JTREG_216_OPTIONS = $(JTREG_COMMON_OPTIONS) $@ $(JAVA_ARGS) -JTREG_322_OPTIONS = $(JTREG_COMMON_OPTIONS) $(JAVA_ARGS:%=-vmoption:%) $@ +# Expect JPRT to set JPRT_ARCHIVE_BUNDLE (path to zip bundle for results) +ARCHIVE_BUNDLE = $(ABS_TEST_OUTPUT_DIR)/ARCHIVE_BUNDLE.zip +ifdef JPRT_ARCHIVE_BUNDLE + ARCHIVE_BUNDLE = $(JPRT_ARCHIVE_BUNDLE) +endif -# Default make rule -all: clean check tests +# How to create the test bundle (pass or fail, we want to create this) +BUNDLE_UP = ( $(MKDIR) -p `dirname $(ARCHIVE_BUNDLE)` \ + && $(CD) $(ABS_TEST_OUTPUT_DIR) \ + && $(ZIP) -q -r $(ARCHIVE_BUNDLE) . ) +BUNDLE_UP_FAILED = ( exitCode=$$? && $(BUNDLE_UP) && exit $${exitCode} ) -# Chaeck to make sure these directories exist -check: $(JT_HOME) $(JAVA_HOME) $(JTREG) +################################################################ -# Prime the test run -primecounts: FRC - @rm -f -r $(JTREG_TOTALS_DIR) - @mkdir -p $(JTREG_TOTALS_DIR) - @echo "0" > $(JTREG_FAILED) - @echo "0" > $(JTREG_PASSED) +# Default make rule (runs jtreg_tests) +all: jtreg_tests + @$(ECHO) "Testing completed successfully" -# Run the tests and determine the 'make' command exit status -# Ultimately we determine the make exit code based on the passed/failed count -tests: primecounts $(TESTDIRS) - @echo "JTREG TOTAL: passed=`cat $(JTREG_PASSED)` failed=`cat $(JTREG_FAILED)`" - zip -q -r $(JPRT_ARCHIVE_BUNDLE) $(JTREG_ALL_OUTPUT_DIRNAME) - @if [ `cat $(JTREG_FAILED)` -ne 0 -o \ - `cat $(JTREG_PASSED)` -le 0 ] ; then \ - echo "JTREG FAILED"; \ - exit 1; \ - else \ - echo "JTREG PASSED"; \ - exit 0; \ - fi - -# Just make sure these directires exist -$(JT_HOME) $(JAVA_HOME): FRC - @if [ ! -d $@ ] ; then \ - echo "ERROR: Directory $@ does not exist"; \ - exit 1; \ - fi - -# Make sure this file exists -$(JTREG): FRC - @if [ ! -f $@ ] ; then \ - echo "ERROR: File $@ does not exist"; \ - exit 1; \ - fi - -# Process each test directory one by one, this rule always completes. -# Note that the use of 'tee' tosses the jtreg process exit status, this -# is as expected because even if jtreg fails, we need to save the -# output. So we update the JTREG_PASSED and JTREG_FAILED count files. -# Note that missing the 'results:' line in the last few lines of output -# will indicate a failure (or a bump by one of the JTREG_FAILED file. -# Note that passed: 0 or no passed: indication means a failure. -# Note that any indication of the word 'failed' indicates failure. -# Ultimately if the contents of JTREG_FAILED is not 0, we have failed -# tests, and if the contents of JTREG_PASSED is 0, we consider that a -# failure. -$(TESTDIRS): FRC - @if [ ! -d $@ ] ; then \ - echo "ERROR: Directory $@ does not exist"; \ - exit 1; \ - fi - @echo "---------------------------------------------------" - @rm -f -r $(JTREG_TEST_OUTPUT_DIR) - @mkdir -p $(JTREG_TEST_OUTPUT_DIR) - @mkdir -p $(JTREG_TEST_WORK_DIR) - @mkdir -p $(JTREG_TEST_WORK_DIR)/scratch - @mkdir -p $(JTREG_TEST_REPORT_DIR) - @mkdir -p $(JTREG_TEST_TEMP_DIR) - @echo "Testing $@" - @echo "Using JAVA_HOME=$(JAVA_HOME)" - @echo "Using JAVA_ARGS=$(JAVA_ARGS)" - @if [ "`$(JTREG) -help 2>&1 | fgrep -- -vmoption`" != "" ] ; then \ - echo "Assume we are using jtreg 3.2.2_01 or newer"; \ - echo "$(JTREG) $(JTREG_322_OPTIONS)"; \ - $(JTREG) $(JTREG_322_OPTIONS) 2>&1 | tee $(JTREG_TEMP_OUTPUT) ; \ - else \ - echo "Assume we are using jtreg 2.1.6"; \ - echo "$(JTREG) $(JTREG_216_OPTIONS)"; \ - $(JTREG) $(JTREG_216_OPTIONS) 2>&1 | tee $(JTREG_TEMP_OUTPUT) ; \ - fi - @echo "---------------------------------------------------" - @echo "Extracting passed and failed counts from jtreg output" - @tail -10 $(JTREG_TEMP_OUTPUT) | fgrep -i 'results:' | \ - tail -1 | tee $(JTREG_TEMP_RESULTS) - @sed -e 's@.*\ passed:\ \([1-9][0-9]*\).*@\1@' $(JTREG_TEMP_RESULTS) \ - > $(JTREG_TEMP_PASSED) - @if [ "`cat $(JTREG_TEMP_PASSED)`" = "" ] ; then \ - echo "ERROR: No passed indication in results"; \ - expr `cat $(JTREG_FAILED)` '+' 1 > $(JTREG_FAILED); \ - elif [ `cat $(JTREG_TEMP_PASSED)` -le 0 ] ; then \ - echo "ERROR: Passed count appears to be 0"; \ - expr `cat $(JTREG_FAILED)` '+' 1 > $(JTREG_FAILED); \ - elif [ "`fgrep -i failed $(JTREG_TEMP_RESULTS)`" = "" ] ; then \ - echo "No indication anything failed"; \ - expr `cat $(JTREG_PASSED)` '+' `cat $(JTREG_TEMP_PASSED)` \ - > $(JTREG_PASSED); \ - else \ - sed -e 's@.*\ failed:\ \([1-9][0-9]*\).*@\1@' $(JTREG_TEMP_FAILED) \ - > $(JTREG_TEMP_FAILED); \ - if [ "`cat $(JTREG_TEMP_FAILED)`" = "" ] ; then \ - echo "ERROR: Failed pattern but no failed count in results"; \ - expr `cat $(JTREG_FAILED)` '+' 1 > $(JTREG_FAILED); \ - elif [ `cat $(JTREG_TEMP_FAILED)` -le 0 ] ; then \ - echo "ERROR: Failed count is 0, did something failed or not?"; \ - expr `cat $(JTREG_FAILED)` '+' 1 > $(JTREG_FAILED); \ - else \ - expr `cat $(JTREG_FAILED)` '+' `cat $(JTREG_TEMP_FAILED)` \ - > $(JTREG_FAILED); \ - fi; \ - fi - @echo "---------------------------------------------------" - @echo "Summary: " - @if [ -f $(JTREG_TEST_SUMMARY) ] ; then \ - cat $(JTREG_TEST_SUMMARY) ; \ - else \ - echo "ERROR: Missing $(JTREG_TEST_SUMMARY)"; \ - fi - @echo "---------------------------------------------------" +# Prep for output +prep: clean + @$(MKDIR) -p $(ABS_TEST_OUTPUT_DIR) + @$(MKDIR) -p `dirname $(ARCHIVE_BUNDLE)` # Cleanup clean: - rm -f -r $(JTREG_ALL_OUTPUT_DIR) - rm -f $(JPRT_ARCHIVE_BUNDLE) + $(RM) -r $(ABS_TEST_OUTPUT_DIR) + $(RM) $(ARCHIVE_BUNDLE) -FRC: +################################################################ + +# jtreg tests + +# Expect JT_HOME to be set for jtreg tests. (home for jtreg) +JT_HOME = $(SLASH_JAVA)/re/jtreg/4.0/promoted/latest/binaries/jtreg +ifdef JPRT_JTREG_HOME + JT_HOME = $(JPRT_JTREG_HOME) +endif + +# Expect JPRT to set TESTDIRS to the jtreg test dirs +JTREG_TESTDIRS = demo/jvmti/gctest demo/jvmti/hprof +ifdef TESTDIRS + JTREG_TESTDIRS = $(TESTDIRS) +endif + +# Default JTREG to run (win32 script works for everybody) +JTREG = $(JT_HOME)/win32/bin/jtreg + +# Option to tell jtreg to not run tests marked with "ignore" +ifeq ($(PLATFORM), windows) + JTREG_KEY_OPTION = -k:!ignore +else + JTREG_KEY_OPTION = -k:\!ignore +endif + +#EXTRA_JTREG_OPTIONS = + +jtreg_tests: prep $(JT_HOME) $(PRODUCT_HOME) $(JTREG) + $(JTREG) -a -v:fail,error \ + $(JTREG_KEY_OPTION) \ + $(EXTRA_JTREG_OPTIONS) \ + -r:$(ABS_TEST_OUTPUT_DIR)/JTreport \ + -w:$(ABS_TEST_OUTPUT_DIR)/JTwork \ + -jdk:$(PRODUCT_HOME) \ + $(JAVA_OPTIONS:%=-vmoption:%) \ + $(JTREG_TESTDIRS) \ + || $(BUNDLE_UP_FAILED) + $(BUNDLE_UP) + +PHONY_LIST += jtreg_tests + +################################################################ + +# packtest + +# Expect JPRT to set JPRT_PACKTEST_HOME. +PACKTEST_HOME = /net/jprt-web.sfbay.sun.com/jprt/allproducts/packtest +ifdef JPRT_PACKTEST_HOME + PACKTEST_HOME = $(JPRT_PACKTEST_HOME) +endif + +#EXTRA_PACKTEST_OPTIONS = + +packtest: prep $(PACKTEST_HOME)/ptest $(PRODUCT_HOME) + ( $(CD) $(PACKTEST_HOME) && \ + $(PACKTEST_HOME)/ptest \ + -t "$(PRODUCT_HOME)" \ + $(PACKTEST_STRESS_OPTION) \ + $(EXTRA_PACKTEST_OPTIONS) \ + -W $(ABS_TEST_OUTPUT_DIR) \ + $(JAVA_OPTIONS:%=-J %) \ + ) || $(BUNDLE_UP_FAILED) + $(BUNDLE_UP) + +packtest_stress: PACKTEST_STRESS_OPTION=-s +packtest_stress: packtest + +PHONY_LIST += packtest packtest_stress + +################################################################ + +# Phony targets (e.g. these are not filenames) +.PHONY: all clean prep $(PHONY_LIST) + +################################################################ diff --git a/hotspot/test/compiler/6646019/Test.java b/hotspot/test/compiler/6646019/Test.java index e724394ff57..99c07617e04 100644 --- a/hotspot/test/compiler/6646019/Test.java +++ b/hotspot/test/compiler/6646019/Test.java @@ -1,23 +1,24 @@ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. * */ diff --git a/hotspot/test/compiler/6689060/Test.java b/hotspot/test/compiler/6689060/Test.java index f6361aee067..4d3f2003baa 100644 --- a/hotspot/test/compiler/6689060/Test.java +++ b/hotspot/test/compiler/6689060/Test.java @@ -1,24 +1,24 @@ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. * */ diff --git a/hotspot/test/compiler/6695810/Test.java b/hotspot/test/compiler/6695810/Test.java index 77297671082..f59db440083 100644 --- a/hotspot/test/compiler/6695810/Test.java +++ b/hotspot/test/compiler/6695810/Test.java @@ -1,24 +1,24 @@ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. * */ diff --git a/hotspot/test/compiler/6700047/Test6700047.java b/hotspot/test/compiler/6700047/Test6700047.java new file mode 100644 index 00000000000..55921d59465 --- /dev/null +++ b/hotspot/test/compiler/6700047/Test6700047.java @@ -0,0 +1,60 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6700047 + * @summary C2 failed in idom_no_update + * @run main Test6700047 + */ + +public class Test6700047 { + public static void main(String[] args) { + for (int i = 0; i < 100000; i++) { + intToLeftPaddedAsciiBytes(); + } + } + + public static int intToLeftPaddedAsciiBytes() { + int offset = 40; + int q; + int r; + int i = 100; + int result = 1; + while (offset > 0) { + q = (i * 52429); + r = i; + offset--; + i = q; + if (i == 0) { + break; + } + } + if (offset > 0) { + for(int j = 0; j < offset; j++) { + result++; + } + } + return result; + } +} diff --git a/hotspot/test/compiler/6712835/Test6712835.java b/hotspot/test/compiler/6712835/Test6712835.java new file mode 100644 index 00000000000..2f1dbda198c --- /dev/null +++ b/hotspot/test/compiler/6712835/Test6712835.java @@ -0,0 +1,1578 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6712835 + * @summary Server compiler fails with assertion (loop_count < K,"infinite loop in PhaseIterGVN::transform") + * @run main/othervm -Xcomp Test6712835 + */ + +/* Complexity upper bound: 349851 ops */ + +abstract class Tester_Class_0 { + boolean var_1 = true; + static double var_2; + float var_3 = 1.8301116E38F; + final String var_4 = "wck"; + final static short var_5 = 25624; + + + public Tester_Class_0() + { + var_2 = (byte)1.7374809293839066E308; + { + double var_18 = false ? 8027040614338917376L * var_3 + - (var_2 = var_5) : (var_3 += (char)4.491494085158084E307); + var_3 *= ~ ((byte)702579792) / 6600332715431236608L; + long var_19 = 0L; + var_18 -= 1759091496; + do + { + final long var_20 = (new long[(byte)(var_3 += + +1.6695243696502334E308)][(byte)((byte)1110410742 | ~var_19)])[var_1 & var_1 ? (byte)1047514041090199552L : (byte)var_5][(byte)(var_1 ? 123309551 : - ((byte)5932930312361050112L))]; + var_19++; + final short var_21 = var_5; + } while (var_19 < 1 && var_1 ^ var_3 == + ((byte)var_5)); + { + int var_22; + } + { + var_4.endsWith("o"); + } + int var_23 = 0; + var_1 &= (var_1 = true); + for (byte var_24 = 26; (var_1 = !var_1) && var_23 < 1; var_18 += var_1 ^ (var_1 |= false) ^ true ? var_24 : (byte)1504077779675035648L) + { + var_18 *= var_23; + var_23++; + float var_25; + (((new Tester_Class_0[var_24][var_24][var_24])[var_24])[var_24 >>= var_19][var_24 &= 6702582681202665472L]).var_3 *= var_5; + } + var_1 = (var_3 -= var_5) > (byte)func_2(1317089759, var_5, (byte)var_19) % (false & true ? 475183200 : 8947159119888251904L); + var_18 /= ~var_19 ^ ((byte)(var_18 %= (int)var_5) >= 6773554922270913536L ? (byte)var_5 : (byte)'u'); + var_3 = ~ ((byte)var_19); + } + double var_26 = 0; + var_1 &= (var_1 |= ! (var_1 |= true)); + while (var_26 < 1) + { + var_2 = 'e'; + var_26++; + var_1 ^= !true | 'j' * ((var_2 = 93384362) + var_5) <= var_5; + var_2 = true ? 2056852215 : var_5; + } + switch ((new char[(byte)var_3])[(byte)(short)var_4.charAt(438929928)] / (new byte[(byte)1779353916050551808L][(byte)+ ~8903539475459755008L])[(byte)836413337621087232L][(byte)784406244]) + { + case 101: + var_3 -= var_5; + break; + + case 'L': + + case 20: + final int var_27 = 2146473580; + break; + + case 18: + + default: + "mwh".substring((byte)(float)'A' % var_5, ']' | var_5 ^ ~ ((byte)'E')); + break; + + case 'H': + + } + var_3 = var_5; + long var_28; + var_28 = (var_1 = 'u' != (var_3 = var_1 ? 1384770002488557568L : ~ ~6691557565676772352L)) ? - ((byte)938410603) : var_5; + ((new Tester_Class_0[(byte)var_26])[(byte)'w']).var_3 = (byte)(short)'I'; + var_2 = (var_1 ^= "sfltwylm".startsWith("ytmeds")) ? 1837260339 * 434565574 : (new double[(byte)var_26])[(byte)var_3]; + } + + + + public boolean equals(Object obj) + { + var_2 = 785819716 / 'i'; + switch ((! (var_1 ^= var_1) ^ (! ((false | (var_1 |= var_1)) ^ !false) ? false : (var_1 |= !false)) ? var_1 : ! !var_1 ^ var_1) ? 1426689390 : var_5 * var_5) + { + case '`': + + case 89: + + case 13: + char var_9 = 'W'; + break; + + case 31: + + case 15: + + case 'm': + var_1 &= var_1; + break; + + case 'Z': + + case 34: + String[] var_10 = (new String[(byte)5534253842608756736L][(byte)'M'])[(byte)8717534666212195328L]; + break; + + case 124: + + } + var_3 += var_5; + var_1 |= (var_1 |= (var_1 = (var_1 |= var_5 >= (var_2 = (byte)var_3)))); + var_1 ^= (var_1 = var_4.endsWith(new String())); + var_2 = (var_3 %= 664966429); + { + var_4.lastIndexOf((int)('i' * (! !true & (true & !var_1) ? (byte)2.2562587635371023E307 : (byte)(var_3 %= var_3)) / var_3), 'P' % (false ? (byte)'N' : (byte)943393108)); + } + var_3 /= false | ! !var_1 ? (char)1.3721055E38F : '\\'; + if (var_1) + { + var_4.compareTo("uaqmqwg"); + } + else + { + var_1 ^= var_1 & (var_1 &= (var_1 ^= (var_1 ^= var_1))); + } + var_3 *= (new int[(byte)1980200282][(byte)'i'])[(byte)(var_2 = (byte)'O')][false ? (byte)2.4739911E38F : (byte)- ((byte)1.6045903096088714E308)]; + var_1 = var_5 != (byte)var_5 & (1.5002759009669559E308 < (byte)5110733568033040384L ^ (var_1 ? (var_1 ^= true) : var_1)); + long var_11; + return (var_2 = (byte)'B') < 550125954; + } + + + public static char func_0(final int arg_0, long[] arg_1, final boolean arg_2) + { + var_2 = (short)(false ? (byte)1.2577737E38F : (byte)'t'); + "xdf".codePointBefore((!arg_2 ? (byte)1426638765 : (byte)541094055) * ((byte)var_5 / var_5)); + ((new Tester_Class_0[(byte)(short)(var_2 = 'A')])[(byte)arg_0]).var_3 = 7823141134226481152L; + ((new Tester_Class_0[(byte)- ~1368497135389664256L])[!false || true ? (byte)2.5393905E38F : (byte)2.4415902E38F]).var_3 -= (int)(false ? (byte)var_5 : (byte)"musnlk".charAt(785792957)); + ((new Tester_Class_0[(byte)357672172])[(byte)7.709380171237795E307]).var_3 = arg_0; + ((new Tester_Class_0[(byte)var_5])[(byte)('Z' / + + -2.6037312E38F)]).var_3 %= arg_2 ? + - - + - + +4.6761156E37F : (byte)- (var_2 = - - ~3113191255384341504L); + (("exseqpham" + "uigdxg").equalsIgnoreCase("oeutvibnv") ? "l" : "qra").replace(false ^ true ? 't' : "jwpf".charAt(+ ((byte)arg_0)), 6.624090730243228E307 > 2.7771497E38F ? 't' : "tcfesyg".charAt(arg_0)); + ((new Tester_Class_0[(byte)arg_0][(byte)6943189372481268736L])[(byte)2.6713643513095145E307][(byte)var_5]).var_1 &= !"ipgqq".endsWith("aecnyvpmf"); + ((new Tester_Class_0[(byte)(+ +2158971337956592640L ^ var_5)])[false ? (byte)8594725249859841024L : (byte)var_5]).var_3 = (byte)"jd".charAt((byte)1.6298661301128909E307 << (byte)'B'); + var_2 = (float)1014982842 * (byte)var_5 * ((new Tester_Class_0[(byte)2.7842814E38F])[(byte)"n".charAt('e' ^ (byte)arg_0)]).var_3; + if (false) + { + ((new Tester_Class_0[(byte)8.702990410251979E307][(byte)8.865924E37F])[(byte)var_5][(byte)+ ((long)var_5)]).var_1 ^= arg_2; + } + else + { + ((new Tester_Class_0[(byte)('I' | var_5)])[(byte)('L' + (+ - - (var_2 = 'N') + 1.324025E38F))]).var_3 = var_5 % '[' + (byte)var_5; + } + ((new Tester_Class_0[(byte)7.41761E37F][(byte)(var_2 = var_5)])[(byte)var_5][(byte)'o']).var_1 &= false; + ((new Tester_Class_0[(byte)+ ((byte)7.9065203E37F)])[(byte)var_5]).var_1 ^= 630582880 > - (var_2 = var_5); + return 'K'; + } + + protected float func_1(int arg_0, final Object arg_1, Object arg_2) + { + var_1 ^= (var_1 ^= true) & !var_1; + { + var_3 -= var_3; + var_2 = var_1 && (var_1 &= ! !true) | + ~3353396000385141760L < 7949306917320622080L ? (byte)306954754 : (byte)var_5; + final long var_12 = 1048994076885686272L; + } + short var_13 = 8706; + byte var_14 = (new byte[(byte)6.697464316212731E307])[(byte)var_4.indexOf("clbr", (byte)var_5 + 'F')]; + ((new Tester_Class_0[var_14][var_14 &= 'b'])[var_14][var_14]).var_1 |= var_14 >= var_3; + (((new String[var_14][var_14])[var_14])[var_14]).codePointAt(585064460); + var_14 -= 2121015302; + var_2 = 1.241922E38F; + { + (((new Tester_Class_0[var_14][var_14 ^= 'y'])[var_14])[var_14 |= var_14]).var_3 *= 5756647686007829504L; + } + { + var_13--; + } + double var_15; + var_1 = (var_1 = true) ? false : true; + arg_0--; + return var_3; + } + + public final static short func_2(int arg_0, final short arg_1, byte arg_2) + { + arg_0 %= (((new Tester_Class_0[arg_2][arg_2])[arg_2++][--arg_2]).var_1 |= true) ? 'e' : var_5 >>> arg_2; + float var_16 = ((false ? ~3951083684045828096L >>> - -3880809660598466560L : arg_0) ^ arg_1) - 1.1257035E37F; + var_2 = var_5 + 3.3679594E38F; + arg_2 += true & (((new Tester_Class_0[arg_2])[arg_2 *= 4301185995603340288L]).var_1 = arg_1 != arg_1) ? (var_2 = arg_0) : 988311987505040384L + ']' >>> --arg_2; + arg_2 = arg_2; + var_16 /= (arg_2 += (arg_0 += (var_16 %= arg_2)) + (var_16 -= arg_2)); + var_16 += 7416220016668043264L; + ((new Tester_Class_0[arg_2])[arg_2]).var_1 &= false; + ((new Tester_Class_0[--arg_2])[--arg_2]).var_1 = true | (true & true ? true : false); + arg_2 -= (var_2 = 7997355759027275776L); + ((new Tester_Class_0[arg_2])[arg_2 %= 8660960251961819136L]).var_3 *= 4180634858198604800L; + arg_0 /= -1.3063173E38F; + var_2 = arg_2; + var_2 = (6266377813429248L ^ 'j') / (!false & (1.1423139843154216E308 >= (var_2 = arg_2) || (((new Tester_Class_0[arg_2])[arg_2]).var_1 ^= true)) ? (short)('e' * arg_0) : var_5); + --arg_0; + var_2 = (+ - ~8598445599816821760L << arg_1) % 1890075208 & (!true & !true ^ false & false ? 'w' : 'm') % (5614521287604667392L / arg_2) & ~193105176465084416L; + arg_2 &= (arg_2 |= arg_0) ^ ((((new Tester_Class_0[arg_2][arg_2])[arg_2])[arg_2]).var_1 ? arg_2 : (new long[arg_2])[arg_2]); + ((new Tester_Class_0[arg_2 &= 'V'][arg_2])[arg_2 /= 5486057194586717184L][arg_2 %= var_16]).var_1 |= (new boolean[((new Tester_Class_0[arg_2])[arg_2]).var_1 ? arg_2 : arg_2])[arg_2]; + return ((((new Tester_Class_0[arg_2][arg_2][arg_2])[--arg_2])[arg_2 |= arg_2][arg_2 %= 6782653882738869248L]).var_1 ? false : !true | "hopq".equalsIgnoreCase("wvm") | "qmhtjvm".endsWith("gewqas")) && ! !false & false ? arg_1 : arg_1; + } + + protected final static char func_3(byte arg_0, final int arg_1, final short arg_2, long[] arg_3) + { + ((new Tester_Class_0[arg_0 ^= 1902924521091955712L])[arg_0]).var_1 &= ((((new Tester_Class_0[arg_0][arg_0])[--arg_0])[arg_0 *= - -1.0959788E38F]).var_1 = false); + { + var_2 = (new float[arg_0][(byte)1082004329])[arg_0][arg_0 <<= 'T']; + } + ((new Tester_Class_0[arg_0 >>= arg_1][arg_0])[arg_0][arg_0]).var_1 |= ((new Tester_Class_0[arg_0])[--arg_0]).var_4.startsWith(((new Tester_Class_0[arg_0])[arg_0]).var_4); + ((new Tester_Class_0[(byte)var_5])[arg_0]).var_4.substring(273513722, 'f' * 'n').substring((new short[arg_0][arg_0])[arg_0][arg_0] % 'C' >> (arg_3[arg_0] - 's') % ("".charAt(arg_1) & var_5)); + var_2 = 'Q' + (char)arg_0; + { + ((new Tester_Class_0[++arg_0])[arg_0]).var_1 ^= !true || !true ? !false ^ false : ! (1.7030813E38F != ~arg_0); + } + { + "jbdu".indexOf(((new Tester_Class_0[arg_0 *= 2628674024589069312L])[arg_0 -= arg_1]).var_4, "gqglwwbab".charAt(~arg_0) >>> 'M'); + } + { + --arg_0; + } + ((new Tester_Class_0[arg_0])[arg_0]).var_1 = 'n' == ('t' | (+9156142987836739584L | 's')) - 2915339344736463872L; + int var_17; + var_17 = 'k'; + var_17 = (((new Tester_Class_0[arg_0])[arg_0]).var_1 &= false) ? (short)'q' : arg_2; + return '`'; + } + + public String toString() + { + String result = "[\n"; + result += "Tester_Class_0.var_5 = "; result += Test6712835.Printer.print(var_5); + result += "\n"; + result += "Tester_Class_0.var_4 = "; result += Test6712835.Printer.print(var_4); + result += "\n"; + result += "Tester_Class_0.var_1 = "; result += Test6712835.Printer.print(var_1); + result += "\n"; + result += "Tester_Class_0.var_2 = "; result += Test6712835.Printer.print(var_2); + result += "\n"; + result += "Tester_Class_0.var_3 = "; result += Test6712835.Printer.print(var_3); + result += ""; + result += "\n]"; + return result; + } +} + + +final class Tester_Class_1 extends Tester_Class_0 { + final boolean var_29 = false; + static short var_30; + Tester_Class_0 var_31; + + + public Tester_Class_1() + { + new String(); + byte var_43 = (var_1 ? var_29 : var_1) ? (byte)(~ ~ ~6520122970162626560L | ~6642750731731981312L) : (byte)(var_30 = var_5); + { + var_2 = Tester_Class_0.var_5; + } + ((Tester_Class_0)(new Object[var_43])[var_43]).var_1 = var_29; + var_43 += 512311665; + } + + + + + final int func_0() + { + Tester_Class_0.var_2 = var_29 ? (var_29 ? (byte)'D' : (byte)Tester_Class_0.var_5) : (!var_1 ^ var_1 | (var_1 ^= var_1) ? (byte)'J' : (byte)51510881); + new String(); + new String(); + new String(); + return 1731501229; + } + + private final static void func_1(final String arg_0, final Object arg_1) + { + long var_32 = ((new Tester_Class_1[(byte)37719380])['I' == Tester_Class_0.var_5 + Tester_Class_0.var_5 ? (byte)(var_30 = (byte)1.3043569561522328E308) : (byte)1.1111420042091164E308]).var_1 ? ~2569063513521638400L - Tester_Class_0.var_5 ^ 'm' : 660383226; + ((Tester_Class_0)arg_1).var_3 += (char)8417109805993570304L; + var_30 = var_5; + var_2 = (new byte[(byte)2102078692])[(byte)7.942050823719592E307]; + if (((new Tester_Class_1[(byte)224717297])[(byte)2889830453578512384L]).var_1) + { + Tester_Class_0.var_2 = (new byte[(byte)'C'])[(byte)Tester_Class_0.var_5]; + } + else + { + var_32 <<= 'u'; + } + Tester_Class_0.var_2 = Tester_Class_0.var_5; + final Object var_33 = arg_1; + final byte var_34 = 40; + ++var_32; + (((new Tester_Class_1[var_34][var_34])[var_34][var_34]).var_31 = ((new Tester_Class_0[var_34][var_34])[var_34])[var_34]).var_1 ^= (((new Tester_Class_1[var_34][var_34])[var_34][var_34]).var_31 = (Tester_Class_0)var_33).var_1; + ((new Tester_Class_1[var_34])[var_34]).var_31 = (((new Tester_Class_1[var_34])[((new Tester_Class_1[var_34][var_34])[var_34][var_34]).var_1 ? var_34 : var_34]).var_31 = (((new Tester_Class_1[(byte)2.4941036E38F])[var_34]).var_31 = (Tester_Class_0)arg_1)); + } + + public static int[][] func_2(long arg_0, final float arg_1, short arg_2, final double arg_3) + { + long var_35; + { + arg_0++; + var_2 = true ? (byte)9.691601510156328E307 : (byte)"a".charAt(~ ((byte)arg_1)); + if (((new Tester_Class_1[(byte)'\\'][(byte)arg_2])[(byte)arg_2][(byte)arg_0]).var_29) + { + arg_2++; + } + else + { + Tester_Class_0.var_2 = arg_2; + var_30 = arg_2; + Tester_Class_0.var_2 = arg_0; + } + arg_2 /= 157487965; + arg_2 -= func_2(~ ((byte)arg_0), (short)arg_3, (byte)+2.2503214E38F); + } + arg_0--; + double var_36; + arg_0 <<= (arg_0 >>= (arg_0 = 'O')); + { + arg_0++; + --arg_0; + } + --arg_2; + ++arg_2; + "gbcrkn".length(); + var_30 = (short)7.14672E37F; + { + arg_0 %= (arg_0 >>= (arg_2 *= (byte)1.5835087622116814E308)) % arg_3; + var_36 = 'n'; + int[][] var_37 = new int[(byte)(double)arg_0][(byte)(arg_2 >>= 'o')]; + if ((byte)1390907656194158592L <= arg_2) + { + "uuoeps".indexOf("", 899321600); + } + else + { + var_36 = - ~ -arg_0; + } + short var_38 = var_5; + var_36 = ~arg_0 + (6482428938632186880L + 6995927649252739072L); + } + if (((new Tester_Class_1[(byte)arg_1][(byte)arg_2])[(new byte[(byte)arg_0])[(byte)var_5]][(byte)'s']).var_1 = false) + { + ++arg_0; + } + else + { + ((new Tester_Class_1[(byte)2.7176027E38F])[(byte)((arg_2 -= 2.595396436487417E307) % 'p')]).var_1 ^= ((new Tester_Class_1[(byte)4.393706E36F])[false ? (byte)4826960994531808256L : (byte)arg_0]).var_29; + } + int var_39 = 0; + arg_2 <<= 'Y'; + while (var_39 < 1 && false) + { + arg_0++; + var_39++; + Object var_40; + ((Tester_Class_0)(var_40 = new long[(byte)3.285531E38F])).var_3 += var_39; + } + Object var_41; + "w".substring(1359453539); + return new int[(byte)((arg_2 /= 4.143015135482291E307) - 3.2659622E38F)][(byte)++arg_2]; + } + + public String toString() + { + String result = "[\n"; + result += "Tester_Class_1.var_5 = "; result += Test6712835.Printer.print(var_5); + result += "\n"; + result += "Tester_Class_1.var_30 = "; result += Test6712835.Printer.print(var_30); + result += "\n"; + result += "Tester_Class_1.var_4 = "; result += Test6712835.Printer.print(var_4); + result += "\n"; + result += "Tester_Class_1.var_1 = "; result += Test6712835.Printer.print(var_1); + result += "\n"; + result += "Tester_Class_1.var_29 = "; result += Test6712835.Printer.print(var_29); + result += "\n"; + result += "Tester_Class_1.var_2 = "; result += Test6712835.Printer.print(var_2); + result += "\n"; + result += "Tester_Class_1.var_3 = "; result += Test6712835.Printer.print(var_3); + result += "\n"; + result += "Tester_Class_1.var_31 = "; result += Test6712835.Printer.print(var_31); + result += ""; + result += "\n]"; + return result; + } +} + + +final class Tester_Class_2 extends Tester_Class_0 { + static float var_44 = 2.7867988E38F; + static byte var_45; + static long var_46 = 4319798868443575296L; + + + public Tester_Class_2() + { + Tester_Class_1.var_30 = (byte)3.1718026E38F; + var_45 = (new byte[(byte)'o'])[var_45 = (byte)Tester_Class_0.var_5]; + Tester_Class_1.var_30 = (Tester_Class_1.var_30 = Tester_Class_0.var_5); + if (true) + { + ++var_46; + boolean var_51 = false ? (var_1 &= !var_1) : true; + --var_46; + if (false) + { + var_3 *= 6.882788442363403E307; + } + else + { + Tester_Class_0.var_2 = '`'; + } + final float var_52 = (var_1 ^= var_1 || (var_1 &= false)) | (var_51 |= (var_51 &= false)) ? (byte)4.751813848964725E307 : (var_3 *= var_5); + (false ? var_4 : var_4).startsWith("j" + var_4); + var_46++; + var_3 %= Tester_Class_1.var_5; + } + else + { + Tester_Class_1.var_30 = (var_45 = (var_45 = (var_45 = (byte)Tester_Class_1.var_5))); + Tester_Class_1.var_2 = (var_3 -= ~ ((byte)var_46) - 2018787280); + Tester_Class_1.var_30 = (Tester_Class_1.var_30 = (Tester_Class_1.var_30 = (Tester_Class_1.var_30 = var_5))); + } + char var_53; + ++var_46; + short var_54 = 138; + ++var_46; + var_2 = 1435782089; + Tester_Class_0.var_2 = var_46; + } + + + + + protected final boolean func_0(final boolean arg_0, final boolean arg_1) + { + var_2 = 2.6153986361247174E307; + var_45 = (var_45 = (var_45 = (var_45 = (var_45 = (byte)(var_44 += var_46))))); + var_46++; + long var_47 = 0L; + var_3 -= + ((byte)(~var_46 * ~var_46 ^ var_46 % 1910419567)); + do + { + ++var_46; + var_47++; + char var_48 = 'b'; + } while (var_47 < 2); + new Tester_Class_1().var_31 = ((new Tester_Class_1[var_45 = (byte)3.0853839E38F])[(new byte[var_45 = (byte)1.4974966426791287E308])[var_45 = (byte)Tester_Class_0.var_5]]).var_1 ? new Tester_Class_1() : new Tester_Class_1(); + var_45 = (var_45 = (byte)var_44); + double var_49 = 0; + var_45 = (byte)(Tester_Class_1.var_30 = Tester_Class_0.var_5); + while (((false ^ (var_1 &= var_1) | (var_1 |= arg_0) ? new Tester_Class_1() : new Tester_Class_1()).var_29 ? var_1 : false && (var_1 ^= arg_0)) && (var_49 < 3 && (true ? new Tester_Class_1() : new Tester_Class_1()).var_1)) + { + var_45 = (var_45 = (var_45 = (var_45 = (var_45 = (byte)1.933612E38F)))); + var_49++; + var_45 = (var_45 = (var_45 = (var_45 = (byte)685709636))); + long var_50; + } + var_45 = (var_45 = (var_45 = (byte)var_5)); + var_46--; + return true; + } + + public String toString() + { + String result = "[\n"; + result += "Tester_Class_2.var_46 = "; result += Test6712835.Printer.print(var_46); + result += "\n"; + result += "Tester_Class_2.var_2 = "; result += Test6712835.Printer.print(var_2); + result += "\n"; + result += "Tester_Class_2.var_3 = "; result += Test6712835.Printer.print(var_3); + result += "\n"; + result += "Tester_Class_2.var_44 = "; result += Test6712835.Printer.print(var_44); + result += "\n"; + result += "Tester_Class_2.var_5 = "; result += Test6712835.Printer.print(var_5); + result += "\n"; + result += "Tester_Class_2.var_45 = "; result += Test6712835.Printer.print(var_45); + result += "\n"; + result += "Tester_Class_2.var_4 = "; result += Test6712835.Printer.print(var_4); + result += "\n"; + result += "Tester_Class_2.var_1 = "; result += Test6712835.Printer.print(var_1); + result += ""; + result += "\n]"; + return result; + } +} + + +class Tester_Class_3 extends Tester_Class_0 { + static boolean var_55 = true; + short var_56; + char var_57 = (char)723612093; + final static byte var_58 = 118; + static float var_59 = true ? -2818156175448416256L : - - (Tester_Class_2.var_44 += var_58); + static Tester_Class_1 var_60; + byte var_61 = 112; + Tester_Class_2[] var_62; + static short var_63 = 19813; + static double var_64 = (var_55 = true) ? (Tester_Class_1.var_2 = 'M') : Tester_Class_2.var_46; + + + public Tester_Class_3() + { + var_56 = var_58; + Tester_Class_1 var_65 = var_60 = (var_60 = (var_60 = (new Tester_Class_1[var_61 |= '\\'])[(var_1 = true) || var_55 ? var_58 : var_61])); + var_64 /= 1253632965 * '`'; + Tester_Class_2.var_46 >>>= var_58; + (((var_61 = var_58) * (var_55 ? 1641980027 : var_63) >= 1490788063 ? var_65 : var_65).var_29 ? var_65 : var_65).var_31 = (new Tester_Class_2[var_58])[var_58]; + ++var_63; + new String(); + var_64 += var_55 ? (var_61 >>>= 'Q') : (var_63 <<= var_57); + ((new Tester_Class_2().var_3 >= Tester_Class_2.var_46 ? !var_55 : var_4.startsWith(var_4, 586086925)) ? "gjsdhuop" : "juqrt").substring(("pm" + ((new Tester_Class_2[var_61][var_58])[var_58][var_58]).var_4).codePointBefore((~var_61 << 3032688286897486848L) - Tester_Class_1.var_5), (var_61 += 4.0796373033184064E306) >> (Tester_Class_2.var_46 >>> var_58)); + var_63 -= (var_63 ^= var_57); + var_64 = var_5 - (Tester_Class_2.var_46 *= var_57); + Tester_Class_2.var_46 &= 7544159045139005440L; + var_55 |= false; + Tester_Class_2.var_46 = var_61; + } + + + + + public String toString() + { + String result = "[\n"; + result += "Tester_Class_3.var_57 = "; result += Test6712835.Printer.print(var_57); + result += "\n"; + result += "Tester_Class_3.var_62 = "; result += Test6712835.Printer.print(var_62); + result += "\n"; + result += "Tester_Class_3.var_2 = "; result += Test6712835.Printer.print(var_2); + result += "\n"; + result += "Tester_Class_3.var_64 = "; result += Test6712835.Printer.print(var_64); + result += "\n"; + result += "Tester_Class_3.var_3 = "; result += Test6712835.Printer.print(var_3); + result += "\n"; + result += "Tester_Class_3.var_59 = "; result += Test6712835.Printer.print(var_59); + result += "\n"; + result += "Tester_Class_3.var_5 = "; result += Test6712835.Printer.print(var_5); + result += "\n"; + result += "Tester_Class_3.var_56 = "; result += Test6712835.Printer.print(var_56); + result += "\n"; + result += "Tester_Class_3.var_63 = "; result += Test6712835.Printer.print(var_63); + result += "\n"; + result += "Tester_Class_3.var_58 = "; result += Test6712835.Printer.print(var_58); + result += "\n"; + result += "Tester_Class_3.var_61 = "; result += Test6712835.Printer.print(var_61); + result += "\n"; + result += "Tester_Class_3.var_4 = "; result += Test6712835.Printer.print(var_4); + result += "\n"; + result += "Tester_Class_3.var_1 = "; result += Test6712835.Printer.print(var_1); + result += "\n"; + result += "Tester_Class_3.var_55 = "; result += Test6712835.Printer.print(var_55); + result += "\n"; + result += "Tester_Class_3.var_60 = "; result += Test6712835.Printer.print(var_60); + result += ""; + result += "\n]"; + return result; + } +} + + +final class Tester_Class_4 { + static long var_66; + final long var_67 = 7113579489152300032L * 985636454; + int[] var_68; + Tester_Class_3 var_69; + final long var_70 = Tester_Class_2.var_46 <<= Tester_Class_1.var_5; + byte var_71 = Tester_Class_3.var_58; + + + public Tester_Class_4() + { + Tester_Class_2.var_46++; + (var_69 = new Tester_Class_3()).var_61 += (!true | (Tester_Class_3.var_55 ^= Tester_Class_3.var_55) ? new Tester_Class_3() : new Tester_Class_3()).var_61; + final String[][] var_79 = new String[var_71 >>= (Tester_Class_3.var_63 ^= 'm')][((Tester_Class_3)(new Tester_Class_1().var_31 = new Tester_Class_2())).var_61 >>= (var_71 >>>= (Tester_Class_2.var_46 += 465205188010511360L))]; + ++(var_69 = (var_69 = (var_69 = (Tester_Class_3)(new Object[Tester_Class_3.var_58][var_71])[Tester_Class_3.var_58][var_71]))).var_61; + (((new Tester_Class_2[var_71][Tester_Class_3.var_58])[Tester_Class_2.var_45 = var_71])[var_71]).var_3 += (Tester_Class_2.var_46 <<= (Tester_Class_2.var_46 /= 9.03047405760868E307) >> (new Tester_Class_2().var_1 ? 2099696051 : Tester_Class_3.var_63)); + Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = new Tester_Class_1()))); + char var_80; + Tester_Class_3.var_64 += 355712574; + ++Tester_Class_2.var_46; + } + + + + + private final static Tester_Class_1 func_0(boolean arg_0, double arg_1) + { + Tester_Class_3.var_60 = (Tester_Class_3.var_60 = new Tester_Class_1()); + byte var_72 = (byte)Tester_Class_2.var_46; + Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = new Tester_Class_1())))); + float var_73 = 0F; + "flfix".offsetByCodePoints((Tester_Class_3.var_63 ^= 3286104714651747328L) + ((Tester_Class_3)(new Tester_Class_0[var_72])[var_72]).var_61, Tester_Class_0.var_5 + Tester_Class_3.var_58); + while (var_73 < 2 && (false ? (Tester_Class_3.var_60 = new Tester_Class_1()) : (Tester_Class_1)(new Tester_Class_0[var_72])[var_72]).var_29) + { + ((Tester_Class_3)(Tester_Class_0)(new Object[var_72])[Tester_Class_3.var_58]).var_61 >>= ((new Tester_Class_4[var_72])[var_72]).var_67; + var_73++; + new String("blod"); + --var_72; + } + ((new Tester_Class_4[Tester_Class_3.var_58][var_72])[new Tester_Class_3().var_61][Tester_Class_3.var_58]).var_69 = new Tester_Class_3(); + float var_74 = (! ("dkcx".lastIndexOf(Tester_Class_1.var_5 >> - (var_72 >>>= 1433506903139345408L)) == Tester_Class_2.var_46) ? 'O' : 'e' - new Tester_Class_2().var_3) * ~ (var_72 ^= var_72); + Tester_Class_3.var_60 = !true ? new Tester_Class_1() : (new Tester_Class_1[Tester_Class_3.var_58])[var_72]; + ((arg_0 &= Tester_Class_3.var_55 | (Tester_Class_3.var_60 = new Tester_Class_1()).var_29) ? (Tester_Class_3.var_60 = (Tester_Class_1)(new Tester_Class_1().var_31 = new Tester_Class_2())) : (Tester_Class_3.var_60 = (new Tester_Class_1[var_72])[Tester_Class_3.var_58])).var_31 = (new Tester_Class_3[var_72 |= 546982927])[Tester_Class_3.var_58]; + long var_75 = 0L; + final double var_76 = +arg_1; + while (var_75 < 1) + { + short var_77; + var_75++; + new Tester_Class_3().var_57 = (false & true ? new Tester_Class_3() : new Tester_Class_3()).var_57; + (Tester_Class_3.var_60 = (new Tester_Class_1[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_31 = (new Tester_Class_2[Tester_Class_3.var_58][var_72])[var_72][var_72]; + } + Tester_Class_3.var_64 *= (arg_0 ? (Tester_Class_3.var_55 ^= (arg_0 ^= arg_0)) & ! (Tester_Class_3.var_55 = arg_0) : arg_0) ^ new Tester_Class_1().var_29 ? ++((new Tester_Class_3[var_72][var_72])[(new byte[Tester_Class_3.var_58])[Tester_Class_3.var_58]][(((new Tester_Class_4[var_72][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_3.var_58]).var_69 = (new Tester_Class_3[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_61]).var_57 : 'C'; + long var_78; + var_74 %= (Tester_Class_3.var_55 |= (arg_0 = (arg_0 ^= (arg_0 &= !arg_0)))) ? new Tester_Class_3().var_61 : (Tester_Class_3.var_63 ^= var_72); + arg_1 /= (Tester_Class_2.var_46 &= 'W'); + --(((new Tester_Class_4[var_72])[var_72]).var_69 = (((new Tester_Class_4[var_72])[var_72]).var_69 = new Tester_Class_3())).var_61; + return (new Tester_Class_1[var_72][Tester_Class_3.var_58])[var_72][new Tester_Class_3().var_61]; + } + + public String toString() + { + String result = "[\n"; + result += "Tester_Class_4.var_68 = "; result += Test6712835.Printer.print(var_68); + result += "\n"; + result += "Tester_Class_4.var_66 = "; result += Test6712835.Printer.print(var_66); + result += "\n"; + result += "Tester_Class_4.var_67 = "; result += Test6712835.Printer.print(var_67); + result += "\n"; + result += "Tester_Class_4.var_70 = "; result += Test6712835.Printer.print(var_70); + result += "\n"; + result += "Tester_Class_4.var_71 = "; result += Test6712835.Printer.print(var_71); + result += "\n"; + result += "Tester_Class_4.var_69 = "; result += Test6712835.Printer.print(var_69); + result += ""; + result += "\n]"; + return result; + } +} + + +final class Tester_Class_5 extends Tester_Class_0 { + static boolean var_81; + final int var_82 = 174395841; + int var_83; + byte var_84; + boolean var_85 = Tester_Class_3.var_55; + static boolean var_86 = Tester_Class_3.var_55; + + + public Tester_Class_5() + { + { + short var_87 = (new short[Tester_Class_3.var_58][var_84 = Tester_Class_3.var_58])[(((new Tester_Class_4[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_69 = (Tester_Class_3)(Tester_Class_0)(new Object[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_61][Tester_Class_3.var_58]; + Tester_Class_4 var_88 = var_85 ^ (var_81 = false) ? (new Tester_Class_4[Tester_Class_3.var_58])[Tester_Class_3.var_58] : (new Tester_Class_4[Tester_Class_3.var_58])[Tester_Class_3.var_58]; + { + ++var_87; + } + short var_89; + (var_88.var_69 = (new Tester_Class_3[var_88.var_71][var_88.var_71])[var_88.var_71][var_88.var_71]).var_61 += (((Tester_Class_2)(new Tester_Class_1().var_31 = new Tester_Class_2())).var_3 = Tester_Class_3.var_58); + var_88 = var_88; + } + { + ++Tester_Class_2.var_46; + --Tester_Class_2.var_46; + } + { + Tester_Class_2.var_46++; + Tester_Class_3.var_64 /= Tester_Class_3.var_59; + ((Tester_Class_4)(new Object[Tester_Class_2.var_45 = Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_71 %= (var_3 /= 3637233239489444864L); + ++Tester_Class_2.var_46; + } + new Tester_Class_3().var_57++; + var_85 &= (Tester_Class_3.var_55 |= false); + Tester_Class_3.var_60 = new Tester_Class_1(); + Tester_Class_2.var_46++; + ((Tester_Class_3)(true ? (new Tester_Class_2[Tester_Class_3.var_58])[Tester_Class_3.var_58] : (new Tester_Class_0[Tester_Class_3.var_58])[Tester_Class_2.var_45 = Tester_Class_3.var_58])).var_57 *= ((new Tester_Class_3[Tester_Class_3.var_58])[(byte)'`']).var_57; + var_3 += (int)Tester_Class_3.var_59 ^ (Tester_Class_2.var_46 -= Tester_Class_2.var_46) % ~((new Tester_Class_4[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_71; + ++Tester_Class_2.var_46; + --Tester_Class_2.var_46; + var_83 = Tester_Class_3.var_58; + } + + + + + public String toString() + { + String result = "[\n"; + result += "Tester_Class_5.var_82 = "; result += Test6712835.Printer.print(var_82); + result += "\n"; + result += "Tester_Class_5.var_83 = "; result += Test6712835.Printer.print(var_83); + result += "\n"; + result += "Tester_Class_5.var_2 = "; result += Test6712835.Printer.print(var_2); + result += "\n"; + result += "Tester_Class_5.var_3 = "; result += Test6712835.Printer.print(var_3); + result += "\n"; + result += "Tester_Class_5.var_5 = "; result += Test6712835.Printer.print(var_5); + result += "\n"; + result += "Tester_Class_5.var_84 = "; result += Test6712835.Printer.print(var_84); + result += "\n"; + result += "Tester_Class_5.var_4 = "; result += Test6712835.Printer.print(var_4); + result += "\n"; + result += "Tester_Class_5.var_1 = "; result += Test6712835.Printer.print(var_1); + result += "\n"; + result += "Tester_Class_5.var_81 = "; result += Test6712835.Printer.print(var_81); + result += "\n"; + result += "Tester_Class_5.var_85 = "; result += Test6712835.Printer.print(var_85); + result += "\n"; + result += "Tester_Class_5.var_86 = "; result += Test6712835.Printer.print(var_86); + result += ""; + result += "\n]"; + return result; + } +} + + +class Tester_Class_6 extends Tester_Class_0 { + long var_90 = 8467263472031702016L; + final static int var_91 = 1648594448 * ']'; + char var_92 = 'x'; + short var_93 = Tester_Class_3.var_63; + Tester_Class_4 var_94; + String[] var_95; + static short var_96 = Tester_Class_3.var_63 -= 83376045 << 40225606; + final static double var_97 = 5.387227213380301E307; + final static short var_98 = Tester_Class_3.var_63 &= var_91; + byte var_99 = 44; + + + public Tester_Class_6() + { + (Tester_Class_3.var_60 = (Tester_Class_1)(new Object[Tester_Class_3.var_58][var_99])[Tester_Class_3.var_58][var_99]).var_31 = true | true ? (Tester_Class_5)(new Object[var_99])[Tester_Class_3.var_58] : (Tester_Class_5)(new Object[Tester_Class_3.var_58])[var_99]; + var_92 &= 'p'; + Tester_Class_5.var_81 = (((new Tester_Class_1[var_99][Tester_Class_3.var_58])[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_29; + { + { + ++Tester_Class_2.var_46; + Tester_Class_3.var_2 = var_98; + var_93 -= var_96; + } + Tester_Class_2.var_46--; + { + (var_5 == (((Tester_Class_3)(new Tester_Class_0[var_99])[Tester_Class_3.var_58]).var_61 /= var_5) ? "fsajxeuao".replace('s', 'K') : var_4).substring('e' >>> var_5).toLowerCase(); + } + var_93 %= ((new Tester_Class_6[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_90; + var_93 /= var_93; + if (Tester_Class_5.var_86) + { + (var_94 = (new Tester_Class_4[var_99])[var_99]).var_69 = (new Tester_Class_3[var_99])[var_99 %= -var_90]; + } + else + { + --var_96; + } + var_93 *= 'O'; + final long var_103 = 7573900518735055872L; + --Tester_Class_3.var_63; + } + Tester_Class_3.var_64 /= var_93; + if (true) + { + --Tester_Class_2.var_46; + Tester_Class_5 var_104; + final double var_105 = Tester_Class_3.var_64 += Tester_Class_5.var_86 & (new Tester_Class_2().var_1 & ((Tester_Class_3.var_55 = (var_1 ^= Tester_Class_5.var_86) & false) & (Tester_Class_5.var_81 = Tester_Class_5.var_86))) ? (byte)'g' : var_99; + Tester_Class_3.var_64 *= var_99; + } + else + { + char var_106 = var_92 -= Tester_Class_3.var_58; + } + double[] var_107 = ((new double[Tester_Class_3.var_58][var_99][var_99])[var_99])[false ? Tester_Class_3.var_58 : Tester_Class_3.var_58]; + var_99 <<= (Tester_Class_3.var_63 >>= Tester_Class_3.var_58); + ++var_99; + } + + + + + final static byte func_0(final byte arg_0, final char arg_1, final Tester_Class_5[] arg_2) + { + ((Tester_Class_4)(new Object[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][arg_0]).var_69 = (Tester_Class_3)(new Tester_Class_0[Tester_Class_3.var_58])[Tester_Class_2.var_45 = Tester_Class_3.var_58]; + long var_100 = 0L; + Tester_Class_3.var_64 /= (Tester_Class_5.var_86 = true) || 'o' > (Tester_Class_3.var_63 -= (float)arg_0) ? var_98 : 1.7875238E38F; + do + { + Tester_Class_3.var_64 %= var_5; + var_100++; + Tester_Class_3.var_64 += var_96 + 'r'; + } while (true && (var_100 < 1 && (new Tester_Class_1().var_29 ? new Tester_Class_1() : (new Tester_Class_1[arg_0][Tester_Class_3.var_58])[arg_0][Tester_Class_3.var_58]).var_29)); + (Tester_Class_3.var_55 ^ (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = new Tester_Class_1()))).var_29 ? new Tester_Class_3() : new Tester_Class_3()).var_57 = ((((new Tester_Class_6[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_3.var_58]).var_94 = (((new Tester_Class_6[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][arg_0]).var_94 = (new Tester_Class_4[Tester_Class_3.var_58][arg_0])[Tester_Class_3.var_58][Tester_Class_3.var_58])).var_69 = new Tester_Class_3()).var_57; + final double var_101 = 1.6798216578519203E308; + Tester_Class_3.var_60 = (Tester_Class_3.var_60 = false ? new Tester_Class_1() : (Tester_Class_3.var_60 = new Tester_Class_1())); + Tester_Class_2 var_102 = new Tester_Class_2(); + return Tester_Class_3.var_58; + } + + public String toString() + { + String result = "[\n"; + result += "Tester_Class_6.var_92 = "; result += Test6712835.Printer.print(var_92); + result += "\n"; + result += "Tester_Class_6.var_91 = "; result += Test6712835.Printer.print(var_91); + result += "\n"; + result += "Tester_Class_6.var_95 = "; result += Test6712835.Printer.print(var_95); + result += "\n"; + result += "Tester_Class_6.var_90 = "; result += Test6712835.Printer.print(var_90); + result += "\n"; + result += "Tester_Class_6.var_2 = "; result += Test6712835.Printer.print(var_2); + result += "\n"; + result += "Tester_Class_6.var_97 = "; result += Test6712835.Printer.print(var_97); + result += "\n"; + result += "Tester_Class_6.var_3 = "; result += Test6712835.Printer.print(var_3); + result += "\n"; + result += "Tester_Class_6.var_5 = "; result += Test6712835.Printer.print(var_5); + result += "\n"; + result += "Tester_Class_6.var_93 = "; result += Test6712835.Printer.print(var_93); + result += "\n"; + result += "Tester_Class_6.var_96 = "; result += Test6712835.Printer.print(var_96); + result += "\n"; + result += "Tester_Class_6.var_98 = "; result += Test6712835.Printer.print(var_98); + result += "\n"; + result += "Tester_Class_6.var_99 = "; result += Test6712835.Printer.print(var_99); + result += "\n"; + result += "Tester_Class_6.var_4 = "; result += Test6712835.Printer.print(var_4); + result += "\n"; + result += "Tester_Class_6.var_1 = "; result += Test6712835.Printer.print(var_1); + result += "\n"; + result += "Tester_Class_6.var_94 = "; result += Test6712835.Printer.print(var_94); + result += ""; + result += "\n]"; + return result; + } +} + + +abstract class Tester_Class_7 { + final static char var_108 = '_'; + static Tester_Class_3 var_109; + final short var_110 = 4360; + short var_111; + Object var_112; + Tester_Class_4 var_113; + static Tester_Class_5 var_114; + final short var_115 = Tester_Class_6.var_96; + final static float var_116 = Tester_Class_3.var_59; + + + public Tester_Class_7() + { + --Tester_Class_2.var_46; + --Tester_Class_6.var_96; + var_113 = (new Tester_Class_4[new Tester_Class_6().var_99])[Tester_Class_3.var_58]; + --Tester_Class_2.var_46; + Tester_Class_6.var_96--; + Tester_Class_3.var_63 -= 'i'; + if (!Tester_Class_5.var_86) + { + Tester_Class_3.var_64 %= var_116; + if ((Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)(Tester_Class_0)(var_112 = "yosyghjm"))).var_29) + { + Tester_Class_2.var_46++; + } + else + { + (var_114 = (var_114 = (Tester_Class_5)(Tester_Class_0)(var_112 = "bxt"))).var_83 = (Tester_Class_2.var_45 = (Tester_Class_2.var_45 = Tester_Class_3.var_58)); + } + var_114 = (var_114 = (var_114 = (var_114 = (var_114 = (var_114 = (Tester_Class_5)(var_112 = "blrobgg")))))); + var_113 = (((Tester_Class_6)(var_112 = "popebwfp")).var_94 = (new Tester_Class_4[Tester_Class_3.var_58])[Tester_Class_3.var_58]); + } + else + { + Tester_Class_3.var_60 = new Tester_Class_1(); + } + final Tester_Class_6 var_122 = new Tester_Class_6(); + var_122.var_92 &= (var_122.var_92 |= var_108); + ((new Tester_Class_5[var_122.var_99])[((new Tester_Class_3[Tester_Class_3.var_58])[var_122.var_99--]).var_61]).var_83 = 1708230145; + } + + + + public boolean equals(Object obj) + { + (((Tester_Class_5.var_81 = (Tester_Class_5.var_81 = false)) ? (Tester_Class_3.var_55 &= false) : !Tester_Class_3.var_55 & ((Tester_Class_1)obj).var_29) ? (new Tester_Class_2[Tester_Class_3.var_58])[Tester_Class_3.var_58] : (Tester_Class_2)obj).equals((Tester_Class_5.var_86 |= Tester_Class_3.var_55) | (Tester_Class_3.var_55 = Tester_Class_3.var_55) ? obj : (Tester_Class_6)(Tester_Class_0)obj); + Tester_Class_3.var_64 *= 2.8258473339654136E307; + { + final int var_118 = 1248523063; + short var_119 = 30906; + Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)obj); + ((Tester_Class_6)(((Tester_Class_1)obj).var_31 = ((var_113 = (Tester_Class_4)obj).var_69 = (Tester_Class_3)obj))).var_94 = (var_113 = (Tester_Class_4)(var_112 = (Tester_Class_1)obj)); + } + final Tester_Class_1 var_120 = false ^ (((Tester_Class_1)obj).var_1 = !true) ^ (((Tester_Class_6)(Tester_Class_0)obj).var_92 *= (((Tester_Class_3)obj).var_57 |= (Tester_Class_2.var_46 >>= 6986775136305733632L))) < (byte)Tester_Class_6.var_97 ? (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)obj)) : (true ? (Tester_Class_1)obj : (Tester_Class_1)obj); + (var_114 = (var_114 = (Tester_Class_5)obj)).var_83 = (((new Tester_Class_6[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_92 &= ((Tester_Class_4)obj).var_70 << (Tester_Class_2.var_45 = Tester_Class_3.var_58)); + var_114 = (Tester_Class_5)obj; + obj = ((Tester_Class_3.var_60 = var_120).var_29 ? false : false) ? (new Tester_Class_6[Tester_Class_3.var_58])[Tester_Class_3.var_58] : obj; + (var_120.var_29 ? (Tester_Class_6)(obj = (Tester_Class_3.var_60 = var_120)) : (new Tester_Class_6[Tester_Class_3.var_58])[((Tester_Class_3)obj).var_61 ^= Tester_Class_6.var_91]).var_90 ^= 2127530040436251648L; + Object var_121; + return (new boolean[Tester_Class_3.var_58])[((var_113 = (Tester_Class_4)obj).var_69 = (var_109 = (new Tester_Class_3[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_3.var_58])).var_61]; + } + + + public String toString() + { + String result = "[\n"; + result += "Tester_Class_7.var_108 = "; result += Test6712835.Printer.print(var_108); + result += "\n"; + result += "Tester_Class_7.var_116 = "; result += Test6712835.Printer.print(var_116); + result += "\n"; + result += "Tester_Class_7.var_110 = "; result += Test6712835.Printer.print(var_110); + result += "\n"; + result += "Tester_Class_7.var_111 = "; result += Test6712835.Printer.print(var_111); + result += "\n"; + result += "Tester_Class_7.var_115 = "; result += Test6712835.Printer.print(var_115); + result += "\n"; + result += "Tester_Class_7.var_114 = "; result += Test6712835.Printer.print(var_114); + result += "\n"; + result += "Tester_Class_7.var_113 = "; result += Test6712835.Printer.print(var_113); + result += "\n"; + result += "Tester_Class_7.var_109 = "; result += Test6712835.Printer.print(var_109); + result += "\n"; + result += "Tester_Class_7.var_112 = "; result += Test6712835.Printer.print(var_112); + result += ""; + result += "\n]"; + return result; + } +} + + +class Tester_Class_8 extends Tester_Class_7 { + static char var_123; + Tester_Class_4 var_124; + static short var_125; + + + public Tester_Class_8() + { + { + Tester_Class_3.var_64 -= (Tester_Class_2.var_46 *= Tester_Class_3.var_64); + { + Tester_Class_2.var_46--; + } + ++Tester_Class_3.var_63; + Tester_Class_5.var_86 |= true; + Tester_Class_6.var_96--; + } + "w".indexOf(312689020); + if (false) + { + (Tester_Class_7.var_114 = (new Tester_Class_5[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_83 = 'I'; + } + else + { + --Tester_Class_6.var_96; + } + switch (Tester_Class_5.var_86 ? Tester_Class_3.var_58 : Tester_Class_3.var_58) + { + case 95: + + case 35: + + } + Tester_Class_6.var_96--; + Tester_Class_3.var_64 *= 4.516167673347119E307; + --Tester_Class_3.var_63; + { + int var_126; + } + Tester_Class_3.var_60 = new Tester_Class_1(); + Tester_Class_2.var_46++; + ((new Tester_Class_6[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_99 &= Tester_Class_6.var_91; + ((new Tester_Class_1[((new Tester_Class_4[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_71])[((Tester_Class_3)(var_112 = "fsmtm")).var_61]).var_31 = (Tester_Class_2)(new Tester_Class_0[Tester_Class_3.var_58])[Tester_Class_3.var_58]; + } + + + + + public String toString() + { + String result = "[\n"; + result += "Tester_Class_8.var_108 = "; result += Test6712835.Printer.print(var_108); + result += "\n"; + result += "Tester_Class_8.var_123 = "; result += Test6712835.Printer.print(var_123); + result += "\n"; + result += "Tester_Class_8.var_116 = "; result += Test6712835.Printer.print(var_116); + result += "\n"; + result += "Tester_Class_8.var_110 = "; result += Test6712835.Printer.print(var_110); + result += "\n"; + result += "Tester_Class_8.var_111 = "; result += Test6712835.Printer.print(var_111); + result += "\n"; + result += "Tester_Class_8.var_115 = "; result += Test6712835.Printer.print(var_115); + result += "\n"; + result += "Tester_Class_8.var_125 = "; result += Test6712835.Printer.print(var_125); + result += "\n"; + result += "Tester_Class_8.var_114 = "; result += Test6712835.Printer.print(var_114); + result += "\n"; + result += "Tester_Class_8.var_113 = "; result += Test6712835.Printer.print(var_113); + result += "\n"; + result += "Tester_Class_8.var_124 = "; result += Test6712835.Printer.print(var_124); + result += "\n"; + result += "Tester_Class_8.var_109 = "; result += Test6712835.Printer.print(var_109); + result += "\n"; + result += "Tester_Class_8.var_112 = "; result += Test6712835.Printer.print(var_112); + result += ""; + result += "\n]"; + return result; + } +} + + +final class Tester_Class_9 { + final static String var_127 = "pxk"; + Tester_Class_2 var_128; + final static char var_129 = '\\'; + static float var_130; + static boolean var_131; + final static float var_132 = Tester_Class_3.var_59; + static Tester_Class_0 var_133; + boolean[] var_134; + + + public Tester_Class_9() + { + Tester_Class_2.var_44 -= Tester_Class_3.var_58; + Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (new Tester_Class_1[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_3.var_58])); + { + Tester_Class_8 var_136; + } + ++Tester_Class_2.var_46; + Tester_Class_6.var_96--; + var_128 = (var_128 = (var_128 = (Tester_Class_2)(var_133 = (new Tester_Class_1[Tester_Class_3.var_58])[Tester_Class_3.var_58]))); + ++Tester_Class_6.var_96; + ++Tester_Class_2.var_46; + Tester_Class_4 var_137; + var_128 = (var_128 = (new Tester_Class_2[Tester_Class_3.var_58])[Tester_Class_3.var_58]); + (Tester_Class_8.var_114 = (Tester_Class_8.var_114 = (new Tester_Class_5[Tester_Class_3.var_58])[Tester_Class_3.var_58])).var_83 = (((new Tester_Class_4[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_3.var_58]).var_69 = (new Tester_Class_3[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_3.var_58]).var_57++; + Tester_Class_2.var_46++; + } + + + + + protected static short func_1() + { + { + Tester_Class_3.var_63--; + } + Tester_Class_3.var_64 *= Tester_Class_2.var_46; + short var_135; + Tester_Class_3.var_64 -= Tester_Class_6.var_96; + return new Tester_Class_6().var_93; + } + + public String toString() + { + String result = "[\n"; + result += "Tester_Class_9.var_129 = "; result += Test6712835.Printer.print(var_129); + result += "\n"; + result += "Tester_Class_9.var_134 = "; result += Test6712835.Printer.print(var_134); + result += "\n"; + result += "Tester_Class_9.var_130 = "; result += Test6712835.Printer.print(var_130); + result += "\n"; + result += "Tester_Class_9.var_132 = "; result += Test6712835.Printer.print(var_132); + result += "\n"; + result += "Tester_Class_9.var_131 = "; result += Test6712835.Printer.print(var_131); + result += "\n"; + result += "Tester_Class_9.var_127 = "; result += Test6712835.Printer.print(var_127); + result += "\n"; + result += "Tester_Class_9.var_128 = "; result += Test6712835.Printer.print(var_128); + result += "\n"; + result += "Tester_Class_9.var_133 = "; result += Test6712835.Printer.print(var_133); + result += ""; + result += "\n]"; + return result; + } +} + + +final class Tester_Class_10 extends Tester_Class_0 { + final static byte var_138 = 78; + Object var_139; + final static boolean var_140 = true; + float var_141 = 1.2816267E38F; + Tester_Class_8 var_142; + static Tester_Class_3 var_143; + short var_144 = var_1 ? (Tester_Class_6.var_96 &= 8024552544994698240L) : Tester_Class_0.var_5; + final boolean var_145 = var_140; + long var_146; + float[] var_147; + + + public Tester_Class_10() + { + "xuc".codePointCount(new Tester_Class_6().var_99 / ((new Tester_Class_9().var_128 = new Tester_Class_2()).var_1 ? var_138 : (int)(Tester_Class_3.var_64 += Tester_Class_3.var_64)), 882345740); + Tester_Class_3.var_64 /= Tester_Class_9.var_132; + Tester_Class_9.var_127.indexOf((Tester_Class_7.var_114 = (Tester_Class_8.var_114 = (Tester_Class_5)(var_139 = "mcyagebtv"))).var_83 = var_145 ? (Tester_Class_2.var_45 = Tester_Class_3.var_58) : Tester_Class_6.var_96); + --Tester_Class_2.var_46; + final float var_148 = 3.0263434E38F; + ((Tester_Class_7.var_114 = (Tester_Class_5)(Tester_Class_9.var_133 = new Tester_Class_1())).var_85 & ((Tester_Class_1)(var_139 = new Tester_Class_6())).var_1 ? "gmxwrgik" : Tester_Class_9.var_127).compareTo(var_4); + --Tester_Class_2.var_46; + new Tester_Class_6(); + ++Tester_Class_2.var_46; + Tester_Class_3.var_60 = Tester_Class_5.var_86 ? new Tester_Class_1() : new Tester_Class_1(); + { + --Tester_Class_6.var_96; + ((Tester_Class_7)(var_139 = new Tester_Class_1().var_4)).var_112 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)(var_139 = "gugsy"))); + } + Tester_Class_9.var_133 = (Tester_Class_3.var_60 = new Tester_Class_1()); + if (var_140 & !var_140) + { + Tester_Class_6.var_96++; + } + else + { + Tester_Class_2.var_46++; + } + { + ++new Tester_Class_6().var_92; + } + Tester_Class_7.var_109 = (((new Tester_Class_4[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_69 = (var_143 = new Tester_Class_3())); + Tester_Class_3.var_63--; + } + + + + + public String toString() + { + String result = "[\n"; + result += "Tester_Class_10.var_147 = "; result += Test6712835.Printer.print(var_147); + result += "\n"; + result += "Tester_Class_10.var_146 = "; result += Test6712835.Printer.print(var_146); + result += "\n"; + result += "Tester_Class_10.var_3 = "; result += Test6712835.Printer.print(var_3); + result += "\n"; + result += "Tester_Class_10.var_141 = "; result += Test6712835.Printer.print(var_141); + result += "\n"; + result += "Tester_Class_10.var_5 = "; result += Test6712835.Printer.print(var_5); + result += "\n"; + result += "Tester_Class_10.var_144 = "; result += Test6712835.Printer.print(var_144); + result += "\n"; + result += "Tester_Class_10.var_138 = "; result += Test6712835.Printer.print(var_138); + result += "\n"; + result += "Tester_Class_10.var_1 = "; result += Test6712835.Printer.print(var_1); + result += "\n"; + result += "Tester_Class_10.var_140 = "; result += Test6712835.Printer.print(var_140); + result += "\n"; + result += "Tester_Class_10.var_145 = "; result += Test6712835.Printer.print(var_145); + result += "\n"; + result += "Tester_Class_10.var_139 = "; result += Test6712835.Printer.print(var_139); + result += "\n"; + result += "Tester_Class_10.var_142 = "; result += Test6712835.Printer.print(var_142); + result += "\n"; + result += "Tester_Class_10.var_2 = "; result += Test6712835.Printer.print(var_2); + result += "\n"; + result += "Tester_Class_10.var_4 = "; result += Test6712835.Printer.print(var_4); + result += "\n"; + result += "Tester_Class_10.var_143 = "; result += Test6712835.Printer.print(var_143); + result += ""; + result += "\n]"; + return result; + } +} + + +interface Tester_Interface_11 { + public Tester_Class_4 func_0(final int arg_0, final byte arg_1); + public Tester_Class_2 func_1(Tester_Class_5 arg_0, final Tester_Class_0 arg_1, final int arg_2); +} + +public class Test6712835 { + final boolean var_149 = false; + Tester_Class_8 var_150; + final long var_151 = 8058077687473630208L; + + + protected final Tester_Class_1 func_0(final Object arg_0, Tester_Class_3 arg_1, final Tester_Class_4 arg_2, int arg_3) + { + Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)arg_0)); + --Tester_Class_3.var_63; + (var_150 = (((new Tester_Class_10[arg_2.var_71])[(((Tester_Class_6)arg_0).var_94 = arg_2).var_71 &= Tester_Class_3.var_63 << ~arg_2.var_71]).var_142 = (var_150 = (((Tester_Class_10)arg_0).var_142 = (Tester_Class_8)arg_0)))).var_113 = arg_2; + Tester_Class_7.var_114 = (Tester_Class_7.var_114 = false ? (Tester_Class_5)arg_0 : (Tester_Class_5)arg_0); + ((((arg_1 = arg_1).var_1 |= "lgcrda".equalsIgnoreCase("ontlkst")) ? (Tester_Class_1)arg_0 : (Tester_Class_3.var_60 = (Tester_Class_1)arg_0)).var_29 ? (arg_1 = (Tester_Class_3)(((Tester_Class_7)arg_0).var_112 = (Tester_Class_9)arg_0)) : arg_1).var_57 >>>= ']'; + Tester_Class_8.var_114 = (Tester_Class_5)arg_0; + ((Tester_Class_3.var_55 &= (arg_1.var_1 = true)) ? (Tester_Class_6)(new Tester_Class_0[Tester_Class_3.var_58][Tester_Class_10.var_138])[Tester_Class_10.var_138][Tester_Class_10.var_138] : (Tester_Class_6)arg_0).var_94 = arg_2; + { + Tester_Class_3.var_55 &= ((Tester_Class_3.var_60 = new Tester_Class_1()).var_1 &= false); + Tester_Class_2.var_44 -= (arg_3 |= + ~6610561718704644096L); + ((Tester_Class_8)arg_0).var_113 = ((((Tester_Class_10)(Tester_Class_0)arg_0).var_142 = (var_150 = (Tester_Class_8)arg_0)).var_124 = arg_2); + (! (false | Tester_Class_5.var_86) ? (Tester_Class_10)arg_0 : (new Tester_Class_10[arg_1.var_61][arg_1.var_61])[Tester_Class_10.var_138][Tester_Class_10.var_138]).var_139 = ((Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)arg_0)).var_31 = (((Tester_Class_9)arg_0).var_128 = (((Tester_Class_9)arg_0).var_128 = (Tester_Class_2)arg_0))); + } + final Tester_Interface_11 var_152 = !((Tester_Class_1)arg_0).var_29 ^ Tester_Class_5.var_86 ? (new Tester_Interface_11[arg_2.var_71][arg_1.var_61])[arg_1.var_61][arg_1.var_61] : (new Tester_Interface_11[arg_2.var_71][arg_2.var_71])[Tester_Class_10.var_138][Tester_Class_3.var_58]; + Tester_Class_3.var_64 /= (arg_3 >>= ++((Tester_Class_6)(Tester_Class_0)arg_0).var_92) * Tester_Class_9.var_132; + Tester_Class_0 var_153 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)arg_0))))).var_31 = (((new Tester_Class_9[arg_1.var_61])[arg_1.var_61 *= 634692606]).var_128 = !false ? (Tester_Class_2)arg_0 : (Tester_Class_2)arg_0); + (Tester_Class_10.var_140 ? (Tester_Class_7)arg_0 : (var_150 = (Tester_Class_8)(Tester_Class_7)arg_0)).var_112 = Tester_Class_3.var_64 != ((((Tester_Class_10)(var_153 = (Tester_Class_8.var_114 = (Tester_Class_5)arg_0))).var_1 |= arg_1.var_1) ? (Tester_Class_6)var_153 : (Tester_Class_6)var_153).var_99-- ? (Tester_Class_7)((var_150 = (Tester_Class_8)arg_0).var_112 = (Tester_Class_10)var_153) : (Tester_Class_7)arg_0; + (((new Tester_Class_7[Tester_Class_10.var_138][arg_2.var_71])[Tester_Class_3.var_58])[arg_2.var_71]).var_112 = arg_0; + if (!false) + { + arg_3 <<= (Tester_Class_2.var_46 /= - ((byte)((Tester_Class_10)arg_0).var_144)) - ((Tester_Class_6)arg_0).var_99; + } + else + { + ((Tester_Class_7)(((Tester_Class_8)arg_0).var_112 = var_153)).var_113 = arg_2; + ((Tester_Class_9)arg_0).var_128 = (((Tester_Class_9)(((Tester_Class_7)arg_0).var_112 = (Tester_Class_7)arg_0)).var_128 = (((Tester_Class_9)arg_0).var_128 = (Tester_Class_2)arg_0)); + } + (((Tester_Class_10)arg_0).var_142 = (Tester_Class_8)arg_0).var_124 = (((Tester_Class_6)var_153).var_94 = arg_2); + final char var_154 = arg_1.var_57 %= ((Tester_Class_6)var_153).var_93--; + (true ? arg_1 : (arg_1 = arg_1)).equals(arg_0); + (Tester_Class_10.var_140 ? (new Tester_Class_6[Tester_Class_10.var_138])[arg_2.var_71] : (new Tester_Class_6[(Tester_Class_10.var_143 = arg_1).var_61])[arg_1.var_61]).var_94 = ((((new Tester_Class_7[arg_2.var_71][arg_1.var_61][Tester_Class_10.var_138])[Tester_Class_10.var_138])[arg_2.var_71 = arg_2.var_71][Tester_Class_10.var_138]).var_113 = (((Tester_Class_7)arg_0).var_113 = arg_2)); + Tester_Class_3.var_60 = ((Tester_Class_10)(((Tester_Class_7)arg_0).var_112 = (Tester_Class_7)(((Tester_Class_10)var_153).var_139 = new Tester_Class_6[Tester_Class_10.var_138][Tester_Class_10.var_138]))).var_1 ? (Tester_Class_3.var_60 = (Tester_Class_1)var_153) : (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)(Tester_Class_9.var_133 = (Tester_Class_10)arg_0))); + ((Tester_Class_7)(((Tester_Class_10)arg_0).var_139 = new Tester_Class_10[Tester_Class_3.var_58][--arg_2.var_71])).var_112 = new byte[(((Tester_Class_8)(Tester_Class_7)((var_150 = (var_150 = (Tester_Class_8)arg_0)).var_112 = arg_2)).var_113 = (((Tester_Class_7)arg_0).var_113 = arg_2)).var_71]; + Tester_Class_8 var_155; + (Tester_Class_3.var_55 & arg_2.equals(arg_0) ? (Tester_Class_10)var_153 : (Tester_Class_10)var_153).var_3 %= Tester_Class_6.var_91; + return ((Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)var_153)))).var_29 ? ! !true : Tester_Class_10.var_140 | Tester_Class_3.var_55) || Tester_Class_3.var_55 ? (Tester_Class_3.var_60 = (Tester_Class_1)(((Tester_Class_10)var_153).var_139 = (Tester_Class_6)var_153)) : new Tester_Class_1(); + } + + protected Tester_Class_5 func_1(Tester_Class_0 arg_0, final float arg_1) + { + (!Tester_Class_10.var_140 ? (Tester_Class_6)arg_0 : (Tester_Class_6)arg_0).var_90 /= ((Tester_Class_8.var_109 = (new boolean[Tester_Class_10.var_138][Tester_Class_3.var_58])[((Tester_Class_6)arg_0).var_99][Tester_Class_10.var_138] ? (Tester_Class_3)((Tester_Class_3.var_60 = (Tester_Class_1)arg_0).var_31 = (Tester_Class_6)arg_0) : (Tester_Class_3)arg_0).var_61 *= Tester_Class_3.var_58); + { + "".toLowerCase(); + } + ((Tester_Class_10)arg_0).var_139 = new Tester_Class_8(); + arg_0 = (new Tester_Class_6[((Tester_Class_6)arg_0).var_99])[Tester_Class_3.var_58]; + if (((Tester_Class_10)(arg_0 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)arg_0)))).var_145) + { + Tester_Class_3.var_63++; + } + else + { + ++Tester_Class_2.var_46; + } + (((Tester_Class_3.var_55 ^= Tester_Class_3.var_55 ^ true) ? (Tester_Class_10)arg_0 : (Tester_Class_10)arg_0).var_145 || true ? (Tester_Class_6)arg_0 : (Tester_Class_6)(((Tester_Class_7)(((Tester_Class_10)arg_0).var_139 = (Tester_Class_10)arg_0)).var_112 = "jlixai")).var_99--; + Tester_Class_5.var_81 = Tester_Class_3.var_55 && ! (arg_0.var_1 = arg_0.var_1); + { + ((new Tester_Class_6[Tester_Class_3.var_58])[(true ? (Tester_Class_6)(Tester_Class_9.var_133 = (Tester_Class_10)arg_0) : (Tester_Class_6)(((Tester_Class_1)arg_0).var_31 = (Tester_Class_10)arg_0)).var_99]).var_90 *= (Tester_Class_3.var_64 %= Tester_Class_3.var_63); + } + ++Tester_Class_2.var_46; + Tester_Class_0 var_156; + Tester_Class_2.var_46++; + Tester_Class_8.var_114 = (Tester_Class_7.var_114 = (Tester_Class_8.var_114 = (Tester_Class_5)arg_0)); + Tester_Class_6.func_2((Tester_Class_7.var_114 = (Tester_Class_7.var_114 = (Tester_Class_7.var_114 = (Tester_Class_5)arg_0))).var_83 = (byte)(((Tester_Class_10)arg_0).var_142 = (new Tester_Class_8[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_10.var_138]).var_110, Tester_Class_6.var_96, (new byte[Tester_Class_3.var_58])[Tester_Class_10.var_138]); + Tester_Class_7.var_114 = (new Tester_Class_5[Tester_Class_10.var_138])[((Tester_Class_3)arg_0).var_61]; + boolean var_157 = Tester_Class_10.var_140; + (Tester_Class_3.var_60 = (Tester_Class_1)arg_0).var_1 ^= Tester_Class_10.var_140; + return Tester_Class_8.var_114 = (Tester_Class_7.var_114 = (Tester_Class_8.var_114 = (Tester_Class_5)arg_0)); + } + + final static int func_2(Tester_Class_6 arg_0) + { + new Tester_Class_9(); + { + ++Tester_Class_3.var_63; + } + new Tester_Class_3().var_57--; + Tester_Class_1 var_158; + String var_159; + --Tester_Class_6.var_96; + { + new String(); + } + var_159 = (var_159 = arg_0.var_4); + { + --Tester_Class_2.var_46; + } + final double var_160 = (Tester_Class_7.var_114 = (Tester_Class_8.var_114 = (Tester_Class_8.var_114 = (Tester_Class_5)(new Tester_Class_0[arg_0.var_99][arg_0.var_99])[Tester_Class_3.var_58][Tester_Class_3.var_58]))).var_1 ? Tester_Class_9.var_132 : Tester_Class_6.var_97; + Tester_Class_8 var_161; + char var_162 = 'O'; + Tester_Class_2.var_46++; + Tester_Class_6.var_96++; + { + new String(); + } + ++Tester_Class_6.var_96; + var_162 >>= ((new Tester_Class_4[arg_0.var_99])[arg_0.var_99++]).var_70 >> Tester_Class_6.var_91; + (Tester_Class_7.var_114 = (Tester_Class_7.var_114 = (new Tester_Class_5[Tester_Class_3.var_58])[++arg_0.var_99])).var_83 = (arg_0.var_93 <<= Tester_Class_7.var_108); + --Tester_Class_6.var_96; + { + new Tester_Class_9().var_128 = new Tester_Class_2(); + } + arg_0 = arg_0; + { + Tester_Class_9 var_163; + } + ((Tester_Class_5)(Tester_Class_9.var_133 = arg_0)).var_83 = (arg_0.var_99 >>= Tester_Class_5.var_5); + arg_0.var_99 = Tester_Class_10.var_138; + Tester_Class_3.var_60 = (var_158 = (Tester_Class_3.var_60 = (Tester_Class_1)(Tester_Class_9.var_133 = arg_0))); + return Tester_Class_6.var_91; + } + + protected final Tester_Class_9 func_3() + { + Tester_Class_2.var_44 = 3210658399310388224L; + ++Tester_Class_6.var_96; + short var_164 = 15978; + var_164++; + Tester_Class_5.var_81 = true; + return Tester_Class_3.var_55 ? new Tester_Class_9() : new Tester_Class_9(); + } + + final static Tester_Class_10 func_4(Tester_Class_3 arg_0, String arg_1, final byte[] arg_2, final Object arg_3) + { + Tester_Class_1 var_165; + Tester_Class_3.var_63 += new Tester_Class_6().var_92 >= 3821095133162842112L ? (arg_0.var_61 |= Tester_Class_6.var_91) : Tester_Class_10.var_138; + return false ? ((var_165 = (Tester_Class_1)arg_3).var_29 ? (Tester_Class_10)arg_3 : (Tester_Class_10)arg_3) : (Tester_Class_10)(Tester_Class_0)arg_3; + } + + private static Object func_7(final short arg_0, String arg_1, final Tester_Class_3 arg_2) + { + Tester_Class_3.var_60 = (new Tester_Class_1[arg_2.var_61])[Tester_Class_10.var_138]; + return ((new Tester_Class_7[arg_2.var_61 |= Tester_Class_3.var_63])[arg_2.var_61 *= Tester_Class_6.var_98]).var_112 = new Tester_Class_8(); + } + + public static String execute() + { + try { + Test6712835 t = new Test6712835(); + try { t.test(); } + catch(Throwable e) { } + try { return t.toString(); } + catch (Throwable e) { return "Error during result conversion to String"; } + } catch (Throwable e) { return "Error during test execution"; } + } + + public static void main(String[] args) + { + try { + Test6712835 t = new Test6712835(); + try { t.test(); } + catch(Throwable e) { } + try { System.out.println(t); } + catch(Throwable e) { } + } catch (Throwable e) { } + } + + private void test() + { + Tester_Class_3.var_60 = true ? (Tester_Class_3.var_60 = new Tester_Class_1()) : new Tester_Class_1(); + double var_170 = 0; + Tester_Class_9.var_133 = (new Tester_Class_4().var_69 = new Tester_Class_3()); + new Tester_Class_6(); + String var_171; + new Tester_Class_9(); + do + { + new String(); + var_170++; + Tester_Class_3.var_64 = 1.0240330514364089E307; + new String(); + var_171 = (var_171 = Tester_Class_9.var_127); + Tester_Class_3.var_63--; + } while (var_170 < 525); + ((new Tester_Class_10[Tester_Class_10.var_138])[Tester_Class_2.var_45 = Tester_Class_3.var_58]).var_142 = (Tester_Class_8)(Tester_Class_7)(new Tester_Class_10().var_139 = new Tester_Class_2()); + long var_172 = 0L; + Tester_Class_3.var_64 /= (((new Tester_Class_6[Tester_Class_3.var_58])[Tester_Class_10.var_138]).var_99 ^= ((new Tester_Class_6[Tester_Class_3.var_58])[Tester_Class_10.var_138]).var_90) > 9.462466046830147E307 ? new Tester_Class_6().var_99 : Tester_Class_3.var_58; + short var_173; + (true ? new Tester_Class_2() : (func_3().var_128 = new Tester_Class_2())).var_3 *= (var_150 = new Tester_Class_8()).var_115; + (Tester_Class_3.var_60 = new Tester_Class_1()).var_31 = (((new Tester_Class_9[Tester_Class_3.var_58])[Tester_Class_10.var_138]).var_128 = (func_3().var_128 = (func_3().var_128 = (new Tester_Class_9().var_128 = new Tester_Class_2())))); + for (((new Tester_Class_10[new Tester_Class_6().var_99])[new Tester_Class_6().var_99++]).var_142 = (new Tester_Class_8[Tester_Class_10.var_138])[Tester_Class_3.var_58]; var_172 < 203 && (Tester_Class_3.var_55 &= (new boolean[Tester_Class_2.var_45 = Tester_Class_3.var_58])[Tester_Class_10.var_138]); Tester_Class_9.var_133 = (Tester_Class_7.var_114 = (new Tester_Class_5[Tester_Class_2.var_45 = Tester_Class_10.var_138][Tester_Class_10.var_138])[Tester_Class_3.var_58][Tester_Class_2.var_45 = Tester_Class_3.var_58])) + { + var_171 = Tester_Class_9.var_127; + var_172++; + Tester_Class_3.var_63++; + Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)(new Object[Tester_Class_3.var_58][Tester_Class_10.var_138])[Tester_Class_3.var_58][Tester_Class_3.var_58]))); + ++Tester_Class_2.var_46; + Tester_Class_2.var_46--; + Tester_Class_3.var_64 -= Tester_Class_3.var_58; + } + (Tester_Class_3.var_60 = new Tester_Class_1()).var_31 = ((new Tester_Class_8().var_124 = new Tester_Class_4()).var_69 = new Tester_Class_3()); + int var_174 = 0; + ((new Tester_Class_6[Tester_Class_10.var_138][Tester_Class_10.var_138])[Tester_Class_2.var_45 = Tester_Class_10.var_138][Tester_Class_2.var_45 = Tester_Class_3.var_58]).var_92 = 'Z'; + while ((Tester_Class_9.var_131 = Tester_Class_3.var_55) && (var_174 < 24 && !true)) + { + new Tester_Class_10(); + var_174++; + Tester_Class_3.var_64 %= (((new Tester_Class_6[Tester_Class_3.var_58])[Tester_Class_2.var_45 = Tester_Class_3.var_58]).var_93 ^= (byte)Tester_Class_3.var_59); + ((Tester_Class_10)(Tester_Class_9.var_133 = (new Tester_Class_5[((Tester_Class_6)(new Tester_Class_0[Tester_Class_10.var_138])[(byte)(Tester_Class_2.var_46 >>>= Tester_Class_7.var_108)]).var_99])[Tester_Class_10.var_138])).var_139 = (new Tester_Class_10[new Tester_Class_6().var_99][new Tester_Class_4().var_71])[new Tester_Class_4().var_71]; + } + int var_175 = 0; + (Tester_Class_10.var_140 ? (Tester_Class_2)(Tester_Class_9.var_133 = (Tester_Class_7.var_114 = (new Tester_Class_5[Tester_Class_10.var_138])[Tester_Class_10.var_138])) : new Tester_Class_2()).var_1 &= Tester_Class_3.var_55; + do + { + Tester_Class_10.var_143 = new Tester_Class_3(); + var_175++; + ++Tester_Class_2.var_46; + } while ((false ? true : var_149) | !Tester_Class_10.var_140 && var_175 < 97); + Tester_Class_9.var_131 = true; + (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = new Tester_Class_1())))).var_1 &= (((new Tester_Class_10().var_1 = !true) ? new Tester_Class_10() : new Tester_Class_10()).var_145 ? new Tester_Class_3() : new Tester_Class_3()).var_1; + (true ? func_3() : func_3()).var_128 = ((((Tester_Class_5.var_86 = (Tester_Class_3.var_55 &= !var_149)) ? new Tester_Class_10() : new Tester_Class_10()).var_145 ? new Tester_Class_9() : func_3()).var_128 = var_149 ? new Tester_Class_2() : new Tester_Class_2()); + Tester_Class_3.var_59 -= (Tester_Class_5.var_81 = new Tester_Class_1().var_29) ^ !true ? 7920143378515332096L : new Tester_Class_6().var_92; + ((Tester_Class_3.var_60 = new Tester_Class_1()).var_1 ? (new Tester_Class_5[Tester_Class_10.var_138][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_3.var_58] : (Tester_Class_8.var_114 = new Tester_Class_5())).var_83 = Tester_Class_10.var_140 ? (Tester_Class_3.var_63 -= 2.0167496E38F) : ++Tester_Class_3.var_63; + double var_176 = 9.327780852480363E307; + } + public String toString() + { + String result = "[\n"; + result += "Test6712835.var_151 = "; result += Printer.print(var_151); + result += "\n"; + result += "Test6712835.var_149 = "; result += Printer.print(var_149); + result += "\n"; + result += "Test6712835.var_150 = "; result += Printer.print(var_150); + result += ""; + result += "\n]"; + return result; + } + static class Printer + { + public static String print(boolean arg) { return String.valueOf(arg); } + public static String print(byte arg) { return String.valueOf(arg); } + public static String print(short arg) { return String.valueOf(arg); } + public static String print(char arg) { return String.valueOf((int)arg); } + public static String print(int arg) { return String.valueOf(arg); } + public static String print(long arg) { return String.valueOf(arg); } + public static String print(float arg) { return String.valueOf(arg); } + public static String print(double arg) { return String.valueOf(arg); } + + + public static String print(Object arg) + { + return print_r(new java.util.Stack(), arg); + } + + private static String print_r(java.util.Stack visitedObjects, Object arg) + { + String result = ""; + if (arg == null) + result += "null"; + else + if (arg.getClass().isArray()) + { + for (int i = 0; i < visitedObjects.size(); i++) + if (visitedObjects.elementAt(i) == arg) return ""; + + visitedObjects.push(arg); + + final String delimiter = ", "; + result += "["; + + if (arg instanceof Object[]) + { + Object[] array = (Object[]) arg; + for (int i = 0; i < array.length; i++) + { + result += print_r(visitedObjects, array[i]); + if (i < array.length - 1) result += delimiter; + } + } + else + if (arg instanceof boolean[]) + { + boolean[] array = (boolean[]) arg; + for (int i = 0; i < array.length; i++) + { + result += print(array[i]); + if (i < array.length - 1) result += delimiter; + } + } + else + if (arg instanceof byte[]) + { + byte[] array = (byte[]) arg; + for (int i = 0; i < array.length; i++) + { + result += print(array[i]); + if (i < array.length - 1) result += delimiter; + } + } + else + if (arg instanceof short[]) + { + short[] array = (short[]) arg; + for (int i = 0; i < array.length; i++) + { + result += print(array[i]); + if (i < array.length - 1) result += delimiter; + } + } + else + if (arg instanceof char[]) + { + char[] array = (char[]) arg; + for (int i = 0; i < array.length; i++) + { + result += print(array[i]); + if (i < array.length - 1) result += delimiter; + } + } + else + if (arg instanceof int[]) + { + int[] array = (int[]) arg; + for (int i = 0; i < array.length; i++) + { + result += print(array[i]); + if (i < array.length - 1) result += delimiter; + } + } + else + if (arg instanceof long[]) + { + long[] array = (long[]) arg; + for (int i = 0; i < array.length; i++) + { + result += print(array[i]); + if (i < array.length - 1) result += delimiter; + } + } + else + if (arg instanceof float[]) + { + float[] array = (float[]) arg; + for (int i = 0; i < array.length; i++) + { + result += print(array[i]); + if (i < array.length - 1) result += delimiter; + } + } + else + if (arg instanceof double[]) + { + double[] array = (double[]) arg; + for (int i = 0; i < array.length; i++) + { + result += print(array[i]); + if (i < array.length - 1) result += delimiter; + } + } + + result += "]"; + visitedObjects.pop(); + + } else + { + result += arg.toString(); + } + + return result; + } + } +} diff --git a/hotspot/test/compiler/6724218/Test.java b/hotspot/test/compiler/6724218/Test.java new file mode 100644 index 00000000000..c2835168567 --- /dev/null +++ b/hotspot/test/compiler/6724218/Test.java @@ -0,0 +1,98 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6724218 + * @summary Fix raise_LCA_above_marks() early termination + * @run main/othervm -Xbatch -XX:CompileCommand=exclude,Test.update Test + */ + +public class Test { + Test next = null; + Object value = null; + + static boolean _closed = false; + static int size = 0; + static Test list = null; + static int cache_size = 0; + static Test cache = null; + + Object get(int i) { + Test t = list; + list = t.next; + size -= 1; + Object o = t.value; + if (i > 0) { + t.next = cache; + t.value = null; + cache = t; + cache_size = +1; + } + return o; + } + + void update() { + // Exclude compilation of this one. + if (size == 0) { + Test t; + if (cache_size > 0) { + t = cache; + cache = t.next; + cache_size = -1; + } else { + t = new Test(); + } + t.value = new Object(); + t.next = list; + list = t; + size += 1; + } + } + + synchronized Object test(int i) { + while (true) { + if (_closed) { + return null; + } else if (size > 0) { + return get(i); + } + update(); + } + } + + public static void main(String argv[]) throws Exception { + Test t = new Test(); + int lim = 500000; + Object o; + for (int j = 0; j < lim; j++) { + o = t.test(j&1); + if (o == null) { + throw new Exception("*** Failed on iteration " + j); + } + if ((j&1) == 0) { + t.update(); + } + } + } +} diff --git a/hotspot/test/compiler/6726999/Test.java b/hotspot/test/compiler/6726999/Test.java new file mode 100644 index 00000000000..69bd2f76cc0 --- /dev/null +++ b/hotspot/test/compiler/6726999/Test.java @@ -0,0 +1,1419 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +/* + * @test + * @bug 6726999 + * @summary nsk/stress/jck12a/jck12a010 assert(n != NULL,"Bad immediate dominator info."); + * @run main/othervm -Xbatch -XX:CompileCommand=exclude,Test.dummy -XX:+AggressiveOpts Test + */ + +import java.lang.reflect.Array; + +class Point { + int x; + int y; +} + +public class Test { + + void dummy() { + // Empty method to verify correctness of DebugInfo. + // Use -XX:CompileCommand=exclude,Test.dummy + } + + int test0_0_0(int y) { + int x = 3; + Point p = new Point(); + dummy(); + p.x = x; + p.y = 3 * x + y; + return p.x * p.y; + } + + int test0_0_1(int y) { + int x = 3; + Point p = null; + dummy(); + p = new Point(); + dummy(); + p.x = x; + p.y = 3 * x + y; + return p.x * p.y; + } + + int test0_0_2(int y) { + int x = 3; + Point p = new Point(); + dummy(); + p = new Point(); + dummy(); + p.x = x; + p.y = 3 * x + y; + return p.x * p.y; + } + + int test0_0_3(int y) { + int x = 3; + Point p[] = new Point[1]; + p[0] = new Point(); + dummy(); + p[0].x = x; + p[0].y = 3 * x + y; + return p[0].x * p[0].y; + } + + int test0_0_4(int y) { + int x = 3; + Point p[] = new Point[1]; + dummy(); + p[0] = new Point(); + dummy(); + p[0].x = x; + p[0].y = 3 * x + y; + return p[0].x * p[0].y; + } + + int test0_0_5(int y) { + int x = 3; + Point p[] = new Point[1]; + dummy(); + p[0] = null; + dummy(); + p[0] = new Point(); + dummy(); + p[0].x = x; + p[0].y = 3 * x + y; + return p[0].x * p[0].y; + } + + int test0_0_6(int y) { + int x = 3; + Point p[] = new Point[1]; + p[0] = new Point(); + dummy(); + p[0] = new Point(); + dummy(); + p[0].x = x; + p[0].y = 3 * x + y; + return p[0].x * p[0].y; + } + + int test0_1_3(int y) { + int x = 3; + Point p1 = new Point(); + dummy(); + Point p[] = new Point[1]; + p[0] = p1; + dummy(); + p[0].x = x; + p[0].y = 3 * x + y; + return p[0].x * p[0].y; + } + + int test0_1_4(int y) { + int x = 3; + Point p1 = new Point(); + dummy(); + Point p[] = new Point[1]; + dummy(); + p[0] = p1; + dummy(); + p[0].x = x; + p[0].y = 3 * x + y; + return p[0].x * p[0].y; + } + + int test0_1_5(int y) { + int x = 3; + Point p1 = new Point(); + dummy(); + Point p[] = new Point[1]; + dummy(); + p[0] = null; + dummy(); + p[0] = p1; + dummy(); + p[0].x = x; + p[0].y = 3 * x + y; + return p[0].x * p[0].y; + } + + int test0_1_6(int y) { + int x = 3; + Point p1 = new Point(); + dummy(); + Point p2 = new Point(); + dummy(); + Point p[] = new Point[1]; + p[0] = p1; + dummy(); + p[0] = p2; + dummy(); + p[0].x = x; + p[0].y = 3 * x + y; + return p[0].x * p[0].y; + } + + int test1_0_0(int y) { + Point p = new Point(); + if ( (y & 1) == 1 ) { + p = new Point(); + } + int x = 3; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test1_0_1(int y) { + Point p = null; + if ( (y & 1) == 1 ) { + p = new Point(); + } + int x = 3; + if ( p == null ) + return (3 * x + y) * x; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test1_0_2(int y) { + Point p[] = new Point[1]; + if ( (y & 1) == 1 ) { + p[0] = new Point(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_0_3(int y) { + Point p[] = new Point[1]; + p[0] = null; + if ( (y & 1) == 1 ) { + p[0] = new Point(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_0_4(int y) { + Point p[] = new Point[1]; + p[0] = new Point(); + if ( (y & 1) == 1 ) { + p[0] = new Point(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_0_5(int y) { + Point p[] = new Point[1]; + if ( (y & 1) == 1 ) { + p[0] = new Point(); + } else { + p[0] = null; + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_0_6(int y) { + Point p[] = new Point[1]; + if ( (y & 1) == 1 ) { + p[0] = new Point(); + } else { + p[0] = new Point(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_1_0(int y) { + Point p = new Point(); + if ( (y & 1) == 1 ) { + dummy(); + p = new Point(); + dummy(); + } + int x = 3; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test1_1_1(int y) { + Point p = null; + if ( (y & 1) == 1 ) { + dummy(); + p = new Point(); + dummy(); + } + int x = 3; + if ( p == null ) + return (3 * x + y) * x; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test1_1_2(int y) { + Point p[] = new Point[1]; + if ( (y & 1) == 1 ) { + dummy(); + p[0] = new Point(); + dummy(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_1_3(int y) { + Point p[] = new Point[1]; + dummy(); + p[0] = null; + if ( (y & 1) == 1 ) { + dummy(); + p[0] = new Point(); + dummy(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_1_4(int y) { + Point p[] = new Point[1]; + dummy(); + p[0] = new Point(); + if ( (y & 1) == 1 ) { + dummy(); + p[0] = new Point(); + dummy(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_1_5(int y) { + Point p[] = new Point[1]; + if ( (y & 1) == 1 ) { + dummy(); + p[0] = new Point(); + dummy(); + } else { + dummy(); + p[0] = null; + dummy(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_1_6(int y) { + Point p[] = new Point[1]; + if ( (y & 1) == 1 ) { + dummy(); + p[0] = new Point(); + dummy(); + } else { + dummy(); + p[0] = new Point(); + dummy(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_2_0(int y) { + Point p1 = new Point(); + dummy(); + Point p = new Point(); + if ( (y & 1) == 1 ) { + dummy(); + p = p1; + dummy(); + } + int x = 3; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test1_2_1(int y) { + Point p1 = new Point(); + dummy(); + Point p = null; + if ( (y & 1) == 1 ) { + dummy(); + p = p1; + dummy(); + } + int x = 3; + if ( p == null ) + return (3 * x + y) * x; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test1_2_2(int y) { + Point p1 = new Point(); + dummy(); + Point p[] = new Point[1]; + if ( (y & 1) == 1 ) { + dummy(); + p[0] = p1; + dummy(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_2_3(int y) { + Point p1 = new Point(); + dummy(); + Point p[] = new Point[1]; + dummy(); + p[0] = null; + if ( (y & 1) == 1 ) { + dummy(); + p[0] = p1; + dummy(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_2_4(int y) { + Point p1 = new Point(); + dummy(); + Point p2 = new Point(); + dummy(); + Point p[] = new Point[1]; + dummy(); + p[0] = p1; + if ( (y & 1) == 1 ) { + dummy(); + p[0] = p2; + dummy(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_2_5(int y) { + Point p1 = new Point(); + dummy(); + Point p[] = new Point[1]; + if ( (y & 1) == 1 ) { + dummy(); + p[0] = p1; + dummy(); + } else { + dummy(); + p[0] = null; + dummy(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test1_2_6(int y) { + Point p1 = new Point(); + dummy(); + Point p2 = new Point(); + dummy(); + Point p[] = new Point[1]; + if ( (y & 1) == 1 ) { + dummy(); + p[0] = p1; + dummy(); + } else { + dummy(); + p[0] = p2; + dummy(); + } + int x = 3; + if ( p[0] == null ) + return (3 * x + y) * x; + p[0].x = x; + p[0].y = 3 * x + y; + dummy(); + return p[0].x * p[0].y; + } + + int test2_0_0(int y) { + Point p = new Point(); + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + p = new Point(); + } + int x = 3; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test2_0_1(int y) { + Point p = null; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + p = new Point(); + } + int x = 3; + if ( p == null ) + return (3 * x + y) * x; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test2_0_2(int y) { + Point p[] = new Point[3]; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + p[i] = new Point(); + } + int x = 3; + int j = (y & 1); + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_0_3(int y) { + Point p[] = new Point[3]; + int j = (y & 1); + p[j] = null; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + p[i] = new Point(); + } + int x = 3; + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_0_4(int y) { + Point p[] = new Point[3]; + int j = (y & 1); + p[j] = new Point(); + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + p[i] = new Point(); + } + int x = 3; + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_0_5(int y) { + Point p[] = new Point[3]; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + p[i] = new Point(); + } + for (int i = 0; i < lim; i++) { + p[i] = null; + } + int x = 3; + int j = (y & 1); + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_0_6(int y) { + Point p[] = new Point[3]; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + p[i] = new Point(); + } + for (int i = 0; i < lim; i++) { + p[i] = new Point(); + } + int x = 3; + int j = (y & 1); + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_1_0(int y) { + Point p = new Point(); + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p = new Point(); + dummy(); + } + int x = 3; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test2_1_1(int y) { + Point p = null; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p = new Point(); + dummy(); + } + int x = 3; + if ( p == null ) + return (3 * x + y) * x; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test2_1_2(int y) { + Point p[] = new Point[3]; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = new Point(); + dummy(); + } + int x = 3; + int j = (y & 1); + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_1_3(int y) { + Point p[] = new Point[3]; + dummy(); + int j = (y & 1); + p[j] = null; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = new Point(); + dummy(); + } + int x = 3; + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_1_4(int y) { + Point p[] = new Point[3]; + dummy(); + int j = (y & 1); + p[j] = new Point(); + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = new Point(); + dummy(); + } + int x = 3; + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_1_5(int y) { + Point p[] = new Point[3]; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = new Point(); + dummy(); + } + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = null; + dummy(); + } + int x = 3; + int j = (y & 1); + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_1_6(int y) { + Point p[] = new Point[3]; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = new Point(); + dummy(); + } + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = new Point(); + dummy(); + } + int x = 3; + int j = (y & 1); + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_2_0(int y) { + Point p1 = new Point(); + dummy(); + Point p = new Point(); + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p = p1; + dummy(); + } + int x = 3; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test2_2_1(int y) { + Point p1 = new Point(); + dummy(); + Point p = null; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p = p1; + dummy(); + } + int x = 3; + if ( p == null ) + return (3 * x + y) * x; + p.x = x; + p.y = 3 * x + y; + dummy(); + return p.x * p.y; + } + + int test2_2_2(int y) { + Point p1 = new Point(); + dummy(); + Point p[] = new Point[3]; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = p1; + dummy(); + } + int x = 3; + int j = (y & 1); + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_2_3(int y) { + Point p1 = new Point(); + dummy(); + Point p[] = new Point[3]; + dummy(); + int j = (y & 1); + p[j] = null; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = p1; + dummy(); + } + int x = 3; + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_2_4(int y) { + Point p1 = new Point(); + dummy(); + Point p2 = new Point(); + dummy(); + Point p[] = new Point[3]; + dummy(); + int j = (y & 1); + p[j] = p1; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = p2; + dummy(); + } + int x = 3; + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_2_5(int y) { + Point p1 = new Point(); + dummy(); + Point p[] = new Point[3]; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = p1; + dummy(); + } + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = null; + dummy(); + } + int x = 3; + int j = (y & 1); + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + int test2_2_6(int y) { + Point p1 = new Point(); + dummy(); + Point p2 = new Point(); + dummy(); + Point p[] = new Point[3]; + int lim = (y & 3); + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = p1; + dummy(); + } + for (int i = 0; i < lim; i++) { + dummy(); + p[i] = p2; + dummy(); + } + int x = 3; + int j = (y & 1); + if ( p[j] == null ) + return (3 * x + y) * x; + p[j].x = x; + p[j].y = 3 * x + y; + dummy(); + return p[j].x * p[0].y; + } + + public static void main(String args[]) { + Test tsr = new Test(); + Point p = new Point(); + Point ptmp = p; + Class cls = Point.class; + int y = 0; + for (int i=0; i<10000; i++) { + y = tsr.test0_0_0(y); + y = tsr.test0_0_0(y); + y = tsr.test0_0_1(y); + y = tsr.test0_0_1(y); + y = tsr.test0_0_2(y); + y = tsr.test0_0_2(y); + y = tsr.test0_0_3(y); + y = tsr.test0_0_3(y); + y = tsr.test0_0_4(y); + y = tsr.test0_0_4(y); + y = tsr.test0_0_5(y); + y = tsr.test0_0_5(y); + y = tsr.test0_0_6(y); + y = tsr.test0_0_6(y); + + y = tsr.test0_1_3(y); + y = tsr.test0_1_3(y); + y = tsr.test0_1_4(y); + y = tsr.test0_1_4(y); + y = tsr.test0_1_5(y); + y = tsr.test0_1_5(y); + y = tsr.test0_1_6(y); + y = tsr.test0_1_6(y); + + y = tsr.test1_0_0(y&~1); + y = tsr.test1_0_1(y&~1); + y = tsr.test1_0_2(y&~1); + y = tsr.test1_0_3(y&~1); + y = tsr.test1_0_4(y&~1); + y = tsr.test1_0_5(y&~1); + y = tsr.test1_0_6(y&~1); + y = tsr.test1_0_0((y&~1)+1); + y = tsr.test1_0_1((y&~1)+1); + y = tsr.test1_0_2((y&~1)+1); + y = tsr.test1_0_3((y&~1)+1); + y = tsr.test1_0_4((y&~1)+1); + y = tsr.test1_0_5((y&~1)+1); + y = tsr.test1_0_6((y&~1)+1); + + y = tsr.test1_1_0(y&~1); + y = tsr.test1_1_1(y&~1); + y = tsr.test1_1_2(y&~1); + y = tsr.test1_1_3(y&~1); + y = tsr.test1_1_4(y&~1); + y = tsr.test1_1_5(y&~1); + y = tsr.test1_1_6(y&~1); + y = tsr.test1_1_0((y&~1)+1); + y = tsr.test1_1_1((y&~1)+1); + y = tsr.test1_1_2((y&~1)+1); + y = tsr.test1_1_3((y&~1)+1); + y = tsr.test1_1_4((y&~1)+1); + y = tsr.test1_1_5((y&~1)+1); + y = tsr.test1_1_6((y&~1)+1); + + y = tsr.test1_2_0(y&~1); + y = tsr.test1_2_1(y&~1); + y = tsr.test1_2_2(y&~1); + y = tsr.test1_2_3(y&~1); + y = tsr.test1_2_4(y&~1); + y = tsr.test1_2_5(y&~1); + y = tsr.test1_2_6(y&~1); + y = tsr.test1_2_0((y&~1)+1); + y = tsr.test1_2_1((y&~1)+1); + y = tsr.test1_2_2((y&~1)+1); + y = tsr.test1_2_3((y&~1)+1); + y = tsr.test1_2_4((y&~1)+1); + y = tsr.test1_2_5((y&~1)+1); + y = tsr.test1_2_6((y&~1)+1); + + y = tsr.test2_0_0(y&~3); + y = tsr.test2_0_1(y&~3); + y = tsr.test2_0_2(y&~3); + y = tsr.test2_0_3(y&~3); + y = tsr.test2_0_4(y&~3); + y = tsr.test2_0_5(y&~3); + y = tsr.test2_0_6(y&~3); + y = tsr.test2_0_0((y&~3)+3); + y = tsr.test2_0_1((y&~3)+3); + y = tsr.test2_0_2((y&~3)+3); + y = tsr.test2_0_3((y&~3)+3); + y = tsr.test2_0_4((y&~3)+3); + y = tsr.test2_0_5((y&~3)+3); + y = tsr.test2_0_6((y&~3)+3); + + y = tsr.test2_1_0(y&~3); + y = tsr.test2_1_1(y&~3); + y = tsr.test2_1_2(y&~3); + y = tsr.test2_1_3(y&~3); + y = tsr.test2_1_4(y&~3); + y = tsr.test2_1_5(y&~3); + y = tsr.test2_1_6(y&~3); + y = tsr.test2_1_0((y&~3)+3); + y = tsr.test2_1_1((y&~3)+3); + y = tsr.test2_1_2((y&~3)+3); + y = tsr.test2_1_3((y&~3)+3); + y = tsr.test2_1_4((y&~3)+3); + y = tsr.test2_1_5((y&~3)+3); + y = tsr.test2_1_6((y&~3)+3); + + y = tsr.test2_2_0(y&~3); + y = tsr.test2_2_1(y&~3); + y = tsr.test2_2_2(y&~3); + y = tsr.test2_2_3(y&~3); + y = tsr.test2_2_4(y&~3); + y = tsr.test2_2_5(y&~3); + y = tsr.test2_2_6(y&~3); + y = tsr.test2_2_0((y&~3)+3); + y = tsr.test2_2_1((y&~3)+3); + y = tsr.test2_2_2((y&~3)+3); + y = tsr.test2_2_3((y&~3)+3); + y = tsr.test2_2_4((y&~3)+3); + y = tsr.test2_2_5((y&~3)+3); + y = tsr.test2_2_6((y&~3)+3); + + } + for (int i=0; i<10000; i++) { + y = tsr.test0_0_0(y); + y = tsr.test0_0_0(y); + y = tsr.test0_0_1(y); + y = tsr.test0_0_1(y); + y = tsr.test0_0_2(y); + y = tsr.test0_0_2(y); + y = tsr.test0_0_3(y); + y = tsr.test0_0_3(y); + y = tsr.test0_0_4(y); + y = tsr.test0_0_4(y); + y = tsr.test0_0_5(y); + y = tsr.test0_0_5(y); + y = tsr.test0_0_6(y); + y = tsr.test0_0_6(y); + + y = tsr.test0_1_3(y); + y = tsr.test0_1_3(y); + y = tsr.test0_1_4(y); + y = tsr.test0_1_4(y); + y = tsr.test0_1_5(y); + y = tsr.test0_1_5(y); + y = tsr.test0_1_6(y); + y = tsr.test0_1_6(y); + + y = tsr.test1_0_0(y&~1); + y = tsr.test1_0_1(y&~1); + y = tsr.test1_0_2(y&~1); + y = tsr.test1_0_3(y&~1); + y = tsr.test1_0_4(y&~1); + y = tsr.test1_0_5(y&~1); + y = tsr.test1_0_6(y&~1); + y = tsr.test1_0_0((y&~1)+1); + y = tsr.test1_0_1((y&~1)+1); + y = tsr.test1_0_2((y&~1)+1); + y = tsr.test1_0_3((y&~1)+1); + y = tsr.test1_0_4((y&~1)+1); + y = tsr.test1_0_5((y&~1)+1); + y = tsr.test1_0_6((y&~1)+1); + + y = tsr.test1_1_0(y&~1); + y = tsr.test1_1_1(y&~1); + y = tsr.test1_1_2(y&~1); + y = tsr.test1_1_3(y&~1); + y = tsr.test1_1_4(y&~1); + y = tsr.test1_1_5(y&~1); + y = tsr.test1_1_6(y&~1); + y = tsr.test1_1_0((y&~1)+1); + y = tsr.test1_1_1((y&~1)+1); + y = tsr.test1_1_2((y&~1)+1); + y = tsr.test1_1_3((y&~1)+1); + y = tsr.test1_1_4((y&~1)+1); + y = tsr.test1_1_5((y&~1)+1); + y = tsr.test1_1_6((y&~1)+1); + + y = tsr.test1_2_0(y&~1); + y = tsr.test1_2_1(y&~1); + y = tsr.test1_2_2(y&~1); + y = tsr.test1_2_3(y&~1); + y = tsr.test1_2_4(y&~1); + y = tsr.test1_2_5(y&~1); + y = tsr.test1_2_6(y&~1); + y = tsr.test1_2_0((y&~1)+1); + y = tsr.test1_2_1((y&~1)+1); + y = tsr.test1_2_2((y&~1)+1); + y = tsr.test1_2_3((y&~1)+1); + y = tsr.test1_2_4((y&~1)+1); + y = tsr.test1_2_5((y&~1)+1); + y = tsr.test1_2_6((y&~1)+1); + + y = tsr.test2_0_0(y&~3); + y = tsr.test2_0_1(y&~3); + y = tsr.test2_0_2(y&~3); + y = tsr.test2_0_3(y&~3); + y = tsr.test2_0_4(y&~3); + y = tsr.test2_0_5(y&~3); + y = tsr.test2_0_6(y&~3); + y = tsr.test2_0_0((y&~3)+3); + y = tsr.test2_0_1((y&~3)+3); + y = tsr.test2_0_2((y&~3)+3); + y = tsr.test2_0_3((y&~3)+3); + y = tsr.test2_0_4((y&~3)+3); + y = tsr.test2_0_5((y&~3)+3); + y = tsr.test2_0_6((y&~3)+3); + + y = tsr.test2_1_0(y&~3); + y = tsr.test2_1_1(y&~3); + y = tsr.test2_1_2(y&~3); + y = tsr.test2_1_3(y&~3); + y = tsr.test2_1_4(y&~3); + y = tsr.test2_1_5(y&~3); + y = tsr.test2_1_6(y&~3); + y = tsr.test2_1_0((y&~3)+3); + y = tsr.test2_1_1((y&~3)+3); + y = tsr.test2_1_2((y&~3)+3); + y = tsr.test2_1_3((y&~3)+3); + y = tsr.test2_1_4((y&~3)+3); + y = tsr.test2_1_5((y&~3)+3); + y = tsr.test2_1_6((y&~3)+3); + + y = tsr.test2_2_0(y&~3); + y = tsr.test2_2_1(y&~3); + y = tsr.test2_2_2(y&~3); + y = tsr.test2_2_3(y&~3); + y = tsr.test2_2_4(y&~3); + y = tsr.test2_2_5(y&~3); + y = tsr.test2_2_6(y&~3); + y = tsr.test2_2_0((y&~3)+3); + y = tsr.test2_2_1((y&~3)+3); + y = tsr.test2_2_2((y&~3)+3); + y = tsr.test2_2_3((y&~3)+3); + y = tsr.test2_2_4((y&~3)+3); + y = tsr.test2_2_5((y&~3)+3); + y = tsr.test2_2_6((y&~3)+3); + + } + for (int i=0; i<10000; i++) { + y = tsr.test0_0_0(y); + y = tsr.test0_0_0(y); + y = tsr.test0_0_1(y); + y = tsr.test0_0_1(y); + y = tsr.test0_0_2(y); + y = tsr.test0_0_2(y); + y = tsr.test0_0_3(y); + y = tsr.test0_0_3(y); + y = tsr.test0_0_4(y); + y = tsr.test0_0_4(y); + y = tsr.test0_0_5(y); + y = tsr.test0_0_5(y); + y = tsr.test0_0_6(y); + y = tsr.test0_0_6(y); + + y = tsr.test0_1_3(y); + y = tsr.test0_1_3(y); + y = tsr.test0_1_4(y); + y = tsr.test0_1_4(y); + y = tsr.test0_1_5(y); + y = tsr.test0_1_5(y); + y = tsr.test0_1_6(y); + y = tsr.test0_1_6(y); + + y = tsr.test1_0_0(y&~1); + y = tsr.test1_0_1(y&~1); + y = tsr.test1_0_2(y&~1); + y = tsr.test1_0_3(y&~1); + y = tsr.test1_0_4(y&~1); + y = tsr.test1_0_5(y&~1); + y = tsr.test1_0_6(y&~1); + y = tsr.test1_0_0((y&~1)+1); + y = tsr.test1_0_1((y&~1)+1); + y = tsr.test1_0_2((y&~1)+1); + y = tsr.test1_0_3((y&~1)+1); + y = tsr.test1_0_4((y&~1)+1); + y = tsr.test1_0_5((y&~1)+1); + y = tsr.test1_0_6((y&~1)+1); + + y = tsr.test1_1_0(y&~1); + y = tsr.test1_1_1(y&~1); + y = tsr.test1_1_2(y&~1); + y = tsr.test1_1_3(y&~1); + y = tsr.test1_1_4(y&~1); + y = tsr.test1_1_5(y&~1); + y = tsr.test1_1_6(y&~1); + y = tsr.test1_1_0((y&~1)+1); + y = tsr.test1_1_1((y&~1)+1); + y = tsr.test1_1_2((y&~1)+1); + y = tsr.test1_1_3((y&~1)+1); + y = tsr.test1_1_4((y&~1)+1); + y = tsr.test1_1_5((y&~1)+1); + y = tsr.test1_1_6((y&~1)+1); + + y = tsr.test1_2_0(y&~1); + y = tsr.test1_2_1(y&~1); + y = tsr.test1_2_2(y&~1); + y = tsr.test1_2_3(y&~1); + y = tsr.test1_2_4(y&~1); + y = tsr.test1_2_5(y&~1); + y = tsr.test1_2_6(y&~1); + y = tsr.test1_2_0((y&~1)+1); + y = tsr.test1_2_1((y&~1)+1); + y = tsr.test1_2_2((y&~1)+1); + y = tsr.test1_2_3((y&~1)+1); + y = tsr.test1_2_4((y&~1)+1); + y = tsr.test1_2_5((y&~1)+1); + y = tsr.test1_2_6((y&~1)+1); + + y = tsr.test2_0_0(y&~3); + y = tsr.test2_0_1(y&~3); + y = tsr.test2_0_2(y&~3); + y = tsr.test2_0_3(y&~3); + y = tsr.test2_0_4(y&~3); + y = tsr.test2_0_5(y&~3); + y = tsr.test2_0_6(y&~3); + y = tsr.test2_0_0((y&~3)+3); + y = tsr.test2_0_1((y&~3)+3); + y = tsr.test2_0_2((y&~3)+3); + y = tsr.test2_0_3((y&~3)+3); + y = tsr.test2_0_4((y&~3)+3); + y = tsr.test2_0_5((y&~3)+3); + y = tsr.test2_0_6((y&~3)+3); + + y = tsr.test2_1_0(y&~3); + y = tsr.test2_1_1(y&~3); + y = tsr.test2_1_2(y&~3); + y = tsr.test2_1_3(y&~3); + y = tsr.test2_1_4(y&~3); + y = tsr.test2_1_5(y&~3); + y = tsr.test2_1_6(y&~3); + y = tsr.test2_1_0((y&~3)+3); + y = tsr.test2_1_1((y&~3)+3); + y = tsr.test2_1_2((y&~3)+3); + y = tsr.test2_1_3((y&~3)+3); + y = tsr.test2_1_4((y&~3)+3); + y = tsr.test2_1_5((y&~3)+3); + y = tsr.test2_1_6((y&~3)+3); + + y = tsr.test2_2_0(y&~3); + y = tsr.test2_2_1(y&~3); + y = tsr.test2_2_2(y&~3); + y = tsr.test2_2_3(y&~3); + y = tsr.test2_2_4(y&~3); + y = tsr.test2_2_5(y&~3); + y = tsr.test2_2_6(y&~3); + y = tsr.test2_2_0((y&~3)+3); + y = tsr.test2_2_1((y&~3)+3); + y = tsr.test2_2_2((y&~3)+3); + y = tsr.test2_2_3((y&~3)+3); + y = tsr.test2_2_4((y&~3)+3); + y = tsr.test2_2_5((y&~3)+3); + y = tsr.test2_2_6((y&~3)+3); + + } + + int z = 0; + y = tsr.test0_0_0(0); + System.out.println("After 'test0_0_0' y=" + y); + y = tsr.test0_0_1(0); + System.out.println("After 'test0_0_1' y=" + y); + y = tsr.test0_0_2(0); + System.out.println("After 'test0_0_2' y=" + y); + y = tsr.test0_0_3(0); + System.out.println("After 'test0_0_3' y=" + y); + y = tsr.test0_0_4(0); + System.out.println("After 'test0_0_4' y=" + y); + y = tsr.test0_0_5(0); + System.out.println("After 'test0_0_5' y=" + y); + y = tsr.test0_0_6(0); + System.out.println("After 'test0_0_6' y=" + y); + y = tsr.test0_1_3(0); + System.out.println("After 'test0_1_3' y=" + y); + y = tsr.test0_1_4(0); + System.out.println("After 'test0_1_4' y=" + y); + y = tsr.test0_1_5(0); + System.out.println("After 'test0_1_5' y=" + y); + y = tsr.test0_1_6(0); + System.out.println("After 'test0_1_6' y=" + y); + + y = tsr.test1_0_0(0); + System.out.println("After 'test1_0_0' y=" + y); + y = tsr.test1_0_1(0); + System.out.println("After 'test1_0_1' y=" + y); + y = tsr.test1_0_2(0); + System.out.println("After 'test1_0_2' y=" + y); + y = tsr.test1_0_3(0); + System.out.println("After 'test1_0_3' y=" + y); + y = tsr.test1_0_4(0); + System.out.println("After 'test1_0_4' y=" + y); + y = tsr.test1_0_5(0); + System.out.println("After 'test1_0_5' y=" + y); + y = tsr.test1_0_6(0); + System.out.println("After 'test1_0_6' y=" + y); + + y = tsr.test1_1_0(0); + System.out.println("After 'test1_1_0' y=" + y); + y = tsr.test1_1_1(0); + System.out.println("After 'test1_1_1' y=" + y); + y = tsr.test1_1_2(0); + System.out.println("After 'test1_1_2' y=" + y); + y = tsr.test1_1_3(0); + System.out.println("After 'test1_1_3' y=" + y); + y = tsr.test1_1_4(0); + System.out.println("After 'test1_1_4' y=" + y); + y = tsr.test1_1_5(0); + System.out.println("After 'test1_1_5' y=" + y); + y = tsr.test1_1_6(0); + System.out.println("After 'test1_1_6' y=" + y); + + y = tsr.test1_2_0(0); + System.out.println("After 'test1_2_0' y=" + y); + y = tsr.test1_2_1(0); + System.out.println("After 'test1_2_1' y=" + y); + y = tsr.test1_2_2(0); + System.out.println("After 'test1_2_2' y=" + y); + y = tsr.test1_2_3(0); + System.out.println("After 'test1_2_3' y=" + y); + y = tsr.test1_2_4(0); + System.out.println("After 'test1_2_4' y=" + y); + y = tsr.test1_2_5(0); + System.out.println("After 'test1_2_5' y=" + y); + y = tsr.test1_2_6(0); + System.out.println("After 'test1_2_6' y=" + y); + + y = tsr.test2_0_0(0); + System.out.println("After 'test2_0_0' y=" + y); + y = tsr.test2_0_1(0); + System.out.println("After 'test2_0_1' y=" + y); + y = tsr.test2_0_2(0); + System.out.println("After 'test2_0_2' y=" + y); + y = tsr.test2_0_3(0); + System.out.println("After 'test2_0_3' y=" + y); + y = tsr.test2_0_4(0); + System.out.println("After 'test2_0_4' y=" + y); + y = tsr.test2_0_5(0); + System.out.println("After 'test2_0_5' y=" + y); + y = tsr.test2_0_6(0); + System.out.println("After 'test2_0_6' y=" + y); + + y = tsr.test2_1_0(0); + System.out.println("After 'test2_1_0' y=" + y); + y = tsr.test2_1_1(0); + System.out.println("After 'test2_1_1' y=" + y); + y = tsr.test2_1_2(0); + System.out.println("After 'test2_1_2' y=" + y); + y = tsr.test2_1_3(0); + System.out.println("After 'test2_1_3' y=" + y); + y = tsr.test2_1_4(0); + System.out.println("After 'test2_1_4' y=" + y); + y = tsr.test2_1_5(0); + System.out.println("After 'test2_1_5' y=" + y); + y = tsr.test2_1_6(0); + System.out.println("After 'test2_1_6' y=" + y); + + y = tsr.test2_2_0(0); + System.out.println("After 'test2_2_0' y=" + y); + y = tsr.test2_2_1(0); + System.out.println("After 'test2_2_1' y=" + y); + y = tsr.test2_2_2(0); + System.out.println("After 'test2_2_2' y=" + y); + y = tsr.test2_2_3(0); + System.out.println("After 'test2_2_3' y=" + y); + y = tsr.test2_2_4(0); + System.out.println("After 'test2_2_4' y=" + y); + y = tsr.test2_2_5(0); + System.out.println("After 'test2_2_5' y=" + y); + y = tsr.test2_2_6(0); + System.out.println("After 'test2_2_6' y=" + y); + + } +} diff --git a/hotspot/test/compiler/6741738/Tester.java b/hotspot/test/compiler/6741738/Tester.java new file mode 100644 index 00000000000..922f5e2f4e4 --- /dev/null +++ b/hotspot/test/compiler/6741738/Tester.java @@ -0,0 +1,50 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6741738 + * @summary TypePtr::add_offset() set incorrect offset when the add overflows + * @run main/othervm -Xcomp -XX:CompileOnly=Tester.foo Tester + */ + +public class Tester { + private String[] values; + private int count; + + String foo() { + int i = Integer.MAX_VALUE-1; + String s; + try { + s = values[i]; + } catch (Throwable e) { + s = ""; + } + return s; + } + + public static void main(String[] args) { + Tester t = new Tester(); + String s = t.foo(); + } +} diff --git a/jaxp/.hgtags b/jaxp/.hgtags index c749c17a66d..26debcbf9b8 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -6,3 +6,9 @@ b996318955c0ad8e9fa0ffb56c74f626786e863f jdk7-b28 617ee8607cfd5fd81f233f3c0b690f85084687a0 jdk7-b29 2d94a238a1641d074e6032dcdceed461d6f85d6a jdk7-b30 255d64ee287e926e8629dd80bc67690e65eeba30 jdk7-b31 +400a5ee432cc2db9031e06852ddde9264a192b48 jdk7-b32 +95375835527f0bf06124ce984266e2ad5de8a6dc jdk7-b33 +01facdf8cabdeaaf68cca037aef56cc5f074897f jdk7-b34 +eac46d1eb7f0935ba04f1c7929ec15423fd0309e jdk7-b35 +c84ca638db42a8b6b227b4e3b63bca192c5ca634 jdk7-b36 +af49591bc486d82aa04b832257de0d18adc9af52 jdk7-b37 diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 0224fa8b6b1..a8f294fe904 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -6,3 +6,9 @@ eefcd5204500a11d6aa802dca9f961cf10ab64c2 jdk7-b28 836c55713abab186e4de0c6eabd06ff008c7b8d0 jdk7-b29 7f2466f8cc7009702e548d1a763254f546024d7e jdk7-b30 f978623825364a2ad9c6f51d02fc9424a8b0bc86 jdk7-b31 +e6daca2eced9d84b01255cabcfcc49164c26405e jdk7-b32 +6dcbcfb9551aaa2a80906c28ab48c9a8564e0e64 jdk7-b33 +7a9f629cd957e3169a1a769f763fe060d078785c jdk7-b34 +b0f01c2508b690dd225298edfec70b5e8b8dc367 jdk7-b35 +f60187f44a0d62906a5e2f6bd0989b5b24c1ca1e jdk7-b36 +a2a6f9edf761934faf59ea60d7fe7178371302cd jdk7-b37 diff --git a/jdk/.hgtags b/jdk/.hgtags index 92c22dd5bf0..8a91ce7fabc 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -7,3 +7,8 @@ e21f4266466cd1306b176aaa08b2cd8337a9be3d jdk7-b29 b6d6877c1155621a175dccd12dc14c54f938fb8b jdk7-b30 b7474b739d13bacd9972f88ac91f6350b7b0be12 jdk7-b31 c51121419e30eac5f0fbbce45ff1711c4ce0de28 jdk7-b32 +fa4c0a6cdd25d97d4e6f5d7aa180bcbb0e0d56af jdk7-b33 +434055a0716ee44bca712ebca02fc04b20e6e288 jdk7-b34 +cf4894b78ceb966326e93bf221db0c2d14d59218 jdk7-b35 +134fd1a656ea85acd1f97f6700f75029b9b472a0 jdk7-b36 +14f50aee4989b75934d385c56a83da0c23d2f68b jdk7-b37 diff --git a/jdk/make/ASSEMBLY_EXCEPTION b/jdk/make/ASSEMBLY_EXCEPTION deleted file mode 100644 index 8b7ac1d0813..00000000000 --- a/jdk/make/ASSEMBLY_EXCEPTION +++ /dev/null @@ -1,27 +0,0 @@ - -OPENJDK ASSEMBLY EXCEPTION - -The OpenJDK source code made available by Sun at openjdk.java.net and -openjdk.dev.java.net ("OpenJDK Code") is distributed under the terms of the -GNU General Public License version 2 -only ("GPL2"), with the following clarification and special exception. - - Linking this OpenJDK Code statically or dynamically with other code - is making a combined work based on this library. Thus, the terms - and conditions of GPL2 cover the whole combination. - - As a special exception, Sun gives you permission to link this - OpenJDK Code with certain code licensed by Sun as indicated at - http://openjdk.java.net/legal/exception-modules-2007-05-08.html - ("Designated Exception Modules") to produce an executable, - regardless of the license terms of the Designated Exception Modules, - and to copy and distribute the resulting executable under GPL2, - provided that the Designated Exception Modules continue to be - governed by the licenses under which they were offered by Sun. - -As such, it allows licensees and sublicensees of Sun's GPL2 OpenJDK Code to -build an executable that includes those portions of necessary code that Sun -could not provide under GPL2 (or that Sun has provided under GPL2 with the -Classpath exception). If you modify or add to the OpenJDK code, that new -GPL2 code may still be combined with Designated Exception Modules if the -new code is made subject to this exception by its copyright holder. diff --git a/jdk/make/LICENSE b/jdk/make/LICENSE deleted file mode 100644 index eeab58c21c9..00000000000 --- a/jdk/make/LICENSE +++ /dev/null @@ -1,347 +0,0 @@ -The GNU General Public License (GPL) - -Version 2, June 1991 - -Copyright (C) 1989, 1991 Free Software Foundation, Inc. -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Everyone is permitted to copy and distribute verbatim copies of this license -document, but changing it is not allowed. - -Preamble - -The licenses for most software are designed to take away your freedom to share -and change it. By contrast, the GNU General Public License is intended to -guarantee your freedom to share and change free software--to make sure the -software is free for all its users. This General Public License applies to -most of the Free Software Foundation's software and to any other program whose -authors commit to using it. (Some other Free Software Foundation software is -covered by the GNU Library General Public License instead.) You can apply it to -your programs, too. - -When we speak of free software, we are referring to freedom, not price. Our -General Public Licenses are designed to make sure that you have the freedom to -distribute copies of free software (and charge for this service if you wish), -that you receive source code or can get it if you want it, that you can change -the software or use pieces of it in new free programs; and that you know you -can do these things. - -To protect your rights, we need to make restrictions that forbid anyone to deny -you these rights or to ask you to surrender the rights. These restrictions -translate to certain responsibilities for you if you distribute copies of the -software, or if you modify it. - -For example, if you distribute copies of such a program, whether gratis or for -a fee, you must give the recipients all the rights that you have. You must -make sure that they, too, receive or can get the source code. And you must -show them these terms so they know their rights. - -We protect your rights with two steps: (1) copyright the software, and (2) -offer you this license which gives you legal permission to copy, distribute -and/or modify the software. - -Also, for each author's protection and ours, we want to make certain that -everyone understands that there is no warranty for this free software. If the -software is modified by someone else and passed on, we want its recipients to -know that what they have is not the original, so that any problems introduced -by others will not reflect on the original authors' reputations. - -Finally, any free program is threatened constantly by software patents. We -wish to avoid the danger that redistributors of a free program will -individually obtain patent licenses, in effect making the program proprietary. -To prevent this, we have made it clear that any patent must be licensed for -everyone's free use or not licensed at all. - -The precise terms and conditions for copying, distribution and modification -follow. - -TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - -0. This License applies to any program or other work which contains a notice -placed by the copyright holder saying it may be distributed under the terms of -this General Public License. The "Program", below, refers to any such program -or work, and a "work based on the Program" means either the Program or any -derivative work under copyright law: that is to say, a work containing the -Program or a portion of it, either verbatim or with modifications and/or -translated into another language. (Hereinafter, translation is included -without limitation in the term "modification".) Each licensee is addressed as -"you". - -Activities other than copying, distribution and modification are not covered by -this License; they are outside its scope. The act of running the Program is -not restricted, and the output from the Program is covered only if its contents -constitute a work based on the Program (independent of having been made by -running the Program). Whether that is true depends on what the Program does. - -1. You may copy and distribute verbatim copies of the Program's source code as -you receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice and -disclaimer of warranty; keep intact all the notices that refer to this License -and to the absence of any warranty; and give any other recipients of the -Program a copy of this License along with the Program. - -You may charge a fee for the physical act of transferring a copy, and you may -at your option offer warranty protection in exchange for a fee. - -2. You may modify your copy or copies of the Program or any portion of it, thus -forming a work based on the Program, and copy and distribute such modifications -or work under the terms of Section 1 above, provided that you also meet all of -these conditions: - - a) You must cause the modified files to carry prominent notices stating - that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in whole or - in part contains or is derived from the Program or any part thereof, to be - licensed as a whole at no charge to all third parties under the terms of - this License. - - c) If the modified program normally reads commands interactively when run, - you must cause it, when started running for such interactive use in the - most ordinary way, to print or display an announcement including an - appropriate copyright notice and a notice that there is no warranty (or - else, saying that you provide a warranty) and that users may redistribute - the program under these conditions, and telling the user how to view a copy - of this License. (Exception: if the Program itself is interactive but does - not normally print such an announcement, your work based on the Program is - not required to print an announcement.) - -These requirements apply to the modified work as a whole. If identifiable -sections of that work are not derived from the Program, and can be reasonably -considered independent and separate works in themselves, then this License, and -its terms, do not apply to those sections when you distribute them as separate -works. But when you distribute the same sections as part of a whole which is a -work based on the Program, the distribution of the whole must be on the terms -of this License, whose permissions for other licensees extend to the entire -whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest your -rights to work written entirely by you; rather, the intent is to exercise the -right to control the distribution of derivative or collective works based on -the Program. - -In addition, mere aggregation of another work not based on the Program with the -Program (or with a work based on the Program) on a volume of a storage or -distribution medium does not bring the other work under the scope of this -License. - -3. You may copy and distribute the Program (or a work based on it, under -Section 2) in object code or executable form under the terms of Sections 1 and -2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable source - code, which must be distributed under the terms of Sections 1 and 2 above - on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three years, to - give any third party, for a charge no more than your cost of physically - performing source distribution, a complete machine-readable copy of the - corresponding source code, to be distributed under the terms of Sections 1 - and 2 above on a medium customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer to - distribute corresponding source code. (This alternative is allowed only - for noncommercial distribution and only if you received the program in - object code or executable form with such an offer, in accord with - Subsection b above.) - -The source code for a work means the preferred form of the work for making -modifications to it. For an executable work, complete source code means all -the source code for all modules it contains, plus any associated interface -definition files, plus the scripts used to control compilation and installation -of the executable. However, as a special exception, the source code -distributed need not include anything that is normally distributed (in either -source or binary form) with the major components (compiler, kernel, and so on) -of the operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the source -code from the same place counts as distribution of the source code, even though -third parties are not compelled to copy the source along with the object code. - -4. You may not copy, modify, sublicense, or distribute the Program except as -expressly provided under this License. Any attempt otherwise to copy, modify, -sublicense or distribute the Program is void, and will automatically terminate -your rights under this License. However, parties who have received copies, or -rights, from you under this License will not have their licenses terminated so -long as such parties remain in full compliance. - -5. You are not required to accept this License, since you have not signed it. -However, nothing else grants you permission to modify or distribute the Program -or its derivative works. These actions are prohibited by law if you do not -accept this License. Therefore, by modifying or distributing the Program (or -any work based on the Program), you indicate your acceptance of this License to -do so, and all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - -6. Each time you redistribute the Program (or any work based on the Program), -the recipient automatically receives a license from the original licensor to -copy, distribute or modify the Program subject to these terms and conditions. -You may not impose any further restrictions on the recipients' exercise of the -rights granted herein. You are not responsible for enforcing compliance by -third parties to this License. - -7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), conditions -are imposed on you (whether by court order, agreement or otherwise) that -contradict the conditions of this License, they do not excuse you from the -conditions of this License. If you cannot distribute so as to satisfy -simultaneously your obligations under this License and any other pertinent -obligations, then as a consequence you may not distribute the Program at all. -For example, if a patent license would not permit royalty-free redistribution -of the Program by all those who receive copies directly or indirectly through -you, then the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply and -the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any patents or -other property right claims or to contest validity of any such claims; this -section has the sole purpose of protecting the integrity of the free software -distribution system, which is implemented by public license practices. Many -people have made generous contributions to the wide range of software -distributed through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing to -distribute software through any other system and a licensee cannot impose that -choice. - -This section is intended to make thoroughly clear what is believed to be a -consequence of the rest of this License. - -8. If the distribution and/or use of the Program is restricted in certain -countries either by patents or by copyrighted interfaces, the original -copyright holder who places the Program under this License may add an explicit -geographical distribution limitation excluding those countries, so that -distribution is permitted only in or among countries not thus excluded. In -such case, this License incorporates the limitation as if written in the body -of this License. - -9. The Free Software Foundation may publish revised and/or new versions of the -General Public License from time to time. Such new versions will be similar in -spirit to the present version, but may differ in detail to address new problems -or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any later -version", you have the option of following the terms and conditions either of -that version or of any later version published by the Free Software Foundation. -If the Program does not specify a version number of this License, you may -choose any version ever published by the Free Software Foundation. - -10. If you wish to incorporate parts of the Program into other free programs -whose distribution conditions are different, write to the author to ask for -permission. For software which is copyrighted by the Free Software Foundation, -write to the Free Software Foundation; we sometimes make exceptions for this. -Our decision will be guided by the two goals of preserving the free status of -all derivatives of our free software and of promoting the sharing and reuse of -software generally. - -NO WARRANTY - -11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR -THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE -STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE -PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND -PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, -YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - -12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL -ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE -PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR -INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA -BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER -OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -END OF TERMS AND CONDITIONS - -How to Apply These Terms to Your New Programs - -If you develop a new program, and you want it to be of the greatest possible -use to the public, the best way to achieve this is to make it free software -which everyone can redistribute and change under these terms. - -To do so, attach the following notices to the program. It is safest to attach -them to the start of each source file to most effectively convey the exclusion -of warranty; and each file should have at least the "copyright" line and a -pointer to where the full notice is found. - - One line to give the program's name and a brief idea of what it does. - - Copyright (C) - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) - any later version. - - This program 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 for - more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., 59 - Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this when it -starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author Gnomovision comes - with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free - software, and you are welcome to redistribute it under certain conditions; - type 'show c' for details. - -The hypothetical commands 'show w' and 'show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may be -called something other than 'show w' and 'show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your school, -if any, to sign a "copyright disclaimer" for the program, if necessary. Here -is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - 'Gnomovision' (which makes passes at compilers) written by James Hacker. - - signature of Ty Coon, 1 April 1989 - - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General Public -License instead of this License. - - -"CLASSPATH" EXCEPTION TO THE GPL - -Certain source files distributed by Sun Microsystems, Inc. are subject to -the following clarification and special exception to the GPL, but only where -Sun has expressly included in the particular source file's header the words -"Sun designates this particular file as subject to the "Classpath" exception -as provided by Sun in the LICENSE file that accompanied this code." - - Linking this library statically or dynamically with other modules is making - a combined work based on this library. Thus, the terms and conditions of - the GNU General Public License cover the whole combination. - - As a special exception, the copyright holders of this library give you - permission to link this library with independent modules to produce an - executable, regardless of the license terms of these independent modules, - and to copy and distribute the resulting executable under terms of your - choice, provided that you also meet, for each linked independent module, - the terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. If - you modify this library, you may extend this exception to your version of - the library, but you are not obligated to do so. If you do not wish to do - so, delete this exception statement from your version. diff --git a/jdk/make/README b/jdk/make/README deleted file mode 100644 index d774ab80b70..00000000000 --- a/jdk/make/README +++ /dev/null @@ -1,34 +0,0 @@ -README: - This file should be located at the top of the jdk Mercurial repository. - - See http://openjdk.java.net/ for more information about the OpenJDK. - -Simple Build Instructions: - - 1. Download and install a JDK 6 from - http://java.sun.com/javase/downloads/index.jsp - Set the environment variable ALT_BOOTDIR to the location of this JDK 6. - - 2. Download and install the Binary Plugs for the most recent JDK7 from - http://download.java.net/openjdk/jdk7/ - Set the environment variable ALT_BINARY_PLUGS_PATH to the location of - these binary plugs. - - 3. Either download and install the latest JDK7 from - http://download.java.net/openjdk/jdk7/, or build your own complete - OpenJDK7 by using the top level Makefile in the OpenJDK Mercurial forest. - Set the environment variable ALT_JDK_IMPORT_PATH to the location of - this latest JDK7 or OpenJDK7 build. - - 4. Check the sanity of doing a build with the current machine: - cd make && gnumake sanity - See README-builds.html if you run into problems. - - 5. Do a partial build of the jdk: - cd make && gnumake all - - 6. Construct the images: - cd make && gnumake images - The resulting JDK image should be found in build/*/j2sdk-image - - diff --git a/jdk/make/README-builds.html b/jdk/make/README-builds.html deleted file mode 100644 index 6530865db54..00000000000 --- a/jdk/make/README-builds.html +++ /dev/null @@ -1,1452 +0,0 @@ - - - -OpenJDK Build README - - -
    - -
    -

    OpenJDK Build README

    -
    - - -
    - -

    Introduction

    - -
    -

    - This README file contains build instructions for the - OpenJDK. - Building the source code for the - OpenJDK - requires - a certain degree of technical expertise. -

    - - -
    - -

    Contents

    - -
    - -
    - - -
    - -

    Minimum Build Environments

    - -
    -

    - This file often describes specific requirements for what we call the - "minimum build environments" (MBE) for the JDK. - Building with the MBE will generate the most compatible - bits that install on, and run correctly on, the most variations - of the same base OS and hardware architecture. - These usually represent what is often called the - least common denominator platforms. - It is understood that most developers will NOT be using these - specific platforms, and in fact creating these specific platforms - may be difficult due to the age of some of this software. -

    - -

    - The minimum OS and C/C++ compiler versions needed for building the - OpenJDK: -

    -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Base OS and ArchitectureOSCompiler
    Linux X86 (32bit)Red Hat Enterprise Linux 4 gcc 4
    Linux X64 (64bit)Red Hat Enterprise Linux 4 gcc 4
    Solaris SPARC (32bit)Solaris 10 + patches -
    - See SunSolve for patch downloads. -
    Sun Studio 11
    Solaris SPARCV9 (64bit)Solaris 10 + patches -
    - See SunSolve for patch downloads. -
    Sun Studio 11
    Solaris X86 (32bit)Solaris 10 + patches -
    - See SunSolve for patch downloads. -
    Sun Studio 11
    Solaris X64 (64bit)Solaris 10 + patches -
    - See SunSolve for patch downloads. -
    Sun Studio 11
    Windows X86 (32bit)Windows XPMicrosoft Visual Studio .NET 2003 Professional
    Windows X64 (64bit)Windows Server 2003 - Enterprise x64 EditionMicrosoft Platform SDK - April 2005
    -
    -
    - - -
    - -

    Specific Developer Build Environments

    - -
    -

    - We won't be listing all the possible environments, but - we will try to provide what information we have available to us. -

    - -

    Fedora

    - -
    - TBD -
    - -

    Debian

    - -
    - TBD -
    - -

    Ubuntu

    - -
    -

    - In addition to needing the Bootstrap JDK and the Binary Plugs, - when building on Ubuntu you will need to - make sure certain packages are installed. - In particular, certain X11 packages, make, m4, gawk, gcc 4, - binutils, cups, freetype - and alsa. - -

    Ubuntu 6.06

    - -

    - The following list of packages for Ubuntu 6.06 is a working set that - does appear to work. - -

    - Note that it's quite possible that some of these - packages are not required, so anyone discovering that some of the - packages listed below are NOT required, - please let the - OpenJDK - team know. -

    - All the packages below can be installed with the - Synaptic Package manager provided with the base Ubuntu 6.06 release. - -

    -
      -
    • binutils (2.16.1cvs20060117-1ubuntu2.1)
    • -
    • cpp (4:4.0.3-1)
    • -
    • cpp-4.0 (4.0.3-1ubuntu5)
    • -
    • libfreetype6-dev
    • -
    • g++ (4:4.0.3-1)
    • -
    • g++-4.0 (4.0.3-1ubuntu5)
    • -
    • gawk (1:3.1.5-2build1)
    • -
    • gcc (4:4.0.3-1)
    • -
    • gcc-4.0 (4.0.3-1ubuntu5)
    • -
    • libasound2-dev (1.0.10-2ubuntu4)
    • -
    • libc6 (2.3.6-0ubuntu20) to 2.3.6-0ubuntu20.4
    • -
    • libc6-dev (2.3.6-0ubuntu20.4)
    • -
    • libc6-i686 (2.3.6-0ubuntu20) to 2.3.6-0ubuntu20.4
    • -
    • libcupsys2-dev (1.2.2-0ubuntu0.6.06)
    • -
    • libgcrypt11-dev (1.2.2-1)
    • -
    • libgnutls-dev (1.2.9-2ubuntu1.1)
    • -
    • libgnutls12 (1.2.9-2ubuntu1) to 1.2.9-2ubuntu1.1
    • -
    • libgpg-error-dev (1.1-4)
    • -
    • libice-dev (2:1.0.0-0ubuntu2)
    • -
    • liblockfile1 (1.06.1)
    • -
    • libopencdk8-dev (0.5.7-2)
    • -
    • libpopt-dev (1.7-5)
    • -
    • libsm-dev (2:1.0.0-0ubuntu2)
    • -
    • libstdc++6-4.0-dev (4.0.3-1ubuntu5)
    • -
    • libtasn1-2-dev (0.2.17-1ubuntu1)
    • -
    • libx11-dev (2:1.0.0-0ubuntu9)
    • -
    • libxau-dev (1:1.0.0-0ubuntu4)
    • -
    • libxaw-headers (2:1.0.1-0ubuntu3)
    • -
    • libxaw7-dev (2:1.0.1-0ubuntu3)
    • -
    • libxdmcp-dev (1:1.0.0-0ubuntu2)
    • -
    • libxext-dev (2:1.0.0-0ubuntu4)
    • -
    • libxi-dev (2:1.0.0-0ubuntu3)
    • -
    • libxmu-dev (2:1.0.0-0ubuntu3)
    • -
    • libxmu-headers (2:1.0.0-0ubuntu3)
    • -
    • libxmuu-dev (2:1.0.0-0ubuntu3)
    • -
    • libxp-dev (6.8.2-11ubuntu2)
    • -
    • libxpm-dev (1:3.5.4.2-0ubuntu3)
    • -
    • libxrandr-dev (1:1.1.0.2-0ubuntu4)
    • -
    • libxt-dev (1:1.0.0-0ubuntu3)
    • -
    • libxtrap-dev (2:1.0.0-0ubuntu2)
    • -
    • libxtst-dev (2:1.0.1-0ubuntu2)
    • -
    • libxv-dev (2:1.0.1-0ubuntu3)
    • -
    • linux-kernel-headers (2.6.11.2-0ubuntu18)
    • -
    • m4 (1.4.4-1)
    • -
    • make (3.80+3.81.b4-1)
    • -
    • ssl-cert (1.0.13)
    • -
    • x-dev (7.0.4-0ubuntu2)
    • -
    • x11proto-core-dev (7.0.4-0ubuntu2)
    • -
    • x11proto-input-dev (1.3.2-0ubuntu2)
    • -
    • x11proto-kb-dev (1.0.2-0ubuntu2)
    • -
    • x11proto-randr-dev (1.1.2-0ubuntu2)
    • -
    • x11proto-record-dev (1.13.2-0ubuntu2)
    • -
    • x11proto-trap-dev (3.4.3-0ubuntu2)
    • -
    • x11proto-video-dev (2.2.2-0ubuntu2)
    • -
    • x11proto-xext-dev (7.0.2-0ubuntu2)
    • -
    • xlibs-dev (7.0.0-0ubuntu45)
    • -
    • zlib1g-dev (1:1.2.3-6ubuntu4)
    • -
    -
    - -

    Ubuntu 7.04

    - -

    - Using the Synaptic Package Manager, download the following - packages (double indented packages are automatically aquired - due to package dependencies): - -

    -
      -
    • build-essential
    • -
        -
      • dpkg-dev
      • -
      • g++
      • -
      • g++-4.1
      • -
      • libc6-dev
      • -
      • libstdc++6.4.1-dev
      • -
      • linux-libc-dev
      • -
      -
    • gawk
    • -
    • m4
    • -
    • libasound2-dev
    • -
    • libcupsys2-dev
    • -
        -
      • libgcrypt11-dev
      • -
      • lgnutls-dev
      • -
      • libgpg-error-dev
      • -
      • liblzo-dev
      • -
      • libopencdk8-dev
      • -
      • libpopt-dev
      • -
      • libtasn1-3-dev
      • -
      • zlib1g-dev
      • -
      -
    • sun-java6-jdk
    • -
        -
      • java-common
      • -
      • libltdl3
      • -
      • odbcinst1debian1
      • -
      • sun-java6-bin
      • -
      • sun-java6-jre
      • -
      • unixodbc
      • -
      -
    • xlibs-dev
    • -
        -
      • (many)
      • -
      -
    • x11proto-print-dev
    • -
    • libxaw7-dev
    • -
        -
      • libxaw-headers
      • -
      -
    • libxp-dev
    • -
    • libfreetype6-dev
    • -
    -
    -
    - - -
    - -

    Source Directory Structure

    - -
    -

    - The source code for the - OpenJDK is - delivered in 3 sibling directories: - hotspot, - langtools, - corba, - jaxws, - jaxp, - jdk - and - The hotspot directory contains the source code and make - files for - building the - OpenJDK - Hotspot Virtual Machine. - The jdk - directory contains the source code and make files for - building the - OpenJDK - runtime libraries, tools and demos. - The top level Makefile is used to build the complete OpenJDK - release including building the hotspot - VM, staging the VM binaries, and building the - OpenJDK - runtime libraries, - tools and demos. -

    - - -
    - -

    Build Information

    - -
    -

    - Building the - OpenJDK - is done with a gmake - command line and various - environment or make variable settings that direct the make rules - to where various components have been installed. - Where possible the makefiles will attempt to located the various - components in the default locations or any component specific - variable settings. - When the normal defaults fail or components cannot be found, - the various - ALT_* variables (alternates) - can be used to help the makefiles locate components. -

    - Refer to the bash/sh/ksh setup file - jdk/make/jdk_generic_profile.sh - if you need help in setting up your environment variables. - A build could be as simple as: -

    -
    
    -                bash
    -                . jdk/make/jdk_generic_profile.sh
    -                gmake sanity && gmake
    -        
    -
    -

    - Of course ksh or sh would work too. - But some customization will probably be necessary. - The sanity rule will make some basic checks on build - dependencies and generate appropriate warning messages - regarding missing, out of date, or newer than expected components - found on your system. -

    - - -
    - -

    GNU make (gmake)

    - -
    -

    - The Makefiles in the - OpenJDK - are only valid when used with the - GNU version of the utility command make - (gmake). - A few notes about using GNU make: -

      -
    • - In general, you need GNU make version 3.78.1 or newer. -
    • -
    • - Place the location of the GNU make binary in the PATH. -
    • -
    • - Linux: - The /usr/bin/make command should work fine for you. -
    • -
    • - Solaris: - Do NOT use /usr/bin/make on Solaris. - If your Solaris system has the software - from the Solaris Companion CD installed, - you should use gmake - which will be located in either the /opt/sfw/bin or - /usr/sfw/bin directory. -
    • -
    • - Windows: - Make sure you start your build inside a bash/sh/ksh shell. -
      - WARNING: Watch out for make version 3.81, it may - not work due to a lack of support for drive letter paths - like C:/. Use a 3.80 version, or find a newer - version that has this problem fixed. -
    • -
    -

    - Information on GNU make, and access to ftp download sites, are - available on the - - GNU make web site - . - The latest source to GNU make is available at - ftp.gnu.org/pub/gnu/make/. -

    - - -
    - -

    Basic Linux System Setup

    - -
    -

    - i586 only: - The minimum recommended hardware for building the Linux version - is a Pentium class processor or better, at least 256 MB of RAM, and - approximately 1.5 GB of free disk space. -

    - X64 only: - The minimum recommended hardware for building the Linux - version is an AMD Opteron class processor, at least 512 MB of RAM, and - approximately 4 GB of free disk space. -

    - The build will use the tools contained in - /bin and - /usr/bin - of a standard installation of the Linux operating environment. - You should ensure that these directories are in your - PATH. -

    - Note that some Linux systems have a habit of pre-populating - your environment variables for you, for example JAVA_HOME - might get pre-defined for you to refer to the JDK installed on - your Linux system. - You will need to unset JAVA_HOME. - It's a good idea to run env and verify the - environment variables you are getting from the default system - settings make sense for building the - OpenJDK. -

    - - - -

    Basic Linux Check List

    - -
    -
      -
    1. - Install the - Bootstrap JDK, set - ALT_BOOTDIR. -
    2. -
    3. - Install the - Binary Plugs, set - ALT_BINARY_PLUGS_PATH. -
    4. -
    5. - Install or upgrade the FreeType development - package. -
    6. -
    -
    - - -
    - -

    Basic Solaris System Setup

    - -
    -

    - The minimum recommended hardware for building the - Solaris SPARC version is an UltraSPARC with 512 MB of RAM. - For building - the Solaris x86 version, a Pentium class processor or better and at - least 128 MB of RAM are recommended. - Approximately 1.4 GB of free disk - space is needed for a 32-bit build. -

    - If you are building the 64bit version, you should - run the command "isainfo -v" to verify that you have a - 64-bit installation. - An additional 7 GB of free disk space is needed - for a 64-bit build. -

    - The build uses the tools contained in /usr/ccs/bin - and /usr/bin of a standard developer or full installation of - the Solaris operating environment. -

    - - - -

    Basic Solaris Check List

    - -
    -
      -
    1. - Install the - Bootstrap JDK, set - ALT_BOOTDIR. -
    2. -
    3. - Install the - Binary Plugs, set - ALT_BINARY_PLUGS_PATH. -
    4. -
    5. - Install the - Sun Studio Compilers, set - ALT_COMPILER_PATH. -
    6. -
    7. - Install the - CUPS Include files, set - ALT_CUPS_HEADERS_PATH. -
    8. -
    -
    - - -
    - -

    Basic Windows System Setup

    - -
    -

    - i586 only: - The minimum recommended hardware for building the 32bit or X86 - Windows version is an Pentium class processor or better, at least - 512 MB of RAM, and approximately 600 MB of free disk space. - - NOTE: The Windows 2000 build machines need to use the - file system NTFS. - Build machines formatted to FAT32 will not work - because FAT32 doesn't support case-sensitivity in file names. - -

    - X64 only: - The minimum recommended hardware for building - the Windows X64 version is an AMD Opteron class processor, at least 1 - GB of RAM, and approximately 10 GB of free disk space. -

    - - - -

    Windows Paths

    - -
    -

    - Windows: - Note that GNU make is a historic utility and is based very - heavily on shell scripting, so it does not tolerate the Windows habit - of having spaces in pathnames or the use of the \characters in pathnames. - Luckily on most Windows systems, you can use /instead of \, and - there is always a 'short' pathname without spaces for any path that - contains spaces. - Unfortunately, this short pathname can be somewhat dynamic and the - formula is difficult to explain. - You can use cygpath utility to map pathnames with spaces - or the \character into the C:/ style of pathname - (called 'mixed'), e.g. - cygpath -s -m "path". -

    - The makefiles will try to translate any pathnames supplied - to it into the C:/ style automatically. -

    - Note that use of CYGWIN creates a unique problem with regards to - setting PATH. Normally on Windows - the PATH variable contains directories - separated with the ";" character (Solaris and Linux uses ":"). - With CYGWIN, it uses ":", but that means that paths like "C:/path" - cannot be placed in the CYGWIN version of PATH and - instead CYGWIN uses something like /cygdrive/c/path - which CYGWIN understands, but only CYGWIN understands. - So be careful with paths on Windows. -

    - - - -

    Basic Windows Check List

    - -
    -
      -
    1. - Install the - CYGWIN product. -
    2. -
    3. - Install the - Bootstrap JDK, set - ALT_BOOTDIR. -
    4. -
    5. - Install the - Binary Plugs, set - ALT_BINARY_PLUGS_PATH.. -
    6. -
    7. - Install the - Microsoft Visual Studio .NET 2003 Professional or the - Microsoft Platform SDK. -
    8. -
    9. - Setup all environment variables for compilers - (see compilers). -
    10. -
    11. - Install - Microsoft DirectX SDK. -
    12. -
    -
    - - -
    - -

    Build Dependencies

    - -
    -

    - Depending on the platform, the - OpenJDK - build process has some basic - dependencies on components not part of the - OpenJDK - sources. - Some of these are specific to a platform, some even specific to - an architecture. - Each dependency will have a set of ALT variables that can be set - to tell the makefiles where to locate the component. - In most cases setting these ALT variables may not be necessary - and the makefiles will find defaults on the system in standard - install locations or through component specific variables. - -

    Bootstrap JDK

    - -
    -

    - All - OpenJDK - builds require access to the previously released - JDK 6, this is often called a bootstrap JDK. - The JDK 6 binaries can be downloaded from Sun's - JDK 6 download site. - For build performance reasons - is very important that this bootstrap JDK be made available on the - local disk of the machine doing the build. - You should always set - ALT_BOOTDIR - to point to the location of - the bootstrap JDK installation, this is the directory pathname - that contains a bin, lib, and include - It's also a good idea to also place its bin directory - in the PATH environment variable, although it's - not required. -

    - Solaris: - Some pre-installed JDK images may be available to you in the - directory /usr/jdk/instances. - If you don't set - ALT_BOOTDIR - the makefiles will look in that location for a JDK it can use. -

    - -

    Binary Plugs

    - -
    -

    - Not all of the source code that makes up the JDK is available - under an open-source license. - In order to build an OpenJDK binary from source code, - you must first download and install the appropriate - binary plug bundles from the OpenJDK Download area. - During the OpenJDK build process these "binary plugs" - for the encumbered components will be copied into your - resulting OpenJDK binary build image. - These binary plug files are only for the purpose of - building an OpenJDK binary. - Download the Binary Plugs by selecting the Downloads - link at - the OpenJDK site, - install the bundle, - and make sure you set - ALT_BINARY_PLUGS_PATH - to the root of this installation. -

    - -

    Certificate Authority File (cacert)

    - -
    -

    - See - www.wikipedia.org/wiki/CAcert - for a better understanding of the Certificate Authority (CA). - A certificates file named "cacerts" - represents a system-wide keystore with CA certificates. - In JDK and JRE - binary bundles, the "cacerts" file contains root CA certificates from - several public CAs (e.g., VeriSign, Thawte, and Baltimore). - The source contain a cacerts file - without CA root certificates. - Formal JDK builders will need to secure - permission from each public CA and include the certificates into their - own custom cacerts file. - Failure to provide a populated cacerts file - will result in verification errors of a certificate chain during runtime. - The variable - ALT_CACERTS_FILE - can be used to override the default location of the - cacerts file that will get placed in your build. - By default an empty cacerts file is provided and that should be - fine for most JDK developers. -

    - -

    Compilers

    - -
    - - - Linux gcc/binutils - - -
    -

    - The GNU gcc compiler version should be 3.2.2 or newer. - The binutils package should be 2.11.93.0.2-11 or newer. - The compiler used should be the default compiler installed - in /usr/bin. -

    - - Solaris: Sun Studio - -
    -

    - At a minimum, the - - Sun Studio 11 Compilers - (containing version 5.8 of the C and C++ compilers) is required, - with patches from the - - SunSolve web site. -

    - Set - ALT_COMPILER_PATH - to point to the location of - the compiler binaries, and place this location in the PATH. -

    - The Sun Studio Express compilers at: - - Sun Studio Express Download site - are also an option, although these compilers have not - been extensively used yet. -

    - - - Windows i586: Microsoft Visual Studio .NET 2003 Professional - - -
    -

    - The 32-bit - OpenJDK - Windows build - requires Microsoft Visual Studio .NET 2003 (VS2003) Professional - Edition compiler. - The compiler and other tools are expected to reside - in the location defined by the variable VS71COMNTOOLS which - is set by the Microsoft Visual Studio .NET installer. -

    - Once the compiler is installed, - it is recommended that you run VCVARS32.BAT - to set the compiler environment variables - MSVCDIR, - INCLUDE, - LIB, and - PATH - prior to building the - OpenJDK. - The above environment variables MUST be set. -

    - The Microsoft Visual Studio .NET 2005 (VS2005) compiler - will not work at this time due to the new runtime dll - and the manifest requirements. -

    - - - Windows X64: Microsoft Platform SDK April 2005 - - -
    -

    - On X64, - the Microsoft Platform Software - Development Kit (SDK), April 2005 Edition compiler, is required for - building the - OpenJDK - because it contains the C/C++ compiler. - You will need to minimally install the Core SDK and - the MDAC SDK features of this compiler. -

    - Once the Platform SDK is installed, - it is recommended that you run SetEnv.Cmd /X64 - to set the compiler environment variables - MSSDK, - MSTOOLS, - INCLUDE, - LIB, and - PATH - prior to building the - OpenJDK. - The above environment variables MUST be set. -

    - Note that this compiler may say it's version is a - Microsoft Visual Studio .NET 2005 (VS2005), but be careful, - it will not match the official VS2005 product. - This Platform SDK compiler is only used on X64 builds. -

    - -
    - -

    Common UNIX Printing System (CUPS) Headers (Solaris & Linux)

    - -
    -

    - Solaris: - CUPS header files are required for building the - OpenJDK on Solaris. - The Solaris header files can be obtained by installing - the package SFWcups from the Solaris Software - Companion CD/DVD, these often will be installed into - /opt/sfw/cups. -

    - Linux: - CUPS header files are required for building the - OpenJDK on Linux. - The Linux header files are usually available from a "cups" - development package, it's recommended that you try and use - the package provided by the particular version of Linux that - you are using. -

    - The CUPS header files can always be downloaded from - www.cups.org. - The variable - ALT_CUPS_HEADERS_PATH - can be used to override the default location of the - CUPS Header files. -

    - -

    FreeType 2

    - -
    -

    - Version 2.3 or newer of FreeType is required for building the OpenJDK. - On Unix systems required files can be available as part of your - distribution (while you still may need to upgrade them). - Note that you need development version of package that - includes both FreeType library and header files. -

    -

    - You can always download latest FreeType version from the - FreeType website. -

    -

    - Makefiles will try to pick FreeType from /usr/lib and /usr/include. - In case it is installed elsewhere you will need to set environment - variables - ALT_FREETYPE_LIB_PATH - and - ALT_FREETYPE_HEADERS_PATH - to refer to place where library and header files are installed. -

    -
    - -

    Advanced Linux Sound Architecture (ALSA) (Linux only)

    - -
    -

    - Linux only: - Version 0.9.1 or newer of the ALSA files are - required for building the - OpenJDK on Linux. - These Linux files are usually available from an "alsa" - of "libasound" - development package, it's recommended that you try and use - the package provided by the particular version of Linux that - you are using. - The makefiles will check this emit a sanity error if it is - missing or the wrong version. - As a last resort you can go to the - - Advanced Linux Sound Architecture Site. -

    - -

    Windows Specific Dependencies

    - -
    - - Unix Command Tools (CYGWIN) - -
    -

    - The - OpenJDK - requires access to a set of unix command tools - on Windows which can be supplied by - CYGWIN. -

    - The - OpenJDK - build - requires CYGWIN version 1.5.12 or newer. - Information about CYGWIN can - be obtained from the CYGWIN website at - www.cygwin.com. -

    - By default CYGWIN doesn't install all the tools required for building - the OpenJDK. - Along with the default installation, you need to install - the following tools. -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Binary NamePackageDescription
    ar.exeDevelbinutils: The GNU assembler, linker and binary - utilities
    make.exeDevelmake: The GNU version of the 'make' utility
    m4.exeInterpretersm4: GNU implementation of the traditional Unix macro - processor
    cpio.exeUtilscpio: A program to manage archives of files
    file.exeUtilsfile: Determines file type using 'magic' numbers
    -
    -
    - - - Microsoft DirectX 9.0 SDK header files and libraries - - -
    -

    - Microsoft DirectX 9.0 SDK (Summer 2004) - headers are required for building - OpenJDK. - This SDK can be downloaded from - - Microsoft DirectX 9.0 SDK (Summer 2004). - If the link above becomes obsolete, the SDK can be found from - the Microsoft Download Site - (search with "DirectX 9.0 SDK Update Summer 2004"). - The location of this SDK can be set with - ALT_DXSDK_PATH - but it's normally found via the DirectX environment variable - DXSDK_DIR. -

    - - - MSVCRT.DLL - - -
    -

    - i586 only: - The - OpenJDK - 32bit build requires - access to MSVCRT.DLL - version 6.00.8337.0 or newer. - If the MSVCRT.DLL is not installed in - the system32 directory set the - ALT_MSVCRT_DLL_PATH - variable to the location. -

    - X64 only: - The OpenJDK 64bit build requires access to - MSVCRT.DLL version 7.0.3790.0 or newer, which is - usually supplied by the - Platform SDK. - If it is not available from the Platform SDK, - set the - ALT_MSVCRT_DLL_PATH - variable to the location. -

    - - - MSVCR71.DLL - - -
    -

    - i586 only: - The - OpenJDK - build requires access to - MSVCR71.DLL version 7.10.3052.4 or newer which should be - supplied by the - Visual Studio product - If the MSVCR71.DLL is not available from the - Visual Studio product - set the - ALT_MSVCR71_DLL_PATH - variable to the location. -

    - -
    - - -
    - - -
    - -

    Creating the Build

    - -
    -

    - Once a machine is setup to build the - OpenJDK, - the steps to create the - build are fairly simple. - The various ALT settings can either be made into variables - or can be supplied on the - gmake - command. -

    -

      -
    1. Use the sanity rule to double check all the ALT settings: -
      - - gmake - sanity - [ARCH_DATA_MODEL=32 or 64] - [other "ALT_" overrides] - -
      -
    2. -
    3. Start the build with the command: -
      - - gmake - [ARCH_DATA_MODEL=32 or 64] - [ALT_OUTPUTDIR=output_directory] - [other "ALT_" overrides] - -
      -
    4. -
    -

    - Solaris: - Note that ARCH_DATA_MODEL is really only needed on Solaris to - indicate you want to built the 64-bit version. - And before the Solaris 64-bit binaries can be used, they - must be merged with the binaries from a separate 32-bit build. - The merged binaries may then be used in either 32-bit or 64-bit mode, with - the selection occurring at runtime - with the -d32 or -d64 options. -

    - - -
    - -

    Testing the Build

    - -
    -

    - When the build is completed, you should see the generated - binaries and associated files in the j2sdk-image - directory in the output directory. - The default output directory is - build/platform, - where platform is one of -

      -
    • solaris-sparc
    • -
    • solaris-sparcv9
    • -
    • solaris-i586
    • -
    • solaris-amd64
    • -
    • linux-i586
    • -
    • linux-amd64
    • -
    • windows-i586
    • -
    • windows-amd64
    • -
    - In particular, the - build/platform/j2sdk-image/bin - directory should contain executables for the - OpenJDK - tools and utilities. -

    - You can test that the build completed properly by using the build - to run the various demos that you will find in the - build/platform/j2sdk-image/demo - directory. -

    - The provided regression tests can be run with the jtreg - utility from - the jtreg site. -

    - - -
    - -

    Environment/Make Variables

    - -

    -Some of the -environment or make variables (just called variables in this -document) that can impact the build are: - -

    - -
    - -
    PATH
    -
    Typically you want to set the PATH to include: -
      -
    • The location of the GNU make binary
    • -
    • The location of the JDK 6 java - (see Bootstrap JDK)
    • -
    • The location of the C/C++ compilers - (see compilers)
    • -
    • The location or locations for the Unix command utilities - (e.g. /usr/bin)
    • -
    -
    - -
    ARCH_DATA_MODEL
    -
    The ARCH_DATA_MODEL variable - is used to specify whether the build is to generate 32-bit or 64-bit - binaries. - The Solaris build supports either 32-bit or 64-bit builds, but - Windows and Linux will support only one, depending on the specific - OS being used. - Normally, setting this variable is only necessary on Solaris. - Set ARCH_DATA_MODEL to 32 for generating 32-bit binaries, - or to 64 for generating 64-bit binaries. -
    - -
    ALT_BOOTDIR
    -
    - The location of the bootstrap JDK installation. - See Bootstrap JDK for more information. - You should always install your own local Bootstrap JDK and - always set ALT_BOOTDIR explicitly. -
    - -
    ALT_OUTPUTDIR
    -
    - An override for specifying the (absolute) path of where the - build output is to go. - The default output directory will be build/platform. -
    - -
    ALT_COMPILER_PATH
    -
    - The location of the C/C++ compiler. - The default varies depending on the platform. -
    - -
    ALT_CACERTS_FILE
    -
    - The location of the cacerts file. - The default will refer to - jdk/src/share/lib/security/cacerts. -
    - -
    ALT_BINARY_PLUGS_PATH
    -
    - The location of the binary plugs installation. - See Binary Plugs for more information. - You should always have a local copy of a - recent Binary Plugs install image - and set this variable to that location. -
    - -
    ALT_CUPS_HEADERS_PATH
    -
    - The location of the CUPS header files. - See CUPS information for more information. - If this path does not exist the fallback path is - /usr/include. -
    - - -
    ALT_FREETYPE_LIB_PATH
    -
    - The location of the FreeType shared library. - See FreeType information for details. -
    - -
    ALT_FREETYPE_HEADERS_PATH
    -
    - The location of the FreeType header files. - See FreeType information for details. -
    - -
    Windows specific:
    -
    -
    -
    ALT_MSDEVTOOLS_PATH
    -
    - The location of the Microsoft Visual Studio .NET 2003 - tools 'bin' directory. - The default is usually derived from - ALT_COMPILER_PATH. -
    - -
    ALT_DXSDK_PATH
    -
    - The location of the - Microsoft DirectX 9 SDK. - The default will be to try and use the DirectX environment - variable DXSDK_DIR, - failing that, look in C:/DXSDK. -
    - -
    ALT_MSVCRT_DLL_PATH
    -
    - The location of the - MSVCRT.DLL. -
    - -
    ALT_MSVCR71_DLL_PATH
    -
    - i586 only: - The location of the - MSVCR71.DLL. -
    -
    -
    - -
    -
    - - -
    - -

    Troubleshooting

    - -
    -

    - A build can fail for any number of reasons. - Most failures - are a result of trying to build in an environment in which all the - pre-build requirements have not been met. - The first step in - troubleshooting a build failure is to recheck that you have satisfied - all the pre-build requirements for your platform. - Look for the check list of the platform you are building on in the - Table of Contents. - -

    - You can validate your build environment by using the sanity - target. - Any errors listed - will stop the build from starting, and any warnings may result in - a flawed product build. - We strongly encourage you to evaluate every - sanity check warning and fix it if required, before you proceed - further with your build. - -

    - Some of the more common problems with builds are briefly described - below, with suggestions for remedies. - -

      -
    • - Slow Builds: -
      -

      - If your build machine seems to be overloaded from too many - simultaneous C++ compiles, try setting the HOTSPOT_BUILD_JOBS - variable to 1 (if you're using a multiple CPU - machine, setting it to more than the the number of CPUs is probably - not a good idea). -

      - Creating the javadocs can be very slow, if you are running - javadoc, consider skipping that step. -

      - Faster hardware and more RAM always helps too. - The VM build tends to be CPU intensive (many C++ compiles), - and the rest of the JDK will often be disk intensive. -

      - Faster compiles are possible using a tool called - ccache. -

      -
    • -
    • - File time issues: -
      -

      - If you see warnings that refer to file time stamps, e.g. -

      - Warning message: File `xxx' has modification time in - the future. -
      - Warning message: Clock skew detected. Your build may - be incomplete. -
      -

      - These warnings can occur when the clock on the build machine is out of - sync with the timestamps on the source files. Other errors, apparently - unrelated but in fact caused by the clock skew, can occur along with - the clock skew warnings. These secondary errors may tend to obscure the - fact that the true root cause of the problem is an out-of-sync clock. - For example, an out-of-sync clock has been known to cause an old - version of javac to be used to compile some files, resulting in errors - when the pre-1.4 compiler ran across the new assert keyword - in the 1.4 source code. -

      - If you see these warnings, reset the clock on the build - machine, run "gmake clobber" or delete the directory - containing the build output, and restart the build from the beginning. -

      -
    • -
    • - Error message: Trouble writing out table to disk -
      -

      - Increase the amount of swap space on your build machine. -

      -
    • -
    • - Error Message: libstdc++ not found: -
      - This is caused by a missing libstdc++.a library. - This is installed as part of a specific package - (e.g. libstdc++.so.devel.386). - By default some 64bit Linux versions (e.g. Fedora) - only install the 64bit version of the libstdc++ package. - Various parts of the JDK build require a static - link of the C++ runtime libraries to allow for maximum - portability of the built images. -
      -
    • -
    • - Error Message: cannot restore segment prot after reloc -
      - This is probably an issue with SELinux (See - http://en.wikipedia.org/wiki/SELinux). - Parts of the VM is built without the -fPIC for - performance reasons. -

      - To completely disable SELinux: -

        - -
      1. $ su root
      2. -
      3. # system-config-securitylevel
      4. -
      5. In the window that appears, select the SELinux tab
      6. -
      7. Disable SELinux
      8. -
      -

      - Alternatively, instead of completely disabling it you could - disable just this one check. -

        -
      1. Select System->Administration->SELinux Management
      2. -
      3. In the SELinux Management Tool which appears, - select "Boolean" from the menu on the left
      4. -
      5. Expand the "Memory Protection" group
      6. -
      7. Check the first item, labeled - "Allow all unconfined executables to use libraries requiring text relocation ..."
      8. -
      -
      -
    • -
    -
    - -
    diff --git a/jdk/make/README.html b/jdk/make/README.html deleted file mode 100644 index ae415b1590a..00000000000 --- a/jdk/make/README.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - OpenJDK README - - -
    -
    -

    OpenJDK README

    -
    - - -
    - -

    TBD

    - -

    Building the OpenJDK

    - -

    - Refer to the OpenJDK Build README - for build instructions. - - - -


    - - - diff --git a/jdk/make/THIRD_PARTY_README b/jdk/make/THIRD_PARTY_README deleted file mode 100644 index 9f4d7e5087a..00000000000 --- a/jdk/make/THIRD_PARTY_README +++ /dev/null @@ -1,1616 +0,0 @@ -DO NOT TRANSLATE OR LOCALIZE. - -%% This notice is provided with respect to Thai dictionary for text breaking, which may be included with this software: - ---- begin of LICENSE file --- - -Copyright (C) 1982 The Royal Institute, Thai Royal Government. - -Copyright (C) 1998 National Electronics and Computer Technology Center, - National Science and Technology Development Agency, - Ministry of Science Technology and Environment, - Thai Royal Government. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without -limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to -whom the Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -USE OR OTHER DEALINGS IN THE SOFTWARE. - ---- end of LICENSE file --- -%% This notice is provided with respect to ASM, which may be included with this software: -Copyright (c) 2000-2005 INRIA, France Telecom -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -3. Neither the name of the copyright holders nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -THE POSSIBILITY OF SUCH DAMAGE. -%% This notice is provided with respect to zlib 1.1.3, which may be included with this software: - -Acknowledgments: - - The deflate format used by zlib was defined by Phil Katz. The deflate - and zlib specifications were written by L. Peter Deutsch. Thanks to all the - people who reported problems and suggested various improvements in zlib; - they are too numerous to cite here. - -Copyright notice: - - (C) 1995-1998 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - -If you use the zlib library in a product, we would appreciate *not* -receiving lengthy legal documents to sign. The sources are provided -for free but without warranty of any kind. The library has been -entirely written by Jean-loup Gailly and Mark Adler; it does not -include third-party code. - -If you redistribute modified sources, we would appreciate that you include -in the file ChangeLog history information documenting your changes. - -%% This notice is provided with respect to W3C (DTD for XML Signatures), which may be included with this software: -W3C® SOFTWARE NOTICE AND LICENSE -Copyright © 1994-2002 World Wide Web Consortium, (Massachusetts Institute of Technology, Institut National de Recherche en Informatique et en Automatique, Keio University). All Rights Reserved. http://www.w3.org/Consortium/Legal/ -This W3C work (including software, documents, or other related items) is being provided by the copyright holders under the following license. By obtaining, using and/or copying this work, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions: -Permission to use, copy, modify, and distribute this software and its documentation, with or without modification,  for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the software and documentation or portions thereof, including modifications, that you make: -1.The full text of this NOTICE in a location viewable to users of the redistributed or derivative work. -2.Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, a short notice of the following form (hypertext is preferred, text is permitted) should be used within the body of any redistributed or derivative code: "Copyright © [$date-of-software] World Wide Web Consortium, (Massachusetts Institute of Technology, Institut National de Recherche en Informatique et en Automatique, Keio University). All Rights Reserved. http://www.w3.org/Consortium/Legal/" -3.Notice of any changes or modifications to the W3C files, including the date changes were made. (We recommend you provide URIs to the location from which the code is derived.) -THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. -COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION. -The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the software without specific, written prior permission. Title to copyright in this software and any associated documentation will at all times remain with copyright holders. -____________________________________ -This formulation of W3C's notice and license became active on August 14 1998 so as to improve compatibility with GPL. This version ensures that W3C software licensing terms are no more restrictive than GPL and consequently W3C software may be distributed in GPL packages. See the older formulation for the policy prior to this date. Please see our Copyright FAQ for common questions about using materials from our site, including specific terms and conditions for packages like libwww, Amaya, and Jigsaw. Other questions about this notice can be directed to site-policy@w3.org. -  -%% This notice is provided with respect to jscheme.jar, which may be included with this software: -Software License Agreement -Copyright © 1998-2002 by Peter Norvig. -Permission is granted to anyone to use this software, in source or object code form, on any computer system, and to modify, compile, decompile, run, and redistribute it to anyone else, subject to the following restrictions: -1.The author makes no warranty of any kind, either expressed or implied, about the suitability of this software for any purpose. -2.The author accepts no liability of any kind for damages or other consequences of the use of this software, even if they arise from defects in the software. -3.The origin of this software must not be misrepresented, either by explicit claim or by omission. -4.Altered versions must be plainly marked as such, and must not be misrepresented as being the original software. Altered versions may be distributed in packages under other licenses (such as the GNU license). -If you find this software useful, it would be nice if you let me (peter@norvig.com) know about it, and nicer still if you send me modifications that you are willing to share. However, you are not required to do so. - - -%% This notice is provided with respect to PC/SC Lite for Suse Linux v. 1.1.1, which may be included with this software: - -Copyright (c) 1999-2004 David Corcoran -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -Changes to this license can be made only by the copyright author with -explicit written consent. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -%% This notice is provided with respect to IAIK PKCS Wrapper, which may be included with this software: - -Copyright (c) 2002 Graz University of Technology. All rights reserved. -Redistribution and use in source and binary forms, with or without modification,are permitted provided that the following conditions are met: - - -1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: - - "This product includes software developed by IAIK of Graz University of Technology." - - Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. - -4. The names "Graz University of Technology" and "IAIK of Graz University of Technology" must not be used to endorse or promote products derived from this software without prior written permission. - -5. Products derived from this software may not be called "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior written permission of Graz University of Technology. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -%% This notice is provided with respect to Document Object Model (DOM) v. Level 3, which may be included with this software: - -W3Cýý SOFTWARE NOTICE AND LICENSE - -http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 - -This work (and included software, documentation such as READMEs, or other related items) is being -provided by the copyright holders under the following license. By obtaining, using and/or copying this work, you -(the licensee) agree that you have read, understood, and will comply with the following terms and conditions. - -Permission to copy, modify, and distribute this software and its documentation, with or without modification, for -any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies -of the software and documentation or portions thereof, including modifications: - 1.The full text of this NOTICE in a location viewable to users of the redistributed or derivative work. - 2.Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, the - W3C Software Short Notice should be included (hypertext is preferred, text is permitted) within the body - of any redistributed or derivative code. - 3.Notice of any changes or modifications to the files, including the date changes were made. (We - recommend you provide URIs to the location from which the code is derived.) -THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKENO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, -WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THEUSE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS,COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. - -COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL ORCONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION. -The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the -software without specific, written prior permission. Title to copyright in this software and any associated -documentation will at all times remain with copyright holders. - -____________________________________ - -This formulation of W3C's notice and license became active on December 31 2002. This version removes the -copyright ownership notice such that this license can be used with materials other than those owned by the -W3C, reflects that ERCIM is now a host of the W3C, includes references to this specific dated version of the -license, and removes the ambiguous grant of "use". Otherwise, this version is the same as the previous -version and is written so as to preserve the Free Software Foundation's assessment of GPL compatibility and -OSI's certification under the Open Source Definition. Please see our Copyright FAQ for common questions -about using materials from our site, including specific terms and conditions for packages like libwww, Amaya, -and Jigsaw. Other questions about this notice can be directed to -site-policy@w3.org. - -%% This notice is provided with respect to Xalan, Xerces, which may be included with this software: - -/* - * The Apache Software License, Version 1.1 - * - * - * Copyright (c) 1999-2003 The Apache Software Foundation. All rights * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * - * 4. The names "Xerces" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation and was - * originally based on software copyright (c) 1999, International - * Business Machines, Inc., http://www.ibm.com. For more - * information on the Apache Software Foundation, please see - * - -%% This notice is provided with respect to JavaScript, which may be included with this software: - -AMENDMENTS -The Netscape Public License Version 1.1 ("NPL") consists of the Mozilla Public License Version 1.1 with the following Amendments, including Exhibit A-Netscape Public License.  Files identified with "Exhibit A-Netscape Public License" are governed by the Netscape Public License Version 1.1. -Additional Terms applicable to the Netscape Public License. -I. Effect. -These additional terms described in this Netscape Public License -- Amendments shall apply to the Mozilla Communicator client code and to all Covered Code under this License. -II. ''Netscape's Branded Code'' means Covered Code that Netscape distributes and/or permits others to distribute under one or more trademark(s) which are controlled by Netscape but which are not licensed for use under this License. -III. Netscape and logo. -This License does not grant any rights to use the trademarks "Netscape'', the "Netscape N and horizon'' logo or the "Netscape lighthouse" logo, "Netcenter", "Gecko", "Java" or "JavaScript", "Smart Browsing" even if such marks are included in the Original Code or Modifications. -IV. Inability to Comply Due to Contractual Obligation. -Prior to licensing the Original Code under this License, Netscape has licensed third party code for use in Netscape's Branded Code. To the extent that Netscape is limited contractually from making such third party code available under this License, Netscape may choose to reintegrate such code into Covered Code without being required to distribute such code in Source Code form, even if such code would otherwise be considered ''Modifications'' under this License. -V. Use of Modifications and Covered Code by Initial Developer. -V.1. In General. -The obligations of Section 3 apply to Netscape, except to the extent specified in this Amendment, Section V.2 and V.3. -V.2. Other Products. -Netscape may include Covered Code in products other than the Netscape's Branded Code which are released by Netscape during the two (2) years following the release date of the Original Code, without such additional products becoming subject to the terms of this License, and may license such additional products on different terms from those contained in this License. -V.3. Alternative Licensing. -Netscape may license the Source Code of Netscape's Branded Code, including Modifications incorporated therein, without such Netscape Branded Code becoming subject to the terms of this License, and may license such Netscape Branded Code on different terms from those contained in this License. -  -VI. Litigation. -Notwithstanding the limitations of Section 11 above, the provisions regarding litigation in Section 11(a), (b) and (c) of the License shall apply to all disputes relating to this License. - -EXHIBIT A-Netscape Public License. -  -''The contents of this file are subject to the Netscape Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/NPL/ -Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. -The Original Code is Mozilla Communicator client code, released March 31, 1998. -The Initial Developer of the Original Code is Netscape Communications Corporation. Portions created by Netscape are Copyright (C) 1998-1999 Netscape Communications Corporation. All Rights Reserved. -Contributor(s): ______________________________________. -  -Alternatively, the contents of this file may be used under the terms of the _____ license (the  "[___] License"), in which case the provisions of [______] License are applicable  instead of those above.  If you wish to allow use of your version of this file only under the terms of the [____] License and not to allow others to use your version of this file under the NPL, indicate your decision by deleting  the provisions above and replace  them with the notice and other provisions required by the [___] License.  If you do not delete the provisions above, a recipient may use your version of this file under either the NPL or the [___] License." - -MOZILLA PUBLIC LICENSE -Version 1.1 - -1. Definitions. -1.0.1. "Commercial Use" means distribution or otherwise making the Covered Code available to a third party. -1.1. ''Contributor'' means each entity that creates or contributes to the creation of Modifications. -1.2. ''Contributor Version'' means the combination of the Original Code, prior Modifications used by a Contributor, and the Modifications made by that particular Contributor. -1.3. ''Covered Code'' means the Original Code or Modifications or the combination of the Original Code and Modifications, in each case including portions thereof. -1.4. ''Electronic Distribution Mechanism'' means a mechanism generally accepted in the software development community for the electronic transfer of data. -1.5. ''Executable'' means Covered Code in any form other than Source Code. -1.6. ''Initial Developer'' means the individual or entity identified as the Initial Developer in the Source Code notice required by Exhibit A. -1.7. ''Larger Work'' means a work which combines Covered Code or portions thereof with code not governed by the terms of this License. -1.8. ''License'' means this document. -1.8.1. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. -1.9. ''Modifications'' means any addition to or deletion from the substance or structure of either the Original Code or any previous Modifications. When Covered Code is released as a series of files, a Modification is: -A. Any addition to or deletion from the contents of a file containing Original Code or previous Modifications. -B. Any new file that contains any part of the Original Code or previous Modifications. -  -1.10. ''Original Code'' means Source Code of computer software code which is described in the Source Code notice required by Exhibit A as Original Code, and which, at the time of its release under this License is not already Covered Code governed by this License. -1.10.1. "Patent Claims" means any patent claim(s), now owned or hereafter acquired, including without limitation,  method, process, and apparatus claims, in any patent Licensable by grantor. -1.11. ''Source Code'' means the preferred form of the Covered Code for making modifications to it, including all modules it contains, plus any associated interface definition files, scripts used to control compilation and installation of an Executable, or source code differential comparisons against either the Original Code or another well known, available Covered Code of the Contributor's choice. The Source Code can be in a compressed or archival form, provided the appropriate decompression or de-archiving software is widely available for no charge. -1.12. "You'' (or "Your")  means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License or a future version of this License issued under Section 6.1. For legal entities, "You'' includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control'' means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. -2. Source Code License. -2.1. The Initial Developer Grant. -The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims: -(a)  under intellectual property rights (other than patent or trademark) Licensable by Initial Developer to use, reproduce, modify, display, perform, sublicense and distribute the Original Code (or portions thereof) with or without Modifications, and/or as part of a Larger Work; and -(b) under Patents Claims infringed by the making, using or selling of Original Code, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Code (or portions thereof). -  -(c) the licenses granted in this Section 2.1(a) and (b) are effective on the date Initial Developer first distributes Original Code under the terms of this License. -(d) Notwithstanding Section 2.1(b) above, no patent license is granted: 1) for code that You delete from the Original Code; 2) separate from the Original Code;  or 3) for infringements caused by: i) the modification of the Original Code or ii) the combination of the Original Code with other software or devices. -  -2.2. Contributor Grant. -Subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license -  -(a)  under intellectual property rights (other than patent or trademark) Licensable by Contributor, to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof) either on an unmodified basis, with other Modifications, as Covered Code and/or as part of a Larger Work; and -(b) under Patent Claims infringed by the making, using, or selling of  Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: 1) Modifications made by that Contributor (or portions thereof); and 2) the combination of  Modifications made by that Contributor with its Contributor Version (or portions of such combination). -(c) the licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first makes Commercial Use of the Covered Code. -(d)    Notwithstanding Section 2.2(b) above, no patent license is granted: 1) for any code that Contributor has deleted from the Contributor Version; 2)  separate from the Contributor Version;  3)  for infringements caused by: i) third party modifications of Contributor Version or ii)  the combination of Modifications made by that Contributor with other software  (except as part of the Contributor Version) or other devices; or 4) under Patent Claims infringed by Covered Code in the absence of Modifications made by that Contributor. - -3. Distribution Obligations. -3.1. Application of License. -The Modifications which You create or to which You contribute are governed by the terms of this License, including without limitation Section 2.2. The Source Code version of Covered Code may be distributed only under the terms of this License or a future version of this License released under Section 6.1, and You must include a copy of this License with every copy of the Source Code You distribute. You may not offer or impose any terms on any Source Code version that alters or restricts the applicable version of this License or the recipients' rights hereunder. However, You may include an additional document offering the additional rights described in Section 3.5. -3.2. Availability of Source Code. -Any Modification which You create or to which You contribute must be made available in Source Code form under the terms of this License either on the same media as an Executable version or via an accepted Electronic Distribution Mechanism to anyone to whom you made an Executable version available; and if made available via Electronic Distribution Mechanism, must remain available for at least twelve (12) months after the date it initially became available, or at least six (6) months after a subsequent version of that particular Modification has been made available to such recipients. You are responsible for ensuring that the Source Code version remains available even if the Electronic Distribution Mechanism is maintained by a third party. -3.3. Description of Modifications. -You must cause all Covered Code to which You contribute to contain a file documenting the changes You made to create that Covered Code and the date of any change. You must include a prominent statement that the Modification is derived, directly or indirectly, from Original Code provided by the Initial Developer and including the name of the Initial Developer in (a) the Source Code, and (b) in any notice in an Executable version or related documentation in which You describe the origin or ownership of the Covered Code. -3.4. Intellectual Property Matters -(a) Third Party Claims. -If Contributor has knowledge that a license under a third party's intellectual property rights is required to exercise the rights granted by such Contributor under Sections 2.1 or 2.2, Contributor must include a text file with the Source Code distribution titled "LEGAL'' which describes the claim and the party making the claim in sufficient detail that a recipient will know whom to contact. If Contributor obtains such knowledge after the Modification is made available as described in Section 3.2, Contributor shall promptly modify the LEGAL file in all copies Contributor makes available thereafter and shall take other steps (such as notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who received the Covered Code that new knowledge has been obtained. -(b) Contributor APIs. -If Contributor's Modifications include an application programming interface and Contributor has knowledge of patent licenses which are reasonably necessary to implement that API, Contributor must also include this information in the LEGAL file. -  -          (c)    Representations. -Contributor represents that, except as disclosed pursuant to Section 3.4(a) above, Contributor believes that Contributor's Modifications are Contributor's original creation(s) and/or Contributor has sufficient rights to grant the rights conveyed by this License. - -3.5. Required Notices. -You must duplicate the notice in Exhibit A in each file of the Source Code.  If it is not possible to put such notice in a particular Source Code file due to its structure, then You must include such notice in a location (such as a relevant directory) where a user would be likely to look for such a notice.  If You created one or more Modification(s) You may add your name as a Contributor to the notice described in Exhibit A.  You must also duplicate this License in any documentation for the Source Code where You describe recipients' rights or ownership rights relating to Covered Code.  You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Code. However, You may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear than any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. -3.6. Distribution of Executable Versions. -You may distribute Covered Code in Executable form only if the requirements of Section 3.1-3.5 have been met for that Covered Code, and if You include a notice stating that the Source Code version of the Covered Code is available under the terms of this License, including a description of how and where You have fulfilled the obligations of Section 3.2. The notice must be conspicuously included in any notice in an Executable version, related documentation or collateral in which You describe recipients' rights relating to the Covered Code. You may distribute the Executable version of Covered Code or ownership rights under a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable version does not attempt to limit or alter the recipient's rights in the Source Code version from the rights set forth in this License. If You distribute the Executable version under a different license You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. -3.7. Larger Works. -You may create a Larger Work by combining Covered Code with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Code. -4. Inability to Comply Due to Statute or Regulation. -If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Code due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be included in the LEGAL file described in Section 3.4 and must be included with all distributions of the Source Code. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. -5. Application of this License. -This License applies to code to which the Initial Developer has attached the notice in Exhibit A and to related Covered Code. -6. Versions of the License. -6.1. New Versions. -Netscape Communications Corporation (''Netscape'') may publish revised and/or new versions of the License from time to time. Each version will be given a distinguishing version number. -6.2. Effect of New Versions. -Once Covered Code has been published under a particular version of the License, You may always continue to use it under the terms of that version. You may also choose to use such Covered Code under the terms of any subsequent version of the License published by Netscape. No one other than Netscape has the right to modify the terms applicable to Covered Code created under this License. -6.3. Derivative Works. -If You create or use a modified version of this License (which you may only do in order to apply it to code which is not already Covered Code governed by this License), You must (a) rename Your license so that the phrases ''Mozilla'', ''MOZILLAPL'', ''MOZPL'', ''Netscape'', "MPL", ''NPL'' or any confusingly similar phrase do not appear in your license (except to note that your license differs from this License) and (b) otherwise make it clear that Your version of the license contains terms which differ from the Mozilla Public License and Netscape Public License. (Filling in the name of the Initial Developer, Original Code or Contributor in the notice described in Exhibit A shall not of themselves be deemed to be modifications of this License.) -7. DISCLAIMER OF WARRANTY. -COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS'' BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. -8. TERMINATION. -8.1.  This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. All sublicenses to the Covered Code which are properly granted shall survive any termination of this License. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. -8.2.  If You initiate litigation by asserting a patent infringement claim (excluding declatory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You file such action is referred to as "Participant")  alleging that: -(a)  such Participant's Contributor Version directly or indirectly infringes any patent, then any and all rights granted by such Participant to You under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively, unless if within 60 days after receipt of notice You either: (i)  agree in writing to pay Participant a mutually agreeable reasonable royalty for Your past and future use of Modifications made by such Participant, or (ii) withdraw Your litigation claim with respect to the Contributor Version against such Participant.  If within 60 days of notice, a reasonable royalty and payment arrangement are not mutually agreed upon in writing by the parties or the litigation claim is not withdrawn, the rights granted by Participant to You under Sections 2.1 and/or 2.2 automatically terminate at the expiration of the 60 day notice period specified above. -(b)  any software, hardware, or device, other than such Participant's Contributor Version, directly or indirectly infringes any patent, then any rights granted to You by such Participant under Sections 2.1(b) and 2.2(b) are revoked effective as of the date You first made, used, sold, distributed, or had made, Modifications made by that Participant. -8.3.  If You assert a patent infringement claim against Participant alleging that such Participant's Contributor Version directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license. -8.4.  In the event of termination under Sections 8.1 or 8.2 above,  all end user license agreements (excluding distributors and resellers) which have been validly granted by You or any distributor hereunder prior to termination shall survive termination. -9. LIMITATION OF LIABILITY. -UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. -10. U.S. GOVERNMENT END USERS. -The Covered Code is a ''commercial item,'' as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of ''commercial computer software'' and ''commercial computer software documentation,'' as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Code with only those rights set forth herein. -11. MISCELLANEOUS. -This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by California law provisions (except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law provisions. With respect to disputes in which at least one party is a citizen of, or an entity chartered or registered to do business in the United States of America, any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California, with venue lying in Santa Clara County, California, with the losing party responsible for costs, including without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. -12. RESPONSIBILITY FOR CLAIMS. -As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. -13. MULTIPLE-LICENSED CODE. -Initial Developer may designate portions of the Covered Code as "Multiple-Licensed".  "Multiple-Licensed" means that the Initial Developer permits you to utilize portions of the Covered Code under Your choice of the NPL or the alternative licenses, if any, specified by the Initial Developer in the file described in Exhibit A. - -EXHIBIT A -Mozilla Public License. -``The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at -http://www.mozilla.org/MPL/ -Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF -ANY KIND, either express or implied. See the License for the specific language governing rights and -limitations under the License. -The Original Code is ______________________________________. -The Initial Developer of the Original Code is ________________________. Portions created by - ______________________ are Copyright (C) ______ _______________________. All Rights -Reserved. -Contributor(s): ______________________________________. -Alternatively, the contents of this file may be used under the terms of the _____ license (the  "[___] License"), in which case the provisions of [______] License are applicable  instead of those above.  If you wish to allow use of your version of this file only under the terms of the [____] License and not to allow others to use your version of this file under the MPL, indicate your decision by deleting  the provisions above and replace  them with the notice and other provisions required by the [___] License.  If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the [___] License." -[NOTE: The text of this Exhibit A may differ slightly from the text of the notices in the Source Code files of the Original Code. You should use the text of this Exhibit A rather than the text found in the Original Code Source Code for Your Modifications.] - -%% This notice is provided with respect to Mesa 3-D graphics library v. 5, which may be included with this software: - -Copyright (c) 2007 The Khronos Group Inc. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and/or associated documentation files (the -"Materials"), to deal in the Materials without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Materials, and to -permit persons to whom the Materials are furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Materials. - -THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. - -%% This notice is provided with respect to Byte Code Engineering Library (BCEL), which may be included with this software: - - Apache Software License - - /* -==================================================================== * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. Allrights - * reserved. - * - * Redistribution and use in source and binary forms, withor without - * modification, are permitted provided that the followingconditions - * are met: - * - * 1. Redistributions of source code must retain the abovecopyright - * notice, this list of conditions and the followingdisclaimer. - * - * 2. Redistributions in binary form must reproduce theabove copyright - * notice, this list of conditions and the followingdisclaimer in - * the documentation and/or other materials providedwith the - * distribution. - * - * 3. The end-user documentation included with theredistribution, - * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation -(http://www.apache.org/)." - * Alternately, this acknowledgment may appear in thesoftware itself, - * if and wherever such third-party acknowledgmentsnormally appear. - * - * 4. The names "Apache" and "Apache Software Foundation"and - * "Apache BCEL" must not be used to endorse or promoteproducts - * derived from this software without prior writtenpermission. For - * written permission, please contact apache@apache.org. * - * 5. Products derived from this software may not be called"Apache", - * "Apache BCEL", nor may "Apache" appear in their name,without - * prior written permission of the Apache SoftwareFoundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED ORIMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIEDWARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSEARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWAREFOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVERCAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICTLIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING INANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF - * SUCH DAMAGE. - * -==================================================================== * - * This software consists of voluntary contributions madeby many - * individuals on behalf of the Apache Software -Foundation. For more - * information on the Apache Software Foundation, pleasesee - * . - */ - -%% This notice is provided with respect to Regexp, Regular Expression Package, which may be included with this software: - -The Apache Software License, Version 1.1 -Copyright (c) 2001 The Apache Software Foundation. All rights -reserved. -Redistribution and use in source and binary forms, with or without modification,are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in -the documentation and/or other materials provided with the -distribution. - -3. The end-user documentation included with the redistribution, -if any, must include the following acknowledgment: -"This product includes software developed by the -Apache Software Foundation (http://www.apache.org/)." -Alternately, this acknowledgment may appear in the software itself, -if and wherever such third-party acknowledgments normally appear. - -4. The names "Apache" and "Apache Software Foundation" and -"Apache Turbine" must not be used to endorse or promote products -derived from this software without prior written permission. For -written permission, please contact apache@apache.org. - -5. Products derived from this software may not be called "Apache", -"Apache Turbine", nor may "Apache" appear in their name, without -prior written permission of the Apache Software Foundation. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR -ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. - -==================================================================== -This software consists of voluntary contributions made by many -individuals on behalf of the Apache Software Foundation. For more -information on the Apache Software Foundation, please see - -http://www.apache.org. - -%% This notice is provided with respect to CUP Parser Generator for Java, which may be included with this software: - -CUP Parser Generator Copyright Notice, License, and Disclaimer - -Copyright 1996-1999 by Scott Hudson, Frank Flannery, C. Scott Ananian -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, provided thatthe above copyright notice appear in all copies and that both the copyrightnotice and this permission notice and warranty disclaimer appear in -supporting documentation, and that the names of the authors or their employersnot be used in advertising or publicity pertaining to distribution of -the software without specific, written prior permission. - -The authors and their employers disclaim all warranties with regard to thissoftware, including all implied warranties of merchantability and -fitness. In no event shall the authors or their employers be liable for anyspecial, indirect or consequential damages or any damages whatsoever -resulting from loss of use, data or profits, whether in an action of contract,negligence or other tortious action, arising out of or in connection withthe use or performance of this software. - -%% This notice is provided with respect to SAX v. 2.0.1, which may be included with this software: - -Copyright Status - - SAX is free! - - In fact, it's not possible to own a license to SAX, since it's been placed in the public - domain. - - No Warranty - - Because SAX is released to the public domain, there is no warranty for the design or for - the software implementation, to the extent permitted by applicable law. Except when - otherwise stated in writing the copyright holders and/or other parties provide SAX "as is" - without warranty of any kind, either expressed or implied, including, but not limited to, the - implied warranties of merchantability and fitness for a particular purpose. The entire risk as - to the quality and performance of SAX is with you. Should SAX prove defective, you - assume the cost of all necessary servicing, repair or correction. - - In no event unless required by applicable law or agreed to in writing will any copyright - holder, or any other party who may modify and/or redistribute SAX, be liable to you for - damages, including any general, special, incidental or consequential damages arising out of - the use or inability to use SAX (including but not limited to loss of data or data being - rendered inaccurate or losses sustained by you or third parties or a failure of the SAX to - operate with any other programs), even if such holder or other party has been advised of - the possibility of such damages. - - Copyright Disclaimers - - This page includes statements to that effect by David Megginson, who would have been - able to claim copyright for the original work. - SAX 1.0 - - Version 1.0 of the Simple API for XML (SAX), created collectively by the membership of - the XML-DEV mailing list, is hereby released into the public domain. - - No one owns SAX: you may use it freely in both commercial and non-commercial - applications, bundle it with your software distribution, include it on a CD-ROM, list the - source code in a book, mirror the documentation at your own web site, or use it in any - other way you see fit. - - David Megginson, sax@megginson.com - 1998-05-11 - - SAX 2.0 - - I hereby abandon any property rights to SAX 2.0 (the Simple API for XML), and release - all of the SAX 2.0 source code, compiled code, and documentation contained in this - distribution into the Public Domain. SAX comes with NO WARRANTY or guarantee of - fitness for any purpose. - - David Megginson, david@megginson.com - 2000-05-05 - -%% This notice is provided with respect to Cryptix, which may be included with this software: - -Cryptix General License - -Copyright © 1995-2003 The Cryptix Foundation Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions aremet: - - 1.Redistributions of source code must retain the copyright notice, this list of conditions and the following disclaimer. 2.Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE CRYPTIX FOUNDATION LIMITED AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS ORIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CRYPTIX FOUNDATION LIMITED OR CONTRIBUTORS BELIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOTLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESSINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OFTHE POSSIBILITY OF SUCH DAMAGE. - -%% This notice is provided with respect to X Window System, which may be included with this software: - -Copyright The Open Group - -Permission to use, copy, modify, distribute, and sell this software and itsdocumentation for any purpose is hereby granted without fee, provided that theabove copyright notice appear in all copies and that both that copyright noticeand this permission notice appear in supporting documentation. - -The above copyright notice and this permission notice shall be included in allcopies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESSFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUPBE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OFCONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THESOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. - -Portions also covered by other licenses as noted in the above URL. - -%% This notice is provided with respect to Retroweaver, which may be included with this software: - -Copyright (c) February 2004, Toby Reyelts -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -Neither the name of Toby Reyelts nor the names of his contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICTLIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -%% This notice is provided with respect to stripper, which may be included with this software: - -Stripper : debug information stripper - Copyright (c) 2003 Kohsuke Kawaguchi - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holders nor the names of its - contributors may be used to endorse or promote products derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -%% This notice is provided with respect to libpng official PNG reference library, which may be included with this software: - -This copy of the libpng notices is provided for your convenience. In case ofany discrepancy between this copy and the notices in the file png.h that isincluded in the libpng distribution, the latter shall prevail. - -COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: - -If you modify libpng you may insert additional notices immediately followingthis sentence. - -libpng version 1.2.6, December 3, 2004, is -Copyright (c) 2004 Glenn Randers-Pehrson, and is -distributed according to the same disclaimer and license as libpng-1.2.5with the following individual added to the list of Contributing Authors - Cosmin Truta - -libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, areCopyright (c) 2000-2002 Glenn Randers-Pehrson, and are -distributed according to the same disclaimer and license as libpng-1.0.6with the following individuals added to the list of Contributing Authors - Simon-Pierre Cadieux - Eric S. Raymond - Gilles Vollant - -and with the following additions to the disclaimer: - - There is no warranty against interference with your enjoyment of the library or against infringement. There is no warranty that our - efforts or the library will fulfill any of your particular purposes or needs. This library is provided with all faults, and the entire risk of satisfactory quality, performance, accuracy, and effort is with the user. - -libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, areCopyright (c) 1998, 1999 Glenn Randers-Pehrson, and are -distributed according to the same disclaimer and license as libpng-0.96,with the following individuals added to the list of Contributing Authors: - Tom Lane - Glenn Randers-Pehrson - Willem van Schaik - -libpng versions 0.89, June 1996, through 0.96, May 1997, are -Copyright (c) 1996, 1997 Andreas Dilger -Distributed according to the same disclaimer and license as libpng-0.88,with the following individuals added to the list of Contributing Authors: - John Bowler - Kevin Bracey - Sam Bushell - Magnus Holmgren - Greg Roelofs - Tom Tanner - -libpng versions 0.5, May 1995, through 0.88, January 1996, are -Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. - -For the purposes of this copyright and license, "Contributing Authors"is defined as the following set of individuals: - - Andreas Dilger - Dave Martindale - Guy Eric Schalnat - Paul Schmidt - Tim Wegner - -The PNG Reference Library is supplied "AS IS". The Contributing Authorsand Group 42, Inc. disclaim all warranties, expressed or implied, -including, without limitation, the warranties of merchantability and offitness for any purpose. The Contributing Authors and Group 42, Inc. -assume no liability for direct, indirect, incidental, special, exemplary,or consequential damages, which may result from the use of the PNG -Reference Library, even if advised of the possibility of such damage. - -Permission is hereby granted to use, copy, modify, and distribute thissource code, or portions hereof, for any purpose, without fee, subjectto the following restrictions: - -1. The origin of this source code must not be misrepresented. - -2. Altered versions must be plainly marked as such and must not - be misrepresented as being the original source. - -3. This Copyright notice may not be removed or altered from any - source or altered source distribution. - -The Contributing Authors and Group 42, Inc. specifically permit, withoutfee, and encourage the use of this source code as a component to -supporting the PNG file format in commercial products. If you use thissource code in a product, acknowledgment is not required but would be -appreciated. - - -A "png_get_copyright" function is available, for convenient use in "about"boxes and the like: - - printf("%s",png_get_copyright(NULL)); - -Also, the PNG logo (in PNG format, of course) is supplied in the -files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). - -Libpng is OSI Certified Open Source Software. OSI Certified Open Source is acertification mark of the Open Source Initiative. - -Glenn Randers-Pehrson -glennrp at users.sourceforge.net -December 3, 2004 - -%% This notice is provided with respect to Libungif - An uncompressed GIF library, which may be included with this software: - -The GIFLIB distribution is Copyright (c) 1997 Eric S. Raymond - -Permission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files (the "Software"), to dealin the Software without restriction, including without limitation the rightsto use, copy, modify, merge, publish, distribute, sublicense, and/or sellcopies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included inall copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THEAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS INTHE SOFTWARE. - -%% This notice is provided with respect to XML Resolver library, Xalan J2, and StAX API, which may be included with this software: - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. - "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." - "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. - - You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - -%% Some Portions licensed from IBM are available at: -http://www.ibm.com/software/globalization/icu/ - -%% This notice is provided with respect to ICU4J, ICU 1.8.1 and later, which may be included with this software: - -ICU License - ICU 1.8.1 and later COPYRIGHT AND PERMISSION NOTICE Cop -yright (c) -1995-2003 International Business Machines Corporation and others All rightsreserved. Permission is hereby granted, free of charge, to any person obtaininga copy of this software and associated documentation files (the "Software"), todeal in the Software without restriction, including without limitation therights to use, copy, modify, merge, publish, distribute, and/or sell copies ofthe Software, and to permit persons to whom the Software is furnished to do so,provided that the above copyright notice(s) and this permission notice appear inall copies of the Software and that both the above copyright notice(s) and thispermission notice appear in supporting documentation. THE SOFTWARE IS PROVIDED"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOTLIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSEAND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHTHOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY C - LAIM, OR ANYSPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTINGFROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCEOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE ORPERFORMANCE OF THIS SOFTWARE. Except as contained in this notice, the name of acopyright holder shall not be used in advertising or otherwise to promote thesale, use or other dealings in this Software without prior written authorizationof the copyright holder. - -%% This notice is provided with respect to Jing, which may be included with this software: - -Jing Copying Conditions - -Copyright (c) 2001-2003 Thai Open Source Software Center Ltd -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification,are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice,this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice,this list of conditions and the following disclaimer in the documentation and/orother materials provided with the distribution. - * Neither the name of the Thai Open Source Software Center Ltd nor the namesof its contributors may be used to endorse or promote products derived from thissoftware without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ANDANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIEDWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AREDISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ONANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -%% This notice is provided with respect to RELAX NG Object Model/Parser, which may be included with this software: - - -The MIT License - -Copyright (c) - -Permission is hereby granted, free of charge, to any person obtaining a copy ofthis software and associated documentation files (the "Software"), to deal inthe Software without restriction, including without limitation the rights touse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies ofthe Software, and to permit persons to whom the Software is furnished to do so,subject to the following conditions: - -The above copyright notice and this permission notice shall be included in allcopies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESSFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS ORCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHERIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR INCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -%% This notice is provided with respect to XFree86-VidMode Extension, which may be included with this software: - -Version 1.1 of XFree86 ProjectLicence. - - Copyright (C) 1994-2004 The XFree86 Project, Inc. All rights reserved. - - Permission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files (the "Software"), to deal inthe Software without restriction, including without limitation the rights touse, copy, modify, merge, publish, distribute, sublicence, and/or sell copies ofthe Software, and to permit persons to whom the Software is furnished to do so,subject to the following conditions: - - 1. Redistributions of source code must retain the above copyright notice,this list of conditions, and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyrightnotice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution, and in thesame place and form as other copyright, license and disclaimer information. 3. The end-user documentation included with the redistribution, if any,must include the following acknowledgment: "This product includes softwaredeveloped by The XFree86 Project, Inc (http://www.xfree86.org/) and itscontributors", in the same place and form as other third-party acknowledgments.Alternately, this acknowledgment may appear in the software itself, in the sameform and location as other such third-party acknowledgments. - 4. Except as contained in this notice, the name of The XFree86 Project,Inc shall not be used in advertising or otherwise to promote the sale, use orother dealings in this Software without prior written authorization from TheXFree86 Project, Inc. - - THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY ANDFITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE XFREE86PROJECT, INC OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; ORBUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER INCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITYOF SUCH DAMAGE. - -%% This notice is provided with respect to XML Security, which may be included with this software: - - The Apache Software License, - Version 1.1 - - - PDF - - - Copyright (C) 2002 The Apache SoftwareFoundation. - All rights reserved. Redistribution anduse in - source and binary forms, with or withoutmodifica- - tion, are permitted provided that thefollowing - conditions are met: 1. Redistributions ofsource - code must retain the above copyrightnotice, this - list of conditions and the followingdisclaimer. - 2. Redistributions in binary form mustreproduce - the above copyright notice, this list of conditions and the following disclaimerin the - documentation and/or other materialsprovided with - the distribution. 3. The end-userdocumentation - included with the redistribution, if any,must - include the following acknowledgment:"This - product includes software developed bythe Apache - Software Foundation -(http://www.apache.org/)." - Alternately, this acknowledgment mayappear in the - software itself, if and wherever suchthird-party - acknowledgments normally appear. 4. Thenames - "Apache Forrest" and "Apache SoftwareFoundation" - must not be used to endorse or promoteproducts - derived from this software without priorwritten - permission. For written permission,please contact - apache@apache.org. 5. Products derivedfrom this - software may not be called "Apache", normay - "Apache" appear in their name, withoutprior - written permission of the Apache Software Foundation. THIS SOFTWARE IS PROVIDED``AS IS'' - AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THEIMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESSFOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NOEVENT - SHALL THE APACHE SOFTWARE FOUNDATION ORITS - CONTRIBUTORS BE LIABLE FOR ANY DIRECT,INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, ORCONSEQUENTIAL - DAMAGES (INCLU- DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ORSERVICES; LOSS - OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANYTHEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICTLIABILITY, - OR TORT (INCLUDING NEGLIGENCE OROTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF - SUCH DAMAGE. This software consists ofvoluntary - contributions made by many individuals onbehalf - of the Apache Software Foundation. Formore - information on the Apache SoftwareFoundation, - please see . - -%% This notice is provided with respect to Independent JPEG Group's software (libjpeg), which may be included with this software: - -In plain English: - -1. We don't promise that this software works. (But if you find any bugs, - please let us know!) -2. You can use this software for whatever you want. You don't have to pay us. -3. You may not pretend that you wrote this software. If you use it in a program, you must acknowledge somewhere in your documentation that you've used the IJG code. - -In legalese: - -The authors make NO WARRANTY or representation, either express or implied, with respect to this software, its quality, accuracy, merchantability, or fitness for a particular purpose. This software is provided "AS IS", and you, its user, assume the entire risk as to its quality and accuracy. - -This software is copyright (C) 1991-1998, Thomas G. Lane. -All Rights Reserved except as specified below. - -Permission is hereby granted to use, copy, modify, and distribute this software (or portions thereof) for any purpose, without fee, subject to these conditions: - -(1) If any part of the source code for this software is distributed, then this -README file must be included, with this copyright and no-warranty notice unaltered; and any additions, deletions, or changes to the original files must be clearly indicated in accompanying documentation. - -(2) If only executable code is distributed, then the accompanying documentation must state that "this software is based in part on the work of the Independent JPEG Group". - -(3) Permission for use of this software is granted only if the user accepts full responsibility for any undesirable consequences; the authors accept NO LIABILITY for damages of any kind. - -These conditions apply to any software derived from or based on the IJG code, not just to the unmodified library. If you use our work, you ought to acknowledge us. - -Permission is NOT granted for the use of any IJG author's name or company name in advertising or publicity relating to this software or products derived from it. This software may be referred to only as "the Independent JPEG Group's software". - -We specifically permit and encourage the use of this software as the basis of commercial products, provided that all warranty or liability claims are assumed by the product vendor. - -ansi2knr.c is included in this distribution by permission of L. Peter Deutsch, sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA. ansi2knr.c is NOT covered by the above copyright and conditions, but instead by the usual distribution terms of the Free Software Foundation; principally, that you must include source code if you redistribute it. (See the file ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part of any program generated from the IJG code, this does not limit you more than the foregoing paragraphs do. - -The Unix configuration script "configure" was produced with GNU Autoconf. It is copyright by the Free Software Foundation but is freely distributable. The same holds for its supporting scripts (config.guess, config.sub, ltconfig, ltmain.sh). Another support script, install-sh, is copyright by M.I.T. but is also freely distributable. - -It appears that the arithmetic coding option of the JPEG spec is covered by patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot legally be used without obtaining one or more licenses. For this reason, support for arithmetic coding has been removed from the free JPEG software. (Since arithmetic coding provides only a marginal gain over the unpatented Huffman mode, it is unlikely that very many implementations will support it.) So far as we are aware, there are no patent restrictions on the remaining code. - -The IJG distribution formerly included code to read and write GIF files. To avoid entanglement with the Unisys LZW patent, GIF reading support has been removed altogether, and the GIF writer has been simplified to produce "uncompressed GIFs". This technique does not use the LZW algorithm; the resulting GIF files are larger than usual, but are readable by all standard GIF decoders. - -We are required to state that - "The Graphics Interchange Format(c) is the Copyright property of - CompuServe Incorporated. GIF(sm) is a Service Mark property of - CompuServe Incorporated." - -%% This notice is provided with respect to X Resize and Rotate (Xrandr) Extension, which may be included with this software: -2. XFree86 License - -XFree86 code without an explicit copyright is covered by the following -copyright/license: - -Copyright (C) 1994-2003 The XFree86 Project, Inc. All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 -PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the XFree86 Project shall not be -used in advertising or otherwise to promote the sale, use or other dealings in -this Software without prior written authorization from the XFree86 Project. - -%% This notice is provided with respect to fontconfig, which may be included with this software: -Id: COPYING,v 1.3 2003/04/04 20:17:40 keithp Exp $ -Copyright 2001,2003 Keith Packard - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the name of Keith Packard not be used in -advertising or publicity pertaining to distribution of the software without -specific, written prior permission. Keith Packard makes no -representations about the suitability of this software for any purpose. It -is provided "as is" without express or implied warranty. - -KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -%% This notice is provided with respect to XFree86, which may be included with this software: -Copyright (C) 1994-2002 The XFree86 Project, Inc. All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated -documentation files (the "Software"), to deal in the Software without -restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to the -following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the XFree86 Project shall not be -used in advertising or otherwise -to promote the sale, use or other dealings in this Software without prior -written authorization from the XFree86 -Project. -%% This notice is provided with respect to Fast Infoset, which may be included with this software: -* Fast Infoset ver. 0.1 software ("Software") -* -* Copyright, 2004-2005 Sun Microsystems, Inc. All Rights Reserved. -* -* Software is licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. You may -* obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -* License for the specific language governing permissions and limitations. -* -* Sun supports and benefits from the global community of open source -* developers, and thanks the community for its important contributions and -* open standards-based technology, which Sun has adopted into many of its -* products. -* -* Please note that portions of Software may be provided with notices and -* open source licenses from such communities and third parties that govern the -* use of those portions, and any licenses granted hereunder do not alter any -* rights and obligations you may have under such open source licenses, -* however, the disclaimer of warranty and limitation of liability provisions -* in this License will apply to all Software in this distribution. -* -* You acknowledge that the Software is not designed, licensed or intended -* for use in the design, construction, operation or maintenance of any nuclear -* facility. -* -* Apache License -* Version 2.0, January 2004 -* http://www.apache.org/licenses/ -* -*/ -/* -* ==================================================================== -* -* This code is subject to the freebxml License, Version 1.1 -* -* Copyright (c) 2001 - 2005 freebxml.org. All rights reserved. -* -* $Header: /cvs/fi/FastInfoset/src/com/sun/xml/internal/fastinfoset/AbstractResourceBundle.java,v 1.2 -*  ==================================================================== -*/ -%% This notice is provided with respect to Kerberos, which may be included with this software: - -/* - * Copyright (C) 1998 by the FundsXpress, INC. - * - * All rights reserved. - * - * Export of this software from the United States of America may require - * a specific license from the United States Government.  It is the - * responsibility of any person or organization contemplating export to - * obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of FundsXpress. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. FundsXpress makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -%% This notice is provided with respect to Unicode's CLDR data repository, which may be included with this software: - - Unicode Copyright - - For the general privacy policy governing access to this site, see the -Unicode Privacy Policy. For trademark usage, see the the Unicode Consortium -Trademarks and Logo Policy. - Notice to End User: Terms of Use - Carefully read the following legal agreement ("Agreement"). Use or copying -of the software and/or codes provided with this agreement (The "Software") -constitutes your acceptance of these terms - - 1. Unicode Copyright. - 1. Copyright © 1991-2005 Unicode, Inc. All rights reserved. - 2. Certain documents and files on this website contain a legend -indicating that "Modification is permitted." Any person is hereby authorized, -without fee, to modify such documents and files to create derivative works -conforming to the Unicode® Standard, subject to Terms and Conditions herein. - 3. Any person is hereby authorized, without fee, to view, use, -reproduce, and distribute all documents and files solely for informational -purposes in the creation of products supporting the Unicode Standard, subject to -the Terms and Conditions herein. - 4. Further specifications of rights and restrictions pertaining to -the use of the particular set of data files known as the "Unicode Character -Database" can be found in Exhibit 1. - 5. Further specifications of rights and restrictions pertaining to -the use of the particular set of files that constitute the online edition of The -Unicode Standard, Version 4.0, may be found in V4.0 online edition. - 6. No license is granted to "mirror" the Unicode website where a -fee is charged for access to the "mirror" site. - 7. Modification is not permitted with respect to this document. All -copies of this document must be verbatim. - 2. Restricted Rights Legend. Any technical data or software which is -licensed to the United States of America, its agencies and/or instrumentalities -under this Agreement is commercial technical data or commercial computer -software developed exclusively at private expense as defined in FAR 2.101, or -DFARS 252.227-7014 (June 1995), as applicable. For technical data, use, -duplication, or disclosure by the Government is subject to restrictions as set -forth in DFARS 202.227-7015 Technical Data, Commercial and Items (Nov 1995) and -this Agreement. For Software, in accordance with FAR 12-212 or DFARS 227-7202, -as applicable, use, duplication or disclosure by the Government is subject to -the restrictions set forth in this Agreement. - 3. Warranties and Disclaimers. - 1. This publication and/or website may include technical or -typographical errors or other inaccuracies . Changes are periodically added to -the information herein; these changes will be incorporated in new editions of -the publication and/or website. Unicode may make improvements and/or changes in -the product(s) and/or program(s) described in this publication and/or website at -any time. - 2. If this file has been purchased on magnetic or optical media -from Unicode, Inc. the sole and exclusive remedy for any claim will be exchange -of the defective media within ninety (90) days of original purchase. - 3. EXCEPT AS PROVIDED IN SECTION C.2, THIS PUBLICATION AND/OR -SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS, -IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. UNICODE -AND ITS LICENSORS ASSUME NO RESPONSIBILITY FOR ERRORS OR OMISSIONS IN THIS -PUBLICATION AND/OR SOFTWARE OR OTHER DOCUMENTS WHICH ARE REFERENCED BY OR LINKED -TO THIS PUBLICATION OR THE UNICODE WEBSITE. - 4. Waiver of Damages. In no event shall Unicode or its licensors be -liable for any special, incidental, indirect or consequential damages of any -kind, or any damages whatsoever, whether or not Unicode was advised of the -possibility of the damage, including, without limitation, those resulting from -the following: loss of use, data or profits, in connection with the use, -modification or distribution of this information or its derivatives. - 5. Trademarks. - 1. Unicode and the Unicode logo are registered trademarks of -Unicode, Inc. - 2. This site contains product names and corporate names of other -companies. All product names and company names and logos mentioned herein are -the trademarks or registered trademarks of their respective owners. Other -products and corporate names mentioned herein which are trademarks of a third -party are used only for explanation and for the owners' benefit and with no -intent to infringe. - 3. Use of third party products or information referred to herein is -at the user's risk. - 6. Miscellaneous. - 1. Jurisdiction and Venue. This server is operated from a location -in the State of California, United States of America. Unicode makes no -representation that the materials are appropriate for use in other locations. If -you access this server from other locations, you are responsible for compliance -with local laws. This Agreement, all use of this site and any claims and damages -resulting from use of this site are governed solely by the laws of the State of -California without regard to any principles which would apply the laws of a -different jurisdiction. The user agrees that any disputes regarding this site -shall be resolved solely in the courts located in Santa Clara County, -California. The user agrees said courts have personal jurisdiction and agree to -waive any right to transfer the dispute to any other forum. - 2. Modification by Unicode Unicode shall have the right to modify -this Agreement at any time by posting it to this site. The user may not assign -any part of this Agreement without Unicode's prior written consent. - 3. Taxes. The user agrees to pay any taxes arising from access to -this website or use of the information herein, except for those based on -Unicode's net income. - 4. Severability. If any provision of this Agreement is declared -invalid or unenforceable, the remaining provisions of this Agreement shall -remain in effect. - 5. Entire Agreement. This Agreement constitutes the entire -agreement between the parties. - -EXHIBIT 1 -UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE - - Unicode Data Files include all data files under the directories -http://www.unicode.org/Public/ and http://www.unicode.org/reports/. Unicode -Software includes any source code under the directories -http://www.unicode.org/Public/ and http://www.unicode.org/reports/. - - NOTICE TO USER: Carefully read the following legal agreement. BY -DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES -("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND -AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU -DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES -OR SOFTWARE. - - COPYRIGHT AND PERMISSION NOTICE - - Copyright Ã?Â,Ã,© 1991-2004 Unicode, Inc. All rights reserved. Distributed under -the Terms of Use in http://www.unicode.org/copyright.html. - - Permission is hereby granted, free of charge, to any person obtaining a copy -of the Unicode data files and associated documentation (the "Data Files") or -Unicode software and associated documentation (the "Software") to deal in the -Data Files or Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, and/or sell copies of -the Data Files or Software, and to permit persons to whom the Data Files or -Software are furnished to do so, provided that (a) the above copyright notice(s) -and this permission notice appear with all copies of the Data Files or Software, -(b) both the above copyright notice(s) and this permission notice appear in -associated documentation, and (c) there is clear notice in each modified Data -File or in the Software as well as in the documentation associated with the Data -File(s) or Software that the data or software has been modified. - - THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD -PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS -NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL -DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING -OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. - - Except as contained in this notice, the name of a copyright holder shall not -be used in advertising or otherwise to promote the sale, use or other dealings -in these Data Files or Software without prior written authorization of the -copyright holder. - - Unicode and the Unicode logo are trademarks of Unicode, Inc., and may be -registered in some jurisdictions. All other trademarks and registered trademarks -mentioned herein are the property of their respective owners. -%% This notice is provided with respect to RSA PKCS#11 Header Files & Specification, which may be included with this software: - -/* - * Copyright (C) 1998 by the FundsXpress, INC. - * - * All rights reserved. - * - * Export of this software from the United States of America may require - * a specific license from the United States Government.  It is the - * responsibility of any person or organization contemplating export to - * obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of FundsXpress. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission.  FundsXpress makes no representations about the suitability of - * this software for any purpose.  It is provided "as is" without express - * or implied warranty. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -%% This notice is provided with respect to certain files/code which may included in the implementation of AWT within the software: - -****************************************************** -BEGIN  src/solaris/native/sun/awt/HPkeysym.h -Copyright 1987, 1998  The Open Group - -All Rights Reserved. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, - -All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the names of Hewlett Packard -or Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD -TO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE.  Hewlett-Packard shall not be liable for errors -contained herein or direct, indirect, special, incidental or -consequential damages in connection with the furnishing, -performance, or use of this material. - -END  src/solaris/native/sun/awt/HPkeysym.h -****************************************************** -****************************************************** -BEGIN src/solaris/native/sun/awt/Xrandr.h -/* - * $XFree86: xc/lib/Xrandr/Xrandr.h,v 1.9 2002/09/29 23:39:44 keithp Exp $ - * - * Copyright © 2000 Compaq Computer Corporation, Inc. - * Copyright © 2002 Hewlett-Packard Company, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Compaq not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission.  HP makes no representations about the - * suitability of this software for any purpose.  It is provided "as is" - * without express or implied warranty. - * - * HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL COMPAQ - * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Author:  Jim Gettys, HP Labs, HP. - */ - - -END src/solaris/native/sun/awt/Xrandr.h -****************************************************** -BEGIN src/solaris/native/sun/awt/extutil.h -/* - * $Xorg: extutil.h,v 1.3 2000/08/18 04:05:45 coskrey Exp $ - * -Copyright 1989, 1998  The Open Group - -All Rights Reserved. - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - * - * Author:  Jim Fulton, MIT The Open Group - * - *                     Xlib Extension-Writing Utilities - * - * This package contains utilities for writing the client API for various - * protocol extensions.  THESE INTERFACES ARE NOT PART OF THE X STANDARD AND - * ARE SUBJECT TO CHANGE! - */ -/* $XFree86: xc/include/extensions/extutil.h,v 1.5 2001/01/17 17:53:20 dawes Exp $ */ - -END src/solaris/native/sun/awt/extutil.h -****************************************************** -BEGIN   src/solaris/native/sun/awt/fontconfig.h -/* - * $RCSId: xc/lib/fontconfig/fontconfig/fontconfig.h,v 1.30 2002/09/26 00:17:27 -keithp Exp $ - * - * Copyright © 2001 Keith Packard - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission.  Keith Packard makes no - * representations about the suitability of this software for any purpose.  It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - -END   src/solaris/native/sun/awt/fontconfig.h -****************************************************** -BEGIN src/solaris/native/sun/awt/list.c -AND  src/solaris/native/sun/awt/list.h -AND src/solaris/native/sun/awt/multiVis.c -AND  src/solaris/native/sun/awt/multiVis.h -AND  src/solaris/native/sun/awt/wsutils.h - -Copyright (c) 1994 Hewlett-Packard Co. -Copyright (c) 1996  X Consortium - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the X Consortium shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the X Consortium. - -END src/solaris/native/sun/awt/list.c -AND  src/solaris/native/sun/awt/list.h -AND src/solaris/native/sun/awt/multiVis.c -AND  src/solaris/native/sun/awt/multiVis.h -AND  src/solaris/native/sun/awt/wsutils.h - -***************************************************************** -BEGIN src/solaris/native/sun/awt/randr.h - - * - * Copyright © 2000, Compaq Computer Corporation, - * Copyright © 2002, Hewlett Packard, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Compaq or HP not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission.  HP makes no representations about the - * suitability of this software for any purpose.  It is provided "as is" - * without express or implied warranty. - * - * HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL HP - * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Author:  Jim Gettys, HP Labs, Hewlett-Packard, Inc. - -END src/solaris/native/sun/awt/randr.h -***************************************************** - -BEGIN src/solaris/native/sun/java2d/opengl/J2D_GL/glx.h - * Mesa 3-D graphics library - * Version:  4.1 - * - * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -END src/solaris/native/sun/java2d/opengl/J2D_GL/glx.h diff --git a/jdk/make/com/sun/Makefile b/jdk/make/com/sun/Makefile index 0328f120d31..188e73670ad 100644 --- a/jdk/make/com/sun/Makefile +++ b/jdk/make/com/sun/Makefile @@ -41,7 +41,7 @@ endif # Omit mirror since it's built with the apt tool. SUBDIRS = $(SCRIPT_SUBDIR) image security crypto/provider jndi jmx \ java inputmethods org xml rowset net/httpserver net/ssl demo \ - tools jarsigner tracing + tools jarsigner tracing servicetag all build clean clobber:: $(SUBDIRS-loop) diff --git a/jdk/make/com/sun/crypto/provider/Makefile b/jdk/make/com/sun/crypto/provider/Makefile index 64e4320b19a..f8134de149b 100644 --- a/jdk/make/com/sun/crypto/provider/Makefile +++ b/jdk/make/com/sun/crypto/provider/Makefile @@ -193,7 +193,7 @@ build-jar: $(UNSIGNED_DIR)/sunjce_provider.jar $(UNSIGNED_DIR)/sunjce_provider.jar: build $(JCE_MANIFEST_FILE) $(prep-target) $(BOOT_JAR_CMD) cmf $(JCE_MANIFEST_FILE) $@ $(JAR_DIRS) \ - $(JAR_JFLAGS) + $(BOOT_JAR_JFLAGS) @$(java-vm-cleanup) @@ -253,7 +253,7 @@ endif @$(CD) $(OBFUS_DIR); $(java-vm-cleanup) $(BOOT_JAR_CMD) cmf $(JCE_MANIFEST_FILE) $@ \ -C $(OBFUS_DIR)/build com \ - $(JAR_JFLAGS) + $(BOOT_JAR_JFLAGS) $(sign-target) @$(java-vm-cleanup) diff --git a/jdk/make/com/sun/inputmethods/indicim/Makefile b/jdk/make/com/sun/inputmethods/indicim/Makefile index 638854a0b37..e6e7c0dfdf2 100644 --- a/jdk/make/com/sun/inputmethods/indicim/Makefile +++ b/jdk/make/com/sun/inputmethods/indicim/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -71,7 +71,7 @@ $(IMJAR): $(FILES_class) $(FILES_copy) $(PROVIDER_CONF_FILE) $(BOOT_JAR_CMD) -cf $@ \ -C $(CLASSDESTDIR) com \ -C $(CLASSDESTDIR) $(SERVICESDIR) \ - $(JAR_JFLAGS) + $(BOOT_JAR_JFLAGS) @$(java-vm-cleanup) clean:: diff --git a/jdk/make/com/sun/inputmethods/thaiim/Makefile b/jdk/make/com/sun/inputmethods/thaiim/Makefile index e565319aaf8..d4f47a69d53 100644 --- a/jdk/make/com/sun/inputmethods/thaiim/Makefile +++ b/jdk/make/com/sun/inputmethods/thaiim/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -71,7 +71,7 @@ $(IMJAR): $(FILES_class) $(FILES_copy) $(PROVIDER_CONF_FILE) $(BOOT_JAR_CMD) -cf $@ \ -C $(CLASSDESTDIR) com \ -C $(CLASSDESTDIR) $(SERVICESDIR) \ - $(JAR_JFLAGS) + $(BOOT_JAR_JFLAGS) @$(java-vm-cleanup) clean:: diff --git a/jdk/make/com/sun/java/pack/Makefile b/jdk/make/com/sun/java/pack/Makefile index 9229e3f4c99..c8b4e990984 100644 --- a/jdk/make/com/sun/java/pack/Makefile +++ b/jdk/make/com/sun/java/pack/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/jdk/make/com/sun/security/auth/module/Makefile b/jdk/make/com/sun/security/auth/module/Makefile index d9f705d4df7..d7a4abdf165 100644 --- a/jdk/make/com/sun/security/auth/module/Makefile +++ b/jdk/make/com/sun/security/auth/module/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/jdk/make/com/sun/servicetag/Makefile b/jdk/make/com/sun/servicetag/Makefile new file mode 100644 index 00000000000..e7914e8278e --- /dev/null +++ b/jdk/make/com/sun/servicetag/Makefile @@ -0,0 +1,80 @@ +# Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Sun designates this +# particular file as subject to the "Classpath" exception as provided +# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. + +BUILDDIR = ../../.. +PACKAGE = com.sun.servicetag +PRODUCT = sun +include $(BUILDDIR)/common/Defs.gmk + +# +# Files to compile +# +AUTO_FILES_JAVA_DIRS = com/sun/servicetag + +# +# Rules +# +include $(BUILDDIR)/common/Classes.gmk + +SERVICETAG_LIBDIR = $(LIBDIR)/servicetag +SERVICETAG_RESOURCES_DIR = $(CLASSDESTDIR)/com/sun/servicetag/resources +FILES_copy = $(SERVICETAG_RESOURCES_DIR)/product_registration.xsd \ + $(SERVICETAG_RESOURCES_DIR)/register.html \ + $(SERVICETAG_RESOURCES_DIR)/register_ja.html \ + $(SERVICETAG_RESOURCES_DIR)/register_zh_CN.html \ + $(SERVICETAG_LIBDIR)/jdk_header.png + +# Add all properties files to the FILES_copy list +SWORDFISH_properties := $(shell \ + $(CD) $(SHARE_SRC)/classes/com/sun/servicetag/resources; \ + $(FIND) . -name 'javase_*_swordfish.properties' -print ; \ + ) +FILES_copy += $(shell \ + for f in $(SWORDFISH_properties) ; do \ + echo $(SERVICETAG_RESOURCES_DIR)/$$f ; \ + done \ +) + + +# +#OTHER_JAVACFLAGS += -Xlint:unchecked + +build: install-servicetag-lib copy-files + +copy-files: $(FILES_copy) + +$(CLASSBINDIR)/%: $(SHARE_SRC)/classes/% + $(install-file) + +$(SERVICETAG_LIBDIR)/jdk_header.png: $(SHARE_SRC)/classes/com/sun/servicetag/resources/jdk_header.png + $(install-file) + $(CHMOD) 444 $@ + +install-servicetag-lib: + @$(RM) -rf $(SERVICETAG_LIBDIR) + $(MKDIR) $(SERVICETAG_LIBDIR) + +clean clobber:: + @$(RM) $(FILES_copy) + +.PHONY: copy-files diff --git a/jdk/make/common/BuildToolJar.gmk b/jdk/make/common/BuildToolJar.gmk index 7d4ad4169fc..2c5ad8e3f6e 100644 --- a/jdk/make/common/BuildToolJar.gmk +++ b/jdk/make/common/BuildToolJar.gmk @@ -1,5 +1,5 @@ # -# Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ $(BUILDTOOL_JAR_FILE): $(BUILDTOOL_MANIFEST_FILE) \ -sourcepath $(BUILDTOOL_SOURCE_ROOT) $(BUILDTOOL_MAIN_SOURCE_FILE) $(BOOT_JAR_CMD) cfm $@ $(BUILDTOOL_MANIFEST_FILE) \ -C $(BUILDTOOLCLASSDIR) $(PKGDIR) \ - $(JAR_JFLAGS) || $(RM) $@ + $(BOOT_JAR_JFLAGS) || $(RM) $@ @$(java-vm-cleanup) # Printing out a build tool information line diff --git a/jdk/make/common/Defs-linux.gmk b/jdk/make/common/Defs-linux.gmk index 65814ba472a..28d58376fe2 100644 --- a/jdk/make/common/Defs-linux.gmk +++ b/jdk/make/common/Defs-linux.gmk @@ -86,18 +86,22 @@ HPIS = native # # Default optimization # -CC_HIGHEST_OPT = -O3 -CC_HIGHER_OPT = -O3 -CC_LOWER_OPT = -O2 -CC_NO_OPT = -ifeq ($(PRODUCT), java) - _OPT = $(CC_HIGHER_OPT) -else - _OPT = $(CC_LOWER_OPT) - CPPFLAGS_DBG += -DLOGGING +ifndef OPTIMIZATION_LEVEL + ifeq ($(PRODUCT), java) + OPTIMIZATION_LEVEL = HIGHER + else + OPTIMIZATION_LEVEL = LOWER + endif endif +CC_OPT/NONE = +CC_OPT/LOWER = -O2 +CC_OPT/HIGHER = -O3 +CC_OPT/HIGHEST = -O3 + +CC_OPT = $(CC_OPT/$(OPTIMIZATION_LEVEL)) + # For all platforms, do not omit the frame pointer register usage. # We need this frame pointer to make it easy to walk the stacks. # This should be the default on X86, but ia64 and amd64 may not have this @@ -112,18 +116,6 @@ LDFLAGS_COMMON_sparc += -m32 -mcpu=v9 CFLAGS_REQUIRED = $(CFLAGS_REQUIRED_$(ARCH)) LDFLAGS_COMMON += $(LDFLAGS_COMMON_$(ARCH)) -# Add in platform specific optimizations for all opt levels -CC_HIGHEST_OPT += $(_OPT_$(ARCH)) -CC_HIGHER_OPT += $(_OPT_$(ARCH)) -CC_LOWER_OPT += $(_OPT_$(ARCH)) - -# If NO_OPTIMIZATIONS is defined in the environment, turn all optimzations off -ifdef NO_OPTIMIZATIONS - CC_HIGHEST_OPT = $(CC_NO_OPT) - CC_HIGHER_OPT = $(CC_NO_OPT) - CC_LOWER_OPT = $(CC_NO_OPT) -endif - # # Selection of warning messages # @@ -162,19 +154,19 @@ ifeq ($(FASTDEBUG), true) endif endif -CFLAGS_OPT = $(POPT) +CFLAGS_OPT = $(CC_OPT) CFLAGS_DBG = $(DEBUG_FLAG) CFLAGS_COMMON += $(CFLAGS_REQUIRED) CXXFLAGS_COMMON = $(GLOBAL_KPIC) -DCC_NOEX $(GCC_WARNINGS) -CXXFLAGS_OPT = $(POPT) +CXXFLAGS_OPT = $(CC_OPT) CXXFLAGS_DBG = $(DEBUG_FLAG) CXXFLAGS_COMMON += $(CFLAGS_REQUIRED) # FASTDEBUG: Optimize the code in the -g versions, gives us a faster debug java ifeq ($(FASTDEBUG), true) - CFLAGS_DBG += $(CC_LOWER_OPT) - CXXFLAGS_DBG += $(CC_LOWER_OPT) + CFLAGS_DBG += $(CC_OPT/LOWER) + CXXFLAGS_DBG += $(CC_OPT/LOWER) endif CPPFLAGS_COMMON = -D$(ARCH) -DARCH='"$(ARCH)"' -DLINUX $(VERSION_DEFINES) \ @@ -186,6 +178,9 @@ endif CPPFLAGS_OPT = CPPFLAGS_DBG = -DDEBUG +ifneq ($(PRODUCT), java) + CPPFLAGS_DBG += -DLOGGING +endif ifdef LIBRARY # Libraries need to locate other libraries at runtime, and you can tell diff --git a/jdk/make/common/Defs-solaris.gmk b/jdk/make/common/Defs-solaris.gmk index d0874e43070..9b5cc8b721b 100644 --- a/jdk/make/common/Defs-solaris.gmk +++ b/jdk/make/common/Defs-solaris.gmk @@ -86,15 +86,16 @@ HPIS = native # # Java default optimization (-x04/-O2) etc. Applies to the VM. # -ifeq ($(PRODUCT), java) - _OPT = $(CC_HIGHER_OPT) -else - _OPT = $(CC_LOWER_OPT) - CPPFLAGS_DBG += -DLOGGING -DDBINFO +ifndef OPTIMIZATION_LEVEL + ifeq ($(PRODUCT), java) + OPTIMIZATION_LEVEL = HIGHER + else + OPTIMIZATION_LEVEL = LOWER + endif endif # -# If -Xa is in CFLAGS_COMMON it will end up ahead of $(POPT) for the +# If -Xa is in CFLAGS_COMMON it will end up ahead of $(CC_OPT) for the # optimized build, and that ordering of the flags completely freaks # out cc. Hence, -Xa is instead in each CFLAGS variant. # @@ -123,8 +124,8 @@ endif # # Debug flag for C and C++ compiler # -CFLAGS_DEBUG_OPTION=-g -CXXFLAGS_DEBUG_OPTION=-g +CFLAGS_DEBUG_OPTION = -g $(CC_OPT/NONE) +CXXFLAGS_DEBUG_OPTION = -g $(CXX_OPT/NONE) # Turn off -g if we are doing tcov build ifdef TCOV_BUILD @@ -142,9 +143,8 @@ endif # Performance/size of files should be about the same, maybe smaller. # ifeq ($(FASTDEBUG), true) - CC_FASTDEBUG_OPT = $(CC_LOWER_OPT) - CFLAGS_DEBUG_OPTION = -g $(CC_FASTDEBUG_OPT) - CXXFLAGS_DEBUG_OPTION = -g0 $(CC_FASTDEBUG_OPT) + CFLAGS_DEBUG_OPTION = -g $(CC_OPT/LOWER) + CXXFLAGS_DEBUG_OPTION = -g0 $(CXX_OPT/LOWER) endif CFLAGS_COMMON = -L$(OBJDIR) @@ -160,7 +160,7 @@ CFLAGS_COMMON += -errshort=tags CXXFLAGS_COMMON += -errtags=yes # Optimization flags -CFLAGS_OPT = $(POPT) +CFLAGS_OPT = $(CC_OPT) # Debug version flags CFLAGS_DBG = $(CFLAGS_DEBUG_OPTION) @@ -197,7 +197,7 @@ ifeq ($(COMPILER_WARNINGS_FATAL),true) CXXFLAGS_COMMON += -errwarn=%all endif -CXXFLAGS_OPT = $(POPT) +CXXFLAGS_OPT = $(CXX_OPT) CXXFLAGS_DBG = $(CXXFLAGS_DEBUG_OPTION) CXXFLAGS_COMMON += $(CFLAGS_REQUIRED) @@ -267,6 +267,10 @@ CPPFLAGS_COMMON = -D__solaris__ -D$(ARCH_FAMILY) CPPFLAGS_OPT = -DNDEBUG CPPFLAGS_DBG = -DDEBUG +ifneq ($(PRODUCT), java) + CPPFLAGS_DBG += -DLOGGING -DDBINFO +endif + ifeq ($(ARCH_FAMILY), i586) # The macro _LITTLE_ENDIAN needs to be defined the same to avoid the # Sun C compiler warning message: warning: macro redefined: _LITTLE_ENDIAN @@ -410,63 +414,151 @@ endif # Different "levels" of optimization. # ifeq ($(CC_VERSION),gcc) - CC_HIGHEST_OPT = -O3 - CC_HIGHER_OPT = -O3 - CC_LOWER_OPT = -O2 + + CC_OPT/NONE = + CC_OPT/LOWER = -O2 + CC_OPT/HIGHER = -O3 + CC_OPT/HIGHEST = -O3 + + CXX_OPT/NONE = + CXX_OPT/LOWER = -O2 + CXX_OPT/HIGHER = -O3 + CXX_OPT/HIGHEST = -O3 + CFLAGS_REQUIRED_i586 += -fno-omit-frame-pointer CFLAGS_REQUIRED_amd64 += -fno-omit-frame-pointer + # Automatic precompiled header option to use (if COMPILE_APPROACH=batch) # (See Rules.gmk) May need to wait for gcc 5? AUTOMATIC_PCH_OPTION = + else + # Highest could be -xO5, but indications are that -xO5 should be reserved # for a per-file use, on sources with known performance impacts. - CC_HIGHEST_OPT = -xO4 - CC_HIGHER_OPT = -xO4 - CC_LOWER_OPT = -xO2 + OPT_LEVEL/LOWER = 2 + OPT_LEVEL/HIGHER = 4 + OPT_LEVEL/HIGHEST = 4 + + CC_OPT/NONE = + CC_OPT/LOWER = $(OPT_LEVEL/LOWER:%=-xO%) + CC_OPT/HIGHER = $(OPT_LEVEL/HIGHER:%=-xO%) + CC_OPT/HIGHEST = $(OPT_LEVEL/HIGHEST:%=-xO%) + + CXX_OPT/NONE = + CXX_OPT/LOWER = $(OPT_LEVEL/LOWER:%=-xO%) + CXX_OPT/HIGHER = $(OPT_LEVEL/HIGHER:%=-xO%) + CXX_OPT/HIGHEST = $(OPT_LEVEL/HIGHEST:%=-xO%) + + # We need stack frames at all times + USE_XKEEPFRAME_OPTION = false + ifeq ($(USE_XKEEPFRAME_OPTION),true) + + # Unknown spelling on this option at this time (Maybe in SS13?) + CC_XKEEPFRAME_OPTIONS = -xkeepframe + CXX_XKEEPFRAME_OPTIONS = -xkeepframe + + else + + # On X86, make sure tail call optimization is off + # The z and y are the tail call optimizations. + ifeq ($(ARCH_FAMILY), i586) + ifeq ($(shell $(EXPR) $(CC_VER) \> 5.8), 1) + # Somehow, tail call optimization is creeping in. + # Make sure it is off. + # WARNING: These may cause compiler warnings about duplicate -O options + CC_XKEEPFRAME_OPTIONS += -Wu,-O$(OPT_LEVEL/$(OPTIMIZATION_LEVEL))~yz + CXX_XKEEPFRAME_OPTIONS += -Qoption ube -O$(OPT_LEVEL/$(OPTIMIZATION_LEVEL))~yz + endif + endif + + # On i586 we need to tell the code generator to ALWAYS use a + # frame pointer. + ifeq ($(ARCH_FAMILY), i586) + # Note that in 5.7, this is done with -xregs=no%frameptr + ifeq ($(CC_VER), 5.5) + # It's not exactly clear when this optimization kicks in, the + # current assumption is -xO4 or greater and for C++ with + # the -features=no%except option and -xO4 and greater. + # Bottom line is, we ALWAYS want a frame pointer! + CC_XKEEPFRAME_OPTIONS += -Wu,-Z~B + CXX_XKEEPFRAME_OPTIONS += -Qoption ube -Z~B + endif + ifeq ($(shell $(EXPR) $(CC_VER) \> 5.6), 1) + # Do NOT use frame pointer register as a general purpose opt register + CC_OPT/NONE += -xregs=no%frameptr + CXX_OPT/NONE += -xregs=no%frameptr + CC_XKEEPFRAME_OPTIONS += -xregs=no%frameptr + CXX_XKEEPFRAME_OPTIONS += -xregs=no%frameptr + endif + endif + + # Optimizer for sparc needs to be told not to do certain things + # related to frames or save instructions. + ifeq ($(ARCH_FAMILY), sparc) + # Do not use save instructions instead of add instructions + # This was an optimization starting in SC5.0 that made it hard for us to + # find the "save" instruction (which got turned into an "add") + CC_XKEEPFRAME_OPTIONS += -Wc,-Qrm-s + CXX_XKEEPFRAME_OPTIONS += -Qoption cg -Qrm-s + # Don't allow tail call code optimization. Started in SC5.0. + # We don't like code of this form: + # save + # + # call foo + # restore + # because we can't tell if the method will have a stack frame + # and register windows or not. + CC_XKEEPFRAME_OPTIONS += -Wc,-Qiselect-T0 + CXX_XKEEPFRAME_OPTIONS += -Qoption cg -Qiselect-T0 + endif + + endif + + # Extra options used with HIGHEST # - # WARNING: Use of _OPT=$(CC_HIGHEST_OPT) in your Makefile needs to be + # WARNING: Use of OPTIMIZATION_LEVEL=HIGHEST in your Makefile needs to be # done with care, there are some assumptions below that need to # be understood about the use of pointers, and IEEE behavior. # # Use non-standard floating point mode (not IEEE 754) - CC_HIGHEST_OPT += -fns + CC_HIGHEST_EXTRAS += -fns # Do some simplification of floating point arithmetic (not IEEE 754) - CC_HIGHEST_OPT += -fsimple + CC_HIGHEST_EXTRAS += -fsimple # Use single precision floating point with 'float' - CC_HIGHEST_OPT += -fsingle + CC_HIGHEST_EXTRAS += -fsingle # Assume memory references via basic pointer types do not alias # (Source with excessing pointer casting and data access with mixed # pointer types are not recommended) - CC_HIGHEST_OPT += -xalias_level=basic + CC_HIGHEST_EXTRAS += -xalias_level=basic # Use intrinsic or inline versions for math/std functions # (If you expect perfect errno behavior, do not use this) - CC_HIGHEST_OPT += -xbuiltin=%all + CC_HIGHEST_EXTRAS += -xbuiltin=%all # Loop data dependency optimizations (need -xO3 or higher) - CC_HIGHEST_OPT += -xdepend + CC_HIGHEST_EXTRAS += -xdepend # Pointer parameters to functions do not overlap # (Similar to -xalias_level=basic usage, but less obvious sometimes. # If you pass in multiple pointers to the same data, do not use this) - CC_HIGHEST_OPT += -xrestrict + CC_HIGHEST_EXTRAS += -xrestrict # Inline some library routines # (If you expect perfect errno behavior, do not use this) - CC_HIGHEST_OPT += -xlibmil + CC_HIGHEST_EXTRAS += -xlibmil # Use optimized math routines # (If you expect perfect errno behavior, do not use this) # Can cause undefined external on Solaris 8 X86 on __sincos, removing for now - # CC_HIGHEST_OPT += -xlibmopt + # CC_HIGHEST_EXTRAS += -xlibmopt ifeq ($(ARCH_FAMILY), sparc) # Assume at most 8byte alignment, raise SIGBUS on error ### Presents an ABI issue with customer JNI libs? - ####CC_HIGHEST_OPT += -xmemalign=8s + ####CC_HIGHEST_EXTRAS += -xmemalign=8s # Automatic prefetch instructions, explicit prefetch macros - CC_HIGHEST_OPT += -xprefetch=auto,explicit + CC_HIGHEST_EXTRAS += -xprefetch=auto,explicit # Pick ultra as the chip to optimize to - CC_HIGHEST_OPT += -xchip=ultra + CC_HIGHEST_EXTRAS += -xchip=ultra endif ifeq ($(ARCH), i586) # Pick pentium as the chip to optimize to - CC_HIGHEST_OPT += -xchip=pentium + CC_HIGHEST_EXTRAS += -xchip=pentium endif ifdef LIBRARY # The Solaris CBE (Common Build Environment) requires that the use @@ -476,9 +568,6 @@ else CFLAGS_REQUIRED_sparcv9 += -xregs=no%appl endif ifeq ($(shell $(EXPR) $(CC_VER) \> 5.6), 1) - # Do NOT use the frame pointer register as a general purpose opt register - CFLAGS_REQUIRED_i586 += -xregs=no%frameptr - CFLAGS_REQUIRED_amd64 += -xregs=no%frameptr # We MUST allow data alignment of 4 for sparc V8 (32bit) # Presents an ABI issue with customer JNI libs? We must be able to # to handle 4byte aligned objects? (rare occurance, but possible?) @@ -492,77 +581,28 @@ else # Automatic precompiled header option to use (if COMPILE_APPROACH=batch) # (See Rules.gmk) The SS11 -xpch=auto* options appear to be broken. AUTOMATIC_PCH_OPTION = + + # Add in keep frame options + CC_OPT/LOWER += $(CC_XKEEPFRAME_OPTIONS) + CC_OPT/HIGHER += $(CC_XKEEPFRAME_OPTIONS) + CC_OPT/HIGHEST += $(CC_XKEEPFRAME_OPTIONS) + CXX_OPT/LOWER += $(CXX_XKEEPFRAME_OPTIONS) + CXX_OPT/HIGHER += $(CXX_XKEEPFRAME_OPTIONS) + CXX_OPT/HIGHEST += $(CXX_XKEEPFRAME_OPTIONS) + + # Add in highest optimization settings + CC_OPT/HIGHEST += $(CC_HIGHEST_EXTRAS) + CXX_OPT/HIGHEST += $(CC_HIGHEST_EXTRAS) + endif -CC_NO_OPT = -# If NO_OPTIMIZATIONS is defined in the environment, turn all optimzations off -ifdef NO_OPTIMIZATIONS - CC_HIGHEST_OPT = $(CC_NO_OPT) - CC_HIGHER_OPT = $(CC_NO_OPT) - CC_LOWER_OPT = $(CC_NO_OPT) -endif +# Default optimization settings based on level. +CC_OPT = $(CC_OPT/$(OPTIMIZATION_LEVEL)) +CXX_OPT = $(CXX_OPT/$(OPTIMIZATION_LEVEL)) # Flags required all the time CFLAGS_REQUIRED = $(CFLAGS_REQUIRED_$(ARCH)) -# Add processor specific options for optimizations -CC_HIGHEST_OPT += $(_OPT_$(ARCH)) -CC_HIGHER_OPT += $(_OPT_$(ARCH)) -CC_LOWER_OPT += $(_OPT_$(ARCH)) - -# Secret compiler optimization options that should be in the above macros -# but since they differ in format from C to C++, are added into the C or -# C++ specific macros for compiler flags. -# -# On i586 we need to tell the code generator to ALWAYS use a -# frame pointer. -ifeq ($(ARCH_FAMILY), i586) - # Note that in 5.7, this is done with -xregs=no%frameptr - ifeq ($(CC_VER), 5.5) - # It's not exactly clear when this optimization kicks in, the - # current assumption is -xO4 or greater and for C++ with - # the -features=no%except option and -xO4 and greater. - # Bottom line is, we ALWAYS want a frame pointer! - CXXFLAGS_OPT += -Qoption ube -Z~B - CFLAGS_OPT += -Wu,-Z~B - ifeq ($(FASTDEBUG), true) - CXXFLAGS_DBG += -Qoption ube -Z~B - CFLAGS_DBG += -Wu,-Z~B - endif - endif -endif -# -# Optimizer for sparc needs to be told not to do certain things -# related to frames or save instructions. -ifeq ($(ARCH_FAMILY), sparc) - # NOTE: Someday the compilers will provide a high-level option for this. - # Use save instructions instead of add instructions - # This was an optimization starting in SC5.0 that made it hard for us to - # find the "save" instruction (which got turned into an "add") - CXXFLAGS_OPT += -Qoption cg -Qrm-s - CFLAGS_OPT += -Wc,-Qrm-s - ifeq ($(FASTDEBUG), true) - CXXFLAGS_DBG += -Qoption cg -Qrm-s - CFLAGS_DBG += -Wc,-Qrm-s - endif - # - # NOTE: Someday the compilers will provide a high-level option for this. - # Don't allow tail call code optimization. Started in SC5.0. - # We don't like code of this form: - # save - # - # call foo - # restore - # because we can't tell if the method will have a stack frame - # and register windows or not. - CXXFLAGS_OPT += -Qoption cg -Qiselect-T0 - CFLAGS_OPT += -Wc,-Qiselect-T0 - ifeq ($(FASTDEBUG), true) - CXXFLAGS_DBG += -Qoption cg -Qiselect-T0 - CFLAGS_DBG += -Wc,-Qiselect-T0 - endif -endif - # # Path and option to link against the VM, if you have to. Note that # there are libraries that link against only -ljava, but they do get diff --git a/jdk/make/common/Defs-windows.gmk b/jdk/make/common/Defs-windows.gmk index d7c11837e96..4ec2a0467a8 100644 --- a/jdk/make/common/Defs-windows.gmk +++ b/jdk/make/common/Defs-windows.gmk @@ -84,6 +84,15 @@ EXTRA_LFLAGS += /LIBPATH:$(DXSDK_LIB_PATH) # # Default optimization # + +ifndef OPTIMIZATION_LEVEL + ifeq ($(PRODUCT), java) + OPTIMIZATION_LEVEL = HIGHER + else + OPTIMIZATION_LEVEL = LOWER + endif +endif + ifeq ($(CC_VERSION),msvc) # Visual Studio .NET 2003 or VS2003 compiler option definitions: # -O1 Favors reduced size over speed (-Og -Os -Oy -Ob2 -Gs -GF -Gy) @@ -113,21 +122,28 @@ ifeq ($(CC_VERSION),msvc) # NOTE: With VC6, -Ox, -O1, and -O2 used -Ob1, not -Ob2. # NOTE: With VC6, -O1 and -O2 used -Gf, not -GF. # + + CC_OPT/NONE = -Od + CC_OPT/LOWER = -O2 + CC_OPT/HIGHER = -O3 + CC_OPT/HIGHEST = -O3 + ifeq ($(COMPILER_VERSION), VC6) # VC6 (6.2) msvc compiler (the way Tiger and early Mustang were built) # Automatic precompiled header option to use (if COMPILE_APPROACH=batch) AUTOMATIC_PCH_OPTION = GX_OPTION = -GX ifeq ($(ARCH_DATA_MODEL), 32) - CC_HIGHEST_OPT = -Ox -Gy -Os -GB - CC_HIGHER_OPT = -Ox -Gy -Os -GB - CC_LOWER_OPT = -Ox -Gy -Os -GB + CC_OPT/HIGHEST = -Ox -Gy -Os -GB + CC_OPT/HIGHER = -Ox -Gy -Os -GB + CC_OPT/LOWER = -Ox -Gy -Os -GB else - CC_HIGHEST_OPT = -Ox -Gy -Op - CC_HIGHER_OPT = -Ox -Gy -Op - CC_LOWER_OPT = -Ox -Gy -Op + CC_OPT/HIGHEST = -Ox -Gy -Op + CC_OPT/HIGHER = -Ox -Gy -Op + CC_OPT/LOWER = -Ox -Gy -Op endif endif + ifeq ($(COMPILER_VERSION), VS2003) # Automatic precompiled header option to use (if COMPILE_APPROACH=batch) AUTOMATIC_PCH_OPTION = -YX @@ -135,53 +151,45 @@ ifeq ($(CC_VERSION),msvc) GX_OPTION = -GX ifeq ($(ARCH_DATA_MODEL), 32) # Lowered opt level to try and reduce footprint, dll size especially. - # Was: CC_HIGHEST_OPT = -O2 -G6 - # Was: CC_HIGHER_OPT = -O2 - CC_HIGHEST_OPT = -O2 - CC_HIGHER_OPT = -O1 - CC_LOWER_OPT = -O1 + # Was: CC_OPT/HIGHEST = -O2 -G6 + # Was: CC_OPT/HIGHER = -O2 + CC_OPT/HIGHEST = -O2 + CC_OPT/HIGHER = -O1 + CC_OPT/LOWER = -O1 else - CC_HIGHEST_OPT = -O2 -Op - CC_HIGHER_OPT = -O2 -Op - CC_LOWER_OPT = -O1 -Op + CC_OPT/HIGHEST = -O2 -Op + CC_OPT/HIGHER = -O2 -Op + CC_OPT/LOWER = -O1 -Op endif endif + ifeq ($(COMPILER_VERSION), VS2005) # Automatic precompiled header option to use (if COMPILE_APPROACH=batch) AUTOMATIC_PCH_OPTION = # VS2005 compiler, only with Platform SDK right now? GX_OPTION = -EHsc ifeq ($(ARCH_DATA_MODEL), 32) - CC_HIGHEST_OPT = -O2 - CC_HIGHER_OPT = -O1 - CC_LOWER_OPT = -O1 + CC_OPT/HIGHEST = -O2 + CC_OPT/HIGHER = -O1 + CC_OPT/LOWER = -O1 else - CC_HIGHEST_OPT = -O2 - CC_HIGHER_OPT = -O1 - CC_LOWER_OPT = -O1 + CC_OPT/HIGHEST = -O2 + CC_OPT/HIGHER = -O1 + CC_OPT/LOWER = -O1 endif endif - CC_NO_OPT = -Od + else # CC_VERSION + # GCC not supported, but left for historical reference... - CC_HIGHEST_OPT = -O3 - CC_HIGHER_OPT = -O2 - CC_LOWER_OPT = -O2 - CC_NO_OPT = + CC_OPT/NONE = + CC_OPT/LOWER = -O2 + CC_OPT/HIGHER = -O2 + CC_OPT/HIGHEST = -O3 + endif -# If NO_OPTIMIZATIONS is defined in the environment, turn all optimzations off -ifdef NO_OPTIMIZATIONS - CC_HIGHEST_OPT = $(CC_NO_OPT) - CC_HIGHER_OPT = $(CC_NO_OPT) - CC_LOWER_OPT = $(CC_NO_OPT) -endif - -ifeq ($(PRODUCT), java) - _OPT = $(CC_HIGHER_OPT) -else - _OPT = $(CC_LOWER_OPT) -endif +CC_OPT = $(CC_OPT/$(OPTIMIZATION_LEVEL)) # Select the runtime support library carefully, need to be consistent # @@ -233,7 +241,7 @@ ifeq ($(CC_VERSION),msvc) # Use static link for the C++ runtime (so msvcp71.dll not needed) # CFLAGS_COMMON += -Zi -nologo - CFLAGS_OPT = $(POPT) + CFLAGS_OPT = $(CC_OPT) CFLAGS_DBG = -Od $(MS_RUNTIME_DEBUG_OPTION) # Starting from VS2005 the wchar_t is handled as a built-in C/C++ data type diff --git a/jdk/make/common/Defs.gmk b/jdk/make/common/Defs.gmk index 16eb1e2258f..33eedad16a4 100644 --- a/jdk/make/common/Defs.gmk +++ b/jdk/make/common/Defs.gmk @@ -451,7 +451,7 @@ vpath %.$(OBJECT_SUFFIX) $(OBJDIR) # 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$(CLASSPATH_SEPARATOR)$(SHARE_SRC)/javavm/include$(CLASSPATH_SEPARATOR)$(PLATFORM_SRC)/javavm/include +VPATH.h = $(PLATFORM_SRC)/javavm/export$(CLASSPATH_SEPARATOR)$(SHARE_SRC)/javavm/export vpath %.h $(VPATH.h) # @@ -482,11 +482,6 @@ PKGDIR = $(subst .,/,$(PACKAGE)) # include $(JDK_MAKE_SHARED_DIR)/Defs-java.gmk -# -# Set opt level to ALT_OPT if set otherwise _OPT -# -POPT = $(_OPT$(ALT_OPT))$(ALT_OPT) - # # Convenient macros # @@ -709,7 +704,20 @@ endif # Install of imported file (JDK_IMPORT_PATH, or some other external location) define install-import-file @$(ECHO) "ASSEMBLY_IMPORT: $@" -$(install-file) +$(prep-target) +$(CP) $< $@ +@if [ "$(PLATFORM)" = "linux" -a "$(@F)" = "libjvm.so" ] ; then \ + if [ -x /usr/sbin/selinuxenabled ] ; then \ + /usr/sbin/selinuxenabled; \ + if [ $$? = 0 ] ; then \ + $(ECHO) "/usr/bin/chcon -t textrel_shlib_t $@"; \ + /usr/bin/chcon -t textrel_shlib_t $@; \ + if [ $$? != 0 ]; then \ + echo "ERROR: Cannot chcon $@"; \ + fi; \ + fi; \ + fi; \ +fi endef .PHONY: all build clean clobber diff --git a/jdk/make/common/Demo.gmk b/jdk/make/common/Demo.gmk index 086a1da97a7..12a3ce105e4 100644 --- a/jdk/make/common/Demo.gmk +++ b/jdk/make/common/Demo.gmk @@ -1,5 +1,5 @@ # -# Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -251,7 +251,7 @@ $(DEMO_JAR): \ @$(DEMO_JAVAC_INPUT) $(BOOT_JAR_CMD) -cfm $@ $(DEMO_MANIFEST) \ -C $(DEMO_JAR_IMAGE) . \ - $(JAR_JFLAGS) + $(BOOT_JAR_JFLAGS) @$(java-vm-cleanup) endif @@ -317,7 +317,11 @@ bundles: $(DEMO_BUILD_SRCZIP) # Applets are special, no jar file, no src.zip, everything expanded. ifdef DEMO_IS_APPLET @$(ECHO) "Expanding jar file into demos area at $(DEMO_DESTDIR)" - ( $(CD) $(DEMO_DESTDIR) && $(BOOT_JAR_CMD) -xfv $(DEMONAME).jar && $(RM) -r META-INF $(DEMONAME).jar ) + ( $(CD) $(DEMO_DESTDIR) && \ + $(BOOT_JAR_CMD) -xfv $(DEMONAME).jar \ + $(BOOT_JAR_JFLAGS) && \ + $(RM) -r META-INF $(DEMONAME).jar && \ + $(java-vm-cleanup) ) @( $(CD) $(DEMO_DESTDIR) && $(java-vm-cleanup) ) @$(ECHO) "Expanding source into demos area at $(DEMO_DESTDIR)" ( $(CD) $(DEMO_DESTDIR) && $(UNZIP) -o src.zip && $(RM) src.zip ) diff --git a/jdk/make/common/Library.gmk b/jdk/make/common/Library.gmk index 2b9fe5d46dc..3e4318ecd23 100644 --- a/jdk/make/common/Library.gmk +++ b/jdk/make/common/Library.gmk @@ -1,5 +1,5 @@ # -# Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -238,7 +238,7 @@ else # PLATFORM # $(ACTUAL_LIBRARY):: $(COMPILE_FILES_o) $(FILES_m) $(FILES_reorder) @$(prep-target) - @$(ECHO) "STATS: LIBRARY=$(LIBRARY), PRODUCT=$(PRODUCT), _OPT=$(_OPT)" + @$(ECHO) "STATS: LIBRARY=$(LIBRARY), PRODUCT=$(PRODUCT), OPTIMIZATION_LEVEL=$(OPTIMIZATION_LEVEL)" @$(ECHO) "Rebuilding $@ because of $?" ifeq ($(LIBRARY), fdlibm) $(AR) -r $@ $(FILES_o) diff --git a/jdk/make/common/Release.gmk b/jdk/make/common/Release.gmk index 42de79f70d6..76a1bc466f2 100644 --- a/jdk/make/common/Release.gmk +++ b/jdk/make/common/Release.gmk @@ -63,15 +63,6 @@ endif JTG_DOCS = $(JDK_TOPDIR)/src/solaris/doc -# Choose the right set of documents for the images -ifdef OPENJDK - SHARE_JDK_DOC_SRC = $(JDK_TOPDIR)/make - SHARE_JRE_DOC_SRC = $(JDK_TOPDIR)/make -else - SHARE_JDK_DOC_SRC = $(CLOSED_SHARE_SRC)/doc/jdk - SHARE_JRE_DOC_SRC = $(CLOSED_SHARE_SRC)/doc/jre -endif - #We use this for man page header jdkversion := $(JDK_MAJOR_VERSION).$(JDK_MINOR_VERSION).$(JDK_MICRO_VERSION) @@ -81,13 +72,20 @@ ifeq ($(PLATFORM), windows) endif # The base names of all the license and document files for the jdk and jre +# (These files get placed in the jdk and jre install images) ifdef OPENJDK + # Where to find these files + SHARE_JDK_DOC_SRC = $(JDK_TOPDIR) + SHARE_JRE_DOC_SRC = $(JDK_TOPDIR) # Same files for jdk and jre, no name changes LICENSE_DOCLIST_JDK = LICENSE ASSEMBLY_EXCEPTION LICENSE_DOCLIST_JRE = LICENSE ASSEMBLY_EXCEPTION - OTHER_DOCLIST_JDK = README.html THIRD_PARTY_README - OTHER_DOCLIST_JRE = README.html THIRD_PARTY_README + OTHER_DOCLIST_JDK = THIRD_PARTY_README + OTHER_DOCLIST_JRE = THIRD_PARTY_README else + # Where to find these files + SHARE_JDK_DOC_SRC = $(CLOSED_SHARE_SRC)/doc/jdk + SHARE_JRE_DOC_SRC = $(CLOSED_SHARE_SRC)/doc/jre # Select the pre-release or FCS license version based on the build milestone. LICENSE_VERSION=.pre ifeq ($(MILESTONE), fcs) @@ -662,7 +660,7 @@ $(RES_JAR_ARGLIST): $(RES_JAR_FILELIST) $(RESOURCES_JAR): $(RES_JAR_ARGLIST) $(JAR_MANIFEST_FILE) $(prep-target) $(BOOT_JAR_CMD) c0mf $(JAR_MANIFEST_FILE) $@ \ - @$(RES_JAR_ARGLIST) $(JAR_JFLAGS) + @$(RES_JAR_ARGLIST) $(BOOT_JAR_JFLAGS) @$(java-vm-cleanup) # Create jsse.jar containing SunJSSE implementation classes @@ -671,7 +669,7 @@ $(JSSE_JAR): $(JAR_MANIFEST_FILE) $(prep-target) $(BOOT_JAR_CMD) c0mf $(JAR_MANIFEST_FILE) $@ \ $(JSSE_CLASSES_DIRS:%=-C $(CLASSBINDIR) %) \ - $(JAR_JFLAGS) + $(BOOT_JAR_JFLAGS) @$(java-vm-cleanup) # Create sec-bin.zip @@ -721,7 +719,7 @@ $(RT_JAR_ARGLIST): $(RT_JAR_FILELIST) $(RT_JAR): $(RT_JAR_ARGLIST) $(JAR_MANIFEST_FILE) $(prep-target) $(BOOT_JAR_CMD) c0mf $(JAR_MANIFEST_FILE) $@ \ - @$(RT_JAR_ARGLIST) $(JAR_JFLAGS) + @$(RT_JAR_ARGLIST) $(BOOT_JAR_JFLAGS) @$(java-vm-cleanup) # Meta-index construction to make core class loaders lazier @@ -955,7 +953,7 @@ initial-image-jdk:: initial-image-jdk-setup \ @# $(BOOT_JAR_CMD) c0f $(LIBDIR)/tools.jar $(addprefix \ -C $(CLASSBINDIR) , $(TOOLS)) \ - $(JAR_JFLAGS) + $(BOOT_JAR_JFLAGS) @$(java-vm-cleanup) $(CP) $(LIBDIR)/tools.jar $(JDK_IMAGE_DIR)/lib/tools.jar @# @@ -968,7 +966,7 @@ initial-image-jdk:: initial-image-jdk-setup \ -Acom.sun.tools.javac.sym.Dest=$(OUTPUTDIR)/symbols/META-INF/sym/rt.jar \ $(CORE_PKGS) $(NON_CORE_PKGS) $(EXCLUDE_PROPWARN_PKGS) $(BOOT_JAR_CMD) c0f $(LIBDIR)/ct.sym \ - -C $(OUTPUTDIR)/symbols META-INF $(JAR_JFLAGS) + -C $(OUTPUTDIR)/symbols META-INF $(BOOT_JAR_JFLAGS) @$(java-vm-cleanup) $(CP) $(LIBDIR)/ct.sym $(JDK_IMAGE_DIR)/lib/ct.sym @# @@ -1132,11 +1130,11 @@ endef COMPARE_FILTER = | $(EGREP) -v /fastdebug/ | $(EGREP) -v /demo/ | $(EGREP) -v /sample/ # If a previuous image is provided, no need to install it. -ifdef PREVIOUS_JDK_IMAGE +ifdef PREVIOUS_RELEASE_IMAGE # Just use the pre-installed images - PREV_JRE_IMAGE_DIR=$(PREVIOUS_JDK_IMAGE)/jre - PREV_JDK_IMAGE_DIR=$(PREVIOUS_JDK_IMAGE) + PREV_JRE_IMAGE_DIR=$(PREVIOUS_RELEASE_IMAGE)/jre + PREV_JDK_IMAGE_DIR=$(PREVIOUS_RELEASE_IMAGE) else diff --git a/jdk/make/common/Sanity.gmk b/jdk/make/common/Sanity.gmk index a4ae86f47bd..3388be0403f 100644 --- a/jdk/make/common/Sanity.gmk +++ b/jdk/make/common/Sanity.gmk @@ -1,5 +1,5 @@ # -# Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -70,7 +70,6 @@ sanity-base: pre-sanity \ sane-compiler \ sane-cacerts \ sane-ant_version \ - sane-findbugs_version \ sane-zip_version \ sane-msvcrt_path diff --git a/jdk/make/common/internal/BinaryPlugs.gmk b/jdk/make/common/internal/BinaryPlugs.gmk index a52b6175286..bb2d64262ed 100644 --- a/jdk/make/common/internal/BinaryPlugs.gmk +++ b/jdk/make/common/internal/BinaryPlugs.gmk @@ -185,7 +185,8 @@ endef # import-binary-plug-file define import-binary-plug-classes @$(MKDIR) -p $(CLASSDESTDIR) @$(CAT) $1 | $(SED) -e 's/^/PLUG IMPORT: /' -($(CD) $(CLASSDESTDIR) && $(BOOT_JAR_CMD) xf $(PLUG_IMPORT_JARFILE) @$1) +($(CD) $(CLASSDESTDIR) && $(BOOT_JAR_CMD) xf $(PLUG_IMPORT_JARFILE) @$1 $(BOOT_JAR_JFLAGS) ) +($(CD) $(CLASSDESTDIR) && $(java-vm-cleanup) ) endef # import-binary-plug-classes # Import specific area classes (the classes are always created) @@ -275,7 +276,8 @@ $(PLUG_EXPORT_JARFILE): $(PLUG_TEMPDIR)/all.clist $(PLUG_TEMPDIR)/all.jargs @$(prep-target) @$(ECHO) "PLUG EXPORT: $(@F)" @$(CAT) $(PLUG_TEMPDIR)/all.clist | $(SED) -e 's/^/PLUG EXPORT: /' - $(BOOT_JAR_CMD) cf $@ @$(PLUG_TEMPDIR)/all.jargs + $(BOOT_JAR_CMD) cf $@ @$(PLUG_TEMPDIR)/all.jargs $(BOOT_JAR_JFLAGS) + @$(java-vm-cleanup) export-binary-plugs-jar: $(PLUG_EXPORT_JARFILE) # Export native libraries diff --git a/jdk/make/common/internal/ImportComponents.gmk b/jdk/make/common/internal/ImportComponents.gmk index d089f230a4c..743659407db 100644 --- a/jdk/make/common/internal/ImportComponents.gmk +++ b/jdk/make/common/internal/ImportComponents.gmk @@ -1,5 +1,5 @@ # -# Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -107,8 +107,9 @@ endef define Unjar ( \ $(MKDIR) -p $1; \ - $(ECHO) "( $(CD) $1 && $(BOOT_JAR_CMD) xfv $2 $3 )" ; \ - ( $(CD) $1 && $(BOOT_JAR_CMD) xfv $2 $3 ) \ + $(ECHO) "( $(CD) $1 && $(BOOT_JAR_CMD) xfv $2 $3 $(BOOT_JAR_JFLAGS) )" ; \ + ( $(CD) $1 && $(BOOT_JAR_CMD) xfv $2 $3 $(BOOT_JAR_JFLAGS) ) && \ + ( $(CD) $1 && $(java-vm-cleanup) ) \ ) endef diff --git a/jdk/make/common/shared/Compiler-sun.gmk b/jdk/make/common/shared/Compiler-sun.gmk index b4806bb4bc3..b3c4e2a90b1 100644 --- a/jdk/make/common/shared/Compiler-sun.gmk +++ b/jdk/make/common/shared/Compiler-sun.gmk @@ -31,11 +31,8 @@ COMPILER_NAME=Sun Studio # Sun Studio Compiler settings specific to Solaris ifeq ($(PLATFORM), solaris) - # FIXUP: Change to SS12 when validated - #COMPILER_VERSION=SS12 - #REQUIRED_CC_VER=5.9 - COMPILER_VERSION=SS11 - REQUIRED_CC_VER=5.8 + COMPILER_VERSION=SS12 + REQUIRED_CC_VER=5.9 CC = $(COMPILER_PATH)cc CPP = $(COMPILER_PATH)cc -E CXX = $(COMPILER_PATH)CC diff --git a/jdk/make/common/shared/Defs-java.gmk b/jdk/make/common/shared/Defs-java.gmk index 179e53a01a9..9bfb96da453 100644 --- a/jdk/make/common/shared/Defs-java.gmk +++ b/jdk/make/common/shared/Defs-java.gmk @@ -1,5 +1,5 @@ # -# Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -190,6 +190,7 @@ ifeq ($(JAVAC_WARNINGS_FATAL), true) BOOT_JAVACFLAGS += -Werror endif BOOT_JAVACFLAGS += -encoding ascii +BOOT_JAR_JFLAGS += $(JAR_JFLAGS) BOOT_JAVA_CMD = $(BOOTDIR)/bin/java $(JAVA_TOOLS_FLAGS) BOOT_JAVAC_CMD = $(BOOTDIR)/bin/javac $(JAVAC_JVM_FLAGS) $(BOOT_JAVACFLAGS) diff --git a/jdk/make/common/shared/Defs-windows.gmk b/jdk/make/common/shared/Defs-windows.gmk index 250604136bc..35fa8ce344f 100644 --- a/jdk/make/common/shared/Defs-windows.gmk +++ b/jdk/make/common/shared/Defs-windows.gmk @@ -1,5 +1,5 @@ # -# Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -539,6 +539,8 @@ else WSCRIPT :=$(call FileExists,$(_WSCRIPT1),$(_WSCRIPT2)) endif WSCRIPT:=$(call AltCheckSpaces,WSCRIPT) +# batch mode no modal dialogs on errors, please. +WSCRIPT += -B # CSCRIPT: path to cscript.exe (used in creating install bundles) ifdef ALT_CSCRIPT @@ -561,6 +563,10 @@ else MSIVAL2 :=$(call FileExists,$(_MSIVAL2_1),$(_MSIVAL2_2)) endif MSIVAL2:=$(call AltCheckSpaces,MSIVAL2) +# suppress msival2 checks, as it hangs jprt builds +ifdef SKIP_MSIVAL2 + MSIVAL2 := $(ECHO) +endif # LOGOCUB: path to cub file for (used in validating install msi files) ifdef ALT_LOGOCUB diff --git a/jdk/make/common/shared/Defs.gmk b/jdk/make/common/shared/Defs.gmk index af86be8085d..638cd363696 100644 --- a/jdk/make/common/shared/Defs.gmk +++ b/jdk/make/common/shared/Defs.gmk @@ -279,9 +279,6 @@ PROMOTED_BUILD_LATEST = latest PROMOTED_BUILD_BASEDIR = $(PROMOTED_RE_AREA)/$(PROMOTED_BUILD_LATEST) PROMOTED_BUILD_BINARIES = $(PROMOTED_BUILD_BASEDIR)/binaries -# OPT: Changes what the optimizations settings (in _OPT) -POPT = $(_OPT$(ALT_OPT))$(ALT_OPT) - # PARALLEL_COMPILE_JOBS: is the number of compiles done in parallel. # If the user sets ALT_PARALLEL_COMPILE_JOBS, then COMPILE_APPROACH is set # to parallel. @@ -355,30 +352,6 @@ else HOTSPOT_DOCS_IMPORT_PATH :=$(call DirExists,$(HOTSPOT_IMPORT_PATH)/docs,$(PROMOTED_BUILD_BASEDIR)/docs,/NO_DOCS_DIR) endif -# PREVIOUS_JDK_FILE: filename of install bundle for previous JDK -ifdef ALT_PREVIOUS_JDK_FILE - PREVIOUS_JDK_FILE =$(ALT_PREVIOUS_JDK_FILE) -else - PREVIOUS_JDK_FILE = jdk-$(PREVIOUS_JDK_UNDERSCORE_VERSION)-$(PLATFORM)-$(ARCH)$(BUNDLE_FILE_SUFFIX) -endif -export PREVIOUS_JDK_FILE -PREVIOUS_JDK_FILE:=$(call AltCheckSpaces,PREVIOUS_JDK_FILE) -PREVIOUS_JDK_FILE:=$(call AltCheckValue,PREVIOUS_JDK_FILE) - -# PREVIOUS_JRE_FILE: filename of install bundle for previous JRE -ifdef ALT_PREVIOUS_JRE_FILE - PREVIOUS_JRE_FILE =$(ALT_PREVIOUS_JRE_FILE) -else - PREVIOUS_JRE_FILE = jre-$(PREVIOUS_JDK_UNDERSCORE_VERSION)-$(PLATFORM)-$(ARCH)$(BUNDLE_FILE_SUFFIX) -endif -export PREVIOUS_JRE_FILE -PREVIOUS_JRE_FILE:=$(call AltCheckSpaces,PREVIOUS_JRE_FILE) -PREVIOUS_JRE_FILE:=$(call AltCheckValue,PREVIOUS_JRE_FILE) - -# Set here as shared variables -PREVIOUS_JRE_BUNDLE = $(PREVIOUS_RELEASE_PATH)/$(PREVIOUS_JRE_FILE) -PREVIOUS_JDK_BUNDLE = $(PREVIOUS_RELEASE_PATH)/$(PREVIOUS_JDK_FILE) - # These are the same on all platforms but require the above platform include 1st # BOOTDIR: Bootstrap JDK, previous released JDK. @@ -392,19 +365,70 @@ export BOOTDIR BOOTDIR:=$(call AltCheckSpaces,BOOTDIR) BOOTDIR:=$(call AltCheckValue,BOOTDIR) -# PREVIOUS_RELEASE_PATH: path to where previous release bundles are -ifdef ALT_PREVIOUS_RELEASE_PATH - PREVIOUS_RELEASE_PATH :=$(call OptFullPath,$(ALT_PREVIOUS_RELEASE_PATH)) -else - PREVIOUS_RELEASE_PATH =$(SLASH_JAVA)/re/jdk/$(PREVIOUS_JDK_VERSION)/archive/fcs/bundles/$(PLATFORM)-$(ARCH) -endif -export PREVIOUS_RELEASE_PATH -PREVIOUS_RELEASE_PATH:=$(call AltCheckSpaces,PREVIOUS_RELEASE_PATH) -PREVIOUS_RELEASE_PATH:=$(call AltCheckValue,PREVIOUS_RELEASE_PATH) +# PREVIOUS_FCS_RE_AREA: re path to where previous release binaries/bundles are +PREVIOUS_FCS_RE_AREA = $(SLASH_JAVA)/re/jdk/$(PREVIOUS_JDK_VERSION)/archive/fcs # PREVIOUS_RELEASE_IMAGE: Previous install image to compare against ifdef ALT_PREVIOUS_RELEASE_IMAGE + + # Explicit image provided, no bundle access needed PREVIOUS_RELEASE_IMAGE :=$(call FullPath,$(ALT_PREVIOUS_RELEASE_IMAGE)) + +else + + # PREVIOUS_RELEASE_PATH: path to where previous release bundles are + ifdef ALT_PREVIOUS_RELEASE_PATH + PREVIOUS_RELEASE_PATH :=$(call OptFullPath,$(ALT_PREVIOUS_RELEASE_PATH)) + else + PREVIOUS_RELEASE_PATH := \ + $(call DirExists,$(PREVIOUS_FCS_RE_AREA)/bundles/$(PLATFORM)-$(ARCH),,) + endif + + # Depending on if we have access to these bundles + ifeq ($(PREVIOUS_RELEASE_PATH),) + # Use images in re area or BOOTDIR (which is normally the previous release) + PREVIOUS_RELEASE_IMAGE := \ + $(call DirExists,$(PREVIOUS_FCS_RE_AREA)/binaries/$(PLATFORM)-$(ARCH),$(BOOTDIR),) + else + # Get names of and paths to bundles + PREVIOUS_RELEASE_PATH:=$(call AltCheckSpaces,PREVIOUS_RELEASE_PATH) + PREVIOUS_RELEASE_PATH:=$(call AltCheckValue,PREVIOUS_RELEASE_PATH) + export PREVIOUS_RELEASE_PATH + + # PREVIOUS_JDK_FILE: filename of install bundle for previous JDK + ifdef ALT_PREVIOUS_JDK_FILE + PREVIOUS_JDK_FILE =$(ALT_PREVIOUS_JDK_FILE) + else + PREVIOUS_JDK_FILE = \ + jdk-$(PREVIOUS_JDK_UNDERSCORE_VERSION)-$(PLATFORM)-$(ARCH)$(BUNDLE_FILE_SUFFIX) + endif + export PREVIOUS_JDK_FILE + PREVIOUS_JDK_FILE:=$(call AltCheckSpaces,PREVIOUS_JDK_FILE) + PREVIOUS_JDK_FILE:=$(call AltCheckValue,PREVIOUS_JDK_FILE) + + # PREVIOUS_JRE_FILE: filename of install bundle for previous JRE + ifdef ALT_PREVIOUS_JRE_FILE + PREVIOUS_JRE_FILE =$(ALT_PREVIOUS_JRE_FILE) + else + PREVIOUS_JRE_FILE = \ + jre-$(PREVIOUS_JDK_UNDERSCORE_VERSION)-$(PLATFORM)-$(ARCH)$(BUNDLE_FILE_SUFFIX) + endif + export PREVIOUS_JRE_FILE + PREVIOUS_JRE_FILE:=$(call AltCheckSpaces,PREVIOUS_JRE_FILE) + PREVIOUS_JRE_FILE:=$(call AltCheckValue,PREVIOUS_JRE_FILE) + + # Paths to these bundles + PREVIOUS_JRE_BUNDLE = $(PREVIOUS_RELEASE_PATH)/$(PREVIOUS_JRE_FILE) + PREVIOUS_JDK_BUNDLE = $(PREVIOUS_RELEASE_PATH)/$(PREVIOUS_JDK_FILE) + endif + +endif + +# Indicate we are using an image comparison +ifneq ($(PREVIOUS_RELEASE_IMAGE),) + PREVIOUS_RELEASE_PATH = USING-PREVIOUS_RELEASE_IMAGE + PREVIOUS_JRE_BUNDLE = USING-PREVIOUS_RELEASE_IMAGE + PREVIOUS_JDK_BUNDLE = USING-PREVIOUS_RELEASE_IMAGE endif # CACERTS_FILE: if OPENJDK is false and the internal version of the file @@ -516,23 +540,17 @@ JDK_CUPS_HEADERS_PATH=$(JDK_DEVTOOLS_DIR)/share/cups/include endif endif -# Utilities ant and findbugs -ifeq ($(ANT_HOME),) - ANT_HOME := $(call DirExists,/usr/share/ant,$(JDK_DEVTOOLS_DIR)/share/ant/latest,) +# Utilities ant +ifeq ($(PLATFORM), windows) + ifeq ($(ANT_HOME),) + ANT_HOME := $(call DirExists,$(JDK_DEVTOOLS_DIR)/share/ant/latest,,) + endif endif ifeq ($(ANT_HOME),) ANT = ant else ANT = $(ANT_HOME)/bin/ant endif -ifeq ($(FINDBUGS_HOME),) - FINDBUGS_HOME := $(call DirExists,/usr/share/findbugs,$(JDK_DEVTOOLS_DIR)/share/findbugs/latest,) -endif -ifeq ($(FINDBUGS_HOME),) - FINDBUGS = findbugs -else - FINDBUGS = $(FINDBUGS_HOME)/bin/findbugs -endif ifdef ALT_COPYRIGHT_YEAR COPYRIGHT_YEAR = $(ALT_COPYRIGHT_YEAR) diff --git a/jdk/make/common/shared/Sanity-Settings.gmk b/jdk/make/common/shared/Sanity-Settings.gmk index d7ef8fe0694..911327f5a88 100644 --- a/jdk/make/common/shared/Sanity-Settings.gmk +++ b/jdk/make/common/shared/Sanity-Settings.gmk @@ -1,5 +1,5 @@ # -# Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -79,7 +79,6 @@ ALL_SETTINGS+=$(call addAltSetting,SLASH_JAVA) ALL_SETTINGS+=$(call addRequiredSetting,VARIANT) ALL_SETTINGS+=$(call addAltSetting,JDK_DEVTOOLS_DIR) ALL_SETTINGS+=$(call addOptionalSetting,ANT_HOME) -ALL_SETTINGS+=$(call addOptionalSetting,FINDBUGS_HOME) ALL_SETTINGS+=$(call addAltSetting,UNIXCOMMAND_PATH) ALL_SETTINGS+=$(call addAltSetting,COMPILER_PATH) ALL_SETTINGS+=$(call addAltSetting,DEVTOOLS_PATH) @@ -119,7 +118,6 @@ ifeq ($(PLATFORM),windows) ALL_SETTINGS+=$(call addRequiredVersionSetting,LINK_VER) endif ALL_SETTINGS+=$(call addRequiredVersionSetting,ANT_VER) -ALL_SETTINGS+=$(call addRequiredVersionSetting,FINDBUGS_VER) ALL_SETTINGS+=$(call addRequiredSetting,TEMPDIR) diff --git a/jdk/make/common/shared/Sanity.gmk b/jdk/make/common/shared/Sanity.gmk index 3048281df91..b2cbab12b3f 100644 --- a/jdk/make/common/shared/Sanity.gmk +++ b/jdk/make/common/shared/Sanity.gmk @@ -107,21 +107,9 @@ UNZIP_VER :=$(call GetVersion,"$(_UNZIP_VER)") BOOT_VER :=$(call GetVersion,"$(_BOOT_VER)") REQUIRED_ANT_VER := 1.6.3 -ifeq ($(ANT_HOME),) - _ANT_VER:=$(shell JAVACMD="$(BOOTDIR)/bin/java" $(ANT) -version 2>&1 ) -else - _ANT_VER:=$(shell JAVACMD="$(BOOTDIR)/bin/java" ANT_HOME="$(ANT_HOME)" $(ANT) -version 2>&1 ) -endif +_ANT_VER:=$(shell $(ANT) -version 2>&1 ) ANT_VER:=$(call GetVersion,"$(_ANT_VER)") -REQUIRED_FINDBUGS_VER := 1.2 -ifeq ($(FINDBUGS_HOME),) - _FINDBUGS_VER:=$(shell $(FINDBUGS) -javahome "$(BOOTDIR)" -textui -version 2>&1 ) -else - _FINDBUGS_VER:=$(shell FINDBUGS_HOME="$(FINDBUGS_HOME)" $(FINDBUGS) -javahome "$(BOOTDIR)" -textui -version 2>&1 ) -endif -FINDBUGS_VER:=$(call GetVersion,"$(_FINDBUGS_VER)") - ifdef ALT_BINDIR ALT_BINDIR_VERSION := $(shell $(ALT_BINDIR)/java$(EXE_SUFFIX) -version 2>&1 | $(NAWK) -F'"' '{ print $$2 }') ALT_BINDIR_OK := $(shell $(ECHO) $(ALT_BINDIR_VERSION) | $(EGREP) -c '^$(JDK_MAJOR_VERSION).$(JDK_MINOR_VERSION)') @@ -182,7 +170,6 @@ include $(JDK_MAKE_SHARED_DIR)/Sanity-Settings.gmk sane-alsa-versioncheck \ sane-alsa-headers \ sane-ant_version \ - sane-findbugs_version \ sane-zip_version \ sane-unzip_version \ sane-msvcrt_path \ @@ -1216,19 +1203,6 @@ sane-ant_version: "" >> $(WARNING_FILE) ; \ fi -###################################################### -# Check the findbugs version -###################################################### -FINDBUGS_CHECK :=$(call CheckVersions,$(FINDBUGS_VER),$(REQUIRED_FINDBUGS_VER)) -sane-findbugs_version: - @if [ "$(FINDBUGS_CHECK)" != "same" \ - -a "$(FINDBUGS_CHECK)" != "newer" ]; then \ - $(ECHO) "WARNING: The version of findbugs being used is older than \n" \ - " the required version of '$(REQUIRED_FINDBUGS_VER)'. \n" \ - " The version of findbugs found was '$(FINDBUGS_VER)'. \n" \ - "" >> $(WARNING_FILE) ; \ - fi - ###################################################### # Check the zip file version ###################################################### diff --git a/jdk/make/docs/CORE_PKGS.gmk b/jdk/make/docs/CORE_PKGS.gmk index c768e7023db..4a41a2005bf 100644 --- a/jdk/make/docs/CORE_PKGS.gmk +++ b/jdk/make/docs/CORE_PKGS.gmk @@ -155,8 +155,10 @@ CORE_PKGS = \ javax.lang.model.type \ javax.lang.model.util \ javax.management \ + javax.management.event \ javax.management.loading \ javax.management.monitor \ + javax.management.namespace \ javax.management.relation \ javax.management.openmbean \ javax.management.timer \ diff --git a/jdk/make/java/fdlibm/Makefile b/jdk/make/java/fdlibm/Makefile index ab7a411579c..eeb5e744f41 100644 --- a/jdk/make/java/fdlibm/Makefile +++ b/jdk/make/java/fdlibm/Makefile @@ -1,5 +1,5 @@ # -# Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,7 @@ BUILDDIR = ../.. LIBRARY = fdlibm PRODUCT = java + include $(BUILDDIR)/common/Defs.gmk # @@ -40,14 +41,23 @@ include $(BUILDDIR)/common/Defs.gmk # FDLIBM_SRC = $(SHARE_SRC)/native/java/lang/fdlibm -# windows compiler flags +# Windows: compiler flags ifeq ($(PLATFORM),windows) # Turn all optimizations off - _OPT = $(CC_NO_OPT) + OPTIMIZATION_LEVEL = NONE OTHER_CFLAGS = CPPFLAGS_DBG += -DLOGGING endif +# +# Linux: Disable optimization to get correctly reproducible +# floating-point results. +# +ifeq ($(PLATFORM),linux) + # Turn all optimizations off + OPTIMIZATION_LEVEL = NONE +endif + # # Include path. # @@ -68,15 +78,6 @@ include FILES_c.gmk # include $(BUILDDIR)/common/Library.gmk -# -# Disable optimization to get correctly reproducible -# floating-point results. -# -ifeq ($(PLATFORM),linux) - # Turn all optimizations off - _OPT = $(CC_NO_OPT) -endif - # # Find fdlibm source files. # diff --git a/jdk/make/java/hpi/windows/Makefile b/jdk/make/java/hpi/windows/Makefile index fa04ec6a362..b82d8853ab2 100644 --- a/jdk/make/java/hpi/windows/Makefile +++ b/jdk/make/java/hpi/windows/Makefile @@ -1,5 +1,5 @@ # -# Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/jdk/make/java/java/FILES_java.gmk b/jdk/make/java/java/FILES_java.gmk index b4a07fc352f..3117af8461f 100644 --- a/jdk/make/java/java/FILES_java.gmk +++ b/jdk/make/java/java/FILES_java.gmk @@ -1,5 +1,5 @@ # -# Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -209,6 +209,7 @@ JAVA_JAVA_java = \ sun/util/TimeZoneNameUtility.java \ sun/util/calendar/ZoneInfo.java \ sun/util/calendar/ZoneInfoFile.java \ + sun/util/calendar/TzIDOldMapping.java \ java/util/TooManyListenersException.java \ java/util/Comparator.java \ java/util/Collections.java \ @@ -449,6 +450,7 @@ JAVA_JAVA_java = \ sun/misc/JavaLangAccess.java \ sun/misc/JavaIOAccess.java \ sun/misc/JavaIODeleteOnExitAccess.java \ - sun/misc/JavaIOFileDescriptorAccess.java + sun/misc/JavaIOFileDescriptorAccess.java \ + sun/misc/JavaNioAccess.java FILES_java = $(JAVA_JAVA_java) diff --git a/jdk/make/java/java/mapfile-vers b/jdk/make/java/java/mapfile-vers index ad0380979a9..77a78301af7 100644 --- a/jdk/make/java/java/mapfile-vers +++ b/jdk/make/java/java/mapfile-vers @@ -222,8 +222,6 @@ SUNWprivate_1.1 { Java_java_lang_UNIXProcess_waitForProcessExit; Java_java_lang_UNIXProcess_forkAndExec; Java_java_lang_UNIXProcess_destroyProcess; - Java_java_nio_Bits_copyFromByteArray; - Java_java_nio_Bits_copyToByteArray; Java_java_nio_Bits_copyFromShortArray; Java_java_nio_Bits_copyToShortArray; Java_java_nio_Bits_copyFromIntArray; diff --git a/jdk/make/java/java_crw_demo/Makefile b/jdk/make/java/java_crw_demo/Makefile index c65a84df1e8..6c45bcbd499 100644 --- a/jdk/make/java/java_crw_demo/Makefile +++ b/jdk/make/java/java_crw_demo/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2004-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/jdk/make/java/java_hprof_demo/Makefile b/jdk/make/java/java_hprof_demo/Makefile index 9c97a6a24e5..4e1ef2a31a8 100644 --- a/jdk/make/java/java_hprof_demo/Makefile +++ b/jdk/make/java/java_hprof_demo/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -28,14 +28,14 @@ LIBRARY = hprof PRODUCT = sun LIBRARY_OUTPUT = hprof_jvmti -# Configure the CFLAGS for this library. +# Use highest optimization +OPTIMIZATION_LEVEL = HIGHEST +# Configure the CFLAGS for this library. FILES_m = mapfile-vers include $(BUILDDIR)/common/Defs.gmk -_OPT=$(CC_HIGHEST_OPT) - SRCDIR=$(SHARE_SRC)/demo/jvmti/hprof PSRCDIR=$(PLATFORM_SRC)/demo/jvmti/hprof diff --git a/jdk/make/java/jli/Makefile b/jdk/make/java/jli/Makefile index 5a1c312d7ab..7a0c53f1ce2 100644 --- a/jdk/make/java/jli/Makefile +++ b/jdk/make/java/jli/Makefile @@ -113,7 +113,11 @@ ifeq ($(PLATFORM), windows) JAVALIB = OTHER_LCF = -export:JLI_Launch \ -export:JLI_ManifestIterate \ - -export:JLI_SetTraceLauncher + -export:JLI_SetTraceLauncher \ + -export:JLI_ReportErrorMessage \ + -export:JLI_ReportErrorMessageSys \ + -export:JLI_ReportMessage \ + -export:JLI_ReportExceptionDescription endif diff --git a/jdk/make/java/jli/mapfile-vers b/jdk/make/java/jli/mapfile-vers index a9e8198dea1..e04e4f13db9 100644 --- a/jdk/make/java/jli/mapfile-vers +++ b/jdk/make/java/jli/mapfile-vers @@ -1,5 +1,5 @@ # -# Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,10 @@ SUNWprivate_1.1 { JLI_Launch; JLI_ManifestIterate; JLI_SetTraceLauncher; + JLI_ReportErrorMessage; + JLI_ReportErrorMessageSys; + JLI_ReportMessage; + JLI_ReportExceptionDescription; local: *; }; diff --git a/jdk/make/java/management/Makefile b/jdk/make/java/management/Makefile index 4d39d514e51..466d2212afe 100644 --- a/jdk/make/java/management/Makefile +++ b/jdk/make/java/management/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -93,7 +93,8 @@ endif include $(BUILDDIR)/common/Library.gmk $(AGENTJAR): $(LIBDIR) $(TEMPDIR)/manifest - $(BOOT_JAR_CMD) -cfm $(AGENTJAR) $(TEMPDIR)/manifest + $(BOOT_JAR_CMD) -cfm $(AGENTJAR) $(TEMPDIR)/manifest $(BOOT_JAR_JFLAGS) + @$(java-vm-cleanup) $(TEMPDIR)/manifest: $(MANIFEST) $(install-file) diff --git a/jdk/make/java/net/Makefile b/jdk/make/java/net/Makefile index 4141294c02c..b9a3defdb8c 100644 --- a/jdk/make/java/net/Makefile +++ b/jdk/make/java/net/Makefile @@ -1,5 +1,5 @@ # -# Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/jdk/make/java/net/mapfile-vers b/jdk/make/java/net/mapfile-vers index 86cb351c9f9..d9803f8f944 100644 --- a/jdk/make/java/net/mapfile-vers +++ b/jdk/make/java/net/mapfile-vers @@ -1,5 +1,5 @@ # -# Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -57,7 +57,7 @@ SUNWprivate_1.1 { Java_java_net_Inet6AddressImpl_isReachable0; Java_java_net_NetworkInterface_init; Java_java_net_NetworkInterface_getByName0; - Java_java_net_NetworkInterface_getByIndex; + Java_java_net_NetworkInterface_getByIndex0; Java_java_net_NetworkInterface_getByInetAddress0; Java_java_net_NetworkInterface_getAll; Java_java_net_NetworkInterface_isUp0; diff --git a/jdk/make/java/nio/FILES_java.gmk b/jdk/make/java/nio/FILES_java.gmk index 5958812adfb..0e8c70906aa 100644 --- a/jdk/make/java/nio/FILES_java.gmk +++ b/jdk/make/java/nio/FILES_java.gmk @@ -1,5 +1,5 @@ # -# Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ FILES_src = \ java/nio/Bits.java \ java/nio/Buffer.java \ + java/nio/BufferPoolMXBean.java \ java/nio/ByteOrder.java \ java/nio/MappedByteBuffer.java \ java/nio/StringCharBuffer.java \ @@ -38,6 +39,9 @@ FILES_src = \ java/nio/channels/FileLock.java \ java/nio/channels/GatheringByteChannel.java \ java/nio/channels/InterruptibleChannel.java \ + java/nio/channels/MembershipKey.java \ + java/nio/channels/MulticastChannel.java \ + java/nio/channels/NetworkChannel.java \ java/nio/channels/ReadableByteChannel.java \ java/nio/channels/ScatteringByteChannel.java \ java/nio/channels/SelectableChannel.java \ @@ -72,6 +76,7 @@ FILES_src = \ sun/nio/ch/DatagramSocketAdaptor.java \ sun/nio/ch/DefaultSelectorProvider.java \ sun/nio/ch/DirectBuffer.java \ + sun/nio/ch/ExtendedSocketOption.java \ sun/nio/ch/FileChannelImpl.java \ sun/nio/ch/FileDispatcher.java \ sun/nio/ch/FileKey.java \ @@ -79,12 +84,14 @@ FILES_src = \ sun/nio/ch/IOUtil.java \ sun/nio/ch/IOStatus.java \ sun/nio/ch/IOVecWrapper.java \ + sun/nio/ch/MembershipKeyImpl.java \ + sun/nio/ch/MembershipRegistry.java \ sun/nio/ch/NativeDispatcher.java \ sun/nio/ch/NativeObject.java \ sun/nio/ch/NativeThread.java \ sun/nio/ch/NativeThreadSet.java \ sun/nio/ch/Net.java \ - sun/nio/ch/OptionAdaptor.java \ + sun/nio/ch/OptionKey.java \ sun/nio/ch/PipeImpl.java \ sun/nio/ch/PollArrayWrapper.java \ sun/nio/ch/Reflect.java \ @@ -98,8 +105,7 @@ FILES_src = \ sun/nio/ch/SocketAdaptor.java \ sun/nio/ch/SocketChannelImpl.java \ sun/nio/ch/SocketDispatcher.java \ - sun/nio/ch/SocketOpts.java \ - sun/nio/ch/SocketOptsImpl.java \ + sun/nio/ch/SocketOptionRegistry.java \ sun/nio/ch/SourceChannelImpl.java \ sun/nio/ch/Util.java \ \ @@ -239,6 +245,7 @@ FILES_gen_ex = \ java/nio/InvalidMarkException.java \ java/nio/ReadOnlyBufferException.java \ \ + java/nio/channels/AlreadyBoundException.java \ java/nio/channels/AlreadyConnectedException.java \ java/nio/channels/AsynchronousCloseException.java \ java/nio/channels/ClosedByInterruptException.java \ @@ -257,14 +264,15 @@ FILES_gen_ex = \ java/nio/channels/UnresolvedAddressException.java \ java/nio/channels/UnsupportedAddressTypeException.java \ \ - sun/nio/ch/AlreadyBoundException.java \ - \ java/nio/charset/CharacterCodingException.java \ java/nio/charset/IllegalCharsetNameException.java \ java/nio/charset/UnsupportedCharsetException.java FILES_gen_csp = sun/nio/cs/StandardCharsets.java -FILES_gen = $(FILES_gen_coder) $(FILES_gen_buffer) $(FILES_gen_ex) $(FILES_gen_csp) +FILES_gen_sor = sun/nio/ch/SocketOptionRegistry.java + +FILES_gen = $(FILES_gen_coder) $(FILES_gen_buffer) $(FILES_gen_ex) \ + $(FILES_gen_csp) $(FILES_gen_sor) FILES_java = $(FILES_src) $(FILES_gen) diff --git a/jdk/make/java/nio/Makefile b/jdk/make/java/nio/Makefile index cff9ce5ceb2..26c2f2fc68d 100644 --- a/jdk/make/java/nio/Makefile +++ b/jdk/make/java/nio/Makefile @@ -56,18 +56,18 @@ FILES_java += \ sun/nio/ch/DevPollSelectorProvider.java \ sun/nio/ch/InheritedChannel.java \ sun/nio/ch/PollSelectorProvider.java \ - sun/nio/ch/PollSelectorImpl.java + sun/nio/ch/PollSelectorImpl.java FILES_c += \ DevPollArrayWrapper.c \ InheritedChannel.c \ - PollArrayWrapper.c \ - NativeThread.c + NativeThread.c \ + PollArrayWrapper.c FILES_export += \ sun/nio/ch/DevPollArrayWrapper.java \ sun/nio/ch/InheritedChannel.java \ - sun/nio/ch/NativeThread.java + sun/nio/ch/NativeThread.java endif # PLATFORM = solaris ifeq ($(PLATFORM), windows) @@ -94,14 +94,14 @@ FILES_java += \ FILES_c += \ EPollArrayWrapper.c \ - PollArrayWrapper.c \ InheritedChannel.c \ - NativeThread.c + NativeThread.c \ + PollArrayWrapper.c FILES_export += \ sun/nio/ch/EPollArrayWrapper.java \ sun/nio/ch/InheritedChannel.java \ - sun/nio/ch/NativeThread.java + sun/nio/ch/NativeThread.java endif # PLATFORM = linux # Find platform-specific C source files @@ -618,12 +618,6 @@ $(BUF_GEN)/%Exception.java: genExceptions.sh $(BUF_SRC)/exceptions @$(RM) $@.temp $(GEN_EX_CMD) $(BUF_SRC)/exceptions $(BUF_GEN) -$(SCH_GEN)/%Exception.java: genExceptions.sh $(SCH_SRC)/exceptions - $(prep-target) - @$(RM) $@.temp - $(GEN_EX_CMD) $(SCH_SRC)/exceptions $(SCH_GEN) - - # # Generated charset-provider classes # @@ -638,4 +632,29 @@ $(SCS_GEN)/StandardCharsets.java: genCharsetProvider.sh \ HASHER="$(BOOT_JAVA_CMD) -jar $(HASHER_JARFILE)" \ $(SH) -e genCharsetProvider.sh $(SCS_SRC)/standard-charsets $(SCS_GEN) +# +# Generated channel implementation classes. +# C source is compiled in TEMPDIR to avoid turds left by Windows compilers. +# + +GENSOR_SRC = $(SHARE_SRC)/native/sun/nio/ch/genSocketOptionRegistry.c + +GENSOR_EXE = $(TEMPDIR)/genSocketOptionRegistry$(EXE_SUFFIX) + +SOR_COPYRIGHT_YEARS = $(shell $(CAT) $(GENSOR_SRC) | \ + $(NAWK) '/^.*Copyright.*Sun/ { print $$3 }') + +$(TEMPDIR)/$(GENSOR_SRC) : $(GENSOR_SRC) + $(install-file) + +$(GENSOR_EXE) : $(TEMPDIR)/$(GENSOR_SRC) + $(prep-target) + ($(CD) $(TEMPDIR); $(CC) $(CPPFLAGS) $(LDDFLAGS) \ + -o genSocketOptionRegistry$(EXE_SUFFIX) $(GENSOR_SRC)) + +$(SCH_GEN)/SocketOptionRegistry.java: $(GENSOR_EXE) + $(prep-target) + NAWK="$(NAWK)" SH="$(SH)" $(SH) -e addNotices.sh $(SOR_COPYRIGHT_YEARS) > $@ + $(GENSOR_EXE) >> $@ + .PHONY: sources diff --git a/jdk/make/java/nio/genCoder.sh b/jdk/make/java/nio/genCoder.sh index 769b98cd523..b5f4faaa71a 100644 --- a/jdk/make/java/nio/genCoder.sh +++ b/jdk/make/java/nio/genCoder.sh @@ -1,7 +1,7 @@ #! /bin/sh # -# Copyright 2000-2001 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/jdk/make/java/nio/mapfile-linux b/jdk/make/java/nio/mapfile-linux index dc2044c9d79..3fb47b0eb7c 100644 --- a/jdk/make/java/nio/mapfile-linux +++ b/jdk/make/java/nio/mapfile-linux @@ -1,3 +1,27 @@ +# +# Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Sun designates this +# particular file as subject to the "Classpath" exception as provided +# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# SUNWprivate_1.1 { global: @@ -18,6 +42,8 @@ SUNWprivate_1.1 { Java_sun_nio_ch_EPollArrayWrapper_fdLimit; Java_sun_nio_ch_EPollArrayWrapper_init; Java_sun_nio_ch_EPollArrayWrapper_interrupt; + Java_sun_nio_ch_EPollArrayWrapper_offsetofData; + Java_sun_nio_ch_EPollArrayWrapper_sizeofEPollEvent; Java_sun_nio_ch_FileChannelImpl_close0; Java_sun_nio_ch_FileChannelImpl_force0; Java_sun_nio_ch_FileChannelImpl_initIDs; @@ -59,20 +85,29 @@ SUNWprivate_1.1 { Java_sun_nio_ch_NativeThread_init; Java_sun_nio_ch_NativeThread_signal; Java_sun_nio_ch_Net_socket0; - Java_sun_nio_ch_Net_bind; - Java_sun_nio_ch_Net_connect; + Java_sun_nio_ch_Net_bind0; + Java_sun_nio_ch_Net_connect0; + Java_sun_nio_ch_Net_listen; Java_sun_nio_ch_Net_localPort; Java_sun_nio_ch_Net_localInetAddress; Java_sun_nio_ch_Net_getIntOption0; Java_sun_nio_ch_Net_setIntOption0; Java_sun_nio_ch_Net_initIDs; + Java_sun_nio_ch_Net_isIPv6Available0; + Java_sun_nio_ch_Net_joinOrDrop4; + Java_sun_nio_ch_Net_blockOrUnblock4; + Java_sun_nio_ch_Net_joinOrDrop6; + Java_sun_nio_ch_Net_blockOrUnblock6; + Java_sun_nio_ch_Net_setInterface4; + Java_sun_nio_ch_Net_getInterface4; + Java_sun_nio_ch_Net_setInterface6; + Java_sun_nio_ch_Net_getInterface6; + Java_sun_nio_ch_Net_shutdown; Java_sun_nio_ch_PollArrayWrapper_interrupt; Java_sun_nio_ch_PollArrayWrapper_poll0; Java_sun_nio_ch_ServerSocketChannelImpl_accept0; Java_sun_nio_ch_ServerSocketChannelImpl_initIDs; - Java_sun_nio_ch_ServerSocketChannelImpl_listen; Java_sun_nio_ch_SocketChannelImpl_checkConnect; - Java_sun_nio_ch_SocketChannelImpl_shutdown; local: *; diff --git a/jdk/make/java/nio/mapfile-solaris b/jdk/make/java/nio/mapfile-solaris index 77ef8ea2ad9..6e109e2faba 100644 --- a/jdk/make/java/nio/mapfile-solaris +++ b/jdk/make/java/nio/mapfile-solaris @@ -1,3 +1,27 @@ +# +# Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Sun designates this +# particular file as subject to the "Classpath" exception as provided +# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# SUNWprivate_1.1 { global: @@ -59,20 +83,29 @@ SUNWprivate_1.1 { Java_sun_nio_ch_NativeThread_init; Java_sun_nio_ch_NativeThread_signal; Java_sun_nio_ch_Net_socket0; - Java_sun_nio_ch_Net_bind; - Java_sun_nio_ch_Net_connect; + Java_sun_nio_ch_Net_bind0; + Java_sun_nio_ch_Net_connect0; + Java_sun_nio_ch_Net_listen; Java_sun_nio_ch_Net_localPort; Java_sun_nio_ch_Net_localInetAddress; Java_sun_nio_ch_Net_getIntOption0; Java_sun_nio_ch_Net_setIntOption0; Java_sun_nio_ch_Net_initIDs; + Java_sun_nio_ch_Net_isIPv6Available0; + Java_sun_nio_ch_Net_joinOrDrop4; + Java_sun_nio_ch_Net_blockOrUnblock4; + Java_sun_nio_ch_Net_joinOrDrop6; + Java_sun_nio_ch_Net_blockOrUnblock6; + Java_sun_nio_ch_Net_setInterface4; + Java_sun_nio_ch_Net_getInterface4; + Java_sun_nio_ch_Net_setInterface6; + Java_sun_nio_ch_Net_getInterface6; + Java_sun_nio_ch_Net_shutdown; Java_sun_nio_ch_PollArrayWrapper_interrupt; Java_sun_nio_ch_PollArrayWrapper_poll0; Java_sun_nio_ch_ServerSocketChannelImpl_accept0; Java_sun_nio_ch_ServerSocketChannelImpl_initIDs; - Java_sun_nio_ch_ServerSocketChannelImpl_listen; Java_sun_nio_ch_SocketChannelImpl_checkConnect; - Java_sun_nio_ch_SocketChannelImpl_shutdown; local: *; diff --git a/jdk/make/java/npt/Makefile b/jdk/make/java/npt/Makefile index fe9eb0ad4e3..57e6a663805 100644 --- a/jdk/make/java/npt/Makefile +++ b/jdk/make/java/npt/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2004-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/jdk/make/java/verify/Makefile b/jdk/make/java/verify/Makefile index c647d508569..24bcc0f48d4 100644 --- a/jdk/make/java/verify/Makefile +++ b/jdk/make/java/verify/Makefile @@ -1,5 +1,5 @@ # -# Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -52,12 +52,6 @@ FILES_c = \ check_code.c \ check_format.c -# -# libverify.so needs these 2 header files (opcodes.h opcodes.length) -# from the VM. -# -CPPFLAGS += -I$(SHARE_SRC)/javavm/include - # # Targets. # diff --git a/jdk/make/java/zip/Makefile b/jdk/make/java/zip/Makefile index 00b381d5085..48e8c3904e9 100644 --- a/jdk/make/java/zip/Makefile +++ b/jdk/make/java/zip/Makefile @@ -1,5 +1,5 @@ # -# Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/jdk/make/javax/crypto/Makefile b/jdk/make/javax/crypto/Makefile index 86588e855ef..216ff6e222d 100644 --- a/jdk/make/javax/crypto/Makefile +++ b/jdk/make/javax/crypto/Makefile @@ -230,7 +230,7 @@ build-jar: $(UNSIGNED_DIR)/jce.jar $(UNSIGNED_DIR)/jce.jar: prebuild build $(JCE_MANIFEST_FILE) $(prep-target) $(BOOT_JAR_CMD) cmf $(JCE_MANIFEST_FILE) $@ $(JAR_DIRS) \ - $(JAR_JFLAGS) + $(BOOT_JAR_JFLAGS) $(CP) -r $(CLASSDESTDIR)/* $(CLASSBINDIR) @$(java-vm-cleanup) @@ -268,7 +268,7 @@ $(UNSIGNED_POLICY_BUILDDIR)/unlimited/US_export_policy.jar: \ $(prep-target) $(BOOT_JAR_CMD) cmf policy/unlimited/UNLIMITED $@ \ -C policy/unlimited default_US_export.policy \ - $(JAR_JFLAGS) + $(BOOT_JAR_JFLAGS) @$(java-vm-cleanup) $(UNSIGNED_POLICY_BUILDDIR)/unlimited/local_policy.jar: \ @@ -277,7 +277,7 @@ $(UNSIGNED_POLICY_BUILDDIR)/unlimited/local_policy.jar: \ $(prep-target) $(BOOT_JAR_CMD) cmf policy/unlimited/UNLIMITED $@ \ -C policy/unlimited default_local.policy \ - $(JAR_JFLAGS) + $(BOOT_JAR_JFLAGS) @$(java-vm-cleanup) # @@ -302,7 +302,7 @@ $(UNSIGNED_POLICY_BUILDDIR)/limited/local_policy.jar: \ $(BOOT_JAR_CMD) cmf policy/limited/LIMITED $@ \ -C policy/limited default_local.policy \ -C policy/limited exempt_local.policy \ - $(JAR_JFLAGS) + $(BOOT_JAR_JFLAGS) @$(java-vm-cleanup) UNSIGNED_POLICY_FILES = \ @@ -402,7 +402,7 @@ endif $(BOOT_JAR_CMD) cmf $(JCE_MANIFEST_FILE) $@ \ -C $(OBFUS_DIR)/build javax \ -C $(OBFUS_DIR)/build sun \ - $(JAR_JFLAGS) + $(BOOT_JAR_JFLAGS) $(sign-target) @$(java-vm-cleanup) diff --git a/jdk/make/javax/swing/Makefile b/jdk/make/javax/swing/Makefile index c2056a45ce2..e112e609cd9 100644 --- a/jdk/make/javax/swing/Makefile +++ b/jdk/make/javax/swing/Makefile @@ -33,7 +33,7 @@ include $(BUILDDIR)/common/Defs.gmk # Files # include FILES.gmk -AUTO_FILES_JAVA_DIRS = javax/swing sun/swing +AUTO_FILES_JAVA_DIRS = javax/swing sun/swing com/sun/java/swing AUTO_JAVA_PRUNE = plaf SUBDIRS = html32dtd plaf diff --git a/jdk/make/javax/swing/beaninfo/SwingBeans.gmk b/jdk/make/javax/swing/beaninfo/SwingBeans.gmk index daead86fd6c..66f16aae1a1 100644 --- a/jdk/make/javax/swing/beaninfo/SwingBeans.gmk +++ b/jdk/make/javax/swing/beaninfo/SwingBeans.gmk @@ -1,5 +1,5 @@ # -# Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -170,7 +170,7 @@ mkpackaging: $(BOOT_JAR_CMD) cf $(TEMPDIR)/tmp.jar \ -C $(BEANCLASSDIR) javax \ -C $(BEANCLASSDIR) sun \ - $(JAR_JFLAGS) + $(BOOT_JAR_JFLAGS) $(MV) $(TEMPDIR)/tmp.jar $(JDK_IMAGE_DIR)/lib/dt.jar @$(java-vm-cleanup) diff --git a/jdk/make/jpda/back/Makefile b/jdk/make/jpda/back/Makefile index bd9818365e3..5237d9c798c 100644 --- a/jdk/make/jpda/back/Makefile +++ b/jdk/make/jpda/back/Makefile @@ -1,5 +1,5 @@ # -# Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/jdk/make/jpda/transport/shmem/Makefile b/jdk/make/jpda/transport/shmem/Makefile index a1e2382500a..fcc8c632de4 100644 --- a/jdk/make/jpda/transport/shmem/Makefile +++ b/jdk/make/jpda/transport/shmem/Makefile @@ -1,5 +1,5 @@ # -# Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/jdk/make/jpda/transport/socket/Makefile b/jdk/make/jpda/transport/socket/Makefile index 828613d49ed..65f8018477f 100644 --- a/jdk/make/jpda/transport/socket/Makefile +++ b/jdk/make/jpda/transport/socket/Makefile @@ -1,5 +1,5 @@ # -# Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/jdk/make/jprt.config b/jdk/make/jprt.config index 99ee4c4e793..d720475cecd 100644 --- a/jdk/make/jprt.config +++ b/jdk/make/jprt.config @@ -100,20 +100,16 @@ share="${jdk_devtools}/share" # Needed for langtools, maybe other parts of the build ANT_HOME="${share}/ant/latest" export ANT_HOME -FINDBUGS_HOME="${share}/findbugs/latest" -export FINDBUGS_HOME # The 3 bin directories in common to all platforms sharebin="${share}/bin" antbin="${ANT_HOME}/bin" -findbugsbin="${FINDBUGS_HOME}/bin" # Check input dirMustExist "${bootdir}" ALT_BOOTDIR dirMustExist "${slashjava}" ALT_SLASH_JAVA dirMustExist "${jdk_import}" ALT_JDK_IMPORT_PATH dirMustExist "${ANT_HOME}" ANT_HOME -dirMustExist "${FINDBUGS_HOME}" FINDBUGS_HOME # Use the JDK import for now (FIXME: use the binary plugs?) if [ "${OPENJDK}" = true ] ; then @@ -137,15 +133,13 @@ if [ "${osname}" = SunOS ] ; then if [ "${JPRT_SOLARIS_COMPILER_NAME}" != "" ] ; then compiler_name=${JPRT_SOLARIS_COMPILER_NAME} else - # FIXUP: Change to SS12 when validated - #compiler_name=SS12 - compiler_name=SS11 + compiler_name=SS12 fi compiler_path=${jdk_devtools}/${solaris_arch}/SUNWspro/${compiler_name}/bin ALT_COMPILER_PATH="${compiler_path}" export ALT_COMPILER_PATH dirMustExist "${compiler_path}" ALT_COMPILER_PATH - path4sdk=${compiler_path}:${sharebin}:${antbin}:${findbugsbin} + path4sdk=${compiler_path}:${sharebin}:${antbin} # Add basic solaris system paths path4sdk=${path4sdk}:/usr/ccs/bin:/usr/ccs/lib:/usr/bin:/bin:/usr/sfw/bin @@ -182,7 +176,7 @@ elif [ "${osname}" = Linux ] ; then ALT_COMPILER_PATH="${compiler_path}" export ALT_COMPILER_PATH dirMustExist "${compiler_path}" ALT_COMPILER_PATH - path4sdk=${compiler_path}:${sharebin}:${antbin}:${findbugsbin} + path4sdk=${compiler_path}:${sharebin}:${antbin} # Add basic paths path4sdk=${path4sdk}:/usr/bin:/bin:/usr/sbin:/sbin @@ -230,7 +224,7 @@ else dosname="${mkshome}/mksnt/dosname -s" # Most unix utilities are in the mksnt directory of ROOTDIR unixcommand_path="${mkshome}/mksnt" - path4sdk="${sharebin};${antbin};${findbugsbin};${unixcommand_path}" + path4sdk="${sharebin};${antbin};${unixcommand_path}" dirMustExist "${unixcommand_path}" ALT_UNIXCOMMAND_PATH devtools_path="${jdk_devtools}/win32/bin" path4sdk="${devtools_path};${path4sdk}" @@ -248,7 +242,7 @@ else dosname="/usr/bin/cygpath -a -m -s" # Most unix utilities are in the /usr/bin unixcommand_path="/usr/bin" - path4sdk="${sharebin};${antbin};${findbugsbin};${unixcommand_path}" + path4sdk="${sharebin};${antbin};${unixcommand_path}" dirMustExist "${unixcommand_path}" ALT_UNIXCOMMAND_PATH # Find GNU make make="${unixcommand_path}/make.exe" diff --git a/jdk/make/jprt.properties b/jdk/make/jprt.properties index 06abef8c8e6..c909f36aa3c 100644 --- a/jdk/make/jprt.properties +++ b/jdk/make/jprt.properties @@ -1,5 +1,5 @@ # -# Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -55,6 +55,5 @@ jprt.solaris_x64.build.platform.match32=solaris_i586_5.10 jprt.test.targets=*-*-*-jvm98 # Directories needed to build -jprt.bundle.src.dirs=make src jprt.bundle.exclude.src.dirs=build diff --git a/jdk/make/mksample/nio/Makefile b/jdk/make/mksample/nio/Makefile index a6e8fc46d96..e05106293bb 100644 --- a/jdk/make/mksample/nio/Makefile +++ b/jdk/make/mksample/nio/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2004-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ BUILDDIR = ../.. PRODUCT = java include $(BUILDDIR)/common/Defs.gmk -SUBDIRS = server +SUBDIRS = multicast server all build clean clobber:: $(SUBDIRS-loop) diff --git a/jdk/make/mksample/nio/multicast/Makefile b/jdk/make/mksample/nio/multicast/Makefile new file mode 100644 index 00000000000..179d3d4a97c --- /dev/null +++ b/jdk/make/mksample/nio/multicast/Makefile @@ -0,0 +1,52 @@ +# +# Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Sun designates this +# particular file as subject to the "Classpath" exception as provided +# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# + +# +# Makefile for the nio/multicast sample code +# + +BUILDDIR = ../../.. + +PRODUCT = java + +include $(BUILDDIR)/common/Defs.gmk + +SAMPLE_SRC_DIR = $(SHARE_SRC)/sample/nio/multicast +SAMPLE_DST_DIR = $(SAMPLEDIR)/nio/multicast + +SAMPLE_FILES = \ + $(SAMPLE_DST_DIR)/Reader.java \ + $(SAMPLE_DST_DIR)/Sender.java \ + $(SAMPLE_DST_DIR)/MulticastAddress.java + +all build: $(SAMPLE_FILES) + +$(SAMPLE_DST_DIR)/%: $(SAMPLE_SRC_DIR)/% + $(install-file) + +clean clobber: + $(RM) -r $(SAMPLE_DST_DIR) + +.PHONY: all build clean clobber diff --git a/jdk/make/netbeans/awt2d/README b/jdk/make/netbeans/awt2d/README index a990726b787..040c9e76919 100644 --- a/jdk/make/netbeans/awt2d/README +++ b/jdk/make/netbeans/awt2d/README @@ -145,7 +145,6 @@ Notes on using CND (C/C++ pack) with this project and NetBeans. (a somewhat complete list of awt and 2d native directories on windows): ../../src/share/javavm/export; - ../../src/share/javavm/include; ../../src/share/native/common; ../../src/share/native/sun/awt/debug; ../../src/share/native/sun/awt/image/cvutils; diff --git a/jdk/make/netbeans/jconsole/build.properties b/jdk/make/netbeans/jconsole/build.properties index ab2a0a1aef6..dd442d93d20 100644 --- a/jdk/make/netbeans/jconsole/build.properties +++ b/jdk/make/netbeans/jconsole/build.properties @@ -1,5 +1,5 @@ # -# Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -44,3 +44,4 @@ build.jdk.version = 1.7.0 build.release = ${build.jdk.version}-opensource build.number = b00 jconsole.version = ${build.release}-${user.name}-${build.number} +jconsole.args = -debug diff --git a/jdk/make/netbeans/jconsole/build.xml b/jdk/make/netbeans/jconsole/build.xml index 0f51d1c3b5d..8d56df7c73d 100644 --- a/jdk/make/netbeans/jconsole/build.xml +++ b/jdk/make/netbeans/jconsole/build.xml @@ -1,5 +1,5 @@ - + - + - + - + + - + - + diff --git a/jdk/make/sun/awt/Makefile b/jdk/make/sun/awt/Makefile index 2754dd75ec3..a3dfce97a57 100644 --- a/jdk/make/sun/awt/Makefile +++ b/jdk/make/sun/awt/Makefile @@ -28,17 +28,13 @@ PACKAGE = sun.awt LIBRARY = awt PRODUCT = sun -# # Tell Defs.gmk that VIS is needed -# VIS_NEEDED=true -include $(BUILDDIR)/common/Defs.gmk - -# # Use highest optimization level -# -_OPT = $(CC_HIGHEST_OPT) +OPTMIZATION_LEVEL = HIGHEST + +include $(BUILDDIR)/common/Defs.gmk OTHER_CFLAGS += -D__MEDIALIB_OLD_NAMES -D__USE_J2D_NAMES diff --git a/jdk/make/sun/cmm/kcms/Makefile b/jdk/make/sun/cmm/kcms/Makefile index 000f2527e5b..10ff72b4f57 100644 --- a/jdk/make/sun/cmm/kcms/Makefile +++ b/jdk/make/sun/cmm/kcms/Makefile @@ -1,5 +1,5 @@ # -# Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/jdk/make/sun/font/Makefile b/jdk/make/sun/font/Makefile index ae06bbe8225..2663144a5f3 100644 --- a/jdk/make/sun/font/Makefile +++ b/jdk/make/sun/font/Makefile @@ -35,6 +35,9 @@ PRODUCT = sun # Indicate we want the C++ compiler to do the linking. CPLUSPLUSLIBRARY=true +# Use higher optimization level +OPTIMIZATION_LEVEL = HIGHER + include $(BUILDDIR)/common/Defs.gmk # @@ -48,11 +51,6 @@ endif # Files # -# -# Use higher optimization level -# -_OPT = $(CC_HIGHER_OPT) - include FILES_c.gmk AUTO_FILES_JAVA_DIRS = sun/font diff --git a/jdk/make/sun/font/t2k/Makefile b/jdk/make/sun/font/t2k/Makefile index 65f7f99a4dd..d01e825159b 100644 --- a/jdk/make/sun/font/t2k/Makefile +++ b/jdk/make/sun/font/t2k/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -41,12 +41,10 @@ CPLUSPLUSLIBRARY=true # for a few ones with native methods) so shouldn't clobber them. DONT_CLOBBER_CLASSES=true -include $(BUILDDIR)/common/Defs.gmk - -# # Use higher optimization level -# -_OPT = $(CC_HIGHER_OPT) +OPTIMIZATION_LEVEL = HIGHER + +include $(BUILDDIR)/common/Defs.gmk # # Files diff --git a/jdk/make/sun/image/generic/Makefile b/jdk/make/sun/image/generic/Makefile index 6157c79f59f..5caedf6d7d0 100644 --- a/jdk/make/sun/image/generic/Makefile +++ b/jdk/make/sun/image/generic/Makefile @@ -1,5 +1,5 @@ # -# Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -31,12 +31,11 @@ BUILDDIR = ../../.. PACKAGE = sun.awt.medialib LIBRARY = mlib_image PRODUCT = sun -include $(BUILDDIR)/common/Defs.gmk -# # Use highest level of optimization on this library -# -_OPT = $(CC_HIGHEST_OPT) +OPTIMIZATION_LEVEL = HIGHEST + +include $(BUILDDIR)/common/Defs.gmk # # Use mapfile diff --git a/jdk/make/sun/image/vis/Makefile b/jdk/make/sun/image/vis/Makefile index 00c11c361b8..b0e399b0878 100644 --- a/jdk/make/sun/image/vis/Makefile +++ b/jdk/make/sun/image/vis/Makefile @@ -1,5 +1,5 @@ # -# Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -31,17 +31,13 @@ PACKAGE = sun.awt.medialib LIBRARY = mlib_image_v PRODUCT = sun -# # Tell Defs.gmk we need VIS instructions -# VIS_NEEDED=true -include $(BUILDDIR)/common/Defs.gmk - -# # Select highest level of optimization for this library -# -_OPT = $(CC_HIGHEST_OPT) +OPTIMIZATION_LEVEL = HIGHEST + +include $(BUILDDIR)/common/Defs.gmk # # Use generic mapfile diff --git a/jdk/make/sun/javazic/tzdata/VERSION b/jdk/make/sun/javazic/tzdata/VERSION index 95ed6ee539e..2f4f9df808f 100644 --- a/jdk/make/sun/javazic/tzdata/VERSION +++ b/jdk/make/sun/javazic/tzdata/VERSION @@ -21,4 +21,4 @@ # CA 95054 USA or visit www.sun.com if you need additional information or # have any questions. # -tzdata2007h +tzdata2008e diff --git a/jdk/make/sun/javazic/tzdata/africa b/jdk/make/sun/javazic/tzdata/africa index f1f4b5f1b7a..8141f080997 100644 --- a/jdk/make/sun/javazic/tzdata/africa +++ b/jdk/make/sun/javazic/tzdata/africa @@ -409,9 +409,63 @@ Zone Africa/Nouakchott -1:03:48 - LMT 1912 0:00 - GMT # Mauritius + +# From Steffen Thorsen (2008-06-25): +# Mauritius plans to observe DST from 2008-11-01 to 2009-03-31 on a trial +# basis.... +# It seems that Mauritius observed daylight saving time from 1982-10-10 to +# 1983-03-20 as well, but that was not successful.... +# http://www.timeanddate.com/news/time/mauritius-daylight-saving-time.html + +# From Alex Krivenyshev (2008-06-25): +# http://economicdevelopment.gov.mu/portal/site/Mainhomepage/menuitem.a42b24128104d9845dabddd154508a0c/?content_id=0a7cee8b5d69a110VgnVCM1000000a04a8c0RCRD + +# From Arthur David Olson (2008-06-30): +# The www.timeanddate.com article cited by Steffen Thorsen notes that "A +# final decision has yet to be made on the times that daylight saving +# would begin and end on these dates." As a place holder, use midnight. + +# From Paul Eggert (2008-06-30): +# Follow Thorsen on DST in 1982/1983, instead of Shanks & Pottenger. + +# From Steffen Thorsen (2008-07-10): +# According to +# +# http://www.lexpress.mu/display_article.php?news_id=111216 +# +# (in French), Mauritius will start and end their DST a few days earlier +# than previously announced (2008-11-01 to 2009-03-31). The new start +# date is 2008-10-26 at 02:00 and the new end date is 2009-03-27 (no time +# given, but it is probably at either 2 or 3 wall clock time). +# +# A little strange though, since the article says that they moved the date +# to align itself with Europe and USA which also change time on that date, +# but that means they have not paid attention to what happened in +# USA/Canada last year (DST ends first Sunday in November). I also wonder +# why that they end on a Friday, instead of aligning with Europe which +# changes two days later. + +# From Alex Krivenyshev (2008-07-11): +# Seems that English language article "The revival of daylight saving +# time: Energy conservation?"-# No. 16578 (07/11/2008) was originally +# published on Monday, June 30, 2008... +# +# I guess that article in French "Le gouvernement avance l'introduction +# de l'heure d'ete" stating that DST in Mauritius starting on October 26 +# and ending on March 27, 2009 is the most recent one. +# ... +# +# http://www.worldtimezone.com/dst_news/dst_news_mauritius02.html +# + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Mauritius 1982 only - Oct 10 0:00 1:00 S +Rule Mauritius 1983 only - Mar 21 0:00 0 - +Rule Mauritius 2008 only - Oct 26 2:00s 1:00 S +Rule Mauritius 2009 only - Mar 27 2:00s 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis - 4:00 - MUT # Mauritius Time + 4:00 Mauritius MU%sT # Mauritius Time # Agalega Is, Rodriguez # no information; probably like Indian/Mauritius @@ -422,6 +476,77 @@ Zone Indian/Mayotte 3:00:56 - LMT 1911 Jul # Mamoutzou # Morocco # See the `europe' file for Spanish Morocco (Africa/Ceuta). + +# From Alex Krivenyshev (2008-05-09): +# Here is an article that Morocco plan to introduce Daylight Saving Time between +# 1 June, 2008 and 27 September, 2008. +# +# "... Morocco is to save energy by adjusting its clock during summer so it will +# be one hour ahead of GMT between 1 June and 27 September, according to +# Communication Minister and Gov ernment Spokesman, Khalid Naciri...." +# +# +# http://www.worldtimezone.net/dst_news/dst_news_morocco01.html +# +# OR +# +# http://en.afrik.com/news11892.html +# + +# From Alex Krivenyshev (2008-05-09): +# The Morocco time change can be confirmed on Morocco web site Maghreb Arabe Presse: +# +# http://www.map.ma/eng/sections/box3/morocco_shifts_to_da/view +# +# +# Morocco shifts to daylight time on June 1st through September 27, Govt. +# spokesman. + +# From Patrice Scattolin (2008-05-09): +# According to this article: +# +# http://www.avmaroc.com/actualite/heure-dete-comment-a127896.html +# +# (and republished here: +# +# http://www.actu.ma/heure-dete-comment_i127896_0.html +# +# ) +# the changes occurs at midnight: +# +# saturday night may 31st at midnight (which in french is to be +# intrepreted as the night between saturday and sunday) +# sunday night the 28th at midnight +# +# Seeing that the 28th is monday, I am guessing that she intends to say +# the midnight of the 28th which is the midnight between sunday and +# monday, which jives with other sources that say that it's inclusive +# june1st to sept 27th. +# +# The decision was taken by decree *2-08-224 *but I can't find the decree +# published on the web. +# +# It's also confirmed here: +# +# http://www.maroc.ma/NR/exeres/FACF141F-D910-44B0-B7FA-6E03733425D1.htm +# +# on a government portal as being between june 1st and sept 27th (not yet +# posted in english). +# +# The following google query will generate many relevant hits: +# +# http://www.google.com/search?hl=en&q=Conseil+de+gouvernement+maroc+heure+avance&btnG=Search +# + +# From Alex Krivenyshev (2008-05-09): +# Is Western Sahara (part which administrated by Morocco) going to follow +# Morocco DST changes? Any information? What about other part of +# Western Sahara - under administration of POLISARIO Front (also named +# SADR Saharawi Arab Democratic Republic)? + +# From Arthur David Olson (2008-05-09): +# XXX--guess that it is only Morocco for now; guess only 2008 for now. + # RULE NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Morocco 1939 only - Sep 12 0:00 1:00 S Rule Morocco 1939 only - Nov 19 0:00 0 - @@ -438,11 +563,13 @@ Rule Morocco 1976 only - Aug 1 0:00 0 - Rule Morocco 1977 only - Sep 28 0:00 0 - Rule Morocco 1978 only - Jun 1 0:00 1:00 S Rule Morocco 1978 only - Aug 4 0:00 0 - +Rule Morocco 2008 only - Jun 1 0:00 1:00 S +Rule Morocco 2008 only - Sep 28 0:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Africa/Casablanca -0:30:20 - LMT 1913 Oct 26 0:00 Morocco WE%sT 1984 Mar 16 1:00 - CET 1986 - 0:00 - WET + 0:00 Morocco WE%sT # Western Sahara Zone Africa/El_Aaiun -0:52:48 - LMT 1934 Jan -1:00 - WAT 1976 Apr 14 diff --git a/jdk/make/sun/javazic/tzdata/asia b/jdk/make/sun/javazic/tzdata/asia index bec343b7796..be581970001 100644 --- a/jdk/make/sun/javazic/tzdata/asia +++ b/jdk/make/sun/javazic/tzdata/asia @@ -251,6 +251,28 @@ Rule PRC 1987 1991 - Apr Sun>=10 0:00 1:00 D # (could be true), for the moment I am assuming that those two # counties are mistakes in the astro.com data. +# From Paul Eggert (2008-02-11): +# I just now checked Google News for western news sources that talk +# about China's single time zone, and couldn't find anything before 1986 +# talking about China being in one time zone. (That article was: Jim +# Mann, "A clumsy embrace for another western custom: China on daylight +# time--sort of", Los Angeles Times, 1986-05-05. By the way, this +# article confirms the tz database's data claiming that China began +# observing daylight saving time in 1986. +# +# From Thomas S. Mullaney (2008-02-11): +# I think you're combining two subjects that need to treated +# separately: daylight savings (which, you're correct, wasn't +# implemented until the 1980s) and the unified time zone centered near +# Beijing (which was implemented in 1949). Briefly, there was also a +# "Lhasa Time" in Tibet and "Urumqi Time" in Xinjiang. The first was +# ceased, and the second eventually recognized (again, in the 1980s). +# +# From Paul Eggert (2008-06-30): +# There seems to be a good chance China switched to a single time zone in 1949 +# rather than in 1980 as Shanks & Pottenger have it, but we don't have a +# reliable documentary source saying so yet, so for now we still go with +# Shanks & Pottenger. # Zone NAME GMTOFF RULES FORMAT [UNTIL] # Changbai Time ("Long-white Time", Long-white = Heilongjiang area) @@ -468,13 +490,13 @@ Zone Asia/Dili 8:22:20 - LMT 1912 # India # Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Asia/Calcutta 5:53:28 - LMT 1880 # Kolkata +Zone Asia/Kolkata 5:53:28 - LMT 1880 # Kolkata 5:53:20 - HMT 1941 Oct # Howrah Mean Time? 6:30 - BURT 1942 May 15 # Burma Time 5:30 - IST 1942 Sep 5:30 1:00 IST 1945 Oct 15 5:30 - IST -# The following are like Asia/Calcutta: +# The following are like Asia/Kolkata: # Andaman Is # Lakshadweep (Laccadive, Minicoy and Amindivi Is) # Nicobar Is @@ -599,6 +621,15 @@ Zone Asia/Jayapura 9:22:48 - LMT 1932 Nov # daylight saving time ... # http://uk.reuters.com/article/oilRpt/idUKBLA65048420070916 # +# From Roozbeh Pournader (2007-11-05): +# This is quoted from Official Gazette of the Islamic Republic of +# Iran, Volume 63, Number 18242, dated Tuesday 1386/6/24 +# [2007-10-16]. I am doing the best translation I can:... +# The official time of the country will be moved forward for one hour +# on the 24 hours of the first day of the month of Farvardin and will +# be changed back to its previous state on the 24 hours of the +# thirtieth day of Shahrivar. +# # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Iran 1978 1980 - Mar 21 0:00 1:00 D Rule Iran 1978 only - Oct 21 0:00 0 S @@ -673,6 +704,21 @@ Zone Asia/Tehran 3:25:44 - LMT 1916 # # So we'll ignore the Economist's claim. +# From Steffen Thorsen (2008-03-10): +# The cabinet in Iraq abolished DST last week, according to the following +# news sources (in Arabic): +# +# http://www.aljeeran.net/wesima_articles/news-20080305-98602.html +# +# +# http://www.aswataliraq.info/look/article.tpl?id=2047&IdLanguage=17&IdPublication=4&NrArticle=71743&NrIssue=1&NrSection=10 +# +# +# We have published a short article in English about the change: +# +# http://www.timeanddate.com/news/time/iraq-dumps-daylight-saving.html +# + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Iraq 1982 only - May 1 0:00 1:00 D Rule Iraq 1982 1984 - Oct 1 0:00 0 S @@ -683,8 +729,8 @@ Rule Iraq 1986 1990 - Mar lastSun 1:00s 1:00 D # IATA SSIM (1991/1996) says Apr 1 12:01am UTC; guess the `:01' is a typo. # Shanks & Pottenger say Iraq did not observe DST 1992/1997; ignore this. # -Rule Iraq 1991 max - Apr 1 3:00s 1:00 D -Rule Iraq 1991 max - Oct 1 3:00s 0 S +Rule Iraq 1991 2007 - Apr 1 3:00s 1:00 D +Rule Iraq 1991 2007 - Oct 1 3:00s 0 S # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Baghdad 2:57:40 - LMT 1890 2:57:36 - BMT 1918 # Baghdad Mean Time? @@ -1374,6 +1420,42 @@ Zone Indian/Maldives 4:54:00 - LMT 1880 # Male # They decided not to adopt daylight-saving time.... # http://www.mongolnews.mn/index.php?module=unuudur&sec=view&id=15742 +# From Deborah Goldsmith (2008-03-30): +# We received a bug report claiming that the tz database UTC offset for +# Asia/Choibalsan (GMT+09:00) is incorrect, and that it should be GMT +# +08:00 instead. Different sources appear to disagree with the tz +# database on this, e.g.: +# +# +# http://www.timeanddate.com/worldclock/city.html?n=1026 +# +# +# http://www.worldtimeserver.com/current_time_in_MN.aspx +# +# +# both say GMT+08:00. + +# From Steffen Thorsen (2008-03-31): +# eznis airways, which operates several domestic flights, has a flight +# schedule here: +# +# http://www.eznis.com/Container.jsp?id=112 +# +# (click the English flag for English) +# +# There it appears that flights between Choibalsan and Ulaanbatar arrive +# about 1:35 - 1:50 hours later in local clock time, no matter the +# direction, while Ulaanbaatar-Khvod takes 2 hours in the Eastern +# direction and 3:35 back, which indicates that Ulaanbatar and Khvod are +# in different time zones (like we know about), while Choibalsan and +# Ulaanbatar are in the same time zone (correction needed). + +# From Arthur David Olson (2008-05-19): +# Assume that Choibalsan is indeed offset by 8:00. +# XXX--in the absence of better information, assume that transition +# was at the start of 2008-03-31 (the day of Steffen Thorsen's report); +# this is almost surely wrong. + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Mongol 1983 1984 - Apr 1 0:00 1:00 S Rule Mongol 1983 only - Oct 1 0:00 0 - @@ -1409,7 +1491,8 @@ Zone Asia/Ulaanbaatar 7:07:32 - LMT 1905 Aug Zone Asia/Choibalsan 7:38:00 - LMT 1905 Aug 7:00 - ULAT 1978 8:00 - ULAT 1983 Apr - 9:00 Mongol CHO%sT # Choibalsan Time + 9:00 Mongol CHO%sT 2008 Mar 31 # Choibalsan Time + 8:00 Mongol CHO%sT # Nepal # Zone NAME GMTOFF RULES FORMAT [UNTIL] @@ -1459,10 +1542,32 @@ Zone Asia/Muscat 3:54:20 - LMT 1920 # The minister told a news conference that the experiment had rather # shown 8 per cent higher consumption of electricity. +# From Alex Krivenyshev (2008-05-15): +# +# Here is an article that Pakistan plan to introduce Daylight Saving Time +# on June 1, 2008 for 3 months. +# +# "... The federal cabinet on Wednesday announced a new conservation plan to help +# reduce load shedding by approving the closure of commercial centres at 9pm and +# moving clocks forward by one hour for the next three months. +# ...." +# +# +# http://www.worldtimezone.net/dst_news/dst_news_pakistan01.html +# +# OR +# +# http://www.dailytimes.com.pk/default.asp?page=2008%5C05%5C15%5Cstory_15-5-2008_pg1_4 +# + +# From Arthur David Olson (2008-05-19): +# XXX--midnight transitions is a guess; 2008 only is a guess. # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Pakistan 2002 only - Apr Sun>=2 0:01 1:00 S Rule Pakistan 2002 only - Oct Sun>=2 0:01 0 - +Rule Pakistan 2008 only - Jun 1 0:00 1:00 S +Rule Pakistan 2008 only - Sep 1 0:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Karachi 4:28:12 - LMT 1907 5:30 - IST 1942 Sep @@ -1700,7 +1805,7 @@ Zone Asia/Singapore 6:55:25 - LMT 1901 Jan 1 # kept their clocks set five and a half hours ahead of Greenwich Mean # Time (GMT), in line with neighbor India. # From Paul Eggert (2006-04-18): -# People who live in regions under Tamil control can use TZ='Asia/Calcutta', +# People who live in regions under Tamil control can use [TZ='Asia/Kolkata'], # as that zone has agreed with the Tamil areas since our cutoff date of 1970. # From K Sethu (2006-04-25): @@ -1790,10 +1895,62 @@ Rule Syria 2006 only - Sep 22 0:00 0 - # From Paul Eggert (2007-03-29): # Today the AP reported "Syria will switch to summertime at midnight Thursday." # http://www.iht.com/articles/ap/2007/03/29/africa/ME-GEN-Syria-Time-Change.php -# For lack of better info, assume the rule changed to "last Friday in March" -# this year. -Rule Syria 2007 max - Mar lastFri 0:00 1:00 S -Rule Syria 2007 max - Oct 1 0:00 0 - +Rule Syria 2007 only - Mar lastFri 0:00 1:00 S +# From Jesper Norgard (2007-10-27): +# The sister center ICARDA of my work CIMMYT is confirming that Syria DST will +# not take place 1.st November at 0:00 o'clock but 1.st November at 24:00 or +# rather Midnight between Thursday and Friday. This does make more sence than +# having it between Wednesday and Thursday (two workdays in Syria) since the +# weekend in Syria is not Saturday and Sunday, but Friday and Saturday. So now +# it is implemented at midnight of the last workday before weekend... +# +# From Steffen Thorsen (2007-10-27): +# Jesper Norgaard Welen wrote: +# +# > "Winter local time in Syria will be observed at midnight of Thursday 1 +# > November 2007, and the clock will be put back 1 hour." +# +# I found confirmation on this in this gov.sy-article (Arabic): +# http://wehda.alwehda.gov.sy/_print_veiw.asp?FileName=12521710520070926111247 +# +# which using Google's translate tools says: +# Council of Ministers also approved the commencement of work on +# identifying the winter time as of Friday, 2/11/2007 where the 60th +# minute delay at midnight Thursday 1/11/2007. +Rule Syria 2007 only - Nov Fri>=1 0:00 0 - + +# From Stephen Colebourne (2008-03-17): +# For everyone's info, I saw an IATA time zone change for [Syria] for +# this month (March 2008) in the last day or so...This is the data IATA +# are now using: +# Country Time Standard --- DST Start --- --- DST End --- DST +# Name Zone Variation Time Date Time Date +# Variation +# Syrian Arab +# Republic SY +0200 2200 03APR08 2100 30SEP08 +0300 +# 2200 02APR09 2100 30SEP09 +0300 +# 2200 01APR10 2100 30SEP10 +0300 + +# From Arthur David Olson (2008-03-17): +# Here's a link to English-language coverage by the Syrian Arab News +# Agency (SANA)... +# +# http://www.sana.sy/eng/21/2008/03/11/165173.htm +# ...which reads (in part) "The Cabinet approved the suggestion of the +# Ministry of Electricity to begin daylight savings time on Friday April +# 4th, advancing clocks one hour ahead on midnight of Thursday April 3rd." +# Since Syria is two hours east of UTC, the 2200 and 2100 transition times +# shown above match up with midnight in Syria. + +# From Arthur David Olson (2008-03-18): +# My buest guess at a Syrian rule is "the Friday nearest April 1"; +# coding that involves either using a "Mar Fri>=29" construct that old time zone +# compilers can't handle or having multiple Rules (a la Israel). +# For now, use "Apr Fri>=1", and go with IATA on a uniform Sep 30 end. + +Rule Syria 2008 max - Apr Fri>=1 0:00 1:00 S +Rule Syria 2008 max - Oct 1 0:00 0 - + # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Damascus 2:25:12 - LMT 1920 # Dimashq 2:00 Syria EE%sT @@ -1847,13 +2004,13 @@ Zone Asia/Tashkent 4:37:12 - LMT 1924 May 2 # Vietnam -# From Paul Eggert (1993-11-18): -# Saigon's official name is Thanh-Pho Ho Chi Minh, but it's too long. -# We'll stick with the traditional name for now. +# From Arthur David Olson (2008-03-18): +# The English-language name of Vietnam's most populous city is "Ho Chi Min City"; +# we use Ho_Chi_Minh below to avoid a name of more than 14 characters. # From Shanks & Pottenger: # Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Asia/Saigon 7:06:40 - LMT 1906 Jun 9 +Zone Asia/Ho_Chi_Minh 7:06:40 - LMT 1906 Jun 9 7:06:20 - SMT 1911 Mar 11 0:01 # Saigon MT? 7:00 - ICT 1912 May 8:00 - ICT 1931 May diff --git a/jdk/make/sun/javazic/tzdata/australasia b/jdk/make/sun/javazic/tzdata/australasia index eee5c0b5478..823550415e0 100644 --- a/jdk/make/sun/javazic/tzdata/australasia +++ b/jdk/make/sun/javazic/tzdata/australasia @@ -1368,7 +1368,7 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901 # * Tonga will introduce DST in November # # I was given this link by John Letts: -# +# # http://news.bbc.co.uk/hi/english/world/asia-pacific/newsid_424000/424764.stm # # @@ -1378,7 +1378,7 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901 # (12 + 1 hour DST). # From Arthur David Olson (1999-09-20): -# According to # http://www.tongaonline.com/news/sept1799.html # : # "Daylight Savings Time will take effect on Oct. 2 through April 15, 2000 diff --git a/jdk/make/sun/javazic/tzdata/backward b/jdk/make/sun/javazic/tzdata/backward index 0e64882a465..85522740f41 100644 --- a/jdk/make/sun/javazic/tzdata/backward +++ b/jdk/make/sun/javazic/tzdata/backward @@ -46,12 +46,15 @@ Link America/St_Thomas America/Virgin Link Asia/Ashgabat Asia/Ashkhabad Link Asia/Chongqing Asia/Chungking Link Asia/Dhaka Asia/Dacca +Link Asia/Kolkata Asia/Calcutta Link Asia/Macau Asia/Macao Link Asia/Jerusalem Asia/Tel_Aviv +Link Asia/Ho_Chi_Minh Asia/Saigon Link Asia/Thimphu Asia/Thimbu Link Asia/Makassar Asia/Ujung_Pandang Link Asia/Ulaanbaatar Asia/Ulan_Bator Link Atlantic/Faroe Atlantic/Faeroe +Link Europe/Oslo Atlantic/Jan_Mayen Link Australia/Sydney Australia/ACT Link Australia/Sydney Australia/Canberra Link Australia/Lord_Howe Australia/LHI diff --git a/jdk/make/sun/javazic/tzdata/europe b/jdk/make/sun/javazic/tzdata/europe index 16fedf8036d..30724328383 100644 --- a/jdk/make/sun/javazic/tzdata/europe +++ b/jdk/make/sun/javazic/tzdata/europe @@ -479,7 +479,7 @@ Rule EU 1979 1995 - Sep lastSun 1:00u 0 - Rule EU 1981 max - Mar lastSun 1:00u 1:00 S Rule EU 1996 max - Oct lastSun 1:00u 0 - # The most recent directive covers the years starting in 2002. See: -# # Directive 2000/84/EC of the European Parliament and of the Council # of 19 January 2001 on summer-time arrangements. # @@ -502,9 +502,48 @@ Rule C-Eur 1940 only - Apr 1 2:00s 1:00 S Rule C-Eur 1942 only - Nov 2 2:00s 0 - Rule C-Eur 1943 only - Mar 29 2:00s 1:00 S Rule C-Eur 1943 only - Oct 4 2:00s 0 - -Rule C-Eur 1944 only - Apr 3 2:00s 1:00 S +Rule C-Eur 1944 1945 - Apr Mon>=1 2:00s 1:00 S # Whitman gives 1944 Oct 7; go with Shanks & Pottenger. Rule C-Eur 1944 only - Oct 2 2:00s 0 - +# From Jesper Norgaard Welen (2008-07-13): +# +# I found what is probably a typo of 2:00 which should perhaps be 2:00s +# in the C-Eur rule from tz database version 2008d (this part was +# corrected in version 2008d). The circumstancial evidence is simply the +# tz database itself, as seen below: +# +# Zone Europe/Paris 0:09:21 - LMT 1891 Mar 15 0:01 +# 0:00 France WE%sT 1945 Sep 16 3:00 +# +# Zone Europe/Monaco 0:29:32 - LMT 1891 Mar 15 +# 0:00 France WE%sT 1945 Sep 16 3:00 +# +# Zone Europe/Belgrade 1:22:00 - LMT 1884 +# 1:00 1:00 CEST 1945 Sep 16 2:00s +# +# Rule France 1945 only - Sep 16 3:00 0 - +# Rule Belgium 1945 only - Sep 16 2:00s 0 - +# Rule Neth 1945 only - Sep 16 2:00s 0 - +# +# The rule line to be changed is: +# +# Rule C-Eur 1945 only - Sep 16 2:00 0 - +# +# It seems that Paris, Monaco, Rule France, Rule Belgium all agree on +# 2:00 standard time, e.g. 3:00 local time. However there are no +# countries that use C-Eur rules in September 1945, so the only items +# affected are apparently these ficticious zones that translates acronyms +# CET and MET: +# +# Zone CET 1:00 C-Eur CE%sT +# Zone MET 1:00 C-Eur ME%sT +# +# It this is right then the corrected version would look like: +# +# Rule C-Eur 1945 only - Sep 16 2:00s 0 - +# +# A small step for mankind though 8-) +Rule C-Eur 1945 only - Sep 16 2:00s 0 - Rule C-Eur 1977 1980 - Apr Sun>=1 2:00s 1:00 S Rule C-Eur 1977 only - Sep lastSun 2:00s 0 - Rule C-Eur 1978 only - Oct 1 2:00s 0 - @@ -747,7 +786,8 @@ Rule Bulg 1981 only - Sep 27 2:00 0 - Zone Europe/Sofia 1:33:16 - LMT 1880 1:56:56 - IMT 1894 Nov 30 # Istanbul MT? 2:00 - EET 1942 Nov 2 3:00 - 1:00 C-Eur CE%sT 1945 Apr 2 3:00 + 1:00 C-Eur CE%sT 1945 + 1:00 - CET 1945 Apr 2 3:00 2:00 - EET 1979 Mar 31 23:00 2:00 Bulg EE%sT 1982 Sep 26 2:00 2:00 C-Eur EE%sT 1991 @@ -1115,33 +1155,40 @@ Zone Europe/Paris 0:09:21 - LMT 1891 Mar 15 0:01 # [See tz-link.htm for the URL.] # From Joerg Schilling (2002-10-23): -# In 1945, Berlin was switched to Moscow Summer time (GMT+4) by +# In 1945, Berlin was switched to Moscow Summer time (GMT+4) by +# # General [Nikolai] Bersarin. # From Paul Eggert (2003-03-08): # +# http://www.parlament-berlin.de/pds-fraktion.nsf/727459127c8b66ee8525662300459099/defc77cb784f180ac1256c2b0030274b/$FILE/bersarint.pdf +# # says that Bersarin issued an order to use Moscow time on May 20. # However, Moscow did not observe daylight saving in 1945, so # this was equivalent to CEMT (GMT+3), not GMT+4. # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S -Rule Germany 1945 only - Apr 2 2:00s 1:00 S -Rule Germany 1945 only - May 24 2:00 2:00 M # Midsummer -Rule Germany 1945 only - Sep 24 3:00 1:00 S -Rule Germany 1945 only - Nov 18 2:00s 0 - Rule Germany 1946 only - Apr 14 2:00s 1:00 S Rule Germany 1946 only - Oct 7 2:00s 0 - Rule Germany 1947 1949 - Oct Sun>=1 2:00s 0 - -Rule Germany 1947 only - Apr 6 2:00s 1:00 S +# http://www.ptb.de/de/org/4/44/441/salt.htm says the following transition +# occurred at 3:00 MEZ, not the 2:00 MEZ given in Shanks & Pottenger. +# Go with the PTB. +Rule Germany 1947 only - Apr 6 3:00s 1:00 S Rule Germany 1947 only - May 11 2:00s 2:00 M Rule Germany 1947 only - Jun 29 3:00 1:00 S Rule Germany 1948 only - Apr 18 2:00s 1:00 S Rule Germany 1949 only - Apr 10 2:00s 1:00 S + +Rule SovietZone 1945 only - May 24 2:00 2:00 M # Midsummer +Rule SovietZone 1945 only - Sep 24 3:00 1:00 S +Rule SovietZone 1945 only - Nov 18 2:00s 0 - + # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Europe/Berlin 0:53:28 - LMT 1893 Apr - 1:00 C-Eur CE%sT 1945 Apr 2 2:00 + 1:00 C-Eur CE%sT 1945 May 24 2:00 + 1:00 SovietZone CE%sT 1946 1:00 Germany CE%sT 1980 1:00 EU CE%sT @@ -1218,7 +1265,7 @@ Rule Hungary 1980 only - Apr 6 1:00 1:00 S Zone Europe/Budapest 1:16:20 - LMT 1890 Oct 1:00 C-Eur CE%sT 1918 1:00 Hungary CE%sT 1941 Apr 6 2:00 - 1:00 C-Eur CE%sT 1945 May 1 23:00 + 1:00 C-Eur CE%sT 1945 1:00 Hungary CE%sT 1980 Sep 28 2:00s 1:00 EU CE%sT @@ -1736,7 +1783,6 @@ Zone Europe/Oslo 0:43:00 - LMT 1895 Jan 1 # come up with more definitive info about the timekeeping during the # war years it's probably best just do do the following for now: Link Europe/Oslo Arctic/Longyearbyen -Link Europe/Oslo Atlantic/Jan_Mayen # Poland # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S @@ -2136,7 +2182,8 @@ Zone Asia/Anadyr 11:49:56 - LMT 1924 May 2 # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Europe/Belgrade 1:22:00 - LMT 1884 1:00 - CET 1941 Apr 18 23:00 - 1:00 C-Eur CE%sT 1945 May 8 2:00s + 1:00 C-Eur CE%sT 1945 + 1:00 - CET 1945 May 8 2:00s 1:00 1:00 CEST 1945 Sep 16 2:00s # Metod Kozelj reports that the legal date of # transition to EU rules was 1982-11-27, for all of Yugoslavia at the time. diff --git a/jdk/make/sun/javazic/tzdata/iso3166.tab b/jdk/make/sun/javazic/tzdata/iso3166.tab index d976eb1a1a6..6931ee04a71 100644 --- a/jdk/make/sun/javazic/tzdata/iso3166.tab +++ b/jdk/make/sun/javazic/tzdata/iso3166.tab @@ -28,7 +28,7 @@ # # This file contains a table with the following columns: # 1. ISO 3166-1 alpha-2 country code, current as of -# ISO 3166-1 Newsletter No. V-12 (2006-09-26). See: +# ISO 3166-1 Newsletter VI-1 (2007-09-21). See: # # ISO 3166 Maintenance agency (ISO 3166/MA) # . @@ -69,6 +69,7 @@ BG Bulgaria BH Bahrain BI Burundi BJ Benin +BL St Barthelemy BM Bermuda BN Brunei BO Bolivia @@ -181,6 +182,7 @@ MA Morocco MC Monaco MD Moldova ME Montenegro +MF St Martin (French part) MG Madagascar MH Marshall Islands MK Macedonia diff --git a/jdk/make/sun/javazic/tzdata/leapseconds b/jdk/make/sun/javazic/tzdata/leapseconds index 77d28dae9dd..4526cddf5b6 100644 --- a/jdk/make/sun/javazic/tzdata/leapseconds +++ b/jdk/make/sun/javazic/tzdata/leapseconds @@ -66,8 +66,10 @@ Leap 1995 Dec 31 23:59:60 + S Leap 1997 Jun 30 23:59:60 + S Leap 1998 Dec 31 23:59:60 + S Leap 2005 Dec 31 23:59:60 + S +Leap 2008 Dec 31 23:59:60 + S # INTERNATIONAL EARTH ROTATION AND REFERENCE SYSTEMS SERVICE (IERS) +# # SERVICE INTERNATIONAL DE LA ROTATION TERRESTRE ET DES SYSTEMES DE REFERENCE # # SERVICE DE LA ROTATION TERRESTRE @@ -75,30 +77,38 @@ Leap 2005 Dec 31 23:59:60 + S # 61, Av. de l'Observatoire 75014 PARIS (France) # Tel. : 33 (0) 1 40 51 22 26 # FAX : 33 (0) 1 40 51 22 91 -# Internet : services.iers@obspm.fr +# e-mail : services.iers@obspm.fr +# http://hpiers.obspm.fr/eop-pc # -# Paris, 28 June 2007 +# Paris, 4 July 2008 # -# Bulletin C 34 +# Bulletin C 36 # # To authorities responsible # for the measurement and # distribution of time # -# INFORMATION ON UTC - TAI +# UTC TIME STEP +# on the 1st of January 2009 # -# NO positive leap second will be introduced at the end of December 2007. -# The difference between Coordinated Universal Time UTC and the -# International Atomic Time TAI is : +# A positive leap second will be introduced at the end of December 2008. +# The sequence of dates of the UTC second markers will be: # -# from 2006 January 1, 0h UTC, until further notice : UTC-TAI = -33 s +# 2008 December 31, 23h 59m 59s +# 2008 December 31, 23h 59m 60s +# 2009 January 1, 0h 0m 0s +# +# The difference between UTC and the International Atomic Time TAI is: +# +# from 2006 January 1, 0h UTC, to 2009 January 1 0h UTC : UTC-TAI = - 33s +# from 2009 January 1, 0h UTC, until further notice : UTC-TAI = - 34s # # Leap seconds can be introduced in UTC at the end of the months of December -# or June, depending on the evolution of UT1-TAI. Bulletin C is mailed every -# six months, either to announce a time step in UTC, or to confirm that there +# or June, depending on the evolution of UT1-TAI. Bulletin C is mailed every +# six months, either to announce a time step in UTC or to confirm that there # will be no time step at the next possible date. # # Daniel GAMBIS -# Director +# Head # Earth Orientation Center of IERS # Observatoire de Paris, France diff --git a/jdk/make/sun/javazic/tzdata/northamerica b/jdk/make/sun/javazic/tzdata/northamerica index ab5bb5b2153..6e0317277b7 100644 --- a/jdk/make/sun/javazic/tzdata/northamerica +++ b/jdk/make/sun/javazic/tzdata/northamerica @@ -2098,8 +2098,8 @@ Zone America/Antigua -4:07:12 - LMT 1912 Mar 2 # http://www.jonesbahamas.com/?c=45&a=10412 # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S -Rule Bahamas 1964 2006 - Oct lastSun 2:00 0 S -Rule Bahamas 1964 1986 - Apr lastSun 2:00 1:00 D +Rule Bahamas 1964 1975 - Oct lastSun 2:00 0 S +Rule Bahamas 1964 1975 - Apr lastSun 2:00 1:00 D # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone America/Nassau -5:09:24 - LMT 1912 Mar 2 -5:00 Bahamas E%sT 1976 @@ -2209,6 +2209,69 @@ Zone America/Costa_Rica -5:36:20 - LMT 1890 # San Jose # says Cuban clocks will advance at midnight on March 10. # For lack of better information, assume Cuba will use US rules, # except that it switches at midnight standard time as usual. +# +# From Steffen Thorsen (2007-10-25): +# Carlos Alberto Fonseca Arauz informed me that Cuba will end DST one week +# earlier - on the last Sunday of October, just like in 2006. +# +# He supplied these references: +# +# http://www.prensalatina.com.mx/article.asp?ID=%7B4CC32C1B-A9F7-42FB-8A07-8631AFC923AF%7D&language=ES +# http://actualidad.terra.es/sociedad/articulo/cuba_llama_ahorrar_energia_cambio_1957044.htm +# +# From Alex Kryvenishev (2007-10-25): +# Here is also article from Granma (Cuba): +# +# [Regira] el Horario Normal desde el [proximo] domingo 28 de octubre +# http://www.granma.cubaweb.cu/2007/10/24/nacional/artic07.html +# +# http://www.worldtimezone.com/dst_news/dst_news_cuba03.html + +# From Arthur David Olson (2008-03-09): +# I'm in Maryland which is now observing United States Eastern Daylight +# Time. At 9:44 local time I used RealPlayer to listen to +# +# http://media.enet.cu/radioreloj +# , a Cuban information station, and heard +# the time announced as "ocho cuarenta y cuatro" ("eight forty-four"), +# indicating that Cuba is still on standard time. + +# From Steffen Thorsen (2008-03-12): +# It seems that Cuba will start DST on Sunday, 2007-03-16... +# It was announced yesterday, according to this source (in Spanish): +# +# http://www.nnc.cubaweb.cu/marzo-2008/cien-1-11-3-08.htm +# +# +# Some more background information is posted here: +# +# http://www.timeanddate.com/news/time/cuba-starts-dst-march-16.html +# +# +# The article also says that Cuba has been observing DST since 1963, +# while Shanks (and tzdata) has 1965 as the first date (except in the +# 1940's). Many other web pages in Cuba also claim that it has been +# observed since 1963, but with the exception of 1970 - an exception +# which is not present in tzdata/Shanks. So there is a chance we need to +# change some historic records as well. +# +# One example: +# +# http://www.radiohc.cu/espanol/noticias/mar07/11mar/hor.htm +# + +# From Jesper Norgaard Welen (2008-03-13): +# The Cuban time change has just been confirmed on the most authoritative +# web site, the Granma. Please check out +# +# http://www.granma.cubaweb.cu/2008/03/13/nacional/artic10.html +# +# +# Basically as expected after Steffen Thorsens information, the change +# will take place midnight between Saturday and Sunday. + +# From Arthur David Olson (2008-03-12): +# Assume Sun>=15 (third Sunday) going forward. # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Cuba 1928 only - Jun 10 0:00 1:00 D @@ -2240,9 +2303,9 @@ Rule Cuba 1997 only - Oct 12 0:00s 0 S Rule Cuba 1998 1999 - Mar lastSun 0:00s 1:00 D Rule Cuba 1998 2003 - Oct lastSun 0:00s 0 S Rule Cuba 2000 2006 - Apr Sun>=1 0:00s 1:00 D -Rule Cuba 2006 only - Oct lastSun 0:00s 0 S -Rule Cuba 2007 max - Mar Sun>=8 0:00s 1:00 D -Rule Cuba 2007 max - Nov Sun>=1 0:00s 0 S +Rule Cuba 2006 max - Oct lastSun 0:00s 0 S +Rule Cuba 2007 only - Mar Sun>=8 0:00s 1:00 D +Rule Cuba 2008 max - Mar Sun>=15 0:00s 1:00 D # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone America/Havana -5:29:28 - LMT 1890 @@ -2309,6 +2372,10 @@ Zone America/Grenada -4:07:00 - LMT 1911 Jul # St George's # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone America/Guadeloupe -4:06:08 - LMT 1911 Jun 8 # Pointe a Pitre -4:00 - AST +# St Barthelemy +Link America/Guadeloupe America/St_Barthelemy +# St Martin (French part) +Link America/Guadeloupe America/Marigot # Guatemala # diff --git a/jdk/make/sun/javazic/tzdata/southamerica b/jdk/make/sun/javazic/tzdata/southamerica index a147a1b0870..06a8d130e39 100644 --- a/jdk/make/sun/javazic/tzdata/southamerica +++ b/jdk/make/sun/javazic/tzdata/southamerica @@ -127,7 +127,11 @@ Rule Arg 1989 1992 - Oct Sun>=15 0:00 1:00 S # which did not result in the switch of a time zone, as they stayed 9 hours # from the International Date Line. Rule Arg 1999 only - Oct Sun>=1 0:00 1:00 S -Rule Arg 2000 only - Mar Sun>=1 0:00 0 - +# From Paul Eggert (2007-12-28): +# DST was set to expire on March 5, not March 3, but since it was converted +# to standard time on March 3 it's more convenient for us to pretend that +# it ended on March 3. +Rule Arg 2000 only - Mar 3 0:00 0 - # # From Peter Gradelski via Steffen Thorsen (2000-03-01): # We just checked with our Sao Paulo office and they say the government of @@ -162,6 +166,30 @@ Rule Arg 2000 only - Mar Sun>=1 0:00 0 - # This kind of things had always been done this way in Argentina. # We are still -03:00 all year round in all of the country. # +# From Steffen Thorsen (2007-12-21): +# A user (Leonardo Chaim) reported that Argentina will adopt DST.... +# all of the country (all Zone-entries) are affected. News reports like +# http://www.lanacion.com.ar/opinion/nota.asp?nota_id=973037 indicate +# that Argentina will use DST next year as well, from October to +# March, although exact rules are not given. +# +# From Jesper Norgaard Welen (2007-12-26) +# The last hurdle of Argentina DST is over, the proposal was approved in +# the lower chamber too (Deputados) with a vote 192 for and 2 against. +# By the way thanks to Mariano Absatz and Daniel Mario Vega for the link to +# the original scanned proposal, where the dates and the zero hours are +# clear and unambiguous...This is the article about final approval: +# +# http://www.lanacion.com.ar/politica/nota.asp?nota_id=973996 +# +# +# From Paul Eggert (2007-12-22): +# For dates after mid-2008, the following rules are my guesses and +# are quite possibly wrong, but are more likely than no DST at all. +Rule Arg 2007 only - Dec 30 0:00 1:00 S +Rule Arg 2008 max - Mar Sun>=15 0:00 0 - +Rule Arg 2008 max - Oct Sun>=1 0:00 1:00 S + # From Mariano Absatz (2004-05-21): # Today it was officially published that the Province of Mendoza is changing # its timezone this winter... starting tomorrow night.... @@ -222,10 +250,80 @@ Rule Arg 2000 only - Mar Sun>=1 0:00 0 - # http://www.sanjuan.gov.ar/prensa/archivo/000426.html # http://www.sanjuan.gov.ar/prensa/archivo/000441.html +# From Alex Krivenyshev (2008-01-17): +# Here are articles that Argentina Province San Luis is planning to end DST +# as earlier as upcoming Monday January 21, 2008 or February 2008: +# +# Provincia argentina retrasa reloj y marca diferencia con resto del pais +# (Argentine Province delayed clock and mark difference with the rest of the +# country) +# +# http://cl.invertia.com/noticias/noticia.aspx?idNoticia=200801171849_EFE_ET4373&idtel +# +# +# Es inminente que en San Luis atrasen una hora los relojes +# (It is imminent in San Luis clocks one hour delay) +# +# http://www.lagaceta.com.ar/vernotae.asp?id_nota=253414 +# +# +# +# http://www.worldtimezone.net/dst_news/dst_news_argentina02.html +# + +# From Jesper Norgaard Welen (2008-01-18): +# The page of the San Luis provincial government +# +# http://www.sanluis.gov.ar/notas.asp?idCanal=0&id=22812 +# +# confirms what Alex Krivenyshev has earlier sent to the tz +# emailing list about that San Luis plans to return to standard +# time much earlier than the rest of the country. It also +# confirms that upon request the provinces San Juan and Mendoza +# refused to follow San Luis in this change. +# +# The change is supposed to take place Monday the 21.st at 0:00 +# hours. As far as I understand it if this goes ahead, we need +# a new timezone for San Luis (although there are also documented +# independent changes in the southamerica file of San Luis in +# 1990 and 1991 which has not been confirmed). + +# From Jesper Norgaard Welen (2008-01-25): +# Unfortunately the below page has become defunct, about the San Luis +# time change. Perhaps because it now is part of a group of pages "Most +# important pages of 2008." +# +# You can use +# +# http://www.sanluis.gov.ar/notas.asp?idCanal=8141&id=22834 +# +# instead it seems. Or use "Buscador" from the main page of the San Luis +# government, and fill in "huso" and click OK, and you will get 3 pages +# from which the first one is identical to the above. + +# From Mariano Absatz (2008-01-28): +# I can confirm that the Province of San Luis (and so far only that +# province) decided to go back to UTC-3 effective midnight Jan 20th 2008 +# (that is, Monday 21st at 0:00 is the time the clocks were delayed back +# 1 hour), and they intend to keep UTC-3 as their timezone all year round +# (that is, unless they change their mind any minute now). +# +# So we'll have to add yet another city to 'southamerica' (I think San +# Luis city is the mos populated city in the Province, so it'd be +# America/Argentina/San_Luis... of course I can't remember if San Luis's +# history of particular changes goes along with Mendoza or San Juan :-( +# (I only remember not being able to collect hard facts about San Luis +# back in 2004, when these provinces changed to UTC-4 for a few days, I +# mailed them personally and never got an answer). + +# From Paul Eggert (2008-06-30): # Unless otherwise specified, data are from Shanks & Pottenger through 1992, # from the IATA otherwise. As noted below, Shanks & Pottenger say that -# America/Cordoba split into 6 subregions during 1991/1992, but we -# haven't verified this yet so for now we'll keep it a single region. +# America/Cordoba split into 6 subregions during 1991/1992, one of which +# was America/San_Luis, but we haven't verified this yet so for now we'll +# keep America/Cordoba a single region rather than splitting it into the +# other 5 subregions. + # # Zone NAME GMTOFF RULES FORMAT [UNTIL] # @@ -236,18 +334,16 @@ Zone America/Argentina/Buenos_Aires -3:53:48 - LMT 1894 Oct 31 -4:00 Arg AR%sT 1969 Oct 5 -3:00 Arg AR%sT 1999 Oct 3 -4:00 Arg AR%sT 2000 Mar 3 - -3:00 - ART + -3:00 Arg AR%sT # # Santa Fe (SF), Entre Rios (ER), Corrientes (CN), Misiones (MN), Chaco (CC), # Formosa (FM), Salta (SA), Santiago del Estero (SE), Cordoba (CB), -# San Luis (SL), La Pampa (LP), Neuquen (NQ), Rio Negro (RN) +# La Pampa (LP), Neuquen (NQ), Rio Negro (RN) # # Shanks & Pottenger also make the following claims, which we haven't verified: # - Formosa switched to -3:00 on 1991-01-07. # - Misiones switched to -3:00 on 1990-12-29. # - Chaco switched to -3:00 on 1991-01-04. -# - San Luis switched to -4:00 on 1990-03-14, then to -3:00 on 1990-10-15, -# then to -4:00 on 1991-03-01, then to -3:00 on 1991-06-01. # - Santiago del Estero switched to -4:00 on 1991-04-01, # then to -3:00 on 1991-04-26. # @@ -259,7 +355,7 @@ Zone America/Argentina/Cordoba -4:16:48 - LMT 1894 Oct 31 -4:00 - WART 1991 Oct 20 -3:00 Arg AR%sT 1999 Oct 3 -4:00 Arg AR%sT 2000 Mar 3 - -3:00 - ART + -3:00 Arg AR%sT # # Tucuman (TM) Zone America/Argentina/Tucuman -4:20:52 - LMT 1894 Oct 31 @@ -272,7 +368,7 @@ Zone America/Argentina/Tucuman -4:20:52 - LMT 1894 Oct 31 -4:00 Arg AR%sT 2000 Mar 3 -3:00 - ART 2004 Jun 1 -4:00 - WART 2004 Jun 13 - -3:00 - ART + -3:00 Arg AR%sT # # La Rioja (LR) Zone America/Argentina/La_Rioja -4:27:24 - LMT 1894 Oct 31 @@ -285,7 +381,7 @@ Zone America/Argentina/La_Rioja -4:27:24 - LMT 1894 Oct 31 -4:00 Arg AR%sT 2000 Mar 3 -3:00 - ART 2004 Jun 1 -4:00 - WART 2004 Jun 20 - -3:00 - ART + -3:00 Arg AR%sT # # San Juan (SJ) Zone America/Argentina/San_Juan -4:34:04 - LMT 1894 Oct 31 @@ -298,7 +394,7 @@ Zone America/Argentina/San_Juan -4:34:04 - LMT 1894 Oct 31 -4:00 Arg AR%sT 2000 Mar 3 -3:00 - ART 2004 May 31 -4:00 - WART 2004 Jul 25 - -3:00 - ART + -3:00 Arg AR%sT # # Jujuy (JY) Zone America/Argentina/Jujuy -4:21:12 - LMT 1894 Oct 31 @@ -312,7 +408,7 @@ Zone America/Argentina/Jujuy -4:21:12 - LMT 1894 Oct 31 -3:00 1:00 ARST 1992 -3:00 Arg AR%sT 1999 Oct 3 -4:00 Arg AR%sT 2000 Mar 3 - -3:00 - ART + -3:00 Arg AR%sT # # Catamarca (CT), Chubut (CH) Zone America/Argentina/Catamarca -4:23:08 - LMT 1894 Oct 31 @@ -325,7 +421,7 @@ Zone America/Argentina/Catamarca -4:23:08 - LMT 1894 Oct 31 -4:00 Arg AR%sT 2000 Mar 3 -3:00 - ART 2004 Jun 1 -4:00 - WART 2004 Jun 20 - -3:00 - ART + -3:00 Arg AR%sT # # Mendoza (MZ) Zone America/Argentina/Mendoza -4:35:16 - LMT 1894 Oct 31 @@ -342,6 +438,23 @@ Zone America/Argentina/Mendoza -4:35:16 - LMT 1894 Oct 31 -4:00 Arg AR%sT 2000 Mar 3 -3:00 - ART 2004 May 23 -4:00 - WART 2004 Sep 26 + -3:00 Arg AR%sT +# +# San Luis (SL) +Zone America/Argentina/San_Luis -4:25:24 - LMT 1894 Oct 31 + -4:16:48 - CMT 1920 May + -4:00 - ART 1930 Dec + -4:00 Arg AR%sT 1969 Oct 5 + -3:00 Arg AR%sT 1990 + -3:00 1:00 ARST 1990 Mar 14 + -4:00 - WART 1990 Oct 15 + -4:00 1:00 WARST 1991 Mar 1 + -4:00 - WART 1991 Jun 1 + -3:00 - ART 1999 Oct 3 + -4:00 1:00 WARST 2000 Mar 3 + -3:00 - ART 2004 May 31 + -4:00 - WART 2004 Jul 25 + -3:00 Arg AR%sT 2008 Jan 21 -3:00 - ART # # Santa Cruz (SC) @@ -353,7 +466,7 @@ Zone America/Argentina/Rio_Gallegos -4:36:52 - LMT 1894 Oct 31 -4:00 Arg AR%sT 2000 Mar 3 -3:00 - ART 2004 Jun 1 -4:00 - WART 2004 Jun 20 - -3:00 - ART + -3:00 Arg AR%sT # # Tierra del Fuego, Antartida e Islas del Atlantico Sur (TF) Zone America/Argentina/Ushuaia -4:33:12 - LMT 1894 Oct 31 @@ -364,7 +477,7 @@ Zone America/Argentina/Ushuaia -4:33:12 - LMT 1894 Oct 31 -4:00 Arg AR%sT 2000 Mar 3 -3:00 - ART 2004 May 30 -4:00 - WART 2004 Jun 20 - -3:00 - ART + -3:00 Arg AR%sT # Aruba # Zone NAME GMTOFF RULES FORMAT [UNTIL] @@ -450,6 +563,50 @@ Zone America/La_Paz -4:32:36 - LMT 1890 # Brazil will start DST on 2007-10-14 00:00 and end on 2008-02-17 00:00: # http://www.mme.gov.br/site/news/detail.do;jsessionid=BBA06811AFCAAC28F0285210913513DA?newsId=13975 +# From Paul Schulze (2008-06-24): +# ...by law number 11.662 of April 24, 2008 (published in the "Diario +# Oficial da Uniao"...) in Brazil there are changes in the timezones, +# effective today (00:00am at June 24, 2008) as follows: +# +# a) The timezone UTC+5 is e[x]tinguished, with all the Acre state and the +# part of the Amazonas state that had this timezone now being put to the +# timezone UTC+4 +# b) The whole Para state now is put at timezone UTC+3, instead of just +# part of it, as was before. +# +# This change follows a proposal of senator Tiao Viana of Acre state, that +# proposed it due to concerns about open television channels displaying +# programs inappropriate to youths in the states that had the timezone +# UTC+5 too early in the night. In the occasion, some more corrections +# were proposed, trying to unify the timezones of any given state. This +# change modifies timezone rules defined in decree 2.784 of 18 June, +# 1913. + +# From Rodrigo Severo (2008-06-24): +# Just correcting the URL: +# +# https://www.in.gov.br/imprensa/visualiza/index.jsp?jornal=3Ddo&secao=3D1&pagina=3D1&data=3D25/04/2008 +# +# +# As a result of the above Decree I believe the America/Rio_Branco +# timezone shall be modified from UTC-5 to UTC-4 and a new timezone shall +# be created to represent the the west side of the Para State. I +# suggest this new timezone be called Santarem as the most +# important/populated city in the affected area. +# +# This new timezone would be the same as the Rio_Branco timezone up to +# the 2008/06/24 change which would be to UTC-3 instead of UTC-4. + +# From Alex Krivenyshev (2008-06-24): +# This is a quick reference page for New and Old Brazil Time Zones map. +# +# http://www.worldtimezone.com/brazil-time-new-old.php +# +# +# - 4 time zones replaced by 3 time zones-eliminating time zone UTC- 05 +# (state Acre and the part of the Amazonas will be UTC/GMT- 04) - western +# part of Par state is moving to one timezone UTC- 03 (from UTC -04). + # From Paul Eggert (2002-10-10): # The official decrees referenced below are mostly taken from # @@ -572,13 +729,13 @@ Rule Brazil 2000 only - Feb 27 0:00 0 - Rule Brazil 2000 2001 - Oct Sun>=8 0:00 1:00 S Rule Brazil 2001 2006 - Feb Sun>=15 0:00 0 - # Decree 4,399 (2002-10-01) repeals DST in AL, CE, MA, PB, PE, PI, RN, SE. -# +# 4,399 Rule Brazil 2002 only - Nov 3 0:00 1:00 S # Decree 4,844 (2003-09-24; corrected 2003-09-26) repeals DST in BA, MT, TO. -# +# 4,844 Rule Brazil 2003 only - Oct 19 0:00 1:00 S # Decree 5,223 (2004-10-01) reestablishes DST in MT. -# +# 5,223 Rule Brazil 2004 only - Nov 2 0:00 1:00 S # Decree 5,539 (2005-09-19), # adopted by the same states as before. @@ -587,9 +744,8 @@ Rule Brazil 2005 only - Oct 16 0:00 1:00 S # adopted by the same states as before. Rule Brazil 2006 only - Nov 5 0:00 1:00 S Rule Brazil 2007 only - Feb 25 0:00 0 - -# (Decree number not yet known) -# http://www.brasil.gov.br/noticias/ultimas_noticias/horario_verao070920/ -# (2007-09-20) after a heads-up from Steffen Thorsen: +# Decree 6,212 (2007-09-26), +# adopted by the same states as before. Rule Brazil 2007 max - Oct Sun>=8 0:00 1:00 S Rule Brazil 2008 max - Feb Sun>=15 0:00 0 - # The latest ruleset listed above says that the following states observe DST: @@ -597,7 +753,6 @@ Rule Brazil 2008 max - Feb Sun>=15 0:00 0 - # For dates after mid-2008, the above rules with TO="max" are guesses # and are quite possibly wrong, but are more likely than no DST at all. - # Zone NAME GMTOFF RULES FORMAT [UNTIL] # # Fernando de Noronha (administratively part of PE) @@ -623,6 +778,13 @@ Zone America/Belem -3:13:56 - LMT 1914 -3:00 Brazil BR%sT 1988 Sep 12 -3:00 - BRT # +# west Para (PA) +# West Para includes Altamira, Oribidos, Prainha, Oriximina, and Santarem. +Zone America/Santarem -3:38:48 - LMT 1914 + -4:00 Brazil AM%sT 1988 Sep 12 + -4:00 - AMT 2008 Jun 24 00:00 + -3:00 - BRT +# # Maranhao (MA), Piaui (PI), Ceara (CE), Rio Grande do Norte (RN), # Paraiba (PB) Zone America/Fortaleza -2:34:00 - LMT 1914 @@ -685,8 +847,7 @@ Zone America/Cuiaba -3:44:20 - LMT 1914 -4:00 - AMT 2004 Oct 1 -4:00 Brazil AM%sT # -# west Para (PA), Rondonia (RO) -# West Para includes Altamira, Oribidos, Prainha, Oriximina, and Santarem. +# Rondonia (RO) Zone America/Porto_Velho -4:15:36 - LMT 1914 -4:00 Brazil AM%sT 1988 Sep 12 -4:00 - AMT @@ -713,13 +874,14 @@ Zone America/Eirunepe -4:39:28 - LMT 1914 -5:00 Brazil AC%sT 1988 Sep 12 -5:00 - ACT 1993 Sep 28 -5:00 Brazil AC%sT 1994 Sep 22 - -5:00 - ACT + -5:00 - ACT 2008 Jun 24 00:00 + -4:00 - AMT # # Acre (AC) Zone America/Rio_Branco -4:31:12 - LMT 1914 -5:00 Brazil AC%sT 1988 Sep 12 - -5:00 - ACT - + -5:00 - ACT 2008 Jun 24 00:00 + -4:00 - AMT # Chile @@ -753,6 +915,26 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914 # America/Santiago. The pre-1980 Pacific/Easter data are dubious, # but we have no other source. +# From German Poo-Caaman~o (2008-03-03): +# Due to drought, Chile extends Daylight Time in three weeks. This +# is one-time change (Saturday 3/29 at 24:00 for America/Santiago +# and Saturday 3/29 at 22:00 for Pacific/Easter) +# The Supreme Decree is located at +# +# http://www.shoa.cl/servicios/supremo316.pdf +# +# and the instructions for 2008 are located in: +# +# http://www.horaoficial.cl/cambio.htm +# . + +# From Jose Miguel Garrido (2008-03-05): +# ... +# You could see the announces of the change on +# +# http://www.shoa.cl/noticias/2008/04hora/hora.htm +# . + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Chile 1927 1932 - Sep 1 0:00 1:00 S Rule Chile 1928 1932 - Apr 1 0:00 0 - @@ -783,7 +965,11 @@ Rule Chile 1998 only - Mar Sun>=9 3:00u 0 - Rule Chile 1998 only - Sep 27 4:00u 1:00 S Rule Chile 1999 only - Apr 4 3:00u 0 - Rule Chile 1999 max - Oct Sun>=9 4:00u 1:00 S -Rule Chile 2000 max - Mar Sun>=9 3:00u 0 - +Rule Chile 2000 2007 - Mar Sun>=9 3:00u 0 - +# N.B.: the end of March 29 in Chile is March 30 in Universal time, +# which is used below in specifying the transition. +Rule Chile 2008 only - Mar 30 3:00u 0 - +Rule Chile 2009 max - Mar Sun>=9 3:00u 0 - # IATA SSIM anomalies: (1992-02) says 1992-03-14; # (1996-09) says 1998-03-08. Ignore these. # Zone NAME GMTOFF RULES FORMAT [UNTIL] @@ -1129,19 +1315,17 @@ Zone America/Montevideo -3:44:44 - LMT 1898 Jun 28 # Venezuela # -# From Kiraz Janicke (2007-09-25), in -# http://www.venezuelanalysis.com/analysis/2645: -# The proposal ... involves turning the clock back half an hour from -# +4.00 Greenwich Mean Time (GMT), to +4.30GMT, the time zone -# Venezuela had until December 31, 1964, when the current time zone -# was adopted. The change was due to take place on September 17 and -# then on September 24, but has since been postponed until December -# 31, to allow for compliance with international organizations, such -# as the International Office of Weights and Measures. +# From John Stainforth (2007-11-28): +# ... the change for Venezuela originally expected for 2007-12-31 has +# been brought forward to 2007-12-09. The official announcement was +# published today in the "Gaceta Oficial de la Republica Bolivariana +# de Venezuela, numero 38.819" (official document for all laws or +# resolution publication) +# http://www.globovision.com/news.php?nid=72208 # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone America/Caracas -4:27:44 - LMT 1890 -4:27:40 - CMT 1912 Feb 12 # Caracas Mean Time? -4:30 - VET 1965 # Venezuela Time - -4:00 - VET 2008 + -4:00 - VET 2007 Dec 9 03:00 -4:30 - VET diff --git a/jdk/make/sun/javazic/tzdata/zone.tab b/jdk/make/sun/javazic/tzdata/zone.tab index b252abd4fd0..a9c686227ec 100644 --- a/jdk/make/sun/javazic/tzdata/zone.tab +++ b/jdk/make/sun/javazic/tzdata/zone.tab @@ -64,7 +64,8 @@ AQ -7824+10654 Antarctica/Vostok Vostok Station, S Magnetic Pole AQ -6640+14001 Antarctica/DumontDUrville Dumont-d'Urville Station, Terre Adelie AQ -690022+0393524 Antarctica/Syowa Syowa Station, E Ongul I AR -3436-05827 America/Argentina/Buenos_Aires Buenos Aires (BA, CF) -AR -3124-06411 America/Argentina/Cordoba most locations (CB, CC, CN, ER, FM, LP, MN, NQ, RN, SA, SE, SF, SL) +AR -3124-06411 America/Argentina/Cordoba most locations (CB, CC, CN, ER, FM, LP, MN, NQ, RN, SA, SE, SF) +AR -3319-06621 America/Argentina/San_Luis San Luis (SL) AR -2411-06518 America/Argentina/Jujuy Jujuy (JY) AR -2649-06513 America/Argentina/Tucuman Tucuman (TM) AR -2828-06547 America/Argentina/Catamarca Catamarca (CT), Chubut (CH) @@ -99,6 +100,7 @@ BG +4241+02319 Europe/Sofia BH +2623+05035 Asia/Bahrain BI -0323+02922 Africa/Bujumbura BJ +0629+00237 Africa/Porto-Novo +BL +1753-06251 America/St_Barthelemy BM +3217-06446 Atlantic/Bermuda BN +0456+11455 Asia/Brunei BO -1630-06809 America/La_Paz @@ -112,7 +114,8 @@ BR -1259-03831 America/Bahia Bahia BR -2332-04637 America/Sao_Paulo S & SE Brazil (GO, DF, MG, ES, RJ, SP, PR, SC, RS) BR -2027-05437 America/Campo_Grande Mato Grosso do Sul BR -1535-05605 America/Cuiaba Mato Grosso -BR -0846-06354 America/Porto_Velho W Para, Rondonia +BR -0226-05452 America/Santarem W Para +BR -0846-06354 America/Porto_Velho Rondonia BR +0249-06040 America/Boa_Vista Roraima BR -0308-06001 America/Manaus E Amazonas BR -0640-06952 America/Eirunepe W Amazonas @@ -230,7 +233,7 @@ ID -0232+14042 Asia/Jayapura Irian Jaya & the Moluccas IE +5320-00615 Europe/Dublin IL +3146+03514 Asia/Jerusalem IM +5409-00428 Europe/Isle_of_Man -IN +2232+08822 Asia/Calcutta +IN +2232+08822 Asia/Kolkata IO -0720+07225 Indian/Chagos IQ +3321+04425 Asia/Baghdad IR +3540+05126 Asia/Tehran @@ -272,6 +275,7 @@ MA +3339-00735 Africa/Casablanca MC +4342+00723 Europe/Monaco MD +4700+02850 Europe/Chisinau ME +4226+01916 Europe/Podgorica +MF +1804-06305 America/Marigot MG -1855+04731 Indian/Antananarivo MH +0709+17112 Pacific/Majuro most locations MH +0905+16720 Pacific/Kwajalein Kwajalein @@ -361,8 +365,7 @@ SE +5920+01803 Europe/Stockholm SG +0117+10351 Asia/Singapore SH -1555-00542 Atlantic/St_Helena SI +4603+01431 Europe/Ljubljana -SJ +7800+01600 Arctic/Longyearbyen Svalbard -SJ +7059-00805 Atlantic/Jan_Mayen Jan Mayen +SJ +7800+01600 Arctic/Longyearbyen SK +4809+01707 Europe/Bratislava SL +0830-01315 Africa/Freetown SM +4355+01228 Europe/San_Marino @@ -432,7 +435,7 @@ VC +1309-06114 America/St_Vincent VE +1030-06656 America/Caracas VG +1827-06437 America/Tortola VI +1821-06456 America/St_Thomas -VN +1045+10640 Asia/Saigon +VN +1045+10640 Asia/Ho_Chi_Minh VU -1740+16825 Pacific/Efate WF -1318-17610 Pacific/Wallis WS -1350-17144 Pacific/Apia diff --git a/jdk/make/sun/jconsole/Makefile b/jdk/make/sun/jconsole/Makefile index bfbdccbfbd5..ff27063bab8 100644 --- a/jdk/make/sun/jconsole/Makefile +++ b/jdk/make/sun/jconsole/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -82,7 +82,7 @@ $(JARFILE): $(LIBDIR) $(FILES_class) $(FILES_png) $(FILES_gif) $(TEMPDIR)/manife $(BOOT_JAR_CMD) -cfm $(JARFILE) $(TEMPDIR)/manifest \ -C $(CLASSBINDIR) sun/tools/jconsole \ -C $(CLASSBINDIR) com/sun/tools/jconsole \ - $(JAR_JFLAGS) + $(BOOT_JAR_JFLAGS) @$(java-vm-cleanup) clean clobber:: diff --git a/jdk/make/sun/jdbc/Makefile b/jdk/make/sun/jdbc/Makefile index 818a89d0e8b..d7e7eaf1530 100644 --- a/jdk/make/sun/jdbc/Makefile +++ b/jdk/make/sun/jdbc/Makefile @@ -1,5 +1,5 @@ # -# Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/jdk/make/sun/jpeg/Makefile b/jdk/make/sun/jpeg/Makefile index e3513763316..f97e2cd08b8 100644 --- a/jdk/make/sun/jpeg/Makefile +++ b/jdk/make/sun/jpeg/Makefile @@ -1,5 +1,5 @@ # -# Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -27,12 +27,11 @@ BUILDDIR = ../.. PACKAGE = sun.awt LIBRARY = jpeg PRODUCT = sun -include $(BUILDDIR)/common/Defs.gmk -# # Use highest optimization level -# -_OPT = $(CC_HIGHEST_OPT) +OPTIMIZATION_LEVEL = HIGHEST + +include $(BUILDDIR)/common/Defs.gmk # # Files diff --git a/jdk/make/sun/net/spi/Makefile b/jdk/make/sun/net/spi/Makefile index 20583bc4eb7..f969b87992a 100644 --- a/jdk/make/sun/net/spi/Makefile +++ b/jdk/make/sun/net/spi/Makefile @@ -23,10 +23,6 @@ # have any questions. # -# -# Makefile for building com/sun -# - BUILDDIR = ../../.. include $(BUILDDIR)/common/Defs.gmk diff --git a/jdk/make/sun/net/spi/nameservice/Makefile b/jdk/make/sun/net/spi/nameservice/Makefile index b6593c71d55..b0ff374de3d 100644 --- a/jdk/make/sun/net/spi/nameservice/Makefile +++ b/jdk/make/sun/net/spi/nameservice/Makefile @@ -23,10 +23,6 @@ # have any questions. # -# -# Makefile for building com/sun -# - BUILDDIR = ../../../.. include $(BUILDDIR)/common/Defs.gmk diff --git a/jdk/make/sun/net/spi/nameservice/dns/Makefile b/jdk/make/sun/net/spi/nameservice/dns/Makefile index 0a7683f5dac..d86a3c69f00 100644 --- a/jdk/make/sun/net/spi/nameservice/dns/Makefile +++ b/jdk/make/sun/net/spi/nameservice/dns/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ # # -# Makefile for building JNDI service provider toolkit +# Makefile for building JNDI DNS name service provider # BUILDDIR = ../../../../.. @@ -67,7 +67,7 @@ $(JARFILE): $(CLASSDESTDIR)/META-INF/services/$(SERVICE_DESCRIPTION) \ $(BOOT_JAR_CMD) -cf $(JARFILE) \ -C $(CLASSDESTDIR) sun \ -C $(CLASSDESTDIR) META-INF \ - $(JAR_JFLAGS) + $(BOOT_JAR_JFLAGS) @$(java-vm-cleanup) include $(BUILDDIR)/common/Classes.gmk diff --git a/jdk/make/sun/nio/Makefile b/jdk/make/sun/nio/Makefile index c8e8e37cbb4..8dd1f98ccfb 100644 --- a/jdk/make/sun/nio/Makefile +++ b/jdk/make/sun/nio/Makefile @@ -91,7 +91,7 @@ $(CHARSETS_JAR): $(FILES_class) $(CLASSDESTDIR)/$(SERVICE_DESCRIPTION_PATH) $(FI $(BOOT_JAR_CMD) cf $(CHARSETS_JAR) \ -C $(CLASSDESTDIR) sun \ -C $(CLASSDESTDIR) $(SERVICE_DESCRIPTION_PATH) \ - $(JAR_JFLAGS) + $(BOOT_JAR_JFLAGS) @$(java-vm-cleanup) clean:: diff --git a/jdk/make/sun/security/mscapi/Makefile b/jdk/make/sun/security/mscapi/Makefile index 8223b536709..08d6609e166 100644 --- a/jdk/make/sun/security/mscapi/Makefile +++ b/jdk/make/sun/security/mscapi/Makefile @@ -210,7 +210,7 @@ build-jar: $(UNSIGNED_DIR)/sunmscapi.jar $(UNSIGNED_DIR)/sunmscapi.jar: build $(prep-target) $(BOOT_JAR_CMD) cf $@ $(JAR_DIRS) \ - $(JAR_JFLAGS) + $(BOOT_JAR_JFLAGS) @$(java-vm-cleanup) diff --git a/jdk/make/sun/security/pkcs11/Makefile b/jdk/make/sun/security/pkcs11/Makefile index 4508b20f843..f20910b7ed2 100644 --- a/jdk/make/sun/security/pkcs11/Makefile +++ b/jdk/make/sun/security/pkcs11/Makefile @@ -210,7 +210,7 @@ build-jar: $(UNSIGNED_DIR)/sunpkcs11.jar $(UNSIGNED_DIR)/sunpkcs11.jar: build $(prep-target) $(BOOT_JAR_CMD) cf $@ $(JAR_DIRS) \ - $(JAR_JFLAGS) + $(BOOT_JAR_JFLAGS) @$(java-vm-cleanup) diff --git a/jdk/make/sun/text/Makefile b/jdk/make/sun/text/Makefile index d3d49355b58..37b8522156a 100644 --- a/jdk/make/sun/text/Makefile +++ b/jdk/make/sun/text/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -112,7 +112,7 @@ $(CLASSDESTDIR)/sun/text/resources/% : $(TEXT_SRCDIR)/% $(LOCALEDATA_JAR): $(EXTDIR) $(FILES_class) $(BIFILES) $(SPECIALFILES) $(prep-target) $(BOOT_JAR_CMD) -cf $@ -C $(CLASSDESTDIR) sun \ - $(JAR_JFLAGS) + $(BOOT_JAR_JFLAGS) @$(java-vm-cleanup) build: $(LOCALEDATA_JAR) diff --git a/jdk/make/tools/GenerateCharacter/check_class.c.template b/jdk/make/tools/GenerateCharacter/check_class.c.template index d9a880f0970..02307e02a6b 100644 --- a/jdk/make/tools/GenerateCharacter/check_class.c.template +++ b/jdk/make/tools/GenerateCharacter/check_class.c.template @@ -1,5 +1,5 @@ /* - * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,6 @@ #include "bool.h" #include "utf.h" #include "tree.h" -#include "sys_api.h" extern bool_t verify_class_codes(ClassClass *cb); diff --git a/jdk/make/tools/Makefile b/jdk/make/tools/Makefile index 68dfe8ef333..3803fbc6eda 100644 --- a/jdk/make/tools/Makefile +++ b/jdk/make/tools/Makefile @@ -32,7 +32,6 @@ include $(BUILDDIR)/common/Defs.gmk SUBDIRS = \ addjsum \ - auto_multi \ buildmetaindex \ commentchecker \ compile_font_config \ diff --git a/jdk/make/tools/src/build/tools/automulti/AutoMulti.java b/jdk/make/tools/src/build/tools/automulti/AutoMulti.java deleted file mode 100644 index a59edc856ca..00000000000 --- a/jdk/make/tools/src/build/tools/automulti/AutoMulti.java +++ /dev/null @@ -1,458 +0,0 @@ -/* - * Copyright 1998-2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package build.tools.automulti; - -import java.lang.reflect.*; -import java.util.*; -import java.io.*; - -/** - * Automatically generates the Multiplexing UI classes - * for Swing. - *

    - * To use, type 'java AutoMulti ' where - * is the directory containing the source for Swing's UI classes and - * is the package prefix to use before ".swing.plaf.multi". - * For example: - * - *

    - * cd TEST
    - * ../../../../build/solaris-sparc/bin/java AutoMulti ../../../../src/share/classes/javax/swing/plaf javax
    - * 
    - * - * AutoMulti will scour the plaf directory for *UI.java files and - * generate Multi*UI.java files that do the multiplexing thing. - *

    - * NOTE: This tool depends upon the existence of and on the - * compiled classes from being somewhere in the class path. - * - * @author Willie Walker - */ -public class AutoMulti { - static String importLines; - - /** - * A silly list of parameter names to use. Skips "i" because we use - * it as a 'for' loop counter. If you want to get fancy, please feel - * to change how parameter names are obtained. This will break if - * someone decides to create a UI method that takes more than 8 - * parameters. Which one is a bug (this breaking or having a method - * with more than eight parameters) is a subjective thing. - */ - public static String[] paramNames = {"a","b","c","d","e","f","g","h"}; - - /** - * Removes the package names (e.g., javax.swing) from the name. - */ - public static String unqualifyName(String name) { - StringTokenizer parser = new StringTokenizer(name,"."); - String unqualifiedName = null; - while (parser.hasMoreTokens()) { - unqualifiedName = parser.nextToken(); - } - return removeDollars(unqualifiedName); - } - - /** - * Strips the extension from the filename. - */ - public static String stripExtension(String name) { - StringTokenizer parser = new StringTokenizer(name,"."); - return parser.nextToken(); - } - - /** - * Adds some spaces. - */ - public static void indent(StringBuffer s, int i) { - while (i > 0) { - s.append(" "); - i--; - } - } - - /** - * Spits out all the beginning stuff. - */ - public static StringBuffer createPreamble(String prefixName) { - StringBuffer s = new StringBuffer(); - s.append("/*\n"); - s.append(" *\n"); - s.append(" * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.\n"); - s.append(" * \n"); - s.append(" * This software is the proprietary information of Sun Microsystems, Inc. \n"); - s.append(" * Use is subject to license terms.\n"); - s.append(" * \n"); - s.append(" */\n"); - s.append("package " + prefixName + ".swing.plaf.multi;\n"); - s.append("\n"); - return s; - } - - /** - * Replaces 'Xxx$Yyy' with "Xxx'. Used by addImport because you - * can't import nested classes directly. - */ - public static String removeNestedClassName(String s) { - int dollarPosition = s.indexOf('$'); - - if (dollarPosition >= 0) { // s contains '$' - StringBuffer sb = new StringBuffer(s); - sb.setLength(dollarPosition); - return sb.toString(); - } else { // no '$' - return s; - } - } - - /** - * Replaces '$' with ".'. Needed for printing inner class names - * for argument and return types. - */ - public static String removeDollars(String s) { - int dollarPosition = s.indexOf('$'); - - if (dollarPosition >= 0) { // s contains '$' - StringBuffer sb = new StringBuffer(s); - while (dollarPosition >= 0) { - //XXX: will there ever be more than one '$'? - sb.replace(dollarPosition, dollarPosition+1, "."); - dollarPosition = sb.indexOf("$", dollarPosition); - } - return sb.toString(); - } else { // no $ - return s; - } - } - - /** - * Adds an import line to the String. - */ - public static void addImport(String s, Class theClass) { - if (!theClass.isPrimitive() && (theClass != Object.class)) { - String className = removeNestedClassName(theClass.getName()); - String importLine = new String("import " + className + ";\n"); - if (importLines.indexOf(importLine) == -1) { - importLines += importLine; - } - } - } - - /** - * Spits out the class header information. - */ - public static void addHeader(StringBuffer s, String className) { - s.append("/**\n"); - s.append(" * A multiplexing UI used to combine " + className + "s.\n"); - s.append(" * \n"); - s.append(" *

    This file was automatically generated by AutoMulti.\n"); - s.append(" *\n"); - s.append(" * @author Otto Multey\n"); // Get it? I crack myself up. - s.append(" */\n"); - s.append("public class Multi" + className + " extends " + className + " {\n"); - s.append("\n"); - s.append(" /**\n"); - s.append(" * The vector containing the real UIs. This is populated \n"); - s.append(" * in the call to createUI, and can be obtained by calling\n"); - s.append(" * the getUIs method. The first element is guaranteed to be the real UI \n"); - s.append(" * obtained from the default look and feel.\n"); - s.append(" */\n"); - s.append(" protected Vector uis = new Vector();\n"); - s.append("\n"); - s.append("////////////////////\n"); - s.append("// Common UI methods\n"); - s.append("////////////////////\n"); - s.append("\n"); - s.append(" /**\n"); - s.append(" * Returns the list of UIs associated with this multiplexing UI. This \n"); - s.append(" * allows processing of the UIs by an application aware of multiplexing \n"); - s.append(" * UIs on components.\n"); - s.append(" */\n"); - s.append(" public ComponentUI[] getUIs() {\n"); - s.append(" return MultiLookAndFeel.uisToArray(uis);\n"); - s.append(" }\n"); - } - - /** - * Prints out the code for a method. This is pretty specific to the - * Multiplexing UI code, so don't get any fancy ideas. - */ - public static void addMethod(StringBuffer s, Method m, String origName, String className) { - - // Get the method name and the return type. Be a little careful about arrays. - // - String methodName = unqualifyName(m.getName()); - String returnType; - if (!m.getReturnType().isArray()) { - returnType = unqualifyName(m.getReturnType().toString()); - addImport(importLines,m.getReturnType()); - } else { - returnType = unqualifyName(m.getReturnType().getComponentType().toString()) - + "[]"; - addImport(importLines,m.getReturnType().getComponentType()); - } - - // Print the javadoc - // - s.append("\n"); - if (methodName.equals("createUI")) { - s.append(" /**\n"); - s.append(" * Returns a multiplexing UI instance if any of the auxiliary\n"); - s.append(" * LookAndFeels supports this UI. Otherwise, just returns the \n"); - s.append(" * UI object obtained from the default LookAndFeel.\n"); - s.append(" */\n"); - } else if (!returnType.equals("void")) { - s.append(" /**\n"); - s.append(" * Invokes the " + methodName + " method on each UI handled by this object.\n"); - s.append(" * \n"); - s.append(" * @return the value obtained from the first UI, which is\n"); - s.append(" * the UI obtained from the default LookAndFeel\n"); - s.append(" */\n"); - } else { - s.append(" /**\n"); - s.append(" * Invokes the " + methodName - + " method on each UI handled by this object.\n"); - s.append(" */\n"); - } - - // Print the method signature - // - s.append(" public"); - if (Modifier.isStatic(m.getModifiers())) { - s.append(" static"); - } - s.append(" " + returnType); - s.append(" " + methodName); - s.append("("); - - Class[] params = m.getParameterTypes(); - Class temp; - String braces; - for (int i = 0; i < params.length; i++) { - if (i > 0) { - s.append(", "); - } - temp = params[i]; - braces = new String(""); - while (temp.isArray()) { - braces += "[]"; - temp = temp.getComponentType(); - } - s.append(unqualifyName(temp.getName()) + braces + " " + paramNames[i]); - addImport(importLines,temp); - } - s.append(")"); - - // Don't forget about exceptions - // - Class exceptions[] = m.getExceptionTypes(); - String throwsString = new String(""); - - if (exceptions.length > 0) { - s.append("\n"); - indent(s,12); - s.append("throws "); - for (int i = 0; i < exceptions.length; i++) { - if (i > 0) { - s.append(", "); - } - s.append(unqualifyName(exceptions[i].getName())); - addImport(importLines,exceptions[i]); - } - } - s.append(throwsString + " {\n"); - - // Now print out the contents of the method. We do a special thing - // for the createUI method, another thing if the method returns 'void' - // and a third thing if we don't do either of the first two. If - // you want to squash this down, feel free. - // - if (methodName.equals("createUI")) { - indent(s,8); - s.append("ComponentUI mui = new Multi" + origName + "();\n"); - indent(s,8); - s.append("return MultiLookAndFeel.createUIs(mui,\n"); - indent(s,42); - s.append("((Multi" + origName +") mui).uis,\n"); - indent(s,42); - for (int i = 0; i < params.length; i++) { - if (i > 0) { - s.append(","); - } - s.append(paramNames[i]); - } - s.append(");\n"); - } else if (!returnType.equals("void")) { - indent(s,8); - s.append(returnType + " returnValue = \n"); - indent(s,12); - s.append("((" + className + ") (uis.elementAt(0)))." - + methodName + "("); - for (int i = 0; i < params.length; i++) { - if (i > 0) { - s.append(","); - } - s.append(paramNames[i]); - } - s.append(");\n"); - indent(s,8); - s.append("for (int i = 1; i < uis.size(); i++) {\n"); - indent(s,12); - s.append("((" + className + ") (uis.elementAt(i)))." - + methodName + "("); - for (int i = 0; i < params.length; i++) { - if (i > 0) { - s.append(","); - } - s.append(paramNames[i]); - } - s.append(");\n"); - indent(s,8); - s.append("}\n"); - indent(s,8); - s.append("return returnValue;\n"); - } else { - indent(s,8); - s.append("for (int i = 0; i < uis.size(); i++) {\n"); - indent(s,12); - s.append("((" + className + ") (uis.elementAt(i)))." - + methodName + "("); - for (int i = 0; i < params.length; i++) { - if (i > 0) { - s.append(","); - } - s.append(paramNames[i]); - } - s.append(");\n"); - indent(s,8); - s.append("}\n"); - } - indent(s,4); - s.append("}\n"); - } - - /** - * Takes a plaf class name (e.g., "MenuUI") and generates the corresponding - * Multiplexing UI Java source code (e.g., "MultiMenuUI.java"). - */ - public static void generateFile(String prefixName, String className) { - try { - FileOutputStream fos; - PrintWriter outFile; - - importLines = new String(); - importLines += new String("import java.util.Vector;\n"); - - StringBuffer body = new StringBuffer(); - Class wee = Class.forName(prefixName + ".swing.plaf." + className); - String weeName = unqualifyName(wee.getName()); - addImport(importLines,wee); - while (!weeName.equals("Object")) { - body.append("\n"); - body.append("////////////////////\n"); - body.append("// " + weeName + " methods\n"); - body.append("////////////////////\n"); - Method[] methods = wee.getDeclaredMethods(); - for (int i=0; i < methods.length; i++) { - if (Modifier.isPublic(methods[i].getModifiers())) { - addMethod(body,methods[i],className,weeName); - } - } - wee = wee.getSuperclass(); - weeName = unqualifyName(wee.getName()); - addImport(importLines,wee); - } - - fos = new FileOutputStream("Multi" + className + ".java"); - outFile = new PrintWriter(fos); - StringBuffer outText = createPreamble(prefixName); - outText.append(importLines.toString() + "\n"); - addHeader(outText,className); - outText.append(body.toString()); - outText.append("}\n"); - outFile.write(outText.toString()); - outFile.flush(); - outFile.close(); - } catch (Exception e) { - System.err.println(e); - } - } - - /** - * D'Oh! Something bad happened. - */ - public static void usage(String s) throws IOException { - System.err.println("Usage: AutoMulti [com.sun]"); - throw new IllegalArgumentException(s); - } - - /** - * Takes the plaf directory name and generates the multiplexing UI - * source code. - */ - public static void main(String[] args) throws IOException { - - if (args.length < 1) { - usage(""); - } - - String dirName = args[0]; - File dir = new File(dirName); - if (!dir.isDirectory()) { - System.err.println("No such directory: " + dirName); - usage(""); - } - - String prefixName; - if (args.length > 1) { - prefixName = args[1]; - } else { - prefixName = "com.sun.java"; - } - - String plafUIs[] = dir.list(new UIJavaFilter()); - for (int i = 0; i < plafUIs.length; i++) { - generateFile(prefixName,stripExtension(plafUIs[i])); - } - } -} - -/** - * Only accepts file names of the form *UI.java. The one exception - * is not accepting ComponentUI.java because we don't need to generate - * a multiplexing class for it. - */ -class UIJavaFilter implements FilenameFilter { - public boolean accept(File dir, String name) { - if (name.equals("ComponentUI.java")) { - return false; - } else if (name.endsWith("UI.java")) { - return true; - } else { - return false; - } - } -} diff --git a/jdk/make/tools/src/build/tools/automulti/README.txt b/jdk/make/tools/src/build/tools/automulti/README.txt deleted file mode 100644 index b5de5afe910..00000000000 --- a/jdk/make/tools/src/build/tools/automulti/README.txt +++ /dev/null @@ -1,36 +0,0 @@ -AutoMulti is the tool that automatically generates the -Multi*UI classes for the Multiplexing look and feel. -Instructions for using it are in AutoMulti.java. - -TestALFGenerator is a tool (a variation of AutoMulti) -that automatically generates an auxiliary look and -feel that you can use to test the Multiplexing look -and feel. The TestALF look and feel implements every -method by printing the message "In the xxx method of -the TextALFYyyUI class." and, except in the case of -createUI, returning something meaningless (since, -except in the case of createUI, the return value is -ignored). - -TestALFLookAndFeel.java is the only non-auto-generated -file for the TestALF L&F. If you specify a package -argument to TestALFGenerator, you'll have to change -the code in TestALFLookAndFeel.java to reflect the -package name. - -To test any application with the TestALF, make sure the -compiled TestALF classes are in the class path. Then add -this to the /lib/swing.properties file (which -you'll probably have to create): - -swing.auxiliarylaf=TestALFLookAndFeel - -E.g., if you're running SwingSet2 against your solaris -build, then you'd create/edit the swing.properties file -in /build/solaris-sparc/lib. - -Then run any app. You'll see lots of thrilling "In the -Xxxx method of the Yyy class" messages. If you get anything -else (especially an exception), then you've found a bug. -Probably in the default look and feel. - diff --git a/jdk/make/tools/src/build/tools/automulti/TestALFGenerator.java b/jdk/make/tools/src/build/tools/automulti/TestALFGenerator.java deleted file mode 100644 index 9b07dbc4048..00000000000 --- a/jdk/make/tools/src/build/tools/automulti/TestALFGenerator.java +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package build.tools.automulti; - -import java.lang.reflect.*; -import java.util.*; -import java.io.*; - -/** - * Automatically generates an auxiliary look and feel to be - * used for testing the Multiplexing look and feel. - *

    - * To use, type 'java TestALFGenerator []' where - * is the directory containing the source for Swing's UI classes. - * is an optional argument that specifies the package - * of the TestALF classes. If it's omitted, the classes are in - * the default package. - * For example: - * - *

    - * ../../../../build/solaris-sparc/bin/java TestALFGenerator ../../../../src/share/classes/javax/swing/plaf com.myco.myalaf
    - * 
    - * - * TestALFGenerator will scour the plaf directory for *UI.java files and - * generate TestALF*UI.java files. - *

    - * NOTE: This tool depends upon the existence of and on the - * compiled classes from being somewhere in the class path. - * - * @author Willie Walker - */ -public class TestALFGenerator { - static String importLines; - static String packageName; - static String classPrefix = "TestALF"; - - /** - * A silly list of parameter names to use. Skips "i" because we use - * it as a 'for' loop counter. If you want to get fancy, please feel - * to change how parameter names are obtained. This will break if - * someone decides to create a UI method that takes more than 8 - * parameters. Which one is a bug (this breaking or having a method - * with more than eight parameters) is a subjective thing. - */ - public static String[] paramNames = {"a","b","c","d","e","f","g","h"}; - - /** - * Removes the package names (e.g., javax.swing) from the name. - */ - public static String unqualifyName(String name) { - StringTokenizer parser = new StringTokenizer(name,"."); - String unqualifiedName = null; - while (parser.hasMoreTokens()) { - unqualifiedName = parser.nextToken(); - } - return removeDollars(unqualifiedName); - } - - /** - * Strips the extension from the filename. - */ - public static String stripExtension(String name) { - StringTokenizer parser = new StringTokenizer(name,"."); - return parser.nextToken(); - } - - /** - * Adds some spaces. - */ - public static void indent(StringBuffer s, int i) { - while (i > 0) { - s.append(" "); - i--; - } - } - - /** - * Spits out all the beginning stuff. - */ - public static StringBuffer createPreamble(String prefixName) { - StringBuffer s = new StringBuffer(); - s.append("/*\n"); - s.append(" *\n"); - s.append(" * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.\n"); - s.append(" * \n"); - s.append(" * This software is the proprietary information of Sun Microsystems, Inc. \n"); - s.append(" * Use is subject to license terms.\n"); - s.append(" * \n"); - s.append(" */\n"); - if (packageName != null) { - s.append("package " + packageName + ";\n"); - s.append("\n"); - } - return s; - } - - /** - * Replaces 'Xxx$Yyy' with "Xxx'. Used by addImport because you - * can't import nested classes directly. - */ - public static String removeNestedClassName(String s) { - int dollarPosition = s.indexOf('$'); - - if (dollarPosition >= 0) { // s contains '$' - StringBuffer sb = new StringBuffer(s); - sb.setLength(dollarPosition); - return sb.toString(); - } else { // no '$' - return s; - } - } - - /** - * Replaces '$' with ".'. Needed for printing inner class names - * for argument and return types. - */ - public static String removeDollars(String s) { - int dollarPosition = s.indexOf('$'); - - if (dollarPosition >= 0) { // s contains '$' - StringBuffer sb = new StringBuffer(s); - while (dollarPosition >= 0) { - //XXX: will there ever be more than one '$'? - sb.replace(dollarPosition, dollarPosition+1, "."); - dollarPosition = sb.indexOf("$", dollarPosition); - } - return sb.toString(); - } else { // no $ - return s; - } - } - - /** - * Adds an import line to the String. - */ - public static void addImport(String s, Class theClass) { - if (!theClass.isPrimitive() && (theClass != Object.class)) { - String className = removeNestedClassName(theClass.getName()); - String importLine = new String("import " + className + ";\n"); - if (importLines.indexOf(importLine) == -1) { - importLines += importLine; - } - } - } - - /** - * Spits out the class header information. - */ - public static void addHeader(StringBuffer s, String className) { - s.append("/**\n"); - s.append(" * An auxiliary UI for " + className + "s.\n"); - s.append(" * \n"); - s.append(" *

    This file was automatically generated by TestALFGenerator.\n"); - s.append(" *\n"); - s.append(" * @author Otto Multey\n"); // Get it? I crack myself up. - s.append(" */\n"); - s.append("public class " + classPrefix + className + " extends " + className + " {\n"); - s.append("\n"); - } - - /** - * Prints out the code for a method. - */ - public static void addMethod(StringBuffer s, Method m, String origName, String className) { - - // Get the method name and the return type. Be a little careful about arrays. - // - String methodName = unqualifyName(m.getName()); - String returnType; - - if (!m.getReturnType().isArray()) { - returnType = unqualifyName(m.getReturnType().toString()); - addImport(importLines,m.getReturnType()); - } else { - returnType = unqualifyName(m.getReturnType().getComponentType().toString()) - + "[]"; - addImport(importLines,m.getReturnType().getComponentType()); - } - - // Print the javadoc - // - s.append("\n"); - - if (methodName.equals("createUI")) { - s.append(" /**\n"); - s.append(" * Returns a UI object for this component.\n"); - s.append(" */\n"); - } else { - s.append(" /**\n"); - s.append(" * Prints a message saying this method has been invoked.\n"); - s.append(" */\n"); - } - - // Print the method signature - // - s.append(" public"); - if (Modifier.isStatic(m.getModifiers())) { - s.append(" static"); - } - s.append(" " + returnType); - s.append(" " + methodName); - s.append("("); - - Class[] params = m.getParameterTypes(); - Class temp; - String braces; - for (int i = 0; i < params.length; i++) { - if (i > 0) { - s.append(", "); - } - temp = params[i]; - braces = new String(""); - while (temp.isArray()) { - braces += "[]"; - temp = temp.getComponentType(); - } - s.append(unqualifyName(temp.getName()) + braces + " " + paramNames[i]); - addImport(importLines,temp); - } - s.append(")"); - - // Don't forget about exceptions - // - Class exceptions[] = m.getExceptionTypes(); - String throwsString = new String(""); - - if (exceptions.length > 0) { - s.append("\n"); - indent(s,12); - s.append("throws "); - for (int i = 0; i < exceptions.length; i++) { - if (i > 0) { - s.append(", "); - } - s.append(unqualifyName(exceptions[i].getName())); - addImport(importLines,exceptions[i]); - } - } - s.append(throwsString + " {\n"); - - // Now print out the contents of the method. - indent(s,8); - s.append("System.out.println(\"In the " + methodName - + " method of the " - + classPrefix + origName + " class.\");\n"); - if (methodName.equals("createUI")) { - indent(s,8); - s.append("return ui;\n"); - } else { - // If we have to return something, do so. - if (!returnType.equals("void")) { - Class rType = m.getReturnType(); - indent(s,8); - if (!rType.isPrimitive()) { - s.append("return null;\n"); - } else if (rType == Boolean.TYPE) { - s.append("return false;\n"); - } else if (rType == Character.TYPE) { - s.append("return '0';\n"); - } else { // byte, short, int, long, float, or double - s.append("return 0;\n"); - } - } - } - - indent(s,4); - s.append("}\n"); - } - - /** - * Takes a plaf class name (e.g., "MenuUI") and generates the corresponding - * TestALF UI Java source code (e.g., "TestALFMenuUI.java"). - */ - public static void generateFile(String prefixName, String className) { - try { - FileOutputStream fos; - PrintWriter outFile; - - importLines = new String(); - importLines += new String("import java.util.Vector;\n"); - - StringBuffer body = new StringBuffer(); - Class wee = Class.forName(prefixName + ".swing.plaf." + className); - String weeName = unqualifyName(wee.getName()); - String thisClassName = classPrefix + className; - addImport(importLines,wee); - - // Declare and initialize the shared UI object. - body.append("\n"); - body.append("////////////////////\n"); - body.append("// Shared UI object\n"); - body.append("////////////////////\n"); - body.append("private final static " + thisClassName - + " ui = new " + thisClassName + "();\n"); - - while (!weeName.equals("Object")) { - body.append("\n"); - body.append("////////////////////\n"); - body.append("// " + weeName + " methods\n"); - body.append("////////////////////\n"); - Method[] methods = wee.getDeclaredMethods(); - for (int i=0; i < methods.length; i++) { - if (Modifier.isPublic(methods[i].getModifiers())) { - addMethod(body,methods[i],className,weeName); - } - } - wee = wee.getSuperclass(); - weeName = unqualifyName(wee.getName()); - addImport(importLines,wee); - } - - fos = new FileOutputStream(classPrefix + className + ".java"); - outFile = new PrintWriter(fos); - StringBuffer outText = createPreamble(prefixName); - outText.append(importLines.toString() + "\n"); - addHeader(outText,className); - outText.append(body.toString()); - outText.append("}\n"); - outFile.write(outText.toString()); - outFile.flush(); - outFile.close(); - } catch (Exception e) { - System.err.println(e); - } - } - - /** - * D'Oh! Something bad happened. - */ - public static void usage(String s) throws IOException { - System.err.println("Usage: java TestALFGenerator []"); - throw new IllegalArgumentException(s); - } - - /** - * Takes the plaf directory name and generates the TestALF UI - * source code. - */ - public static void main(String[] args) throws IOException { - - if (args.length < 1) { - usage(""); - } - - String dirName = args[0]; - File dir = new File(dirName); - if (!dir.isDirectory()) { - System.err.println("No such directory: " + dirName); - usage(""); - } - - if (args.length > 1) { - packageName = args[1]; - } - - String plafUIs[] = dir.list(new UIJavaFilter()); - for (int i = 0; i < plafUIs.length; i++) { - generateFile("javax",stripExtension(plafUIs[i])); - } - } -} - -/** - * Only accepts file names of the form *UI.java. The one exception - * is not accepting ComponentUI.java because we don't need to generate - * a TestALF class for it. - */ -class UIJavaFilter implements FilenameFilter { - public boolean accept(File dir, String name) { - if (name.equals("ComponentUI.java")) { - return false; - } else if (name.endsWith("UI.java")) { - return true; - } else { - return false; - } - } -} diff --git a/jdk/make/tools/src/build/tools/automulti/TestALFLookAndFeel.java b/jdk/make/tools/src/build/tools/automulti/TestALFLookAndFeel.java deleted file mode 100644 index aadab48cac1..00000000000 --- a/jdk/make/tools/src/build/tools/automulti/TestALFLookAndFeel.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ -//package com.myco.myalaf; //search for myalaf for other refs to package name - - -package build.tools.automulti; - -import java.util.Vector; -import java.lang.reflect.Method; -import javax.swing.*; -import javax.swing.plaf.*; - -/** - *

    An auxiliary look and feel used for testing the Multiplexing - * look and feel. - *

    - * - * @see UIManager#addAuxiliaryLookAndFeel - * @see javax.swing.plaf.multi - * - * @author Kathy Walrath - * @author Will Walker - */ -public class TestALFLookAndFeel extends LookAndFeel { - -////////////////////////////// -// LookAndFeel methods -////////////////////////////// - - /** - * Returns a string, suitable for use in menus, - * that identifies this look and feel. - * - * @return a string such as "Test Auxiliary Look and Feel" - */ - public String getName() { - return "Test Auxiliary Look and Feel"; - } - - /** - * Returns a string, suitable for use by applications/services, - * that identifies this look and feel. - * - * @return "TestALF" - */ - public String getID() { - return "TestALF"; - } - - /** - * Returns a one-line description of this look and feel. - * - * @return a descriptive string such as "Allows multiple UI instances per component instance" - */ - public String getDescription() { - return "Allows multiple UI instances per component instance"; - } - - /** - * Returns false; - * this look and feel is not native to any platform. - * - * @return false - */ - public boolean isNativeLookAndFeel() { - return false; - } - - /** - * Returns true; - * every platform permits this look and feel. - * - * @return true - */ - public boolean isSupportedLookAndFeel() { - return true; - } - - /** - * Creates, initializes, and returns - * the look and feel specific defaults. - * For this look and feel, - * the defaults consist solely of - * mappings of UI class IDs - * (such as "ButtonUI") - * to ComponentUI class names - * (such as "com.myco.myalaf.MultiButtonUI"). - * - * @return an initialized UIDefaults object - * @see javax.swing.JComponent#getUIClassID - */ - public UIDefaults getDefaults() { - System.out.println("In the TestALFLookAndFeel getDefaults method."); - UIDefaults table = new TestALFUIDefaults(); - //String prefix = "com.myco.myalaf.TestALF"; - String prefix = "TestALF"; - Object[] uiDefaults = { - "ButtonUI", prefix + "ButtonUI", - "CheckBoxMenuItemUI", prefix + "MenuItemUI", - "CheckBoxUI", prefix + "ButtonUI", - "ColorChooserUI", prefix + "ColorChooserUI", - "ComboBoxUI", prefix + "ComboBoxUI", - "DesktopIconUI", prefix + "DesktopIconUI", - "DesktopPaneUI", prefix + "DesktopPaneUI", - "EditorPaneUI", prefix + "TextUI", - "FileChooserUI", prefix + "FileChooserUI", - "FormattedTextFieldUI", prefix + "TextUI", - "InternalFrameUI", prefix + "InternalFrameUI", - "LabelUI", prefix + "LabelUI", - "ListUI", prefix + "ListUI", - "MenuBarUI", prefix + "MenuBarUI", - "MenuItemUI", prefix + "MenuItemUI", - "MenuUI", prefix + "MenuItemUI", - "OptionPaneUI", prefix + "OptionPaneUI", - "PanelUI", prefix + "PanelUI", - "PasswordFieldUI", prefix + "TextUI", - "PopupMenuSeparatorUI", prefix + "SeparatorUI", - "PopupMenuUI", prefix + "PopupMenuUI", - "ProgressBarUI", prefix + "ProgressBarUI", - "RadioButtonMenuItemUI", prefix + "MenuItemUI", - "RadioButtonUI", prefix + "ButtonUI", - "RootPaneUI", prefix + "RootPaneUI", - "ScrollBarUI", prefix + "ScrollBarUI", - "ScrollPaneUI", prefix + "ScrollPaneUI", - "SeparatorUI", prefix + "SeparatorUI", - "SliderUI", prefix + "SliderUI", - "SpinnerUI", prefix + "SpinnerUI", - "SplitPaneUI", prefix + "SplitPaneUI", - "TabbedPaneUI", prefix + "TabbedPaneUI", - "TableHeaderUI", prefix + "TableHeaderUI", - "TableUI", prefix + "TableUI", - "TextAreaUI", prefix + "TextUI", - "TextFieldUI", prefix + "TextUI", - "TextPaneUI", prefix + "TextUI", - "ToggleButtonUI", prefix + "ButtonUI", - "ToolBarSeparatorUI", prefix + "SeparatorUI", - "ToolBarUI", prefix + "ToolBarUI", - "ToolTipUI", prefix + "ToolTipUI", - "TreeUI", prefix + "TreeUI", - "ViewportUI", prefix + "ViewportUI", - }; - - table.putDefaults(uiDefaults); - return table; - } - -} - -/** - * We want the Test auxiliary look and feel to be quiet and fallback - * gracefully if it cannot find a UI. This class overrides the - * getUIError method of UIDefaults, which is the method that - * emits error messages when it cannot find a UI class in the - * LAF. - */ -class TestALFUIDefaults extends UIDefaults { - protected void getUIError(String msg) { - System.err.println("Test auxiliary L&F: " + msg); - } -} diff --git a/jdk/src/share/back/ThreadReferenceImpl.c b/jdk/src/share/back/ThreadReferenceImpl.c index a85422863ba..2b8e4782db1 100644 --- a/jdk/src/share/back/ThreadReferenceImpl.c +++ b/jdk/src/share/back/ThreadReferenceImpl.c @@ -1,5 +1,5 @@ /* - * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/back/debugDispatch.c b/jdk/src/share/back/debugDispatch.c index 98a86fe5889..fa633799061 100644 --- a/jdk/src/share/back/debugDispatch.c +++ b/jdk/src/share/back/debugDispatch.c @@ -1,5 +1,5 @@ /* - * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,6 @@ #include "ArrayReferenceImpl.h" #include "EventRequestImpl.h" #include "StackFrameImpl.h" -#include "typedefs.h" static void **l1Array; diff --git a/jdk/src/share/back/error_messages.c b/jdk/src/share/back/error_messages.c index f40af69a335..30acacd4ef2 100644 --- a/jdk/src/share/back/error_messages.c +++ b/jdk/src/share/back/error_messages.c @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,6 @@ #include "util.h" #include "proc_md.h" -#include "typedefs.h" /* Maximim length of a message */ #define MAX_MESSAGE_LEN MAXPATHLEN*2+512 diff --git a/jdk/src/share/back/eventFilter.c b/jdk/src/share/back/eventFilter.c index 955cf8813b4..5d135a78c31 100644 --- a/jdk/src/share/back/eventFilter.c +++ b/jdk/src/share/back/eventFilter.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/back/inStream.c b/jdk/src/share/back/inStream.c index 45534fcdc54..1f5b685c5ad 100644 --- a/jdk/src/share/back/inStream.c +++ b/jdk/src/share/back/inStream.c @@ -1,5 +1,5 @@ /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,6 @@ #include "bag.h" #include "commonRef.h" #include "FrameID.h" -#include "typedefs.h" #define INITIAL_REF_ALLOC 50 #define SMALLEST(a, b) ((a) < (b)) ? (a) : (b) diff --git a/jdk/src/share/back/outStream.h b/jdk/src/share/back/outStream.h index a57cc471151..83d1eb10ffe 100644 --- a/jdk/src/share/back/outStream.h +++ b/jdk/src/share/back/outStream.h @@ -1,5 +1,5 @@ /* - * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,8 +26,6 @@ #ifndef JDWP_OUTSTREAM_H #define JDWP_OUTSTREAM_H -#include "typedefs.h" - #include "transport.h" #include "FrameID.h" diff --git a/jdk/src/share/back/transport.c b/jdk/src/share/back/transport.c index f259a93eef3..05c73941614 100644 --- a/jdk/src/share/back/transport.c +++ b/jdk/src/share/back/transport.c @@ -1,5 +1,5 @@ /* - * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/bin/emessages.h b/jdk/src/share/bin/emessages.h index 03824bba5d1..311a8fa61ce 100644 --- a/jdk/src/share/bin/emessages.h +++ b/jdk/src/share/bin/emessages.h @@ -25,8 +25,8 @@ /* * This file primarily consists of all the error and warning messages, that - * are used in ReportErrorMessage. All message must be defined here, in order - * to help in I18N/L10N the messages. + * are used in JLI_ReportErrorMessage. All message must be defined here, in + * order to help with localizing the messages. */ #ifndef _EMESSAGES_H @@ -50,11 +50,6 @@ #define JAR_ERROR2 "Error: Unable to access jarfile %s" #define JAR_ERROR3 "Error: Invalid or corrupt jarfile %s" -#define CLS_ERROR1 "Error: Could not find the main class %s.\n" JNI_ERROR -#define CLS_ERROR2 "Error: Failed to load Main Class: %s\n%s" -#define CLS_ERROR3 "Error: No main method found in specified class.\n" GEN_ERROR -#define CLS_ERROR4 "Error: Main method not public\n" GEN_ERROR - #define CFG_WARN1 "Warning: %s VM not supported; %s VM will be used" #define CFG_WARN2 "Warning: No leading - on line %d of `%s'" #define CFG_WARN3 "Warning: Missing VM type on line %d of `%s'" diff --git a/jdk/src/share/bin/java.c b/jdk/src/share/bin/java.c index f7cbcdc95bc..0feafc1ed41 100644 --- a/jdk/src/share/bin/java.c +++ b/jdk/src/share/bin/java.c @@ -102,8 +102,7 @@ static jboolean InitializeJVM(JavaVM **pvm, JNIEnv **penv, InvocationFunctions *ifn); static jstring NewPlatformString(JNIEnv *env, char *s); static jobjectArray NewPlatformStringArray(JNIEnv *env, char **strv, int strc); -static jclass LoadClass(JNIEnv *env, char *name); -static jstring GetMainClassName(JNIEnv *env, char *jarname); +static jclass LoadMainClass(JNIEnv *env, jboolean isJar, char *name); static void TranslateApplicationArgs(int jargc, const char **jargv, int *pargc, char ***pargv); static jboolean AddApplicationOptions(int cpathc, const char **cpathv); @@ -148,7 +147,7 @@ static void ShowSplashScreen(); static jboolean IsWildCardEnabled(); #define ARG_CHECK(n, f, a) if (n < 1) { \ - ReportErrorMessage(f, a); \ + JLI_ReportErrorMessage(f, a); \ printUsage = JNI_TRUE; \ *pret = 1; \ return JNI_TRUE; \ @@ -301,6 +300,22 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */ } +#define CHECK_EXCEPTION_NULL_LEAVE(e) \ + if ((*env)->ExceptionOccurred(env)) { \ + JLI_ReportExceptionDescription(env); \ + goto leave; \ + } \ + if ((e) == NULL) { \ + JLI_ReportErrorMessage(JNI_ERROR); \ + goto leave; \ + } + +#define CHECK_EXCEPTION_LEAVE(rv) \ + if ((*env)->ExceptionOccurred(env)) { \ + JLI_ReportExceptionDescription(env); \ + ret = (rv); \ + goto leave; \ + } int JNICALL JavaMain(void * _args) @@ -321,22 +336,16 @@ JavaMain(void * _args) int ret = 0; jlong start, end; - /* Initialize the virtual machine */ - start = CounterGet(); if (!InitializeJVM(&vm, &env, &ifn)) { - ReportErrorMessage(JVM_ERROR1); + JLI_ReportErrorMessage(JVM_ERROR1); exit(1); } if (printVersion || showVersion) { PrintJavaVersion(env, showVersion); - if ((*env)->ExceptionOccurred(env)) { - ReportExceptionDescription(env); - ReportErrorMessage(JNI_ERROR); - goto leave; - } + CHECK_EXCEPTION_LEAVE(0); if (printVersion) { ret = 0; goto leave; @@ -346,11 +355,7 @@ JavaMain(void * _args) /* If the user specified neither a class name nor a JAR file */ if (printXUsage || printUsage || (jarfile == 0 && classname == 0)) { PrintUsage(env, printXUsage); - if ((*env)->ExceptionOccurred(env)) { - ReportExceptionDescription(env); - ReportErrorMessage(JNI_ERROR); - ret=1; - } + CHECK_EXCEPTION_LEAVE(1); goto leave; } @@ -395,99 +400,25 @@ JavaMain(void * _args) * the environment (and remove these comments). */ if (jarfile != 0) { - mainClassName = GetMainClassName(env, jarfile); - if ((*env)->ExceptionOccurred(env)) { - ReportExceptionDescription(env); - ReportErrorMessage(JNI_ERROR); - goto leave; - } - if (mainClassName == NULL) { - ReportErrorMessage(JAR_ERROR1,jarfile, GEN_ERROR); - goto leave; - } - classname = (char *)(*env)->GetStringUTFChars(env, mainClassName, 0); - if (classname == NULL) { - ReportExceptionDescription(env); - ReportErrorMessage(JNI_ERROR); - goto leave; - } - mainClass = LoadClass(env, classname); - if(mainClass == NULL) { /* exception occured */ - ReportExceptionDescription(env); - ReportErrorMessage(CLS_ERROR1, classname); - goto leave; - } - (*env)->ReleaseStringUTFChars(env, mainClassName, classname); + mainClass = LoadMainClass(env, JNI_TRUE, jarfile); } else { - mainClassName = NewPlatformString(env, classname); - if (mainClassName == NULL) { - ReportErrorMessage(CLS_ERROR2, classname, GEN_ERROR); - goto leave; - } - classname = (char *)(*env)->GetStringUTFChars(env, mainClassName, 0); - if (classname == NULL) { - ReportExceptionDescription(env); - ReportErrorMessage(JNI_ERROR); - goto leave; - } - mainClass = LoadClass(env, classname); - if(mainClass == NULL) { /* exception occured */ - ReportExceptionDescription(env); - ReportErrorMessage(CLS_ERROR1, classname); - goto leave; - } - (*env)->ReleaseStringUTFChars(env, mainClassName, classname); + mainClass = LoadMainClass(env, JNI_FALSE, classname); } + CHECK_EXCEPTION_NULL_LEAVE(mainClass); - /* Get the application's main method */ + /* + * The LoadMainClass not only loads the main class, it will also ensure + * that the main method's signature is correct, therefore further checking + * is not required. The main method is invoked here so that extraneous java + * stacks are not in the application stack trace. + */ mainID = (*env)->GetStaticMethodID(env, mainClass, "main", "([Ljava/lang/String;)V"); - if (mainID == NULL) { - if ((*env)->ExceptionOccurred(env)) { - ReportExceptionDescription(env); - ReportErrorMessage(JNI_ERROR); - } else { - ReportErrorMessage(CLS_ERROR3); - } - goto leave; - } - - { /* Make sure the main method is public */ - jint mods; - jmethodID mid; - jobject obj = (*env)->ToReflectedMethod(env, mainClass, - mainID, JNI_TRUE); - - if( obj == NULL) { /* exception occurred */ - ReportExceptionDescription(env); - ReportErrorMessage(JNI_ERROR); - goto leave; - } - - mid = - (*env)->GetMethodID(env, - (*env)->GetObjectClass(env, obj), - "getModifiers", "()I"); - if ((*env)->ExceptionOccurred(env)) { - ReportExceptionDescription(env); - ReportErrorMessage(JNI_ERROR); - goto leave; - } - - mods = (*env)->CallIntMethod(env, obj, mid); - if ((mods & 1) == 0) { /* if (!Modifier.isPublic(mods)) ... */ - ReportErrorMessage(CLS_ERROR4); - goto leave; - } - } + CHECK_EXCEPTION_NULL_LEAVE(mainID); /* Build argument array */ mainArgs = NewPlatformStringArray(env, argv, argc); - if (mainArgs == NULL) { - ReportExceptionDescription(env); - ReportErrorMessage(JNI_ERROR); - goto leave; - } + CHECK_EXCEPTION_NULL_LEAVE(mainArgs); /* Invoke main method. */ (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs); @@ -498,20 +429,18 @@ JavaMain(void * _args) */ ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1; +leave: /* - * Detach the main thread so that it appears to have ended when + * Always detach the main thread so that it appears to have ended when * the application's main method exits. This will invoke the * uncaught exception handler machinery if main threw an * exception. An uncaught exception handler cannot change the * launcher's return code except by calling System.exit. */ if ((*vm)->DetachCurrentThread(vm) != 0) { - ReportErrorMessage(JVM_ERROR2); + JLI_ReportErrorMessage(JVM_ERROR2); ret = 1; - goto leave; } - - leave: /* * Wait for all non-daemon threads to end, then destroy the VM. * This will actually create a trivial new Java waiter thread @@ -525,7 +454,6 @@ JavaMain(void * _args) return ret; } - /* * Checks the command line options to find which JVM type was * specified. If no command line option was given for the JVM type, @@ -635,7 +563,7 @@ CheckJvmType(int *pargc, char ***argv, jboolean speculative) { if (loopCount > knownVMsCount) { if (!speculative) { - ReportErrorMessage(CFG_ERROR1); + JLI_ReportErrorMessage(CFG_ERROR1); exit(1); } else { return "ERROR"; @@ -645,7 +573,7 @@ CheckJvmType(int *pargc, char ***argv, jboolean speculative) { if (nextIdx < 0) { if (!speculative) { - ReportErrorMessage(CFG_ERROR2, knownVMs[jvmidx].alias); + JLI_ReportErrorMessage(CFG_ERROR2, knownVMs[jvmidx].alias); exit(1); } else { return "ERROR"; @@ -660,7 +588,7 @@ CheckJvmType(int *pargc, char ***argv, jboolean speculative) { switch (knownVMs[jvmidx].flag) { case VM_WARN: if (!speculative) { - ReportErrorMessage(CFG_WARN1, jvmtype, knownVMs[0].name + 1); + JLI_ReportErrorMessage(CFG_WARN1, jvmtype, knownVMs[0].name + 1); } /* fall through */ case VM_IGNORE: @@ -670,7 +598,7 @@ CheckJvmType(int *pargc, char ***argv, jboolean speculative) { break; case VM_ERROR: if (!speculative) { - ReportErrorMessage(CFG_ERROR3, jvmtype); + JLI_ReportErrorMessage(CFG_ERROR3, jvmtype); exit(1); } else { return "ERROR"; @@ -879,9 +807,9 @@ SelectVersion(int argc, char **argv, char **main_class) if (jarflag && operand) { if ((res = JLI_ParseManifest(operand, &info)) != 0) { if (res == -1) - ReportErrorMessage(JAR_ERROR2, operand); + JLI_ReportErrorMessage(JAR_ERROR2, operand); else - ReportErrorMessage(JAR_ERROR3, operand); + JLI_ReportErrorMessage(JAR_ERROR3, operand); exit(1); } @@ -948,7 +876,7 @@ SelectVersion(int argc, char **argv, char **main_class) * Check for correct syntax of the version specification (JSR 56). */ if (!JLI_ValidVersionString(info.jre_version)) { - ReportErrorMessage(SPC_ERROR1, info.jre_version); + JLI_ReportErrorMessage(SPC_ERROR1, info.jre_version); exit(1); } @@ -970,7 +898,7 @@ SelectVersion(int argc, char **argv, char **main_class) JLI_MemFree(new_argv); return; } else { - ReportErrorMessage(CFG_ERROR4, info.jre_version); + JLI_ReportErrorMessage(CFG_ERROR4, info.jre_version); exit(1); } } @@ -1040,7 +968,7 @@ ParseArguments(int *pargc, char ***pargv, char **pjarfile, * command line options. */ } else if (JLI_StrCmp(arg, "-fullversion") == 0) { - ReportMessage("%s full version \"%s\"", _launcher_name, GetFullVersion()); + JLI_ReportMessage("%s full version \"%s\"", _launcher_name, GetFullVersion()); return JNI_FALSE; } else if (JLI_StrCmp(arg, "-verbosegc") == 0) { AddOption("-verbose:gc", NULL); @@ -1080,7 +1008,7 @@ ParseArguments(int *pargc, char ***pargv, char **pjarfile, JLI_StrCmp(arg, "-cs") == 0 || JLI_StrCmp(arg, "-noasyncgc") == 0) { /* No longer supported */ - ReportErrorMessage(ARG_WARN, arg); + JLI_ReportErrorMessage(ARG_WARN, arg); } else if (JLI_StrCCmp(arg, "-version:") == 0 || JLI_StrCmp(arg, "-no-jre-restrict-search") == 0 || JLI_StrCmp(arg, "-jre-restrict-search") == 0 || @@ -1143,12 +1071,12 @@ InitializeJVM(JavaVM **pvm, JNIEnv **penv, InvocationFunctions *ifn) #define NULL_CHECK0(e) if ((e) == 0) { \ - ReportErrorMessage(JNI_ERROR); \ + JLI_ReportErrorMessage(JNI_ERROR); \ return 0; \ } #define NULL_CHECK(e) if ((e) == 0) { \ - ReportErrorMessage(JNI_ERROR); \ + JLI_ReportErrorMessage(JNI_ERROR); \ return; \ } @@ -1159,7 +1087,7 @@ static jstring getPlatformEncoding(JNIEnv *env) { if (propname) { jclass cls; jmethodID mid; - NULL_CHECK0 (cls = (*env)->FindClass(env, "java/lang/System")); + NULL_CHECK0 (cls = FindBootStrapClass(env, "java/lang/System")); NULL_CHECK0 (mid = (*env)->GetStaticMethodID( env, cls, "getProperty", @@ -1174,7 +1102,7 @@ static jstring getPlatformEncoding(JNIEnv *env) { static jboolean isEncodingSupported(JNIEnv *env, jstring enc) { jclass cls; jmethodID mid; - NULL_CHECK0 (cls = (*env)->FindClass(env, "java/nio/charset/Charset")); + NULL_CHECK0 (cls = FindBootStrapClass(env, "java/nio/charset/Charset")); NULL_CHECK0 (mid = (*env)->GetStaticMethodID( env, cls, "isSupported", @@ -1203,8 +1131,8 @@ NewPlatformString(JNIEnv *env, char *s) jstring str = 0; (*env)->SetByteArrayRegion(env, ary, 0, len, (jbyte *)s); if (!(*env)->ExceptionOccurred(env)) { + NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String")); if (isEncodingSupported(env, enc) == JNI_TRUE) { - NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String")); NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "", "([BLjava/lang/String;)V")); str = (*env)->NewObject(env, cls, mid, ary, enc); @@ -1215,7 +1143,6 @@ NewPlatformString(JNIEnv *env, char *s) the encoding name, in which the StringCoding class will pickup the iso-8859-1 as the fallback converter for us. */ - NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String")); NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "", "([B)V")); str = (*env)->NewObject(env, cls, mid, ary); @@ -1238,7 +1165,7 @@ NewPlatformStringArray(JNIEnv *env, char **strv, int strc) jarray ary; int i; - NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String")); + NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String")); NULL_CHECK0(ary = (*env)->NewObjectArray(env, strc, cls, 0)); for (i = 0; i < strc; i++) { jstring str = NewPlatformString(env, *strv++); @@ -1250,25 +1177,26 @@ NewPlatformStringArray(JNIEnv *env, char **strv, int strc) } /* - * Loads a class, convert the '.' to '/'. + * Loads a class and verifies that the main class is present and it is ok to + * call it for more details refer to the java implementation. */ static jclass -LoadClass(JNIEnv *env, char *name) +LoadMainClass(JNIEnv *env, jboolean isJar, char *name) { - char *buf = JLI_MemAlloc(JLI_StrLen(name) + 1); - char *s = buf, *t = name, c; jclass cls; + jmethodID mid; + jstring str; + jobject result; jlong start, end; - if (JLI_IsTraceLauncher()) + if (JLI_IsTraceLauncher()) { start = CounterGet(); - - do { - c = *t++; - *s++ = (c == '.') ? '/' : c; - } while (c != '\0'); - cls = (*env)->FindClass(env, buf); - JLI_MemFree(buf); + } + NULL_CHECK0(cls = FindBootStrapClass(env, "sun/launcher/LauncherHelper")); + NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls, "checkAndLoadMain", + "(ZZLjava/lang/String;)Ljava/lang/Object;")); + str = (*env)->NewStringUTF(env, name); + result = (*env)->CallStaticObjectMethod(env, cls, mid, JNI_TRUE, isJar, str); if (JLI_IsTraceLauncher()) { end = CounterGet(); @@ -1277,49 +1205,9 @@ LoadClass(JNIEnv *env, char *name) printf("----_JAVA_LAUNCHER_DEBUG----\n"); } - return cls; + return (jclass)result; } - -/* - * Returns the main class name for the specified jar file. - */ -static jstring -GetMainClassName(JNIEnv *env, char *jarname) -{ -#define MAIN_CLASS "Main-Class" - jclass cls; - jmethodID mid; - jobject jar, man, attr; - jstring str, result = 0; - - NULL_CHECK0(cls = (*env)->FindClass(env, "java/util/jar/JarFile")); - NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "", - "(Ljava/lang/String;)V")); - NULL_CHECK0(str = NewPlatformString(env, jarname)); - NULL_CHECK0(jar = (*env)->NewObject(env, cls, mid, str)); - NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "getManifest", - "()Ljava/util/jar/Manifest;")); - man = (*env)->CallObjectMethod(env, jar, mid); - if (man != 0) { - NULL_CHECK0(mid = (*env)->GetMethodID(env, - (*env)->GetObjectClass(env, man), - "getMainAttributes", - "()Ljava/util/jar/Attributes;")); - attr = (*env)->CallObjectMethod(env, man, mid); - if (attr != 0) { - NULL_CHECK0(mid = (*env)->GetMethodID(env, - (*env)->GetObjectClass(env, attr), - "getValue", - "(Ljava/lang/String;)Ljava/lang/String;")); - NULL_CHECK0(str = NewPlatformString(env, MAIN_CLASS)); - result = (*env)->CallObjectMethod(env, attr, mid, str); - } - } - return result; -} - - /* * For tools, convert command line args thus: * javac -cp foo:foo/"*" -J-ms32m ... @@ -1351,7 +1239,7 @@ TranslateApplicationArgs(int jargc, const char **jargv, int *pargc, char ***parg char *arg = argv[i]; if (arg[0] == '-' && arg[1] == 'J') { if (arg[2] == '\0') { - ReportErrorMessage(ARG_ERROR3); + JLI_ReportErrorMessage(ARG_ERROR3); exit(1); } *nargv++ = arg + 2; @@ -1418,7 +1306,7 @@ AddApplicationOptions(int cpathc, const char **cpathv) } if (!GetApplicationHome(home, sizeof(home))) { - ReportErrorMessage(CFG_ERROR5); + JLI_ReportErrorMessage(CFG_ERROR5); return JNI_FALSE; } @@ -1522,7 +1410,7 @@ PrintJavaVersion(JNIEnv *env, jboolean extraLF) jclass ver; jmethodID print; - NULL_CHECK(ver = (*env)->FindClass(env, "sun/misc/Version")); + NULL_CHECK(ver = FindBootStrapClass(env, "sun/misc/Version")); NULL_CHECK(print = (*env)->GetStaticMethodID(env, ver, (extraLF == JNI_TRUE) ? "println" : "print", @@ -1534,7 +1422,7 @@ PrintJavaVersion(JNIEnv *env, jboolean extraLF) } /* - * Prints default usage or the Xusage message, see sun.launcher.LauncherHelp.java + * Prints default usage or the Xusage message, see sun.launcher.LauncherHelper.java */ static void PrintUsage(JNIEnv* env, jboolean doXUsage) @@ -1544,7 +1432,7 @@ PrintUsage(JNIEnv* env, jboolean doXUsage) jstring jprogname, vm1, vm2; int i; - NULL_CHECK(cls = (*env)->FindClass(env, "sun/launcher/LauncherHelp")); + NULL_CHECK(cls = FindBootStrapClass(env, "sun/launcher/LauncherHelper")); if (doXUsage) { @@ -1691,7 +1579,7 @@ ReadKnownVMs(const char *jrepath, const char * arch, jboolean speculative) jvmCfg = fopen(jvmCfgName, "r"); if (jvmCfg == NULL) { if (!speculative) { - ReportErrorMessage(CFG_ERROR6, jvmCfgName); + JLI_ReportErrorMessage(CFG_ERROR6, jvmCfgName); exit(1); } else { return -1; @@ -1703,7 +1591,7 @@ ReadKnownVMs(const char *jrepath, const char * arch, jboolean speculative) if (line[0] == '#') continue; if (line[0] != '-') { - ReportErrorMessage(CFG_WARN2, lineno, jvmCfgName); + JLI_ReportErrorMessage(CFG_WARN2, lineno, jvmCfgName); } if (cnt >= knownVMsLimit) { GrowKnownVMs(cnt); @@ -1711,13 +1599,13 @@ ReadKnownVMs(const char *jrepath, const char * arch, jboolean speculative) line[JLI_StrLen(line)-1] = '\0'; /* remove trailing newline */ tmpPtr = line + JLI_StrCSpn(line, whiteSpace); if (*tmpPtr == 0) { - ReportErrorMessage(CFG_WARN3, lineno, jvmCfgName); + JLI_ReportErrorMessage(CFG_WARN3, lineno, jvmCfgName); } else { /* Null-terminate this string for JLI_StringDup below */ *tmpPtr++ = 0; tmpPtr += JLI_StrSpn(tmpPtr, whiteSpace); if (*tmpPtr == 0) { - ReportErrorMessage(CFG_WARN3, lineno, jvmCfgName); + JLI_ReportErrorMessage(CFG_WARN3, lineno, jvmCfgName); } else { if (!JLI_StrCCmp(tmpPtr, "KNOWN")) { vmType = VM_KNOWN; @@ -1727,7 +1615,7 @@ ReadKnownVMs(const char *jrepath, const char * arch, jboolean speculative) tmpPtr += JLI_StrSpn(tmpPtr, whiteSpace); } if (*tmpPtr == 0) { - ReportErrorMessage(CFG_WARN3, lineno, jvmCfgName); + JLI_ReportErrorMessage(CFG_WARN3, lineno, jvmCfgName); } else { /* Null terminate altVMName */ altVMName = tmpPtr; @@ -1747,7 +1635,7 @@ ReadKnownVMs(const char *jrepath, const char * arch, jboolean speculative) tmpPtr += JLI_StrSpn(tmpPtr, whiteSpace); } if (*tmpPtr == 0) { - ReportErrorMessage(CFG_WARN4, lineno, jvmCfgName); + JLI_ReportErrorMessage(CFG_WARN4, lineno, jvmCfgName); } else { /* Null terminate server class VM name */ serverClassVMName = tmpPtr; @@ -1756,7 +1644,7 @@ ReadKnownVMs(const char *jrepath, const char * arch, jboolean speculative) vmType = VM_IF_SERVER_CLASS; } } else { - ReportErrorMessage(CFG_WARN5, lineno, &jvmCfgName[0]); + JLI_ReportErrorMessage(CFG_WARN5, lineno, &jvmCfgName[0]); vmType = VM_KNOWN; } } @@ -2019,7 +1907,7 @@ RemovableOption(char * option) * A utility procedure to always print to stderr */ void -ReportMessage(const char* fmt, ...) +JLI_ReportMessage(const char* fmt, ...) { va_list vl; va_start(vl, fmt); diff --git a/jdk/src/share/bin/java.h b/jdk/src/share/bin/java.h index e6a08f3cf00..fe039cdcc88 100644 --- a/jdk/src/share/bin/java.h +++ b/jdk/src/share/bin/java.h @@ -121,24 +121,20 @@ void CreateExecutionEnvironment(int *_argc, char jvmpath[], jint so_jvmpath, char **original_argv); +/* Reports an error message to stderr or a window as appropriate. */ +void JLI_ReportErrorMessage(const char * message, ...); + +/* Reports a system error message to stderr or a window */ +void JLI_ReportErrorMessageSys(const char * message, ...); + +/* Reports an error message only to stderr. */ +void JLI_ReportMessage(const char * message, ...); /* - * Report an error message to stderr or a window as appropriate. - */ -void ReportErrorMessage(const char * message, ...); -void ReportErrorMessageSys(const char * format, ...); - -/* - * Report an error message only to stderr. - */ -void ReportMessage(const char * message, ...); - -/* - * Report an exception which terminates the vm to stderr or a window + * Reports an exception which terminates the vm to stderr or a window * as appropriate. */ -void ReportExceptionDescription(JNIEnv * env); - +void JLI_ReportExceptionDescription(JNIEnv * env); void PrintMachineDependentOptions(); const char *jlong_format_specifier(); @@ -184,4 +180,16 @@ static int ContinueInNewThread(InvocationFunctions* ifn, int argc, char** argv, */ void InitLauncher(jboolean javaw); +/* + * This allows for finding classes from the VM's bootstrap class loader directly, + * FindClass uses the application class loader internally, this will cause + * unnecessary searching of the classpath for the required classes. + * + */ +typedef jclass (JNICALL FindClassFromBootLoader_t(JNIEnv *env, + const char *name, + jboolean init, + jobject loader, + jboolean throwError)); +jclass FindBootStrapClass(JNIEnv *env, const char *classname); #endif /* _JAVA_H_ */ diff --git a/jdk/src/share/classes/com/sun/beans/WeakCache.java b/jdk/src/share/classes/com/sun/beans/WeakCache.java new file mode 100644 index 00000000000..461c48e1fd3 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/WeakCache.java @@ -0,0 +1,84 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +package com.sun.beans; + +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; + +import java.util.Map; +import java.util.WeakHashMap; + +/** + * A hashtable-based cache with weak keys and weak values. + * An entry in the map will be automatically removed + * when its key is no longer in the ordinary use. + * A value will be automatically removed as well + * when it is no longer in the ordinary use. + * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +public final class WeakCache { + private final Map> map = new WeakHashMap>(); + + /** + * Returns a value to which the specified {@code key} is mapped, + * or {@code null} if this map contains no mapping for the {@code key}. + * + * @param key the key whose associated value is returned + * @return a value to which the specified {@code key} is mapped + */ + public V get(K key) { + Reference reference = this.map.get(key); + if (reference == null) { + return null; + } + V value = reference.get(); + if (value == null) { + this.map.remove(key); + } + return value; + } + + /** + * Associates the specified {@code value} with the specified {@code key}. + * Removes the mapping for the specified {@code key} from this cache + * if it is present and the specified {@code value} is {@code null}. + * If the cache previously contained a mapping for the {@code key}, + * the old value is replaced by the specified {@code value}. + * + * @param key the key with which the specified value is associated + * @param value the value to be associated with the specified key + */ + public void put(K key, V value) { + if (value != null) { + this.map.put(key, new WeakReference(value)); + } + else { + this.map.remove(key); + } + } +} diff --git a/jdk/src/share/classes/com/sun/java/swing/SwingUtilities3.java b/jdk/src/share/classes/com/sun/java/swing/SwingUtilities3.java new file mode 100644 index 00000000000..28d9e8af6ec --- /dev/null +++ b/jdk/src/share/classes/com/sun/java/swing/SwingUtilities3.java @@ -0,0 +1,178 @@ +/* + * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.java.swing; + +import sun.awt.EventQueueDelegate; +import sun.awt.AppContext; +import java.util.Map; +import java.util.concurrent.Callable; +import java.awt.AWTEvent; +import java.awt.EventQueue; +import java.awt.Component; +import javax.swing.JComponent; +import javax.swing.RepaintManager; + +/** + * A collection of utility methods for Swing. + *

    + * WARNING: While this class is public, it should not be treated as + * public API and its API may change in incompatable ways between dot dot + * releases and even patch releases. You should not rely on this class even + * existing. + * + * This is a second part of sun.swing.SwingUtilities2. It is required + * to provide services for JavaFX applets. + * + */ +public class SwingUtilities3 { + /** + * The {@code clientProperty} key for delegate {@code RepaintManager} + */ + private static final Object DELEGATE_REPAINT_MANAGER_KEY = + new StringBuilder("DelegateRepaintManagerKey"); + + /** + * Registers delegate RepaintManager for {@code JComponent}. + */ + public static void setDelegateRepaintManager(JComponent component, + RepaintManager repaintManager) { + /* setting up flag in AppContext to speed up lookups in case + * there are no delegate RepaintManagers used. + */ + AppContext.getAppContext().put(DELEGATE_REPAINT_MANAGER_KEY, + Boolean.TRUE); + + component.putClientProperty(DELEGATE_REPAINT_MANAGER_KEY, + repaintManager); + } + + /** + * Returns delegate {@code RepaintManager} for {@code component} hierarchy. + */ + public static RepaintManager getDelegateRepaintManager(Component + component) { + RepaintManager delegate = null; + if (Boolean.TRUE == AppContext.getAppContext().get( + DELEGATE_REPAINT_MANAGER_KEY)) { + while (delegate == null && component != null) { + while (component != null + && ! (component instanceof JComponent)) { + component = component.getParent(); + } + if (component != null) { + delegate = (RepaintManager) + ((JComponent) component) + .getClientProperty(DELEGATE_REPAINT_MANAGER_KEY); + component = component.getParent(); + } + + } + } + return delegate; + } + + /* + * We use maps to avoid reflection. Hopefully it should perform better + * this way. + */ + public static void setEventQueueDelegate( + Map> map) { + EventQueueDelegate.setDelegate(new EventQueueDelegateFromMap(map)); + } + + private static class EventQueueDelegateFromMap + implements EventQueueDelegate.Delegate { + private final AWTEvent[] afterDispatchEventArgument; + private final Object[] afterDispatchHandleArgument; + private final Callable afterDispatchCallable; + + private final AWTEvent[] beforeDispatchEventArgument; + private final Callable beforeDispatchCallable; + + private final EventQueue[] getNextEventEventQueueArgument; + private final Callable getNextEventCallable; + + @SuppressWarnings("unchecked") + public EventQueueDelegateFromMap(Map> objectMap) { + Map methodMap = objectMap.get("afterDispatch"); + afterDispatchEventArgument = (AWTEvent[]) methodMap.get("event"); + afterDispatchHandleArgument = (Object[]) methodMap.get("handle"); + afterDispatchCallable = (Callable) methodMap.get("method"); + + methodMap = objectMap.get("beforeDispatch"); + beforeDispatchEventArgument = (AWTEvent[]) methodMap.get("event"); + beforeDispatchCallable = (Callable) methodMap.get("method"); + + methodMap = objectMap.get("getNextEvent"); + getNextEventEventQueueArgument = + (EventQueue[]) methodMap.get("eventQueue"); + getNextEventCallable = (Callable) methodMap.get("method"); + } + + @Override + public void afterDispatch(AWTEvent event, Object handle) throws InterruptedException { + afterDispatchEventArgument[0] = event; + afterDispatchHandleArgument[0] = handle; + try { + afterDispatchCallable.call(); + } catch (InterruptedException e) { + throw e; + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public Object beforeDispatch(AWTEvent event) throws InterruptedException { + beforeDispatchEventArgument[0] = event; + try { + return beforeDispatchCallable.call(); + } catch (InterruptedException e) { + throw e; + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public AWTEvent getNextEvent(EventQueue eventQueue) throws InterruptedException { + getNextEventEventQueueArgument[0] = eventQueue; + try { + return getNextEventCallable.call(); + } catch (InterruptedException e) { + throw e; + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } +} diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKColorChooserPanel.java b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKColorChooserPanel.java index 9ae2d940443..c70d889f453 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKColorChooserPanel.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKColorChooserPanel.java @@ -442,7 +442,10 @@ class GTKColorChooserPanel extends AbstractColorChooserPanel implements } if (updateModel) { - getColorSelectionModel().setSelectedColor(color); + ColorSelectionModel model = getColorSelectionModel(); + if (model != null) { + model.setSelectedColor(color); + } } triangle.setColor(hue, saturation, brightness); diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/Metacity.java b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/Metacity.java index 14d974b0314..a3eada90d84 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/Metacity.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/Metacity.java @@ -770,33 +770,56 @@ class Metacity implements SynthConstants { JComponent maximizeButton = findChild(titlePane, "InternalFrameTitlePane.maximizeButton"); JComponent closeButton = findChild(titlePane, "InternalFrameTitlePane.closeButton"); - int buttonGap = 0; - Insets button_border = (Insets)gm.get("button_border"); Dimension buttonDim = calculateButtonSize(titlePane); - int x = getInt("left_titlebar_edge"); int y = (button_border != null) ? button_border.top : 0; + if (titlePaneParent.getComponentOrientation().isLeftToRight()) { + int x = getInt("left_titlebar_edge"); - menuButton.setBounds(x, y, buttonDim.width, buttonDim.height); + menuButton.setBounds(x, y, buttonDim.width, buttonDim.height); - x = w - buttonDim.width - getInt("right_titlebar_edge"); - if (button_border != null) { - x -= button_border.right; - } + x = w - buttonDim.width - getInt("right_titlebar_edge"); + if (button_border != null) { + x -= button_border.right; + } - if (frame.isClosable()) { - closeButton.setBounds(x, y, buttonDim.width, buttonDim.height); - x -= (buttonDim.width + buttonGap); - } + if (frame.isClosable()) { + closeButton.setBounds(x, y, buttonDim.width, buttonDim.height); + x -= buttonDim.width; + } - if (frame.isMaximizable()) { - maximizeButton.setBounds(x, y, buttonDim.width, buttonDim.height); - x -= (buttonDim.width + buttonGap); - } + if (frame.isMaximizable()) { + maximizeButton.setBounds(x, y, buttonDim.width, buttonDim.height); + x -= buttonDim.width; + } - if (frame.isIconifiable()) { - minimizeButton.setBounds(x, y, buttonDim.width, buttonDim.height); + if (frame.isIconifiable()) { + minimizeButton.setBounds(x, y, buttonDim.width, buttonDim.height); + } + } else { + int x = w - buttonDim.width - getInt("right_titlebar_edge"); + + menuButton.setBounds(x, y, buttonDim.width, buttonDim.height); + + x = getInt("left_titlebar_edge"); + if (button_border != null) { + x += button_border.left; + } + + if (frame.isClosable()) { + closeButton.setBounds(x, y, buttonDim.width, buttonDim.height); + x += buttonDim.width; + } + + if (frame.isMaximizable()) { + maximizeButton.setBounds(x, y, buttonDim.width, buttonDim.height); + x += buttonDim.width; + } + + if (frame.isIconifiable()) { + minimizeButton.setBounds(x, y, buttonDim.width, buttonDim.height); + } } } } // end TitlePaneLayout @@ -973,10 +996,8 @@ class Metacity implements SynthConstants { String title = jif.getTitle(); if (title != null) { FontMetrics fm = SwingUtilities2.getFontMetrics(jif, g); - if (jif.getComponentOrientation().isLeftToRight()) { - title = SwingUtilities2.clipStringIfNecessary(jif, fm, title, - calculateTitleTextWidth(g, jif)); - } + title = SwingUtilities2.clipStringIfNecessary(jif, fm, title, + calculateTitleArea(jif).width); g.setColor(color); SwingUtilities2.drawString(jif, g, title, x, y + fm.getAscent()); } @@ -1010,9 +1031,10 @@ class Metacity implements SynthConstants { JComponent titlePane = findChild(jif, "InternalFrame.northPane"); Dimension buttonDim = calculateButtonSize(titlePane); Insets title_border = (Insets)frameGeometry.get("title_border"); - Rectangle r = new Rectangle(); + Insets button_border = (Insets)getFrameGeometry().get("button_border"); - r.x = getInt("left_titlebar_edge") + buttonDim.width; + Rectangle r = new Rectangle(); + r.x = getInt("left_titlebar_edge"); r.y = 0; r.height = titlePane.getHeight(); if (title_border != null) { @@ -1021,15 +1043,36 @@ class Metacity implements SynthConstants { r.height -= (title_border.top + title_border.bottom); } - r.width = titlePane.getWidth() - r.x - getInt("right_titlebar_edge"); - if (jif.isClosable()) { - r.width -= buttonDim.width; - } - if (jif.isMaximizable()) { - r.width -= buttonDim.width; - } - if (jif.isIconifiable()) { - r.width -= buttonDim.width; + if (titlePane.getParent().getComponentOrientation().isLeftToRight()) { + r.x += buttonDim.width; + if (button_border != null) { + r.x += button_border.left; + } + r.width = titlePane.getWidth() - r.x - getInt("right_titlebar_edge"); + if (jif.isClosable()) { + r.width -= buttonDim.width; + } + if (jif.isMaximizable()) { + r.width -= buttonDim.width; + } + if (jif.isIconifiable()) { + r.width -= buttonDim.width; + } + } else { + if (jif.isClosable()) { + r.x += buttonDim.width; + } + if (jif.isMaximizable()) { + r.x += buttonDim.width; + } + if (jif.isIconifiable()) { + r.x += buttonDim.width; + } + r.width = titlePane.getWidth() - r.x - getInt("right_titlebar_edge") + - buttonDim.width; + if (button_border != null) { + r.x -= button_border.right; + } } if (title_border != null) { r.width -= title_border.right; diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/DesktopProperty.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/DesktopProperty.java index d7d5c0205d7..139b0db559b 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/DesktopProperty.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/DesktopProperty.java @@ -49,8 +49,7 @@ public class DesktopProperty implements UIDefaults.ActiveValue { /** * ReferenceQueue of unreferenced WeakPCLs. */ - private static ReferenceQueue queue; - + private static ReferenceQueue queue; /** * PropertyChangeListener attached to the Toolkit. @@ -76,7 +75,7 @@ public class DesktopProperty implements UIDefaults.ActiveValue { static { - queue = new ReferenceQueue(); + queue = new ReferenceQueue(); } /** @@ -117,8 +116,8 @@ public class DesktopProperty implements UIDefaults.ActiveValue { XPStyle.invalidateStyle(); } Frame appFrames[] = Frame.getFrames(); - for (int j=0; j < appFrames.length; j++) { - updateWindowUI(appFrames[j]); + for (Frame appFrame : appFrames) { + updateWindowUI(appFrame); } } @@ -128,8 +127,8 @@ public class DesktopProperty implements UIDefaults.ActiveValue { private static void updateWindowUI(Window window) { SwingUtilities.updateComponentTreeUI(window); Window ownedWins[] = window.getOwnedWindows(); - for (int i=0; i < ownedWins.length; i++) { - updateWindowUI(ownedWins[i]); + for (Window ownedWin : ownedWins) { + updateWindowUI(ownedWin); } } @@ -270,13 +269,13 @@ public class DesktopProperty implements UIDefaults.ActiveValue { * is handled via a WeakReference so as not to pin down the * DesktopProperty. */ - private static class WeakPCL extends WeakReference + private static class WeakPCL extends WeakReference implements PropertyChangeListener { private Toolkit kit; private String key; private LookAndFeel laf; - WeakPCL(Object target, Toolkit kit, String key, LookAndFeel laf) { + WeakPCL(DesktopProperty target, Toolkit kit, String key, LookAndFeel laf) { super(target, queue); this.kit = kit; this.key = key; @@ -284,7 +283,7 @@ public class DesktopProperty implements UIDefaults.ActiveValue { } public void propertyChange(PropertyChangeEvent pce) { - DesktopProperty property = (DesktopProperty)get(); + DesktopProperty property = get(); if (property == null || laf != UIManager.getLookAndFeel()) { // The property was GC'ed, we're no longer interested in diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsDesktopManager.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsDesktopManager.java index e27ac218e11..20d87d015aa 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsDesktopManager.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsDesktopManager.java @@ -96,7 +96,7 @@ public class WindowsDesktopManager extends DefaultDesktopManager } } catch (PropertyVetoException e) {} if (f != currentFrame) { - currentFrameRef = new WeakReference(f); + currentFrameRef = new WeakReference(f); } } diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java index 43d840b1d6f..e0fb203e0d3 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java @@ -983,7 +983,7 @@ public class WindowsFileChooserUI extends BasicFileChooserUI { } else if (s.equals("componentOrientation")) { ComponentOrientation o = (ComponentOrientation)e.getNewValue(); JFileChooser cc = (JFileChooser)e.getSource(); - if (o != (ComponentOrientation)e.getOldValue()) { + if (o != e.getOldValue()) { cc.applyComponentOrientation(o); } } else if (s.equals("ancestor")) { @@ -1123,7 +1123,7 @@ public class WindowsFileChooserUI extends BasicFileChooserUI { * Data model for a type-face selection combo-box. */ protected class DirectoryComboBoxModel extends AbstractListModel implements ComboBoxModel { - Vector directories = new Vector(); + Vector directories = new Vector(); int[] depths = null; File selectedDirectory = null; JFileChooser chooser = getFileChooser(); @@ -1162,7 +1162,7 @@ public class WindowsFileChooserUI extends BasicFileChooserUI { // Get the canonical (full) path. This has the side // benefit of removing extraneous chars from the path, // for example /foo/bar/ becomes /foo/bar - File canonical = null; + File canonical; try { canonical = directory.getCanonicalFile(); } catch (IOException e) { @@ -1175,7 +1175,7 @@ public class WindowsFileChooserUI extends BasicFileChooserUI { File sf = useShellFolder ? ShellFolder.getShellFolder(canonical) : canonical; File f = sf; - Vector path = new Vector(10); + Vector path = new Vector(10); do { path.addElement(f); } while ((f = f.getParentFile()) != null); @@ -1183,7 +1183,7 @@ public class WindowsFileChooserUI extends BasicFileChooserUI { int pathCount = path.size(); // Insert chain at appropriate place in vector for (int i = 0; i < pathCount; i++) { - f = (File)path.get(i); + f = path.get(i); if (directories.contains(f)) { int topIndex = directories.indexOf(f); for (int j = i-1; j >= 0; j--) { @@ -1202,12 +1202,12 @@ public class WindowsFileChooserUI extends BasicFileChooserUI { private void calculateDepths() { depths = new int[directories.size()]; for (int i = 0; i < depths.length; i++) { - File dir = (File)directories.get(i); + File dir = directories.get(i); File parent = dir.getParentFile(); depths[i] = 0; if (parent != null) { for (int j = i-1; j >= 0; j--) { - if (parent.equals((File)directories.get(j))) { + if (parent.equals(directories.get(j))) { depths[i] = depths[j] + 1; break; } @@ -1306,8 +1306,8 @@ public class WindowsFileChooserUI extends BasicFileChooserUI { FileFilter currentFilter = getFileChooser().getFileFilter(); boolean found = false; if(currentFilter != null) { - for(int i=0; i < filters.length; i++) { - if(filters[i] == currentFilter) { + for (FileFilter filter : filters) { + if (filter == currentFilter) { found = true; } } diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsInternalFrameTitlePane.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsInternalFrameTitlePane.java index b13033bf76b..5222cd5dd08 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsInternalFrameTitlePane.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsInternalFrameTitlePane.java @@ -137,25 +137,46 @@ public class WindowsInternalFrameTitlePane extends BasicInternalFrameTitlePane { int baseline = (getHeight() + fm.getAscent() - fm.getLeading() - fm.getDescent()) / 2; - int titleX; - Rectangle r = new Rectangle(0, 0, 0, 0); - if (frame.isIconifiable()) r = iconButton.getBounds(); - else if (frame.isMaximizable()) r = maxButton.getBounds(); - else if (frame.isClosable()) r = closeButton.getBounds(); - int titleW; - - if(WindowsGraphicsUtils.isLeftToRight(frame) ) { - if (r.x == 0) r.x = frame.getWidth()-frame.getInsets().right; - titleX = systemLabel.getX() + systemLabel.getWidth() + 2; - if (xp != null) { - titleX += 2; - } - titleW = r.x - titleX - 3; - title = getTitle(frame.getTitle(), fm, titleW); - } else { - titleX = systemLabel.getX() - 2 - - SwingUtilities2.stringWidth(frame,fm,title); + Rectangle lastIconBounds = new Rectangle(0, 0, 0, 0); + if (frame.isIconifiable()) { + lastIconBounds = iconButton.getBounds(); + } else if (frame.isMaximizable()) { + lastIconBounds = maxButton.getBounds(); + } else if (frame.isClosable()) { + lastIconBounds = closeButton.getBounds(); } + + int titleX; + int titleW; + int gap = 2; + if (WindowsGraphicsUtils.isLeftToRight(frame)) { + if (lastIconBounds.x == 0) { // There are no icons + lastIconBounds.x = frame.getWidth() - frame.getInsets().right; + } + titleX = systemLabel.getX() + systemLabel.getWidth() + gap; + if (xp != null) { + titleX += 2; + } + titleW = lastIconBounds.x - titleX - gap; + } else { + if (lastIconBounds.x == 0) { // There are no icons + lastIconBounds.x = frame.getInsets().left; + } + titleW = SwingUtilities2.stringWidth(frame, fm, title); + int minTitleX = lastIconBounds.x + lastIconBounds.width + gap; + if (xp != null) { + minTitleX += 2; + } + int availableWidth = systemLabel.getX() - gap - minTitleX; + if (availableWidth > titleW) { + titleX = systemLabel.getX() - gap - titleW; + } else { + titleX = minTitleX; + titleW = availableWidth; + } + } + title = getTitle(frame.getTitle(), fm, titleW); + if (xp != null) { String shadowType = null; if (isSelected) { @@ -258,8 +279,8 @@ public class WindowsInternalFrameTitlePane extends BasicInternalFrameTitlePane { g.fillRect(0, 0, w, h); } Icon icon = getIcon(); - int iconWidth = 0; - int iconHeight = 0; + int iconWidth; + int iconHeight; if (icon != null && (iconWidth = icon.getIconWidth()) > 0 && (iconHeight = icon.getIconHeight()) > 0) { @@ -304,18 +325,18 @@ public class WindowsInternalFrameTitlePane extends BasicInternalFrameTitlePane { } protected void addSystemMenuItems(JPopupMenu menu) { - JMenuItem mi = (JMenuItem)menu.add(restoreAction); + JMenuItem mi = menu.add(restoreAction); mi.setMnemonic('R'); - mi = (JMenuItem)menu.add(moveAction); + mi = menu.add(moveAction); mi.setMnemonic('M'); - mi = (JMenuItem)menu.add(sizeAction); + mi = menu.add(sizeAction); mi.setMnemonic('S'); - mi = (JMenuItem)menu.add(iconifyAction); + mi = menu.add(iconifyAction); mi.setMnemonic('n'); - mi = (JMenuItem)menu.add(maximizeAction); + mi = menu.add(maximizeAction); mi.setMnemonic('x'); systemPopupMenu.add(new JSeparator()); - mi = (JMenuItem)menu.add(closeAction); + mi = menu.add(closeAction); mi.setMnemonic('C'); } @@ -441,7 +462,7 @@ public class WindowsInternalFrameTitlePane extends BasicInternalFrameTitlePane { public class WindowsPropertyChangeHandler extends PropertyChangeHandler { public void propertyChange(PropertyChangeEvent evt) { - String prop = (String)evt.getPropertyName(); + String prop = evt.getPropertyName(); // Update the internal frame icon for the system menu. if (JInternalFrame.FRAME_ICON_PROPERTY.equals(prop) && diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsScrollBarUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsScrollBarUI.java index b137b38c015..f79f9d644db 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsScrollBarUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsScrollBarUI.java @@ -369,21 +369,21 @@ public class WindowsScrollBarUI extends BasicScrollBarUI { */ private static class Grid { private static final int BUFFER_SIZE = 64; - private static HashMap map; + private static HashMap> map; private BufferedImage image; static { - map = new HashMap(); + map = new HashMap>(); } public static Grid getGrid(Color fg, Color bg) { String key = fg.getRGB() + " " + bg.getRGB(); - WeakReference ref = (WeakReference)map.get(key); - Grid grid = (ref == null) ? null : (Grid)ref.get(); + WeakReference ref = map.get(key); + Grid grid = (ref == null) ? null : ref.get(); if (grid == null) { grid = new Grid(fg, bg); - map.put(key, new WeakReference(grid)); + map.put(key, new WeakReference(grid)); } return grid; } diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsTabbedPaneUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsTabbedPaneUI.java index 54d21e8f00d..b781caa3cfc 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsTabbedPaneUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsTabbedPaneUI.java @@ -53,13 +53,13 @@ public class WindowsTabbedPaneUI extends BasicTabbedPaneUI { * Keys to use for forward focus traversal when the JComponent is * managing focus. */ - private static Set managingFocusForwardTraversalKeys; + private static Set managingFocusForwardTraversalKeys; /** * Keys to use for backward focus traversal when the JComponent is * managing focus. */ - private static Set managingFocusBackwardTraversalKeys; + private static Set managingFocusBackwardTraversalKeys; private boolean contentOpaque = true; @@ -69,13 +69,13 @@ public class WindowsTabbedPaneUI extends BasicTabbedPaneUI { // focus forward traversal key if (managingFocusForwardTraversalKeys==null) { - managingFocusForwardTraversalKeys = new HashSet(); + managingFocusForwardTraversalKeys = new HashSet(); managingFocusForwardTraversalKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0)); } tabPane.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, managingFocusForwardTraversalKeys); // focus backward traversal key if (managingFocusBackwardTraversalKeys==null) { - managingFocusBackwardTraversalKeys = new HashSet(); + managingFocusBackwardTraversalKeys = new HashSet(); managingFocusBackwardTraversalKeys.add( KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK)); } tabPane.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, managingFocusBackwardTraversalKeys); diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsTableHeaderUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsTableHeaderUI.java index e2217e0f35a..0f2b39d8937 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsTableHeaderUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsTableHeaderUI.java @@ -124,7 +124,7 @@ public class WindowsTableHeaderUI extends BasicTableHeaderUI { setIcon(null); sortIcon = null; SortOrder sortOrder = - getColumnSortOrder(header.getTable(), column); + getColumnSortOrder(table, column); if (sortOrder != null) { switch (sortOrder) { case ASCENDING: diff --git a/jdk/src/share/classes/com/sun/jmx/defaults/JmxProperties.java b/jdk/src/share/classes/com/sun/jmx/defaults/JmxProperties.java index 89cd5bf16bf..fcf769bf643 100644 --- a/jdk/src/share/classes/com/sun/jmx/defaults/JmxProperties.java +++ b/jdk/src/share/classes/com/sun/jmx/defaults/JmxProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -176,6 +176,18 @@ public class JmxProperties { public static final String RELATION_LOGGER_NAME = "javax.management.relation"; + /** + * Logger name for Namespaces. + */ + public static final String NAMESPACE_LOGGER_NAME = + "javax.management.namespace"; + + /** + * Logger name for Namespaces. + */ + public static final Logger NAMESPACE_LOGGER = + Logger.getLogger(NAMESPACE_LOGGER_NAME); + /** * Logger for Relation Service. */ diff --git a/jdk/src/share/classes/com/sun/jmx/event/DaemonThreadFactory.java b/jdk/src/share/classes/com/sun/jmx/event/DaemonThreadFactory.java new file mode 100644 index 00000000000..ca2462b32ad --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/event/DaemonThreadFactory.java @@ -0,0 +1,77 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.event; + +import com.sun.jmx.remote.util.ClassLogger; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicInteger; + +public class DaemonThreadFactory implements ThreadFactory { + public DaemonThreadFactory(String nameTemplate) { + this(nameTemplate, null); + } + + // nameTemplate should be a format with %d in it, which will be replaced + // by a sequence number of threads created by this factory. + public DaemonThreadFactory(String nameTemplate, ThreadGroup threadGroup) { + if (logger.debugOn()) { + logger.debug("DaemonThreadFactory", + "Construct a new daemon factory: "+nameTemplate); + } + + if (threadGroup == null) { + SecurityManager s = System.getSecurityManager(); + threadGroup = (s != null) ? s.getThreadGroup() : + Thread.currentThread().getThreadGroup(); + } + + this.nameTemplate = nameTemplate; + this.threadGroup = threadGroup; + } + + public Thread newThread(Runnable r) { + final String name = + String.format(nameTemplate, threadNumber.getAndIncrement()); + Thread t = new Thread(threadGroup, r, name, 0); + t.setDaemon(true); + if (t.getPriority() != Thread.NORM_PRIORITY) + t.setPriority(Thread.NORM_PRIORITY); + + if (logger.debugOn()) { + logger.debug("newThread", + "Create a new daemon thread with the name "+t.getName()); + } + + return t; + } + + private final String nameTemplate; + private final ThreadGroup threadGroup; + private final AtomicInteger threadNumber = new AtomicInteger(1); + + private static final ClassLogger logger = + new ClassLogger("com.sun.jmx.event", "DaemonThreadFactory"); +} diff --git a/jdk/src/share/classes/com/sun/jmx/event/EventBuffer.java b/jdk/src/share/classes/com/sun/jmx/event/EventBuffer.java new file mode 100644 index 00000000000..ed804791097 --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/event/EventBuffer.java @@ -0,0 +1,252 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.event; + +import com.sun.jmx.remote.util.ClassLogger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import javax.management.remote.NotificationResult; +import javax.management.remote.TargetedNotification; + +public class EventBuffer { + + public EventBuffer() { + this(Integer.MAX_VALUE, null); + } + + public EventBuffer(int capacity) { + this(capacity, new ArrayList()); + } + + public EventBuffer(int capacity, final List list) { + if (logger.traceOn()) { + logger.trace("EventBuffer", "New buffer with the capacity: " + +capacity); + } + if (capacity < 1) { + throw new IllegalArgumentException( + "The capacity must be bigger than 0"); + } + + if (list == null) { + throw new NullPointerException("Null list."); + } + + this.capacity = capacity; + this.list = list; + } + + public void add(TargetedNotification tn) { + if (logger.traceOn()) { + logger.trace("add", "Add one notif."); + } + + synchronized(lock) { + if (list.size() == capacity) { // have to throw one + passed++; + list.remove(0); + + if (logger.traceOn()) { + logger.trace("add", "Over, remove the oldest one."); + } + } + + list.add(tn); + lock.notify(); + } + } + + public void add(TargetedNotification[] tns) { + if (tns == null || tns.length == 0) { + return; + } + + if (logger.traceOn()) { + logger.trace("add", "Add notifs: "+tns.length); + } + + synchronized(lock) { + final int d = list.size() - capacity + tns.length; + if (d > 0) { // have to throw + passed += d; + if (logger.traceOn()) { + logger.trace("add", + "Over, remove the oldest: "+d); + } + if (tns.length <= capacity){ + list.subList(0, d).clear(); + } else { + list.clear(); + TargetedNotification[] tmp = + new TargetedNotification[capacity]; + System.arraycopy(tns, tns.length-capacity, tmp, 0, capacity); + tns = tmp; + } + } + + Collections.addAll(list,tns); + lock.notify(); + } + } + + public NotificationResult fetchNotifications(long startSequenceNumber, + long timeout, + int maxNotifications) { + if (logger.traceOn()) { + logger.trace("fetchNotifications", + "Being called: " + +startSequenceNumber+" " + +timeout+" "+maxNotifications); + } + if (startSequenceNumber < 0 || + timeout < 0 || + maxNotifications < 0) { + throw new IllegalArgumentException("Negative value."); + } + + TargetedNotification[] tns = new TargetedNotification[0]; + long earliest = startSequenceNumber < passed ? + passed : startSequenceNumber; + long next = earliest; + + final long startTime = System.currentTimeMillis(); + long toWait = timeout; + synchronized(lock) { + int toSkip = (int)(startSequenceNumber - passed); + + // skip those before startSequenceNumber. + while (!closed && toSkip > 0) { + toWait = timeout - (System.currentTimeMillis() - startTime); + if (list.size() == 0) { + if (toWait <= 0) { + // the notification of startSequenceNumber + // does not arrive yet. + return new NotificationResult(startSequenceNumber, + startSequenceNumber, + new TargetedNotification[0]); + } + + waiting(toWait); + continue; + } + + if (toSkip <= list.size()) { + list.subList(0, toSkip).clear(); + passed += toSkip; + + break; + } else { + passed += list.size(); + toSkip -= list.size(); + + list.clear(); + } + } + + earliest = passed; + + if (list.size() == 0) { + toWait = timeout - (System.currentTimeMillis() - startTime); + + waiting(toWait); + } + + if (list.size() == 0) { + tns = new TargetedNotification[0]; + } else if (list.size() <= maxNotifications) { + tns = list.toArray(new TargetedNotification[0]); + } else { + tns = new TargetedNotification[maxNotifications]; + for (int i=0; i 0) { + try { + lock.wait(toWait); + + toWait = timeout - (System.currentTimeMillis() - startTime); + } catch (InterruptedException ire) { + logger.trace("waiting", ire); + break; + } + } + } + } + + private final int capacity; + private final List list; + private boolean closed; + + private long passed = 0; + private final int[] lock = new int[0]; + + private static final ClassLogger logger = + new ClassLogger("javax.management.event", "EventBuffer"); +} diff --git a/jdk/src/share/classes/com/sun/jmx/event/EventClientFactory.java b/jdk/src/share/classes/com/sun/jmx/event/EventClientFactory.java new file mode 100644 index 00000000000..3cab63ccdc6 --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/event/EventClientFactory.java @@ -0,0 +1,46 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.event; + +import javax.management.event.*; + +/** + * Implemented by objects which are using an {@link EventClient} to + * subscribe for Notifications. + * + */ +public interface EventClientFactory { + /** + * Returns the {@code EventClient} that the object implementing this + * interface uses to subscribe for Notifications. This method returns + * {@code null} if no {@code EventClient} can be used - e.g. because + * the underlying server does not have any {@link EventDelegate}. + * + * @return an {@code EventClient} or {@code null}. + **/ + public EventClient getEventClient(); + +} diff --git a/jdk/src/share/classes/com/sun/jmx/event/EventConnection.java b/jdk/src/share/classes/com/sun/jmx/event/EventConnection.java new file mode 100644 index 00000000000..adadef1931d --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/event/EventConnection.java @@ -0,0 +1,81 @@ +/* + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.event; + +import java.io.IOException; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import javax.management.MBeanServerConnection; +import javax.management.event.EventClient; +import javax.management.event.EventClientDelegate; +import javax.management.event.EventConsumer; +import javax.management.event.NotificationManager; + +/** + * Override the methods related to the notification to use the + * Event service. + */ +public interface EventConnection extends MBeanServerConnection, EventConsumer { + public EventClient getEventClient(); + + public static class Factory { + public static EventConnection make( + final MBeanServerConnection mbsc, + final EventClient eventClient) + throws IOException { + if (!mbsc.isRegistered(EventClientDelegate.OBJECT_NAME)) { + throw new IOException( + "The server does not support the event service."); + } + InvocationHandler ih = new InvocationHandler() { + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable { + Class intf = method.getDeclaringClass(); + try { + if (intf.isInstance(eventClient)) + return method.invoke(eventClient, args); + else + return method.invoke(mbsc, args); + } catch (InvocationTargetException e) { + throw e.getCause(); + } + } + }; + // It is important to declare NotificationManager.class first + // in the array below, so that the relevant addNL and removeNL + // methods will show up with method.getDeclaringClass() as + // being from that interface and not MBeanServerConnection. + return (EventConnection) Proxy.newProxyInstance( + NotificationManager.class.getClassLoader(), + new Class[] { + NotificationManager.class, EventConnection.class, + }, + ih); + } + } +} diff --git a/jdk/src/share/classes/com/sun/jmx/event/EventParams.java b/jdk/src/share/classes/com/sun/jmx/event/EventParams.java new file mode 100644 index 00000000000..7d875e1385b --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/event/EventParams.java @@ -0,0 +1,65 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.event; + +import com.sun.jmx.mbeanserver.GetPropertyAction; +import com.sun.jmx.remote.util.ClassLogger; +import java.security.AccessController; +import javax.management.event.EventClient; + +/** + * + * @author sjiang + */ +public class EventParams { + public static final String DEFAULT_LEASE_TIMEOUT = + "com.sun.event.lease.time"; + + + @SuppressWarnings("cast") // cast for jdk 1.5 + public static long getLeaseTimeout() { + long timeout = EventClient.DEFAULT_LEASE_TIMEOUT; + try { + final GetPropertyAction act = + new GetPropertyAction(DEFAULT_LEASE_TIMEOUT); + final String s = (String)AccessController.doPrivileged(act); + if (s != null) { + timeout = Long.parseLong(s); + } + } catch (RuntimeException e) { + logger.fine("getLeaseTimeout", "exception getting property", e); + } + + return timeout; + } + + /** Creates a new instance of EventParams */ + private EventParams() { + } + + private static final ClassLogger logger = + new ClassLogger("javax.management.event", "EventParams"); +} diff --git a/jdk/src/share/classes/com/sun/jmx/event/LeaseManager.java b/jdk/src/share/classes/com/sun/jmx/event/LeaseManager.java new file mode 100644 index 00000000000..e1761011f0e --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/event/LeaseManager.java @@ -0,0 +1,153 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.event; + +import com.sun.jmx.remote.util.ClassLogger; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +/** + *

    Manage a renewable lease. The lease can be renewed indefinitely + * but if the lease runs to its current expiry date without being renewed + * then the expiry callback is invoked. If the lease has already expired + * when renewal is attempted then the lease method returns zero.

    + * @author sjiang + * @author emcmanus + */ +// The synchronization logic of this class is tricky to deal correctly with the +// case where the lease expires at the same time as the |lease| or |stop| method +// is called. If the lease is active then the field |scheduled| represents +// the expiry task; otherwise |scheduled| is null. Renewing or stopping the +// lease involves canceling this task and setting |scheduled| either to a new +// task (to renew) or to null (to stop). +// +// Suppose the expiry task runs at the same time as the |lease| method is called. +// If the task enters its synchronized block before the method starts, then +// it will set |scheduled| to null and the method will return 0. If the method +// starts before the task enters its synchronized block, then the method will +// cancel the task which will see that when it later enters the block. +// Similar reasoning applies to the |stop| method. It is not expected that +// different threads will call |lease| or |stop| simultaneously, although the +// logic should be correct then too. +public class LeaseManager { + public LeaseManager(Runnable callback) { + this(callback, EventParams.getLeaseTimeout()); + } + + public LeaseManager(Runnable callback, long timeout) { + if (logger.traceOn()) { + logger.trace("LeaseManager", "new manager with lease: "+timeout); + } + if (callback == null) { + throw new NullPointerException("Null callback."); + } + if (timeout <= 0) + throw new IllegalArgumentException("Timeout must be positive: " + timeout); + + this.callback = callback; + schedule(timeout); + } + + /** + *

    Renew the lease for the given time. The new time can be shorter + * than the previous one, in which case the lease will expire earlier + * than it would have.

    + * + *

    Calling this method after the lease has expired will return zero + * immediately and have no other effect.

    + * + * @param timeout the new lifetime. If zero, the lease + * will expire immediately. + */ + public synchronized long lease(long timeout) { + if (logger.traceOn()) { + logger.trace("lease", "new lease to: "+timeout); + } + + if (timeout < 0) + throw new IllegalArgumentException("Negative lease: " + timeout); + + if (scheduled == null) + return 0L; + + scheduled.cancel(false); + + if (logger.traceOn()) + logger.trace("lease", "start lease: "+timeout); + schedule(timeout); + + return timeout; + } + + private class Expire implements Runnable { + ScheduledFuture task; + + public void run() { + synchronized (LeaseManager.this) { + if (task.isCancelled()) + return; + scheduled = null; + } + callback.run(); + executor.shutdown(); + } + } + + private synchronized void schedule(long timeout) { + Expire expire = new Expire(); + scheduled = executor.schedule(expire, timeout, TimeUnit.MILLISECONDS); + expire.task = scheduled; + } + + /** + *

    Cancel the lease without calling the expiry callback.

    + */ + public synchronized void stop() { + logger.trace("stop", "canceling lease"); + scheduled.cancel(false); + scheduled = null; + try { + executor.shutdown(); + } catch (SecurityException e) { + // OK: caller doesn't have RuntimePermission("modifyThread") + // which is unlikely in reality but triggers a test failure otherwise + logger.trace("stop", "exception from executor.shutdown", e); + } + } + + private final Runnable callback; + private ScheduledFuture scheduled; // If null, the lease has expired. + + private final ScheduledExecutorService executor + = Executors.newScheduledThreadPool(1, + new DaemonThreadFactory("JMX LeaseManager %d")); + + private static final ClassLogger logger = + new ClassLogger("javax.management.event", "LeaseManager"); + +} diff --git a/jdk/src/share/classes/com/sun/jmx/event/LeaseRenewer.java b/jdk/src/share/classes/com/sun/jmx/event/LeaseRenewer.java new file mode 100644 index 00000000000..b3f7c7fee07 --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/event/LeaseRenewer.java @@ -0,0 +1,143 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.event; + +import com.sun.jmx.remote.util.ClassLogger; +import java.util.concurrent.Callable; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +/** + * + * @author sjiang + */ +public class LeaseRenewer { + public LeaseRenewer(ScheduledExecutorService scheduler, Callable doRenew) { + if (logger.traceOn()) { + logger.trace("LeaseRenewer", "New LeaseRenewer."); + } + + if (doRenew == null) { + throw new NullPointerException("Null job to call server."); + } + + this.doRenew = doRenew; + nextRenewTime = System.currentTimeMillis(); + + this.scheduler = scheduler; + future = this.scheduler.schedule(myRenew, 0, TimeUnit.MILLISECONDS); + } + + public void close() { + if (logger.traceOn()) { + logger.trace("close", "Close the lease."); + } + + synchronized(lock) { + if (closed) { + return; + } else { + closed = true; + } + } + + try { + future.cancel(false); // not interrupt if running + } catch (Exception e) { + // OK + if (logger.debugOn()) { + logger.debug("close", "Failed to cancel the leasing job.", e); + } + } + } + + public boolean closed() { + synchronized(lock) { + return closed; + } + } + + // ------------------------------ + // private + // ------------------------------ + private final Runnable myRenew = new Runnable() { + public void run() { + synchronized(lock) { + if (closed()) { + return; + } + } + + long next = nextRenewTime - System.currentTimeMillis(); + if (next < MIN_MILLIS) { + try { + if (logger.traceOn()) { + logger.trace("myRenew-run", ""); + } + next = doRenew.call().longValue(); + + } catch (Exception e) { + logger.fine("myRenew-run", "Failed to renew lease", e); + close(); + } + + if (next > 0 && next < Long.MAX_VALUE) { + next = next/2; + next = (next < MIN_MILLIS) ? MIN_MILLIS : next; + } else { + close(); + } + } + + nextRenewTime = System.currentTimeMillis() + next; + + if (logger.traceOn()) { + logger.trace("myRenew-run", "Next leasing: "+next); + } + + synchronized(lock) { + if (!closed) { + future = scheduler.schedule(this, next, TimeUnit.MILLISECONDS); + } + } + } + }; + + private final Callable doRenew; + private ScheduledFuture future; + private boolean closed = false; + private long nextRenewTime; + + private final int[] lock = new int[0]; + + private final ScheduledExecutorService scheduler; + + private static final long MIN_MILLIS = 50; + + private static final ClassLogger logger = + new ClassLogger("javax.management.event", "LeaseRenewer"); +} diff --git a/jdk/src/share/classes/com/sun/jmx/event/ReceiverBuffer.java b/jdk/src/share/classes/com/sun/jmx/event/ReceiverBuffer.java new file mode 100644 index 00000000000..a87e2dfd6f5 --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/event/ReceiverBuffer.java @@ -0,0 +1,97 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.event; + +import com.sun.jmx.remote.util.ClassLogger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import javax.management.remote.NotificationResult; +import javax.management.remote.TargetedNotification; + + +public class ReceiverBuffer { + public void addNotifs(NotificationResult nr) { + if (nr == null) { + return; + } + + TargetedNotification[] tns = nr.getTargetedNotifications(); + + if (logger.traceOn()) { + logger.trace("addNotifs", "" + tns.length); + } + + long impliedStart = nr.getEarliestSequenceNumber(); + final long missed = impliedStart - start; + start = nr.getNextSequenceNumber(); + + if (missed > 0) { + if (logger.traceOn()) { + logger.trace("addNotifs", + "lost: "+missed); + } + + lost += missed; + } + + Collections.addAll(notifList, nr.getTargetedNotifications()); + } + + public TargetedNotification[] removeNotifs() { + if (logger.traceOn()) { + logger.trace("removeNotifs", String.valueOf(notifList.size())); + } + + if (notifList.size() == 0) { + return null; + } + + TargetedNotification[] ret = notifList.toArray( + new TargetedNotification[]{}); + notifList.clear(); + + return ret; + } + + public int size() { + return notifList.size(); + } + + public int removeLost() { + int ret = lost; + lost = 0; + return ret; + } + + private List notifList + = new ArrayList(); + private long start = 0; + private int lost = 0; + + private static final ClassLogger logger = + new ClassLogger("javax.management.event", "ReceiverBuffer"); +} diff --git a/jdk/src/share/classes/com/sun/jmx/event/RepeatedSingletonJob.java b/jdk/src/share/classes/com/sun/jmx/event/RepeatedSingletonJob.java new file mode 100644 index 00000000000..768ed6f30fa --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/event/RepeatedSingletonJob.java @@ -0,0 +1,119 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.event; + +import com.sun.jmx.remote.util.ClassLogger; +import java.util.concurrent.Executor; +import java.util.concurrent.RejectedExecutionException; + +/** + *

    A task that is repeatedly run by an Executor. The task will be + * repeated as long as the {@link #isSuspended()} method returns true. Once + * that method returns false, the task is no longer executed until someone + * calls {@link #resume()}.

    + * @author sjiang + */ +public abstract class RepeatedSingletonJob implements Runnable { + public RepeatedSingletonJob(Executor executor) { + if (executor == null) { + throw new NullPointerException("Null executor!"); + } + + this.executor = executor; + } + + public boolean isWorking() { + return working; + } + + public void resume() { + + synchronized(this) { + if (!working) { + if (logger.traceOn()) { + logger.trace("resume", ""); + } + working = true; + execute(); + } + } + } + + public abstract void task(); + public abstract boolean isSuspended(); + + public void run() { + if (logger.traceOn()) { + logger.trace("run", "execute the task"); + } + try { + task(); + } catch (Exception e) { + // A correct task() implementation should not throw exceptions. + // It may cause isSuspended() to start returning true, though. + logger.trace("run", "failed to execute the task", e); + } + + synchronized(this) { + if (!isSuspended()) { + execute(); + } else { + if (logger.traceOn()) { + logger.trace("run", "suspend the task"); + } + working = false; + } + } + + } + + private void execute() { + try { + executor.execute(this); + } catch (RejectedExecutionException e) { + logger.warning( + "execute", + "Executor threw exception (" + this.getClass().getName() + ")", + e); + throw new RejectedExecutionException( + "Executor.execute threw exception -" + + "should not be possible", e); + // User-supplied Executor should not be configured in a way that + // might cause this exception, for example if it is shared between + // several client objects and doesn't have capacity for one job + // from each one. CR 6732037 will add text to the spec explaining + // the problem. The rethrown exception will propagate either out + // of resume() to user code, or out of run() to the Executor + // (which will probably ignore it). + } + } + + private boolean working = false; + private final Executor executor; + + private static final ClassLogger logger = + new ClassLogger("javax.management.event", "RepeatedSingletonJob"); +} diff --git a/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java b/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java index 99b10ad1e8c..7da3406b911 100644 --- a/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java +++ b/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java @@ -25,33 +25,49 @@ package com.sun.jmx.interceptor; -// java import -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.logging.Level; -import java.util.Set; -import java.util.HashSet; -import java.util.WeakHashMap; + +// JMX RI +import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER; +import com.sun.jmx.mbeanserver.DynamicMBean2; +import com.sun.jmx.mbeanserver.Introspector; +import com.sun.jmx.mbeanserver.MBeanInjector; +import com.sun.jmx.mbeanserver.MBeanInstantiator; +import com.sun.jmx.mbeanserver.ModifiableClassLoaderRepository; +import com.sun.jmx.mbeanserver.NamedObject; +import com.sun.jmx.mbeanserver.NotifySupport; +import com.sun.jmx.mbeanserver.Repository; +import com.sun.jmx.mbeanserver.Repository.RegistrationContext; +import com.sun.jmx.mbeanserver.Util; +import com.sun.jmx.remote.util.EnvHelp; + import java.lang.ref.WeakReference; import java.security.AccessControlContext; -import java.security.Permission; -import java.security.ProtectionDomain; import java.security.AccessController; +import java.security.Permission; import java.security.PrivilegedAction; +import java.security.ProtectionDomain; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.Set; +import java.util.WeakHashMap; +import java.util.logging.Level; // JMX import import javax.management.Attribute; import javax.management.AttributeList; import javax.management.AttributeNotFoundException; import javax.management.DynamicMBean; +import javax.management.DynamicWrapperMBean; import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.IntrospectionException; import javax.management.InvalidAttributeValueException; import javax.management.JMRuntimeException; import javax.management.ListenerNotFoundException; -import javax.management.MalformedObjectNameException; import javax.management.MBeanException; import javax.management.MBeanInfo; import javax.management.MBeanPermission; @@ -64,6 +80,7 @@ import javax.management.MBeanTrustPermission; import javax.management.NotCompliantMBeanException; import javax.management.Notification; import javax.management.NotificationBroadcaster; +import javax.management.NotificationBroadcasterSupport; import javax.management.NotificationEmitter; import javax.management.NotificationFilter; import javax.management.NotificationListener; @@ -75,22 +92,7 @@ import javax.management.ReflectionException; import javax.management.RuntimeErrorException; import javax.management.RuntimeMBeanException; import javax.management.RuntimeOperationsException; - -// JMX RI -import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER; -import com.sun.jmx.mbeanserver.DynamicMBean2; -import com.sun.jmx.mbeanserver.ModifiableClassLoaderRepository; -import com.sun.jmx.mbeanserver.MBeanInstantiator; -import com.sun.jmx.mbeanserver.Repository; -import com.sun.jmx.mbeanserver.NamedObject; -import com.sun.jmx.mbeanserver.Introspector; -import com.sun.jmx.mbeanserver.MBeanInjector; -import com.sun.jmx.mbeanserver.NotifySupport; -import com.sun.jmx.mbeanserver.Repository.RegistrationContext; -import com.sun.jmx.mbeanserver.Util; -import com.sun.jmx.remote.util.EnvHelp; -import javax.management.DynamicWrapperMBean; -import javax.management.NotificationBroadcasterSupport; +import javax.management.namespace.JMXNamespace; /** * This is the default class for MBean manipulation on the agent side. It @@ -113,7 +115,8 @@ import javax.management.NotificationBroadcasterSupport; * * @since 1.5 */ -public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { +public class DefaultMBeanServerInterceptor + extends MBeanServerInterceptorSupport { /** The MBeanInstantiator object used by the * DefaultMBeanServerInterceptor */ @@ -123,7 +126,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { * DefaultMBeanServerInterceptor */ private transient MBeanServer server = null; - /** The MBean server object taht associated to the + /** The MBean server delegate object that is associated to the * DefaultMBeanServerInterceptor */ private final transient MBeanServerDelegate delegate; @@ -138,13 +141,15 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { new WeakHashMap>(); + private final NamespaceDispatchInterceptor dispatcher; + /** The default domain of the object names */ private final String domain; - /** True if the repository perform queries, false otherwise */ - private boolean queryByRepo; + /** The mbeanServerName */ + private final String mbeanServerName; - /** The sequence number identifyng the notifications sent */ + /** The sequence number identifying the notifications sent */ // Now sequence number is handled by MBeanServerDelegate. // private int sequenceNumber=0; @@ -162,11 +167,13 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { * @param instantiator The MBeanInstantiator that will be used to * instantiate MBeans and take care of class loading issues. * @param repository The repository to use for this MBeanServer. + * @param dispatcher The dispatcher used by this MBeanServer */ public DefaultMBeanServerInterceptor(MBeanServer outer, MBeanServerDelegate delegate, MBeanInstantiator instantiator, - Repository repository) { + Repository repository, + NamespaceDispatchInterceptor dispatcher) { if (outer == null) throw new IllegalArgumentException("outer MBeanServer cannot be null"); if (delegate == null) throw new @@ -181,6 +188,8 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { this.instantiator = instantiator; this.repository = repository; this.domain = repository.getDefaultDomain(); + this.dispatcher = dispatcher; + this.mbeanServerName = Util.getMBeanServerSecurityName(delegate); } public ObjectInstance createMBean(String className, ObjectName name) @@ -259,8 +268,8 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { name = nonDefaultDomain(name); } - checkMBeanPermission(className, null, null, "instantiate"); - checkMBeanPermission(className, null, name, "registerMBean"); + checkMBeanPermission(mbeanServerName,className, null, null, "instantiate"); + checkMBeanPermission(mbeanServerName,className, null, name, "registerMBean"); /* Load the appropriate class. */ if (withDefaultLoaderRepository) { @@ -324,7 +333,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { final String infoClassName = getNewMBeanClassName(object); - checkMBeanPermission(infoClassName, null, name, "registerMBean"); + checkMBeanPermission(mbeanServerName,infoClassName, null, name, "registerMBean"); checkMBeanTrustPermission(theClass); return registerObject(infoClassName, object, name); @@ -433,7 +442,8 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { DynamicMBean instance = getMBean(name); // may throw InstanceNotFoundException - checkMBeanPermission(instance, null, name, "unregisterMBean"); + checkMBeanPermission(mbeanServerName, instance, null, name, + "unregisterMBean"); if (instance instanceof MBeanRegistration) preDeregisterInvoke((MBeanRegistration) instance); @@ -453,11 +463,12 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { final ResourceContext context = unregisterFromRepository(resource, instance, name); - - if (instance instanceof MBeanRegistration) - postDeregisterInvoke((MBeanRegistration) instance); - - context.done(); + try { + if (instance instanceof MBeanRegistration) + postDeregisterInvoke(name,(MBeanRegistration) instance); + } finally { + context.done(); + } } public ObjectInstance getObjectInstance(ObjectName name) @@ -466,7 +477,8 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { name = nonDefaultDomain(name); DynamicMBean instance = getMBean(name); - checkMBeanPermission(instance, null, name, "getObjectInstance"); + checkMBeanPermission(mbeanServerName, + instance, null, name, "getObjectInstance"); final String className = getClassName(instance); @@ -478,7 +490,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { if (sm != null) { // Check if the caller has the right to invoke 'queryMBeans' // - checkMBeanPermission((String) null, null, null, "queryMBeans"); + checkMBeanPermission(mbeanServerName,(String) null, null, null, "queryMBeans"); // Perform query without "query". // @@ -491,7 +503,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { new HashSet(list.size()); for (ObjectInstance oi : list) { try { - checkMBeanPermission(oi.getClassName(), null, + checkMBeanPermission(mbeanServerName,oi.getClassName(), null, oi.getObjectName(), "queryMBeans"); allowedList.add(oi); } catch (SecurityException e) { @@ -515,11 +527,6 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { // Set list = repository.query(name, query); - if (queryByRepo) { - // The repository performs the filtering - query = null; - } - return (objectInstancesFromFilteredNamedObjects(list, query)); } @@ -529,7 +536,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { if (sm != null) { // Check if the caller has the right to invoke 'queryNames' // - checkMBeanPermission((String) null, null, null, "queryNames"); + checkMBeanPermission(mbeanServerName,(String) null, null, null, "queryNames"); // Perform query without "query". // @@ -542,7 +549,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { new HashSet(list.size()); for (ObjectInstance oi : list) { try { - checkMBeanPermission(oi.getClassName(), null, + checkMBeanPermission(mbeanServerName, oi.getClassName(), null, oi.getObjectName(), "queryNames"); allowedList.add(oi); } catch (SecurityException e) { @@ -571,11 +578,6 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { // Set list = repository.query(name, query); - if (queryByRepo) { - // The repository performs the filtering - query = null; - } - return (objectNamesFromFilteredNamedObjects(list, query)); } @@ -588,8 +590,8 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { name = nonDefaultDomain(name); -// /* Permission check */ -// checkMBeanPermission(null, null, name, "isRegistered"); + /* No Permission check */ + // isRegistered is always unchecked as per JMX spec. return (repository.contains(name)); } @@ -599,7 +601,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { if (sm != null) { // Check if the caller has the right to invoke 'getDomains' // - checkMBeanPermission((String) null, null, null, "getDomains"); + checkMBeanPermission(mbeanServerName, (String) null, null, null, "getDomains"); // Return domains // @@ -611,8 +613,8 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { List result = new ArrayList(domains.length); for (int i = 0; i < domains.length; i++) { try { - ObjectName domain = Util.newObjectName(domains[i] + ":x=x"); - checkMBeanPermission((String) null, null, domain, "getDomains"); + ObjectName dom = ObjectName.valueOf(domains[i] + ":x=x"); + checkMBeanPermission(mbeanServerName, (String) null, null, dom, "getDomains"); result.add(domains[i]); } catch (SecurityException e) { // OK: Do not add this domain to the list @@ -656,7 +658,8 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { } final DynamicMBean instance = getMBean(name); - checkMBeanPermission(instance, attribute, name, "getAttribute"); + checkMBeanPermission(mbeanServerName, instance, attribute, + name, "getAttribute"); try { return instance.getAttribute(attribute); @@ -701,7 +704,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { // Check if the caller has the right to invoke 'getAttribute' // - checkMBeanPermission(classname, null, name, "getAttribute"); + checkMBeanPermission(mbeanServerName, classname, null, name, "getAttribute"); // Check if the caller has the right to invoke 'getAttribute' // on each specific attribute @@ -710,14 +713,15 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { new ArrayList(attributes.length); for (String attr : attributes) { try { - checkMBeanPermission(classname, attr, + checkMBeanPermission(mbeanServerName, classname, attr, name, "getAttribute"); allowedList.add(attr); } catch (SecurityException e) { // OK: Do not add this attribute to the list } } - allowedAttributes = allowedList.toArray(new String[0]); + allowedAttributes = + allowedList.toArray(new String[allowedList.size()]); } try { @@ -755,7 +759,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { } DynamicMBean instance = getMBean(name); - checkMBeanPermission(instance, attribute.getName(), + checkMBeanPermission(mbeanServerName, instance, attribute.getName(), name, "setAttribute"); try { @@ -798,7 +802,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { // Check if the caller has the right to invoke 'setAttribute' // - checkMBeanPermission(classname, null, name, "setAttribute"); + checkMBeanPermission(mbeanServerName, classname, null, name, "setAttribute"); // Check if the caller has the right to invoke 'setAttribute' // on each specific attribute @@ -807,7 +811,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { for (Iterator i = attributes.iterator(); i.hasNext();) { try { Attribute attribute = (Attribute) i.next(); - checkMBeanPermission(classname, attribute.getName(), + checkMBeanPermission(mbeanServerName, classname, attribute.getName(), name, "setAttribute"); allowedAttributes.add(attribute); } catch (SecurityException e) { @@ -831,7 +835,8 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { name = nonDefaultDomain(name); DynamicMBean instance = getMBean(name); - checkMBeanPermission(instance, operationName, name, "invoke"); + checkMBeanPermission(mbeanServerName, instance, operationName, + name, "invoke"); try { return instance.invoke(operationName, params, signature); } catch (Throwable t) { @@ -933,8 +938,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { "registerMBean", "ObjectName = " + name); } - ObjectName logicalName = name; - logicalName = preRegister(mbean, server, name); + ObjectName logicalName = preRegister(mbean, server, name); // preRegister returned successfully, so from this point on we // must call postRegister(false) if there is any problem. @@ -960,16 +964,17 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { if (logicalName != name && logicalName != null) { logicalName = - ObjectName.getInstance(nonDefaultDomain(logicalName)); + ObjectName.getInstance(nonDefaultDomain(logicalName)); } - checkMBeanPermission(classname, null, logicalName, "registerMBean"); + checkMBeanPermission(mbeanServerName, classname, null, logicalName, + "registerMBean"); if (logicalName == null) { final RuntimeException wrapped = - new IllegalArgumentException("No object name specified"); + new IllegalArgumentException("No object name specified"); throw new RuntimeOperationsException(wrapped, - "Exception occurred trying to register the MBean"); + "Exception occurred trying to register the MBean"); } final Object resource = getResource(mbean); @@ -986,32 +991,35 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { // context = registerWithRepository(resource, mbean, logicalName); + registerFailed = false; registered = true; - } finally { - postRegister(mbean, registered, registerFailed); - } - context.done(); + } finally { + try { + postRegister(logicalName, mbean, registered, registerFailed); + } finally { + if (registered && context!=null) context.done(); + } + } return new ObjectInstance(logicalName, classname); } private static void throwMBeanRegistrationException(Throwable t, String where) throws MBeanRegistrationException { - try { - throw t; - } catch (RuntimeException e) { - throw new RuntimeMBeanException( - e, "RuntimeException thrown " + where); - } catch (Error er) { - throw new RuntimeErrorException(er, "Error thrown " + where); - } catch (MBeanRegistrationException r) { - throw r; - } catch (Exception ex) { - throw new MBeanRegistrationException(ex, "Exception thrown " + where); - } catch (Throwable t1) { - throw new RuntimeException(t); // neither Error nor Exception?? - } + if (t instanceof RuntimeException) { + throw new RuntimeMBeanException((RuntimeException)t, + "RuntimeException thrown " + where); + } else if (t instanceof Error) { + throw new RuntimeErrorException((Error)t, + "Error thrown " + where); + } else if (t instanceof MBeanRegistrationException) { + throw (MBeanRegistrationException)t; + } else if (t instanceof Exception) { + throw new MBeanRegistrationException((Exception)t, + "Exception thrown " + where); + } else // neither Error nor Exception?? + throw new RuntimeException(t); } private static ObjectName preRegister( @@ -1051,7 +1059,8 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { } private static void postRegister( - DynamicMBean mbean, boolean registrationDone, boolean registerFailed) { + ObjectName logicalName, DynamicMBean mbean, + boolean registrationDone, boolean registerFailed) { if (registerFailed && mbean instanceof DynamicMBean2) ((DynamicMBean2) mbean).registerFailed(); @@ -1059,11 +1068,19 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { if (mbean instanceof MBeanRegistration) ((MBeanRegistration) mbean).postRegister(registrationDone); } catch (RuntimeException e) { + MBEANSERVER_LOGGER.fine("While registering MBean ["+logicalName+ + "]: " + "Exception thrown by postRegister: " + + "rethrowing <"+e+">, but keeping the MBean registered"); throw new RuntimeMBeanException(e, - "RuntimeException thrown in postRegister method"); + "RuntimeException thrown in postRegister method: "+ + "rethrowing <"+e+">, but keeping the MBean registered"); } catch (Error er) { + MBEANSERVER_LOGGER.fine("While registering MBean ["+logicalName+ + "]: " + "Error thrown by postRegister: " + + "rethrowing <"+er+">, but keeping the MBean registered"); throw new RuntimeErrorException(er, - "Error thrown in postRegister method"); + "Error thrown in postRegister method: "+ + "rethrowing <"+er+">, but keeping the MBean registered"); } } @@ -1076,15 +1093,28 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { } } - private static void postDeregisterInvoke(MBeanRegistration moi) { + private static void postDeregisterInvoke(ObjectName mbean, + MBeanRegistration moi) { try { moi.postDeregister(); } catch (RuntimeException e) { + MBEANSERVER_LOGGER.fine("While unregistering MBean ["+mbean+ + "]: " + "Exception thrown by postDeregister: " + + "rethrowing <"+e+">, although the MBean is succesfully " + + "unregistered"); throw new RuntimeMBeanException(e, - "RuntimeException thrown in postDeregister method"); + "RuntimeException thrown in postDeregister method: "+ + "rethrowing <"+e+ + ">, although the MBean is sucessfully unregistered"); } catch (Error er) { + MBEANSERVER_LOGGER.fine("While unregistering MBean ["+mbean+ + "]: " + "Error thrown by postDeregister: " + + "rethrowing <"+er+">, although the MBean is succesfully " + + "unregistered"); throw new RuntimeErrorException(er, - "Error thrown in postDeregister method"); + "Error thrown in postDeregister method: "+ + "rethrowing <"+er+ + ">, although the MBean is sucessfully unregistered"); } } @@ -1139,7 +1169,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { if one is supplied where it shouldn't be). */ final String completeName = domain + name; - return Util.newObjectName(completeName); + return ObjectName.valueOf(completeName); } public String getDefaultDomain() { @@ -1205,7 +1235,8 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { } DynamicMBean instance = getMBean(name); - checkMBeanPermission(instance, null, name, "addNotificationListener"); + checkMBeanPermission(mbeanServerName, instance, null, + name, "addNotificationListener"); NotificationBroadcaster broadcaster = getNotificationBroadcaster(name, instance, @@ -1342,7 +1373,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { } DynamicMBean instance = getMBean(name); - checkMBeanPermission(instance, null, name, + checkMBeanPermission(mbeanServerName, instance, null, name, "removeNotificationListener"); /* We could simplify the code by assigning broadcaster after @@ -1413,7 +1444,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { throw new JMRuntimeException("MBean " + name + "has no MBeanInfo"); - checkMBeanPermission(mbi.getClassName(), null, name, "getMBeanInfo"); + checkMBeanPermission(mbeanServerName, mbi.getClassName(), null, name, "getMBeanInfo"); return mbi; } @@ -1421,8 +1452,9 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { public boolean isInstanceOf(ObjectName name, String className) throws InstanceNotFoundException { - DynamicMBean instance = getMBean(name); - checkMBeanPermission(instance, null, name, "isInstanceOf"); + final DynamicMBean instance = getMBean(name); + checkMBeanPermission(mbeanServerName, + instance, null, name, "isInstanceOf"); try { Object resource = getResource(instance); @@ -1473,7 +1505,8 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { throws InstanceNotFoundException { DynamicMBean instance = getMBean(mbeanName); - checkMBeanPermission(instance, null, mbeanName, "getClassLoaderFor"); + checkMBeanPermission(mbeanServerName, instance, null, mbeanName, + "getClassLoaderFor"); return getResourceLoader(instance); } @@ -1488,12 +1521,13 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { throws InstanceNotFoundException { if (loaderName == null) { - checkMBeanPermission((String) null, null, null, "getClassLoader"); + checkMBeanPermission(mbeanServerName, (String) null, null, null, "getClassLoader"); return server.getClass().getClassLoader(); } DynamicMBean instance = getMBean(loaderName); - checkMBeanPermission(instance, null, loaderName, "getClassLoader"); + checkMBeanPermission(mbeanServerName, instance, null, loaderName, + "getClassLoader"); Object resource = getResource(instance); @@ -1543,7 +1577,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { } } else { // Access the filter - MBeanServer oldServer = QueryEval.getMBeanServer(); + final MBeanServer oldServer = QueryEval.getMBeanServer(); query.setMBeanServer(server); try { for (NamedObject no : list) { @@ -1792,26 +1826,30 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { return mbean.getMBeanInfo().getClassName(); } - private static void checkMBeanPermission(DynamicMBean mbean, + private static void checkMBeanPermission(String mbeanServerName, + DynamicMBean mbean, String member, ObjectName objectName, String actions) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { - checkMBeanPermission(safeGetClassName(mbean), + checkMBeanPermission(mbeanServerName, + safeGetClassName(mbean), member, objectName, actions); } } - private static void checkMBeanPermission(String classname, + private static void checkMBeanPermission(String mbeanServerName, + String classname, String member, ObjectName objectName, String actions) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { - Permission perm = new MBeanPermission(classname, + Permission perm = new MBeanPermission(mbeanServerName, + classname, member, objectName, actions); @@ -1877,6 +1915,12 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { throws InstanceAlreadyExistsException, MBeanRegistrationException { + // this will throw an exception if the pair (resource, logicalName) + // violates namespace conventions - for instance, if logicalName + // ends with // but resource is not a JMXNamespace. + // + checkResourceObjectNameConstraints(resource, logicalName); + // Creates a registration context, if needed. // final ResourceContext context = @@ -1942,6 +1986,57 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { return context; } + + /** + * Checks that the ObjectName is legal with regards to the + * type of the MBean resource. + * If the MBean name is domain:type=JMXDomain, the + * MBean must be a JMXDomain. + * If the MBean name is namespace//:type=JMXNamespace, the + * MBean must be a JMXNamespace. + * If the MBean is a JMXDomain, its name + * must be domain:type=JMXDomain. + * If the MBean is a JMXNamespace, its name + * must be namespace//:type=JMXNamespace. + */ + private void checkResourceObjectNameConstraints(Object resource, + ObjectName logicalName) + throws MBeanRegistrationException { + try { + dispatcher.checkLocallyRegistrable(resource, logicalName); + } catch (Throwable x) { + DefaultMBeanServerInterceptor.throwMBeanRegistrationException(x, "validating ObjectName"); + } + } + + /** + * Registers a JMXNamespace with the dispatcher. + * This method is called by the ResourceContext from within the + * repository lock. + * @param namespace The JMXNamespace + * @param logicalName The JMXNamespaceMBean ObjectName + * @param postQueue A queue that will be processed after postRegister. + */ + private void addJMXNamespace(JMXNamespace namespace, + final ObjectName logicalName, + final Queue postQueue) { + dispatcher.addInterceptorFor(logicalName, namespace, postQueue); + } + + /** + * Unregisters a JMXNamespace from the dispatcher. + * This method is called by the ResourceContext from within the + * repository lock. + * @param namespace The JMXNamespace + * @param logicalName The JMXNamespaceMBean ObjectName + * @param postQueue A queue that will be processed after postDeregister. + */ + private void removeJMXNamespace(JMXNamespace namespace, + final ObjectName logicalName, + final Queue postQueue) { + dispatcher.removeInterceptorFor(logicalName, namespace, postQueue); + } + /** * Registers a ClassLoader with the CLR. * This method is called by the ResourceContext from within the @@ -1995,6 +2090,52 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { } } + + /** + * Creates a ResourceContext for a JMXNamespace MBean. + * The resource context makes it possible to add the JMXNamespace to + * (ResourceContext.registering) or resp. remove the JMXNamespace from + * (ResourceContext.unregistered) the NamespaceDispatchInterceptor + * when the associated MBean is added to or resp. removed from the + * repository. + * Note: JMXDomains are special sub classes of JMXNamespaces and + * are also handled by this object. + * + * @param namespace The JMXNamespace MBean being registered or + * unregistered. + * @param logicalName The name of the JMXNamespace MBean. + * @return a ResourceContext that takes in charge the addition or removal + * of the namespace to or from the NamespaceDispatchInterceptor. + */ + private ResourceContext createJMXNamespaceContext( + final JMXNamespace namespace, + final ObjectName logicalName) { + final Queue doneTaskQueue = new LinkedList(); + return new ResourceContext() { + + public void registering() { + addJMXNamespace(namespace, logicalName, doneTaskQueue); + } + + public void unregistered() { + removeJMXNamespace(namespace, logicalName, + doneTaskQueue); + } + + public void done() { + for (Runnable r : doneTaskQueue) { + try { + r.run(); + } catch (RuntimeException x) { + MBEANSERVER_LOGGER.log(Level.FINE, + "Failed to process post queue for "+ + logicalName, x); + } + } + } + }; + } + /** * Creates a ResourceContext for a ClassLoader MBean. * The resource context makes it possible to add the ClassLoader to @@ -2040,10 +2181,16 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { */ private ResourceContext makeResourceContextFor(Object resource, ObjectName logicalName) { + if (resource instanceof JMXNamespace) { + return createJMXNamespaceContext((JMXNamespace) resource, + logicalName); + } if (resource instanceof ClassLoader) { return createClassLoaderContext((ClassLoader) resource, logicalName); } return ResourceContext.NONE; } + + } diff --git a/jdk/src/share/classes/com/sun/jmx/interceptor/DispatchInterceptor.java b/jdk/src/share/classes/com/sun/jmx/interceptor/DispatchInterceptor.java new file mode 100644 index 00000000000..4a79567fed1 --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/interceptor/DispatchInterceptor.java @@ -0,0 +1,557 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.interceptor; + + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Queue; +import java.util.Set; + +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.AttributeNotFoundException; +import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; +import javax.management.IntrospectionException; +import javax.management.InvalidAttributeValueException; +import javax.management.ListenerNotFoundException; +import javax.management.MBeanException; +import javax.management.MBeanInfo; +import javax.management.MBeanRegistrationException; +import javax.management.MBeanServer; +import javax.management.MalformedObjectNameException; +import javax.management.NotCompliantMBeanException; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.ObjectInstance; +import javax.management.ObjectName; +import javax.management.QueryExp; +import javax.management.ReflectionException; +import javax.management.namespace.JMXNamespace; + +/** + * A dispatcher that dispatches to MBeanServers. + *

    + * This API is a Sun internal API and is subject to changes without notice. + *

    + * @since 1.7 + */ +// +// This is the base class for implementing dispatchers. We have two concrete +// dispatcher implementations: +// +// * A NamespaceDispatchInterceptor, which dispatch calls to existing +// namespace interceptors +// * A DomainDispatchInterceptor, which dispatch calls to existing domain +// interceptors. +// +// With the JMX Namespaces feature, the JMX MBeanServer is now structured +// as follows: +// +// The JMX MBeanServer delegates to a NamespaceDispatchInterceptor, +// which either dispatches to a namespace, or delegates to the +// DomainDispatchInterceptor (if the object name contained no namespace). +// The DomainDispatchInterceptor in turn either dispatches to a domain (if +// there is a JMXDomain for that domain) or delegates to the +// DefaultMBeanServerInterceptor (if there is no JMXDomain for that +// domain). This makes the following picture: +// +// JMX MBeanServer (outer shell) +// | +// | +// NamespaceDispatchInterceptor +// / \ +// no namespace in object name? \ +// / \ +// / dispatch to namespace +// DomainDispatchInterceptor +// / \ +// no JMXDomain for domain? \ +// / \ +// / dispatch to domain +// DefaultMBeanServerInterceptor +// / +// invoke locally registered MBean +// +// The logic for maintaining a map of interceptors +// and dispatching to impacted interceptor, is implemented in this +// base class, which both NamespaceDispatchInterceptor and +// DomainDispatchInterceptor extend. +// +public abstract class DispatchInterceptor + + extends MBeanServerInterceptorSupport { + + /** + * This is an abstraction which allows us to handle queryNames + * and queryMBeans with the same algorithm. There are some subclasses + * where we need to override both queryNames & queryMBeans to apply + * the same transformation (usually aggregation of results when + * several namespaces/domains are impacted) to both algorithms. + * Usually the only thing that varies between the algorithm of + * queryNames & the algorithm of queryMBean is the type of objects + * in the returned Set. By using a QueryInvoker we can implement the + * transformation only once and apply it to both queryNames & + * queryMBeans. + * @see QueryInterceptor below, and its subclass in + * {@link DomainDispatcher}. + **/ + static abstract class QueryInvoker { + abstract Set query(MBeanServer mbs, + ObjectName pattern, QueryExp query); + } + + /** + * Used to perform queryNames. A QueryInvoker that invokes + * queryNames on an MBeanServer. + **/ + final static QueryInvoker queryNamesInvoker = + new QueryInvoker() { + Set query(MBeanServer mbs, + ObjectName pattern, QueryExp query) { + return mbs.queryNames(pattern,query); + } + }; + + /** + * Used to perform queryMBeans. A QueryInvoker that invokes + * queryMBeans on an MBeanServer. + **/ + final static QueryInvoker queryMBeansInvoker = + new QueryInvoker() { + Set query(MBeanServer mbs, + ObjectName pattern, QueryExp query) { + return mbs.queryMBeans(pattern,query); + } + }; + + /** + * We use this class to intercept queries. + * There's a special case for JMXNamespace MBeans, because + * "namespace//*:*" matches both "namespace//domain:k=v" and + * "namespace//:type=JMXNamespace". + * Therefore, queries may need to be forwarded to more than + * on interceptor and the results aggregated... + */ + static class QueryInterceptor { + final MBeanServer wrapped; + QueryInterceptor(MBeanServer mbs) { + wrapped = mbs; + } + Set query(ObjectName pattern, QueryExp query, + QueryInvoker invoker, MBeanServer server) { + return invoker.query(server, pattern, query); + } + + public Set queryNames(ObjectName pattern, QueryExp query) { + return query(pattern,query,queryNamesInvoker,wrapped); + } + + public Set queryMBeans(ObjectName pattern, + QueryExp query) { + return query(pattern,query,queryMBeansInvoker,wrapped); + } + } + + // We don't need a ConcurrentHashMap here because getkeys() returns + // an array of keys. Therefore there's no risk to have a + // ConcurrentModificationException. We must however take into + // account the fact that there can be no interceptor for + // some of the returned keys if the map is being modified by + // another thread, or by a callback within the same thread... + // See getKeys() in this class and query() in DomainDispatcher. + // + private final Map handlerMap = + Collections.synchronizedMap( + new HashMap()); + + // The key at which an interceptor for accessing the named MBean can be + // found in the handlerMap. Note: there doesn't need to be an interceptor + // for that key in the Map. + // + abstract String getHandlerKey(ObjectName name); + + // Returns an interceptor for that name, or null if there's no interceptor + // for that name. + abstract MBeanServer getInterceptorOrNullFor(ObjectName name); + + // Returns a QueryInterceptor for that pattern. + abstract QueryInterceptor getInterceptorForQuery(ObjectName pattern); + + // Returns the ObjectName of the JMXNamespace (or JMXDomain) for that + // key (a namespace or a domain name). + abstract ObjectName getHandlerNameFor(String key) + throws MalformedObjectNameException; + + // Creates an interceptor for the given key, name, JMXNamespace (or + // JMXDomain). Note: this will be either a NamespaceInterceptor + // wrapping a JMXNamespace, if this object is an instance of + // NamespaceDispatchInterceptor, or a DomainInterceptor wrapping a + // JMXDomain, if this object is an instance of DomainDispatchInterceptor. + abstract T createInterceptorFor(String key, ObjectName name, + N jmxNamespace, Queue postRegisterQueue); + // + // The next interceptor in the chain. + // + // For the NamespaceDispatchInterceptor, this the DomainDispatchInterceptor. + // For the DomainDispatchInterceptor, this is the + // DefaultMBeanServerInterceptor. + // + // The logic of when to invoke the next interceptor in the chain depends + // on the logic of the concrete dispatcher class. + // + // For instance, the NamespaceDispatchInterceptor invokes the next + // interceptor when the object name doesn't contain any namespace. + // + // On the other hand, the DomainDispatchInterceptor invokes the + // next interceptor when there's no interceptor for the accessed domain. + // + abstract MBeanServer getNextInterceptor(); + + // hook for cleanup in subclasses. + void interceptorReleased(T interceptor, + Queue postDeregisterQueue) { + // hook + } + + // Hook for subclasses. + MBeanServer getInterceptorForCreate(ObjectName name) + throws MBeanRegistrationException { + final MBeanServer ns = getInterceptorOrNullFor(name); + if (ns == null) // name cannot be null here. + throw new MBeanRegistrationException( + new IllegalArgumentException("No such MBean handler: " + + getHandlerKey(name) + " for " +name)); + return ns; + } + + // Hook for subclasses. + MBeanServer getInterceptorForInstance(ObjectName name) + throws InstanceNotFoundException { + final MBeanServer ns = getInterceptorOrNullFor(name); + if (ns == null) // name cannot be null here. + throw new InstanceNotFoundException(String.valueOf(name)); + return ns; + } + + // sanity checks + void validateHandlerNameFor(String key, ObjectName name) { + if (key == null || key.equals("")) + throw new IllegalArgumentException("invalid key for "+name+": "+key); + try { + final ObjectName handlerName = getHandlerNameFor(key); + if (!name.equals(handlerName)) + throw new IllegalArgumentException("bad handler name: "+name+ + ". Should be: "+handlerName); + } catch (MalformedObjectNameException x) { + throw new IllegalArgumentException(name.toString(),x); + } + } + + // Called by the DefaultMBeanServerInterceptor when an instance + // of JMXNamespace (or a subclass of it) is registered as an MBean. + // This method is usually invoked from within the repository lock, + // hence the necessity of the postRegisterQueue. + public void addInterceptorFor(ObjectName name, N jmxNamespace, + Queue postRegisterQueue) { + final String key = getHandlerKey(name); + validateHandlerNameFor(key,name); + synchronized (handlerMap) { + final T exists = + handlerMap.get(key); + if (exists != null) + throw new IllegalArgumentException(key+ + ": handler already exists"); + + final T ns = createInterceptorFor(key,name,jmxNamespace, + postRegisterQueue); + handlerMap.put(key,ns); + } + } + + // Called by the DefaultMBeanServerInterceptor when an instance + // of JMXNamespace (or a subclass of it) is deregistered. + // This method is usually invoked from within the repository lock, + // hence the necessity of the postDeregisterQueue. + public void removeInterceptorFor(ObjectName name, N jmxNamespace, + Queue postDeregisterQueue) { + final String key = getHandlerKey(name); + final T ns; + synchronized(handlerMap) { + ns = handlerMap.remove(key); + } + interceptorReleased(ns,postDeregisterQueue); + } + + // Get the interceptor for that key. + T getInterceptor(String key) { + synchronized (handlerMap) { + return handlerMap.get(key); + } + } + + // We return an array of keys, which makes it possible to make + // concurrent modifications of the handlerMap, provided that + // the code which loops over the keys is prepared to handle null + // interceptors. + // See declaration of handlerMap above, and see also query() in + // DomainDispatcher + // + public String[] getKeys() { + synchronized (handlerMap) { + final int size = handlerMap.size(); + return handlerMap.keySet().toArray(new String[size]); + } + } + + // From MBeanServer + public final ObjectInstance createMBean(String className, ObjectName name) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException { + return getInterceptorForCreate(name).createMBean(className,name); + } + + // From MBeanServer + public final ObjectInstance createMBean(String className, ObjectName name, + ObjectName loaderName) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, InstanceNotFoundException{ + return getInterceptorForCreate(name).createMBean(className,name,loaderName); + } + + // From MBeanServer + public final ObjectInstance createMBean(String className, ObjectName name, + Object params[], String signature[]) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException{ + return getInterceptorForCreate(name). + createMBean(className,name,params,signature); + } + + // From MBeanServer + public final ObjectInstance createMBean(String className, ObjectName name, + ObjectName loaderName, Object params[], + String signature[]) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, InstanceNotFoundException{ + return getInterceptorForCreate(name).createMBean(className,name,loaderName, + params,signature); + } + + // From MBeanServer + public final ObjectInstance registerMBean(Object object, ObjectName name) + throws InstanceAlreadyExistsException, MBeanRegistrationException, + NotCompliantMBeanException { + return getInterceptorForCreate(name).registerMBean(object,name); + } + + // From MBeanServer + public final void unregisterMBean(ObjectName name) + throws InstanceNotFoundException, MBeanRegistrationException { + getInterceptorForInstance(name).unregisterMBean(name); + } + + // From MBeanServer + public final ObjectInstance getObjectInstance(ObjectName name) + throws InstanceNotFoundException { + return getInterceptorForInstance(name).getObjectInstance(name); + } + + // From MBeanServer + public final Set queryMBeans(ObjectName name, + QueryExp query) { + final QueryInterceptor queryInvoker = + getInterceptorForQuery(name); + if (queryInvoker == null) return Collections.emptySet(); + else return queryInvoker.queryMBeans(name,query); + } + + // From MBeanServer + public final Set queryNames(ObjectName name, QueryExp query) { + final QueryInterceptor queryInvoker = + getInterceptorForQuery(name); + if (queryInvoker == null) return Collections.emptySet(); + else return queryInvoker.queryNames(name,query); + } + + // From MBeanServer + public final boolean isRegistered(ObjectName name) { + final MBeanServer mbs = getInterceptorOrNullFor(name); + if (mbs == null) return false; + else return mbs.isRegistered(name); + } + + // From MBeanServer + public Integer getMBeanCount() { + return getNextInterceptor().getMBeanCount(); + } + + // From MBeanServer + public final Object getAttribute(ObjectName name, String attribute) + throws MBeanException, AttributeNotFoundException, + InstanceNotFoundException, ReflectionException { + return getInterceptorForInstance(name).getAttribute(name,attribute); + } + + // From MBeanServer + public final AttributeList getAttributes(ObjectName name, + String[] attributes) + throws InstanceNotFoundException, ReflectionException { + return getInterceptorForInstance(name).getAttributes(name,attributes); + } + + // From MBeanServer + public final void setAttribute(ObjectName name, Attribute attribute) + throws InstanceNotFoundException, AttributeNotFoundException, + InvalidAttributeValueException, MBeanException, + ReflectionException { + getInterceptorForInstance(name).setAttribute(name,attribute); + } + + // From MBeanServer + public final AttributeList setAttributes(ObjectName name, + AttributeList attributes) + throws InstanceNotFoundException, ReflectionException { + return getInterceptorForInstance(name).setAttributes(name,attributes); + } + + // From MBeanServer + public final Object invoke(ObjectName name, String operationName, + Object params[], String signature[]) + throws InstanceNotFoundException, MBeanException, + ReflectionException { + return getInterceptorForInstance(name).invoke(name,operationName,params, + signature); + } + + // From MBeanServer + public String getDefaultDomain() { + return getNextInterceptor().getDefaultDomain(); + } + + /** + * Returns the list of domains in which any MBean is currently + * registered. + */ + public abstract String[] getDomains(); + + // From MBeanServer + public final void addNotificationListener(ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException { + getInterceptorForInstance(name). + addNotificationListener(name,listener,filter, + handback); + } + + + // From MBeanServer + public final void addNotificationListener(ObjectName name, + ObjectName listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException { + getInterceptorForInstance(name). + addNotificationListener(name,listener,filter, + handback); + } + + // From MBeanServer + public final void removeNotificationListener(ObjectName name, + ObjectName listener) + throws InstanceNotFoundException, ListenerNotFoundException { + getInterceptorForInstance(name). + removeNotificationListener(name,listener); + } + + // From MBeanServer + public final void removeNotificationListener(ObjectName name, + ObjectName listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException, ListenerNotFoundException { + getInterceptorForInstance(name). + removeNotificationListener(name,listener,filter, + handback); + } + + + // From MBeanServer + public final void removeNotificationListener(ObjectName name, + NotificationListener listener) + throws InstanceNotFoundException, ListenerNotFoundException { + getInterceptorForInstance(name). + removeNotificationListener(name,listener); + } + + // From MBeanServer + public final void removeNotificationListener(ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException, ListenerNotFoundException { + getInterceptorForInstance(name). + removeNotificationListener(name,listener,filter, + handback); + } + + // From MBeanServer + public final MBeanInfo getMBeanInfo(ObjectName name) + throws InstanceNotFoundException, IntrospectionException, + ReflectionException { + return getInterceptorForInstance(name).getMBeanInfo(name); + } + + + // From MBeanServer + public final boolean isInstanceOf(ObjectName name, String className) + throws InstanceNotFoundException { + return getInterceptorForInstance(name).isInstanceOf(name,className); + } + + // From MBeanServer + public final ClassLoader getClassLoaderFor(ObjectName mbeanName) + throws InstanceNotFoundException { + return getInterceptorForInstance(mbeanName). + getClassLoaderFor(mbeanName); + } + + // From MBeanServer + public final ClassLoader getClassLoader(ObjectName loaderName) + throws InstanceNotFoundException { + return getInterceptorForInstance(loaderName). + getClassLoader(loaderName); + } + +} diff --git a/jdk/src/share/classes/com/sun/jmx/interceptor/DomainDispatchInterceptor.java b/jdk/src/share/classes/com/sun/jmx/interceptor/DomainDispatchInterceptor.java new file mode 100644 index 00000000000..9b9b1d6b19c --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/interceptor/DomainDispatchInterceptor.java @@ -0,0 +1,356 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.interceptor; + +import com.sun.jmx.defaults.JmxProperties; +import com.sun.jmx.mbeanserver.MBeanInstantiator; +import com.sun.jmx.mbeanserver.Repository; +import com.sun.jmx.mbeanserver.Util; +import com.sun.jmx.namespace.DomainInterceptor; +import java.util.Queue; +import java.util.Set; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.management.MBeanServer; +import javax.management.MBeanServerDelegate; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; +import javax.management.QueryExp; +import javax.management.namespace.JMXDomain; +import static javax.management.namespace.JMXNamespaces.NAMESPACE_SEPARATOR; + +/** + * A dispatcher that dispatch incoming MBeanServer requests to + * DomainInterceptors. + *

    + * This API is a Sun internal API and is subject to changes without notice. + *

    + * @since 1.7 + */ +// +// See comments in DispatchInterceptor. +// +class DomainDispatchInterceptor + extends DispatchInterceptor { + + /** + * A logger for this class. + **/ + private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER; + + private static final ObjectName ALL_DOMAINS = + JMXDomain.getDomainObjectName("*"); + + + /** + * A QueryInterceptor that perform & aggregates queries spanning several + * domains. + */ + final static class AggregatingQueryInterceptor extends QueryInterceptor { + + private final DomainDispatchInterceptor parent; + AggregatingQueryInterceptor(DomainDispatchInterceptor dispatcher) { + super(dispatcher.nextInterceptor); + parent = dispatcher; + } + + /** + * Perform queryNames or queryMBeans, depending on which QueryInvoker + * is passed as argument. This is closures without closures. + **/ + @Override + Set query(ObjectName pattern, QueryExp query, + QueryInvoker invoker, MBeanServer localNamespace) { + final Set local = invoker.query(localNamespace, pattern, query); + + // Add all matching MBeans from local namespace. + final Set res = Util.cloneSet(local); + + if (pattern == null) pattern = ObjectName.WILDCARD; + final boolean all = pattern.getDomain().equals("*"); + + final String domain = pattern.getDomain(); + + // If there's no domain pattern, just include the pattern's domain. + // Otherwiae, loop over all virtual domains (parent.getKeys()). + final String[] keys = + (pattern.isDomainPattern() ? + parent.getKeys() : new String[]{domain}); + + // Add all matching MBeans from each virtual domain + // + for (String key : keys) { + // Only invoke those virtual domain which are selected + // by the domain pattern + // + if (!all && !Util.isDomainSelected(key, domain)) + continue; + + try { + final MBeanServer mbs = parent.getInterceptor(key); + + // mbs can be null if the interceptor was removed + // concurrently... + // See handlerMap and getKeys() in DispatchInterceptor + // + if (mbs == null) continue; + + // If the domain is selected, we can replace the pattern + // by the actual domain. This is safer if we want to avoid + // a domain (which could be backed up by an MBeanServer) to + // return names from outside the domain. + // So instead of asking the domain handler for "foo" to + // return all names which match "?o*:type=Bla,*" we're + // going to ask it to return all names which match + // "foo:type=Bla,*" + // + final ObjectName subPattern = pattern.withDomain(key); + res.addAll(invoker.query(mbs, subPattern, query)); + } catch (Exception x) { + LOG.finest("Ignoring exception " + + "when attempting to query namespace "+key+": "+x); + continue; + } + } + return res; + } + } + + private final DefaultMBeanServerInterceptor nextInterceptor; + private final String mbeanServerName; + private final MBeanServerDelegate delegate; + + /** + * Creates a DomainDispatchInterceptor with the specified + * repository instance. + * + * @param outer A pointer to the MBeanServer object that must be + * passed to the MBeans when invoking their + * {@link javax.management.MBeanRegistration} interface. + * @param delegate A pointer to the MBeanServerDelegate associated + * with the new MBeanServer. The new MBeanServer must register + * this MBean in its MBean repository. + * @param instantiator The MBeanInstantiator that will be used to + * instantiate MBeans and take care of class loading issues. + * @param repository The repository to use for this MBeanServer + */ + public DomainDispatchInterceptor(MBeanServer outer, + MBeanServerDelegate delegate, + MBeanInstantiator instantiator, + Repository repository, + NamespaceDispatchInterceptor namespaces) { + nextInterceptor = new DefaultMBeanServerInterceptor(outer, + delegate, instantiator,repository,namespaces); + mbeanServerName = Util.getMBeanServerSecurityName(delegate); + this.delegate = delegate; + } + + final boolean isLocalHandlerNameFor(String domain, + ObjectName handlerName) { + if (domain == null) return true; + return handlerName.getDomain().equals(domain) && + JMXDomain.TYPE_ASSIGNMENT.equals( + handlerName.getKeyPropertyListString()); + } + + @Override + void validateHandlerNameFor(String key, ObjectName name) { + super.validateHandlerNameFor(key,name); + final String[] domains = nextInterceptor.getDomains(); + for (int i=0;i postRegisterQueue) { + final DomainInterceptor ns = + new DomainInterceptor(mbeanServerName,handler,key); + ns.addPostRegisterTask(postRegisterQueue, delegate); + if (LOG.isLoggable(Level.FINER)) { + LOG.finer("DomainInterceptor created: "+ns); + } + return ns; + } + + @Override + final void interceptorReleased(DomainInterceptor interceptor, + Queue postDeregisterQueue) { + interceptor.addPostDeregisterTask(postDeregisterQueue, delegate); + } + + @Override + final DefaultMBeanServerInterceptor getNextInterceptor() { + return nextInterceptor; + } + + /** + * Returns the list of domains in which any MBean is currently + * registered. + */ + @Override + public String[] getDomains() { + // A JMXDomain is registered in its own domain. + // Therefore, nextInterceptor.getDomains() contains all domains. + // In addition, nextInterceptor will perform the necessary + // MBeanPermission checks for getDomains(). + // + return nextInterceptor.getDomains(); + } + + /** + * Returns the number of MBeans registered in the MBean server. + */ + @Override + public Integer getMBeanCount() { + int count = getNextInterceptor().getMBeanCount(); + final String[] keys = getKeys(); + for (String key:keys) { + final MBeanServer mbs = getInterceptor(key); + if (mbs == null) continue; + count += mbs.getMBeanCount(); + } + return count; + } +} diff --git a/jdk/src/share/classes/com/sun/jmx/interceptor/MBeanServerInterceptor.java b/jdk/src/share/classes/com/sun/jmx/interceptor/MBeanServerInterceptor.java index c0a1844f0cc..7b2d836a621 100644 --- a/jdk/src/share/classes/com/sun/jmx/interceptor/MBeanServerInterceptor.java +++ b/jdk/src/share/classes/com/sun/jmx/interceptor/MBeanServerInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,35 +25,14 @@ package com.sun.jmx.interceptor; -import java.util.Set; -// RI import -import javax.management.DynamicMBean; -import javax.management.AttributeNotFoundException; -import javax.management.MBeanException; -import javax.management.ReflectionException; -import javax.management.MBeanAttributeInfo; -import javax.management.MBeanInfo; -import javax.management.QueryExp; -import javax.management.NotificationListener; -import javax.management.NotificationFilter; -import javax.management.ListenerNotFoundException; -import javax.management.IntrospectionException; -import javax.management.OperationsException; -import javax.management.MBeanNotificationInfo; -import javax.management.JMRuntimeException; +import java.io.ObjectInputStream; import javax.management.InstanceNotFoundException; -import javax.management.NotCompliantMBeanException; -import javax.management.MBeanRegistrationException; -import javax.management.InstanceAlreadyExistsException; -import javax.management.InvalidAttributeValueException; +import javax.management.MBeanException; +import javax.management.MBeanServer; import javax.management.ObjectName; -import javax.management.ObjectInstance; -import javax.management.Attribute; -import javax.management.AttributeList; -import javax.management.RuntimeOperationsException; -import javax.management.MBeanServerConnection; -import javax.management.MBeanServerDelegate; +import javax.management.OperationsException; +import javax.management.ReflectionException; import javax.management.loading.ClassLoaderRepository; /** @@ -85,618 +64,67 @@ import javax.management.loading.ClassLoaderRepository; * * @since 1.5 */ -public interface MBeanServerInterceptor extends MBeanServerConnection { +public interface MBeanServerInterceptor extends MBeanServer { /** - * Instantiates and registers an MBean in the MBean server. The - * MBean server will use its {@link - * javax.management.loading.ClassLoaderRepository Default Loader - * Repository} to load the class of the MBean. An object name is - * associated to the MBean. If the object name given is null, the - * MBean must provide its own name by implementing the {@link - * javax.management.MBeanRegistration MBeanRegistration} interface - * and returning the name from the {@link - * javax.management.MBeanRegistration#preRegister preRegister} method. - * - * @param className The class name of the MBean to be instantiated. - * @param name The object name of the MBean. May be null. - * @param params An array containing the parameters of the - * constructor to be invoked. - * @param signature An array containing the signature of the - * constructor to be invoked. - * - * @return An ObjectInstance, containing the - * ObjectName and the Java class name of the newly - * instantiated MBean. - * - * @exception ReflectionException Wraps a - * java.lang.ClassNotFoundException or a - * java.lang.Exception that occurred when trying to - * invoke the MBean's constructor. - * @exception InstanceAlreadyExistsException The MBean is already - * under the control of the MBean server. - * @exception MBeanRegistrationException The - * preRegister (MBeanRegistration - * interface) method of the MBean has thrown an exception. The - * MBean will not be registered. - * @exception MBeanException The constructor of the MBean has - * thrown an exception - * @exception RuntimeOperationsException Wraps a - * java.lang.IllegalArgumentException: The className - * passed in parameter is null, the ObjectName passed - * in parameter contains a pattern or no ObjectName - * is specified for the MBean. + * This method should never be called. + * Usually hrows UnsupportedOperationException. */ - public ObjectInstance createMBean(String className, ObjectName name, - Object params[], String signature[]) - throws ReflectionException, InstanceAlreadyExistsException, - MBeanRegistrationException, MBeanException, - NotCompliantMBeanException; + public Object instantiate(String className) + throws ReflectionException, MBeanException; + /** + * This method should never be called. + * Usually throws UnsupportedOperationException. + */ + public Object instantiate(String className, ObjectName loaderName) + throws ReflectionException, MBeanException, + InstanceNotFoundException; + /** + * This method should never be called. + * Usually throws UnsupportedOperationException. + */ + public Object instantiate(String className, Object[] params, + String[] signature) throws ReflectionException, MBeanException; /** - * Instantiates and registers an MBean in the MBean server. The - * class loader to be used is identified by its object name. An - * object name is associated to the MBean. If the object name of - * the loader is not specified, the ClassLoader that loaded the - * MBean server will be used. If the MBean object name given is - * null, the MBean must provide its own name by implementing the - * {@link javax.management.MBeanRegistration MBeanRegistration} - * interface and returning the name from the {@link - * javax.management.MBeanRegistration#preRegister preRegister} method. - * - * @param className The class name of the MBean to be instantiated. - * @param name The object name of the MBean. May be null. - * @param params An array containing the parameters of the - * constructor to be invoked. - * @param signature An array containing the signature of the - * constructor to be invoked. - * @param loaderName The object name of the class loader to be used. - * - * @return An ObjectInstance, containing the - * ObjectName and the Java class name of the newly - * instantiated MBean. - * - * @exception ReflectionException Wraps a - * java.lang.ClassNotFoundException or a - * java.lang.Exception that occurred when trying to - * invoke the MBean's constructor. - * @exception InstanceAlreadyExistsException The MBean is already - * under the control of the MBean server. - * @exception MBeanRegistrationException The - * preRegister (MBeanRegistration - * interface) method of the MBean has thrown an exception. The - * MBean will not be registered. - * @exception MBeanException The constructor of the MBean has - * thrown an exception - * @exception InstanceNotFoundException The specified class loader - * is not registered in the MBean server. - * @exception RuntimeOperationsException Wraps a - * java.lang.IllegalArgumentException: The className - * passed in parameter is null, the ObjectName passed - * in parameter contains a pattern or no ObjectName - * is specified for the MBean. - * + * This method should never be called. + * Usually throws UnsupportedOperationException. */ - public ObjectInstance createMBean(String className, ObjectName name, - ObjectName loaderName, Object params[], - String signature[]) - throws ReflectionException, InstanceAlreadyExistsException, - MBeanRegistrationException, MBeanException, - NotCompliantMBeanException, InstanceNotFoundException; + public Object instantiate(String className, ObjectName loaderName, + Object[] params, String[] signature) + throws ReflectionException, MBeanException, + InstanceNotFoundException; /** - * Registers a pre-existing object as an MBean with the MBean - * server. If the object name given is null, the MBean must - * provide its own name by implementing the {@link - * javax.management.MBeanRegistration MBeanRegistration} interface - * and returning the name from the {@link - * javax.management.MBeanRegistration#preRegister preRegister} method. - * - * @param object The MBean to be registered as an MBean. - * @param name The object name of the MBean. May be null. - * - * @return The ObjectInstance for the MBean that has - * been registered. - * - * @exception InstanceAlreadyExistsException The MBean is already - * under the control of the MBean server. - * @exception MBeanRegistrationException The - * preRegister (MBeanRegistration - * interface) method of the MBean has thrown an exception. The - * MBean will not be registered. - * @exception NotCompliantMBeanException This object is not a JMX - * compliant MBean - * @exception RuntimeOperationsException Wraps a - * java.lang.IllegalArgumentException: The object - * passed in parameter is null or no object name is specified. + * This method should never be called. + * Usually throws UnsupportedOperationException. */ - public ObjectInstance registerMBean(Object object, ObjectName name) - throws InstanceAlreadyExistsException, MBeanRegistrationException, - NotCompliantMBeanException; + @Deprecated + public ObjectInputStream deserialize(ObjectName name, byte[] data) + throws InstanceNotFoundException, OperationsException; /** - * Unregisters an MBean from the MBean server. The MBean is - * identified by its object name. Once the method has been - * invoked, the MBean may no longer be accessed by its object - * name. - * - * @param name The object name of the MBean to be unregistered. - * - * @exception InstanceNotFoundException The MBean specified is not - * registered in the MBean server. - * @exception MBeanRegistrationException The preDeregister - * ((MBeanRegistration interface) method of the MBean - * has thrown an exception. - * @exception RuntimeOperationsException Wraps a - * java.lang.IllegalArgumentException: The object - * name in parameter is null or the MBean you are when trying to - * unregister is the {@link javax.management.MBeanServerDelegate - * MBeanServerDelegate} MBean. - * + * This method should never be called. + * Usually throws UnsupportedOperationException. */ - public void unregisterMBean(ObjectName name) - throws InstanceNotFoundException, MBeanRegistrationException; + @Deprecated + public ObjectInputStream deserialize(String className, byte[] data) + throws OperationsException, ReflectionException; /** - * Gets the ObjectInstance for a given MBean - * registered with the MBean server. - * - * @param name The object name of the MBean. - * - * @return The ObjectInstance associated to the MBean - * specified by name. - * - * @exception InstanceNotFoundException The MBean specified is not - * registered in the MBean server. + * This method should never be called. + * Usually hrows UnsupportedOperationException. */ - public ObjectInstance getObjectInstance(ObjectName name) - throws InstanceNotFoundException; + @Deprecated + public ObjectInputStream deserialize(String className, + ObjectName loaderName, byte[] data) + throws InstanceNotFoundException, OperationsException, + ReflectionException; /** - * Gets MBeans controlled by the MBean server. This method allows - * any of the following to be obtained: All MBeans, a set of - * MBeans specified by pattern matching on the - * ObjectName and/or a Query expression, a specific - * MBean. When the object name is null or no domain and key - * properties are specified, all objects are to be selected (and - * filtered if a query is specified). It returns the set of - * ObjectInstance objects (containing the - * ObjectName and the Java Class name) for the - * selected MBeans. - * - * @param name The object name pattern identifying the MBeans to - * be retrieved. If null or no domain and key properties are - * specified, all the MBeans registered will be retrieved. - * @param query The query expression to be applied for selecting - * MBeans. If null no query expression will be applied for - * selecting MBeans. - * - * @return A set containing the ObjectInstance - * objects for the selected MBeans. If no MBean satisfies the - * query an empty list is returned. + * This method should never be called. + * Usually throws UnsupportedOperationException. */ - public Set queryMBeans(ObjectName name, QueryExp query); - - /** - * Gets the names of MBeans controlled by the MBean server. This - * method enables any of the following to be obtained: The names - * of all MBeans, the names of a set of MBeans specified by - * pattern matching on the ObjectName and/or a Query - * expression, a specific MBean name (equivalent to testing - * whether an MBean is registered). When the object name is null - * or no domain and key properties are specified, all objects are - * selected (and filtered if a query is specified). It returns the - * set of ObjectNames for the MBeans selected. - * - * @param name The object name pattern identifying the MBean names - * to be retrieved. If null oror no domain and key properties are - * specified, the name of all registered MBeans will be retrieved. - * @param query The query expression to be applied for selecting - * MBeans. If null no query expression will be applied for - * selecting MBeans. - * - * @return A set containing the ObjectNames for the MBeans - * selected. If no MBean satisfies the query, an empty list is - * returned. - */ - public Set queryNames(ObjectName name, QueryExp query); - - /** - * Checks whether an MBean, identified by its object name, is - * already registered with the MBean server. - * - * @param name The object name of the MBean to be checked. - * - * @return True if the MBean is already registered in the MBean - * server, false otherwise. - * - * @exception RuntimeOperationsException Wraps a - * java.lang.IllegalArgumentException: The object - * name in parameter is null. - */ - public boolean isRegistered(ObjectName name); - - /** - * Returns the number of MBeans registered in the MBean server. - */ - public Integer getMBeanCount(); - - /** - * Gets the value of a specific attribute of a named MBean. The MBean - * is identified by its object name. - * - * @param name The object name of the MBean from which the - * attribute is to be retrieved. - * @param attribute A String specifying the name of the attribute - * to be retrieved. - * - * @return The value of the retrieved attribute. - * - * @exception AttributeNotFoundException The attribute specified - * is not accessible in the MBean. - * @exception MBeanException Wraps an exception thrown by the - * MBean's getter. - * @exception InstanceNotFoundException The MBean specified is not - * registered in the MBean server. - * @exception ReflectionException Wraps a - * java.lang.Exception thrown when trying to invoke - * the setter. - * @exception RuntimeOperationsException Wraps a - * java.lang.IllegalArgumentException: The object - * name in parameter is null or the attribute in parameter is - * null. - */ - public Object getAttribute(ObjectName name, String attribute) - throws MBeanException, AttributeNotFoundException, - InstanceNotFoundException, ReflectionException; - - /** - * Enables the values of several attributes of a named MBean. The MBean - * is identified by its object name. - * - * @param name The object name of the MBean from which the - * attributes are retrieved. - * @param attributes A list of the attributes to be retrieved. - * - * @return The list of the retrieved attributes. - * - * @exception InstanceNotFoundException The MBean specified is not - * registered in the MBean server. - * @exception ReflectionException An exception occurred when - * trying to invoke the getAttributes method of a Dynamic MBean. - * @exception RuntimeOperationsException Wrap a - * java.lang.IllegalArgumentException: The object - * name in parameter is null or attributes in parameter is null. - */ - public AttributeList getAttributes(ObjectName name, String[] attributes) - throws InstanceNotFoundException, ReflectionException; - - /** - * Sets the value of a specific attribute of a named MBean. The MBean - * is identified by its object name. - * - * @param name The name of the MBean within which the attribute is - * to be set. - * @param attribute The identification of the attribute to be set - * and the value it is to be set to. - * - * @exception InstanceNotFoundException The MBean specified is not - * registered in the MBean server. - * @exception AttributeNotFoundException The attribute specified - * is not accessible in the MBean. - * @exception InvalidAttributeValueException The value specified - * for the attribute is not valid. - * @exception MBeanException Wraps an exception thrown by the - * MBean's setter. - * @exception ReflectionException Wraps a - * java.lang.Exception thrown when trying to invoke - * the setter. - * @exception RuntimeOperationsException Wraps a - * java.lang.IllegalArgumentException: The object - * name in parameter is null or the attribute in parameter is - * null. - */ - public void setAttribute(ObjectName name, Attribute attribute) - throws InstanceNotFoundException, AttributeNotFoundException, - InvalidAttributeValueException, MBeanException, - ReflectionException; - - - - /** - * Sets the values of several attributes of a named MBean. The MBean is - * identified by its object name. - * - * @param name The object name of the MBean within which the - * attributes are to be set. - * @param attributes A list of attributes: The identification of - * the attributes to be set and the values they are to be set to. - * - * @return The list of attributes that were set, with their new - * values. - * - * @exception InstanceNotFoundException The MBean specified is not - * registered in the MBean server. - * @exception ReflectionException An exception occurred when - * trying to invoke the getAttributes method of a Dynamic MBean. - * @exception RuntimeOperationsException Wraps a - * java.lang.IllegalArgumentException: The object - * name in parameter is null or attributes in parameter is null. - */ - public AttributeList setAttributes(ObjectName name, - AttributeList attributes) - throws InstanceNotFoundException, ReflectionException; - - /** - * Invokes an operation on an MBean. - * - * @param name The object name of the MBean on which the method is - * to be invoked. - * @param operationName The name of the operation to be invoked. - * @param params An array containing the parameters to be set when - * the operation is invoked - * @param signature An array containing the signature of the - * operation. The class objects will be loaded using the same - * class loader as the one used for loading the MBean on which the - * operation was invoked. - * - * @return The object returned by the operation, which represents - * the result ofinvoking the operation on the MBean specified. - * - * @exception InstanceNotFoundException The MBean specified is not - * registered in the MBean server. - * @exception MBeanException Wraps an exception thrown by the - * MBean's invoked method. - * @exception ReflectionException Wraps a - * java.lang.Exception thrown while trying to invoke - * the method. - */ - public Object invoke(ObjectName name, String operationName, - Object params[], String signature[]) - throws InstanceNotFoundException, MBeanException, - ReflectionException; - - /** - * Returns the default domain used for naming the MBean. - * The default domain name is used as the domain part in the ObjectName - * of MBeans if no domain is specified by the user. - */ - public String getDefaultDomain(); - - /** - * Returns the list of domains in which any MBean is currently - * registered. - */ - public String[] getDomains(); - - /** - *

    Adds a listener to a registered MBean.

    - * - *

    A notification emitted by an MBean will be forwarded by the - * MBeanServer to the listener. If the source of the notification - * is a reference to an MBean object, the MBean server will replace it - * by that MBean's ObjectName. Otherwise the source is unchanged. - * - * @param name The name of the MBean on which the listener should - * be added. - * @param listener The listener object which will handle the - * notifications emitted by the registered MBean. - * @param filter The filter object. If filter is null, no - * filtering will be performed before handling notifications. - * @param handback The context to be sent to the listener when a - * notification is emitted. - * - * @exception InstanceNotFoundException The MBean name provided - * does not match any of the registered MBeans. - */ - public void addNotificationListener(ObjectName name, - NotificationListener listener, - NotificationFilter filter, - Object handback) - throws InstanceNotFoundException; - - - /** - *

    Adds a listener to a registered MBean.

    - * - *

    A notification emitted by an MBean will be forwarded by the - * MBeanServer to the listener. If the source of the notification - * is a reference to an MBean object, the MBean server will - * replace it by that MBean's ObjectName. Otherwise the source is - * unchanged.

    - * - *

    The listener object that receives notifications is the one - * that is registered with the given name at the time this method - * is called. Even if it is subsequently unregistered, it will - * continue to receive notifications.

    - * - * @param name The name of the MBean on which the listener should - * be added. - * @param listener The object name of the listener which will - * handle the notifications emitted by the registered MBean. - * @param filter The filter object. If filter is null, no - * filtering will be performed before handling notifications. - * @param handback The context to be sent to the listener when a - * notification is emitted. - * - * @exception InstanceNotFoundException The MBean name of the - * notification listener or of the notification broadcaster does - * not match any of the registered MBeans. - * @exception RuntimeOperationsException Wraps an {@link - * IllegalArgumentException}. The MBean named by - * listener exists but does not implement the {@link - * NotificationListener} interface. - * @exception IOException A communication problem occurred when - * talking to the MBean server. - */ - public void addNotificationListener(ObjectName name, - ObjectName listener, - NotificationFilter filter, - Object handback) - throws InstanceNotFoundException; - - /** - * Removes a listener from a registered MBean. - * - *

    If the listener is registered more than once, perhaps with - * different filters or callbacks, this method will remove all - * those registrations. - * - * @param name The name of the MBean on which the listener should - * be removed. - * @param listener The object name of the listener to be removed. - * - * @exception InstanceNotFoundException The MBean name provided - * does not match any of the registered MBeans. - * @exception ListenerNotFoundException The listener is not - * registered in the MBean. - */ - public void removeNotificationListener(ObjectName name, - ObjectName listener) - throws InstanceNotFoundException, ListenerNotFoundException; - - /** - *

    Removes a listener from a registered MBean.

    - * - *

    The MBean must have a listener that exactly matches the - * given listener, filter, and - * handback parameters. If there is more than one - * such listener, only one is removed.

    - * - *

    The filter and handback parameters - * may be null if and only if they are null in a listener to be - * removed.

    - * - * @param name The name of the MBean on which the listener should - * be removed. - * @param listener A listener that was previously added to this - * MBean. - * @param filter The filter that was specified when the listener - * was added. - * @param handback The handback that was specified when the - * listener was added. - * - * @exception InstanceNotFoundException The MBean name provided - * does not match any of the registered MBeans. - * @exception ListenerNotFoundException The listener is not - * registered in the MBean, or it is not registered with the given - * filter and handback. - */ - public void removeNotificationListener(ObjectName name, - ObjectName listener, - NotificationFilter filter, - Object handback) - throws InstanceNotFoundException, ListenerNotFoundException; - - - /** - *

    Removes a listener from a registered MBean.

    - * - *

    If the listener is registered more than once, perhaps with - * different filters or callbacks, this method will remove all - * those registrations. - * - * @param name The name of the MBean on which the listener should - * be removed. - * @param listener The listener object which will handle the - * notifications emitted by the registered MBean. - * - * @exception InstanceNotFoundException The MBean name provided - * does not match any of the registered MBeans. - * @exception ListenerNotFoundException The listener is not - * registered in the MBean. - */ - public void removeNotificationListener(ObjectName name, - NotificationListener listener) - throws InstanceNotFoundException, ListenerNotFoundException; - - /** - *

    Removes a listener from a registered MBean.

    - * - *

    The MBean must have a listener that exactly matches the - * given listener, filter, and - * handback parameters. If there is more than one - * such listener, only one is removed.

    - * - *

    The filter and handback parameters - * may be null if and only if they are null in a listener to be - * removed.

    - * - * @param name The name of the MBean on which the listener should - * be removed. - * @param listener A listener that was previously added to this - * MBean. - * @param filter The filter that was specified when the listener - * was added. - * @param handback The handback that was specified when the - * listener was added. - * - * @exception InstanceNotFoundException The MBean name provided - * does not match any of the registered MBeans. - * @exception ListenerNotFoundException The listener is not - * registered in the MBean, or it is not registered with the given - * filter and handback. - */ - public void removeNotificationListener(ObjectName name, - NotificationListener listener, - NotificationFilter filter, - Object handback) - throws InstanceNotFoundException, ListenerNotFoundException; - - /** - * This method discovers the attributes and operations that an - * MBean exposes for management. - * - * @param name The name of the MBean to analyze - * - * @return An instance of MBeanInfo allowing the - * retrieval of all attributes and operations of this MBean. - * - * @exception IntrospectionException An exception occurred during - * introspection. - * @exception InstanceNotFoundException The MBean specified was - * not found. - * @exception ReflectionException An exception occurred when - * trying to invoke the getMBeanInfo of a Dynamic MBean. - */ - public MBeanInfo getMBeanInfo(ObjectName name) - throws InstanceNotFoundException, IntrospectionException, - ReflectionException; - - - /** - * Returns true if the MBean specified is an instance of the - * specified class, false otherwise. - * - * @param name The ObjectName of the MBean. - * @param className The name of the class. - * - * @return true if the MBean specified is an instance of the - * specified class, false otherwise. - * - * @exception InstanceNotFoundException The MBean specified is not - * registered in the MBean server. - */ - public boolean isInstanceOf(ObjectName name, String className) - throws InstanceNotFoundException; - - /** - *

    Return the {@link java.lang.ClassLoader} that was used for - * loading the class of the named MBean. - * @param mbeanName The ObjectName of the MBean. - * @return The ClassLoader used for that MBean. - * @exception InstanceNotFoundException if the named MBean is not found. - */ - public ClassLoader getClassLoaderFor(ObjectName mbeanName) - throws InstanceNotFoundException; - - /** - *

    Return the named {@link java.lang.ClassLoader}. - * @param loaderName The ObjectName of the ClassLoader. - * @return The named ClassLoader. - * @exception InstanceNotFoundException if the named ClassLoader is - * not found. - */ - public ClassLoader getClassLoader(ObjectName loaderName) - throws InstanceNotFoundException; + public ClassLoaderRepository getClassLoaderRepository(); } + diff --git a/jdk/src/share/classes/com/sun/jmx/interceptor/MBeanServerInterceptorSupport.java b/jdk/src/share/classes/com/sun/jmx/interceptor/MBeanServerInterceptorSupport.java new file mode 100644 index 00000000000..8e1cf681e86 --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/interceptor/MBeanServerInterceptorSupport.java @@ -0,0 +1,127 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.interceptor; + +import java.io.ObjectInputStream; +import javax.management.InstanceNotFoundException; +import javax.management.MBeanException; +import javax.management.ObjectName; +import javax.management.OperationsException; +import javax.management.ReflectionException; +import javax.management.loading.ClassLoaderRepository; + +/** + * An abstract class for MBeanServerInterceptorSupport. + * Some methods in MBeanServerInterceptor should never be called. + * This base class provides an implementation of these methods that simply + * throw an {@link UnsupportedOperationException}. + *

    + * This API is a Sun internal API and is subject to changes without notice. + *

    + * @since 1.7 + */ +public abstract class MBeanServerInterceptorSupport + implements MBeanServerInterceptor { + /** + * This method should never be called. + * Throws UnsupportedOperationException. + */ + public Object instantiate(String className) + throws ReflectionException, MBeanException { + throw new UnsupportedOperationException("Not applicable."); + } + + /** + * This method should never be called. + * Throws UnsupportedOperationException. + */ + public Object instantiate(String className, ObjectName loaderName) + throws ReflectionException, MBeanException, + InstanceNotFoundException { + throw new UnsupportedOperationException("Not applicable."); + } + + /** + * This method should never be called. + * Throws UnsupportedOperationException. + */ + public Object instantiate(String className, Object[] params, + String[] signature) throws ReflectionException, MBeanException { + throw new UnsupportedOperationException("Not applicable."); + } + + /** + * This method should never be called. + * Throws UnsupportedOperationException. + */ + public Object instantiate(String className, ObjectName loaderName, + Object[] params, String[] signature) + throws ReflectionException, MBeanException, + InstanceNotFoundException { + throw new UnsupportedOperationException("Not applicable."); + } + + /** + * This method should never be called. + * Throws UnsupportedOperationException. + */ + @Deprecated + public ObjectInputStream deserialize(ObjectName name, byte[] data) + throws InstanceNotFoundException, OperationsException { + throw new UnsupportedOperationException("Not applicable."); + } + + /** + * This method should never be called. + * Throws UnsupportedOperationException. + */ + @Deprecated + public ObjectInputStream deserialize(String className, byte[] data) + throws OperationsException, ReflectionException { + throw new UnsupportedOperationException("Not applicable."); + } + + /** + * This method should never be called. + * Throws UnsupportedOperationException. + */ + @Deprecated + public ObjectInputStream deserialize(String className, + ObjectName loaderName, byte[] data) + throws InstanceNotFoundException, OperationsException, + ReflectionException { + throw new UnsupportedOperationException("Not applicable."); + } + + /** + * This method should never be called. + * Throws UnsupportedOperationException. + */ + public ClassLoaderRepository getClassLoaderRepository() { + throw new UnsupportedOperationException("Not applicable."); + } + +} diff --git a/jdk/src/share/classes/com/sun/jmx/interceptor/NamespaceDispatchInterceptor.java b/jdk/src/share/classes/com/sun/jmx/interceptor/NamespaceDispatchInterceptor.java new file mode 100644 index 00000000000..d86c787b898 --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/interceptor/NamespaceDispatchInterceptor.java @@ -0,0 +1,236 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.interceptor; + +import com.sun.jmx.defaults.JmxProperties; +import com.sun.jmx.mbeanserver.MBeanInstantiator; +import com.sun.jmx.mbeanserver.Repository; +import com.sun.jmx.mbeanserver.Util; +import com.sun.jmx.namespace.NamespaceInterceptor; + +import java.util.Queue; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.management.MBeanServer; +import javax.management.MBeanServerDelegate; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; +import javax.management.namespace.JMXDomain; +import javax.management.namespace.JMXNamespace; +import static javax.management.namespace.JMXNamespaces.NAMESPACE_SEPARATOR; + +/** + * A dispatcher that dispatches to NamespaceInterceptors. + *

    + * This API is a Sun internal API and is subject to changes without notice. + *

    + * @since 1.7 + */ +public class NamespaceDispatchInterceptor + extends DispatchInterceptor { + + /** + * A logger for this class. + **/ + private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER; + + private static final int NAMESPACE_SEPARATOR_LENGTH = + NAMESPACE_SEPARATOR.length(); + + private final DomainDispatchInterceptor nextInterceptor; + private final String serverName; + + /** + * Creates a NamespaceDispatchInterceptor with the specified + * repository instance. + *

    Do not forget to call initialize(outer,delegate) + * before using this object. + * + * @param outer A pointer to the MBeanServer object that must be + * passed to the MBeans when invoking their + * {@link javax.management.MBeanRegistration} interface. + * @param delegate A pointer to the MBeanServerDelegate associated + * with the new MBeanServer. The new MBeanServer must register + * this MBean in its MBean repository. + * @param instantiator The MBeanInstantiator that will be used to + * instantiate MBeans and take care of class loading issues. + * @param repository The repository to use for this MBeanServer + */ + public NamespaceDispatchInterceptor(MBeanServer outer, + MBeanServerDelegate delegate, + MBeanInstantiator instantiator, + Repository repository) { + nextInterceptor = new DomainDispatchInterceptor(outer,delegate, + instantiator,repository,this); + serverName = Util.getMBeanServerSecurityName(delegate); + } + + // TODO: Should move that to JMXNamespace? or to ObjectName? + /** + * Get first name space in ObjectName path. Ignore leading namespace + * separators. + **/ + static String getFirstNamespace(ObjectName name) { + if (name == null) return ""; + final String domain = name.getDomain(); + if (domain.equals("")) return ""; + + // skip leading separators + int first = 0; + while (domain.startsWith(NAMESPACE_SEPARATOR,first)) + first += NAMESPACE_SEPARATOR_LENGTH; + + // go to next separator + final int end = domain.indexOf(NAMESPACE_SEPARATOR,first); + if (end == -1) return ""; // no namespace + + // This is the first element in the namespace path. + final String namespace = domain.substring(first,end); + + return namespace; + } + + /** + * Called by the DefaultMBeanServerInterceptor, just before adding an + * MBean to the repository. + * + * @param resource the MBean to be registered. + * @param logicalName the name of the MBean to be registered. + */ + final void checkLocallyRegistrable(Object resource, + ObjectName logicalName) { + if (!(resource instanceof JMXNamespace) && + logicalName.getDomain().contains(NAMESPACE_SEPARATOR)) + throw new IllegalArgumentException(String.valueOf(logicalName)+ + ": Invalid ObjectName for an instance of " + + resource.getClass().getName()); + } + + final boolean isLocalHandlerNameFor(String namespace, + ObjectName handlerName) { + return handlerName.getDomain().equals(namespace+NAMESPACE_SEPARATOR) && + JMXNamespace.TYPE_ASSIGNMENT.equals( + handlerName.getKeyPropertyListString()); + } + + @Override + final MBeanServer getInterceptorOrNullFor(ObjectName name) { + final String namespace = getFirstNamespace(name); + if (namespace.equals("") || isLocalHandlerNameFor(namespace,name) || + name.getDomain().equals(namespace+NAMESPACE_SEPARATOR)) { + LOG.finer("dispatching to local name space"); + return nextInterceptor; + } + final NamespaceInterceptor ns = getInterceptor(namespace); + if (LOG.isLoggable(Level.FINER)) { + if (ns != null) { + LOG.finer("dispatching to name space: " + namespace); + } else { + LOG.finer("no handler for: " + namespace); + } + } + return ns; + } + + @Override + final QueryInterceptor getInterceptorForQuery(ObjectName pattern) { + final String namespace = getFirstNamespace(pattern); + if (namespace.equals("") || isLocalHandlerNameFor(namespace,pattern) || + pattern.getDomain().equals(namespace+NAMESPACE_SEPARATOR)) { + LOG.finer("dispatching to local name space"); + return new QueryInterceptor(nextInterceptor); + } + final NamespaceInterceptor ns = getInterceptor(namespace); + if (LOG.isLoggable(Level.FINER)) { + if (ns != null) { + LOG.finer("dispatching to name space: " + namespace); + } else { + LOG.finer("no handler for: " + namespace); + } + } + if (ns == null) return null; + return new QueryInterceptor(ns); + } + + @Override + final ObjectName getHandlerNameFor(String key) + throws MalformedObjectNameException { + return ObjectName.getInstance(key+NAMESPACE_SEPARATOR, + "type", JMXNamespace.TYPE); + } + + @Override + final public String getHandlerKey(ObjectName name) { + return getFirstNamespace(name); + } + + @Override + final NamespaceInterceptor createInterceptorFor(String key, + ObjectName name, JMXNamespace handler, + Queue postRegisterQueue) { + final NamespaceInterceptor ns = + new NamespaceInterceptor(serverName,handler,key); + if (LOG.isLoggable(Level.FINER)) { + LOG.finer("NamespaceInterceptor created: "+ns); + } + return ns; + } + + @Override + final DomainDispatchInterceptor getNextInterceptor() { + return nextInterceptor; + } + + /** + * Returns the list of domains in which any MBean is currently + * registered. + */ + @Override + public String[] getDomains() { + return nextInterceptor.getDomains(); + } + + @Override + public void addInterceptorFor(ObjectName name, JMXNamespace handler, + Queue postRegisterQueue) { + if (handler instanceof JMXDomain) + nextInterceptor.addInterceptorFor(name, + (JMXDomain)handler,postRegisterQueue); + else super.addInterceptorFor(name,handler,postRegisterQueue); + } + + @Override + public void removeInterceptorFor(ObjectName name, JMXNamespace handler, + Queue postDeregisterQueue) { + if (handler instanceof JMXDomain) + nextInterceptor.removeInterceptorFor(name,(JMXDomain)handler, + postDeregisterQueue); + else super.removeInterceptorFor(name,handler,postDeregisterQueue); + } + + +} diff --git a/jdk/src/share/classes/com/sun/jmx/interceptor/SingleMBeanForwarder.java b/jdk/src/share/classes/com/sun/jmx/interceptor/SingleMBeanForwarder.java new file mode 100644 index 00000000000..4a47d4ce3aa --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/interceptor/SingleMBeanForwarder.java @@ -0,0 +1,416 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.interceptor; + +import com.sun.jmx.mbeanserver.Util; +import java.util.Arrays; +import java.util.Collections; +import java.util.Set; +import java.util.TreeSet; +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.AttributeNotFoundException; +import javax.management.DynamicMBean; +import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; +import javax.management.IntrospectionException; +import javax.management.InvalidAttributeValueException; +import javax.management.ListenerNotFoundException; +import javax.management.MBeanException; +import javax.management.MBeanInfo; +import javax.management.MBeanRegistrationException; +import javax.management.MBeanServer; +import javax.management.NotCompliantMBeanException; +import javax.management.NotificationEmitter; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.ObjectInstance; +import javax.management.ObjectName; +import javax.management.QueryExp; +import javax.management.ReflectionException; +import javax.management.namespace.JMXNamespaces; +import javax.management.namespace.MBeanServerSupport; +import javax.management.remote.IdentityMBeanServerForwarder; + +public class SingleMBeanForwarder extends IdentityMBeanServerForwarder { + + private final ObjectName mbeanName; + private DynamicMBean mbean; + + private MBeanServer mbeanMBS = new MBeanServerSupport() { + + @Override + public DynamicMBean getDynamicMBeanFor(ObjectName name) + throws InstanceNotFoundException { + if (mbeanName.equals(name)) { + return mbean; + } else { + throw new InstanceNotFoundException(name.toString()); + } + } + + @Override + protected Set getNames() { + return Collections.singleton(mbeanName); + } + + @Override + public NotificationEmitter getNotificationEmitterFor( + ObjectName name) { + if (mbean instanceof NotificationEmitter) + return (NotificationEmitter) mbean; + return null; + } + + }; + + public SingleMBeanForwarder(ObjectName mbeanName, DynamicMBean mbean) { + this.mbeanName = mbeanName; + setSingleMBean(mbean); + } + + protected void setSingleMBean(DynamicMBean mbean) { + this.mbean = mbean; + } + + @Override + public void addNotificationListener(ObjectName name, ObjectName listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException { + if (mbeanName.equals(name)) + mbeanMBS.addNotificationListener(name, listener, filter, handback); + else + super.addNotificationListener(name, listener, filter, handback); + } + + @Override + public void addNotificationListener(ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException { + if (mbeanName.equals(name)) + mbeanMBS.addNotificationListener(name, listener, filter, handback); + else + super.addNotificationListener(name, listener, filter, handback); + } + + @Override + public ObjectInstance createMBean(String className, ObjectName name, + ObjectName loaderName, Object[] params, + String[] signature) + throws ReflectionException, + InstanceAlreadyExistsException, + MBeanRegistrationException, + MBeanException, + NotCompliantMBeanException, + InstanceNotFoundException { + if (mbeanName.equals(name)) + throw new InstanceAlreadyExistsException(mbeanName.toString()); + else + return super.createMBean(className, name, loaderName, params, signature); + } + + @Override + public ObjectInstance createMBean(String className, ObjectName name, + Object[] params, String[] signature) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException { + if (mbeanName.equals(name)) + throw new InstanceAlreadyExistsException(mbeanName.toString()); + return super.createMBean(className, name, params, signature); + } + + @Override + public ObjectInstance createMBean(String className, ObjectName name, + ObjectName loaderName) + throws ReflectionException, + InstanceAlreadyExistsException, + MBeanRegistrationException, + MBeanException, + NotCompliantMBeanException, + InstanceNotFoundException { + if (mbeanName.equals(name)) + throw new InstanceAlreadyExistsException(mbeanName.toString()); + return super.createMBean(className, name, loaderName); + } + + @Override + public ObjectInstance createMBean(String className, ObjectName name) + throws ReflectionException, + InstanceAlreadyExistsException, + MBeanRegistrationException, + MBeanException, + NotCompliantMBeanException { + if (mbeanName.equals(name)) + throw new InstanceAlreadyExistsException(mbeanName.toString()); + return super.createMBean(className, name); + } + + @Override + public Object getAttribute(ObjectName name, String attribute) + throws MBeanException, + AttributeNotFoundException, + InstanceNotFoundException, + ReflectionException { + if (mbeanName.equals(name)) + return mbeanMBS.getAttribute(name, attribute); + else + return super.getAttribute(name, attribute); + } + + @Override + public AttributeList getAttributes(ObjectName name, String[] attributes) + throws InstanceNotFoundException, ReflectionException { + if (mbeanName.equals(name)) + return mbeanMBS.getAttributes(name, attributes); + else + return super.getAttributes(name, attributes); + } + + @Override + public ClassLoader getClassLoader(ObjectName loaderName) + throws InstanceNotFoundException { + if (mbeanName.equals(loaderName)) + return mbeanMBS.getClassLoader(loaderName); + else + return super.getClassLoader(loaderName); + } + + @Override + public ClassLoader getClassLoaderFor(ObjectName name) + throws InstanceNotFoundException { + if (mbeanName.equals(name)) + return mbeanMBS.getClassLoaderFor(name); + else + return super.getClassLoaderFor(name); + } + + @Override + public String[] getDomains() { + TreeSet domainSet = + new TreeSet(Arrays.asList(super.getDomains())); + domainSet.add(mbeanName.getDomain()); + return domainSet.toArray(new String[domainSet.size()]); + } + + @Override + public Integer getMBeanCount() { + Integer count = super.getMBeanCount(); + if (!super.isRegistered(mbeanName)) + count++; + return count; + } + + @Override + public MBeanInfo getMBeanInfo(ObjectName name) + throws InstanceNotFoundException, + IntrospectionException, + ReflectionException { + if (mbeanName.equals(name)) + return mbeanMBS.getMBeanInfo(name); + else + return super.getMBeanInfo(name); + } + + @Override + public ObjectInstance getObjectInstance(ObjectName name) + throws InstanceNotFoundException { + if (mbeanName.equals(name)) + return mbeanMBS.getObjectInstance(name); + else + return super.getObjectInstance(name); + } + + @Override + public Object invoke(ObjectName name, String operationName, Object[] params, + String[] signature) + throws InstanceNotFoundException, + MBeanException, + ReflectionException { + if (mbeanName.equals(name)) + return mbeanMBS.invoke(name, operationName, params, signature); + else + return super.invoke(name, operationName, params, signature); + } + + @Override + public boolean isInstanceOf(ObjectName name, String className) + throws InstanceNotFoundException { + if (mbeanName.equals(name)) + return mbeanMBS.isInstanceOf(name, className); + else + return super.isInstanceOf(name, className); + } + + @Override + public boolean isRegistered(ObjectName name) { + if (mbeanName.equals(name)) + return true; + else + return super.isRegistered(name); + } + + /** + * This is a ugly hack. Although jmx.context//*:* matches jmx.context//:* + * queryNames(jmx.context//*:*,null) must not return jmx.context//:* + * @param pattern the pattern to match against. must not be null. + * @return true if mbeanName can be included, false if it must not. + */ + private boolean applies(ObjectName pattern) { + // we know pattern is not null. + if (!pattern.apply(mbeanName)) + return false; + + final String dompat = pattern.getDomain(); + if (!dompat.contains(JMXNamespaces.NAMESPACE_SEPARATOR)) + return true; // We already checked that patterns apply. + + if (mbeanName.getDomain().endsWith(JMXNamespaces.NAMESPACE_SEPARATOR)) { + // only matches if pattern ends with // + return dompat.endsWith(JMXNamespaces.NAMESPACE_SEPARATOR); + } + + // should not come here, unless mbeanName contains a // in the + // middle of its domain, which would be weird. + // let query on mbeanMBS proceed and take care of that. + // + return true; + } + + @Override + public Set queryMBeans(ObjectName name, QueryExp query) { + Set names = super.queryMBeans(name, query); + if (name == null || applies(name) ) { + // Don't assume mbs.queryNames returns a writable set. + names = Util.cloneSet(names); + names.addAll(mbeanMBS.queryMBeans(name, query)); + } + return names; + } + + @Override + public Set queryNames(ObjectName name, QueryExp query) { + Set names = super.queryNames(name, query); + if (name == null || applies(name)) { + // Don't assume mbs.queryNames returns a writable set. + names = Util.cloneSet(names); + names.addAll(mbeanMBS.queryNames(name, query)); + } + return names; + } + + + @Override + public ObjectInstance registerMBean(Object object, ObjectName name) + throws InstanceAlreadyExistsException, + MBeanRegistrationException, + NotCompliantMBeanException { + if (mbeanName.equals(name)) + throw new InstanceAlreadyExistsException(mbeanName.toString()); + else + return super.registerMBean(object, name); + } + + @Override + public void removeNotificationListener(ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException, + ListenerNotFoundException { + if (mbeanName.equals(name)) + mbeanMBS.removeNotificationListener(name, listener, filter, handback); + else + super.removeNotificationListener(name, listener, filter, handback); + } + + @Override + public void removeNotificationListener(ObjectName name, + NotificationListener listener) + throws InstanceNotFoundException, ListenerNotFoundException { + if (mbeanName.equals(name)) + mbeanMBS.removeNotificationListener(name, listener); + else + super.removeNotificationListener(name, listener); + } + + @Override + public void removeNotificationListener(ObjectName name, ObjectName listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException, + ListenerNotFoundException { + if (mbeanName.equals(name)) + mbeanMBS.removeNotificationListener(name, listener, filter, handback); + else + super.removeNotificationListener(name, listener, filter, handback); + } + + @Override + public void removeNotificationListener(ObjectName name, ObjectName listener) + throws InstanceNotFoundException, ListenerNotFoundException { + if (mbeanName.equals(name)) + mbeanMBS.removeNotificationListener(name, listener); + else + super.removeNotificationListener(name, listener); + } + + @Override + public void setAttribute(ObjectName name, Attribute attribute) + throws InstanceNotFoundException, + AttributeNotFoundException, + InvalidAttributeValueException, + MBeanException, + ReflectionException { + if (mbeanName.equals(name)) + mbeanMBS.setAttribute(name, attribute); + else + super.setAttribute(name, attribute); + } + + @Override + public AttributeList setAttributes(ObjectName name, + AttributeList attributes) + throws InstanceNotFoundException, ReflectionException { + if (mbeanName.equals(name)) + return mbeanMBS.setAttributes(name, attributes); + else + return super.setAttributes(name, attributes); + } + + @Override + public void unregisterMBean(ObjectName name) + throws InstanceNotFoundException, + MBeanRegistrationException { + if (mbeanName.equals(name)) + mbeanMBS.unregisterMBean(name); + else + super.unregisterMBean(name); + } +} diff --git a/jdk/src/share/classes/com/sun/jmx/interceptor/package.html b/jdk/src/share/classes/com/sun/jmx/interceptor/package.html index 854436a9404..ad2163aa026 100644 --- a/jdk/src/share/classes/com/sun/jmx/interceptor/package.html +++ b/jdk/src/share/classes/com/sun/jmx/interceptor/package.html @@ -29,5 +29,8 @@ have any questions. Provides specific classes to Sun JMX Reference Implementation. +

    + This API is a Sun internal API and is subject to changes without notice. +

    diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java index 2d97c97b944..b86b2e00128 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java @@ -825,7 +825,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory { final TabularData table = (TabularData) openValue; final Collection rows = cast(table.values()); final Map valueMap = - sortedMap ? newSortedMap() : newMap(); + sortedMap ? newSortedMap() : newInsertionOrderMap(); for (CompositeData row : rows) { final Object key = keyMapping.fromOpenValue(row.get("key")); @@ -1172,10 +1172,10 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory { final Class propertyNamesClass = ConstructorProperties.class; Class targetClass = getTargetClass(); - Constructor[] constrs = targetClass.getConstructors(); + Constructor[] constrs = targetClass.getConstructors(); // Applicable if and only if there are any annotated constructors - List annotatedConstrList = newList(); + List> annotatedConstrList = newList(); for (Constructor constr : constrs) { if (Modifier.isPublic(constr.getModifiers()) && constr.getAnnotation(propertyNamesClass) != null) @@ -1206,7 +1206,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory { // Also remember the set of properties in that constructor // so we can test unambiguity. Set getterIndexSets = newSet(); - for (Constructor constr : annotatedConstrList) { + for (Constructor constr : annotatedConstrList) { String[] propertyNames = constr.getAnnotation(propertyNamesClass).value(); @@ -1363,10 +1363,10 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory { } private static class Constr { - final Constructor constructor; + final Constructor constructor; final int[] paramIndexes; final BitSet presentParams; - Constr(Constructor constructor, int[] paramIndexes, + Constr(Constructor constructor, int[] paramIndexes, BitSet presentParams) { this.constructor = constructor; this.paramIndexes = paramIndexes; diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/DynamicMBean2.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/DynamicMBean2.java index 270f7ad77a6..d67b1660703 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/DynamicMBean2.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/DynamicMBean2.java @@ -1,5 +1,5 @@ /* - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java index 1554444f508..52783fd5a60 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java @@ -228,7 +228,15 @@ public class Introspector { // to generate the appropriate exception. } if (c != null) { - MXBeanMappingFactory factory = MXBeanMappingFactory.forInterface(c); + MXBeanMappingFactory factory; + try { + factory = MXBeanMappingFactory.forInterface(c); + } catch (IllegalArgumentException e) { + NotCompliantMBeanException ncmbe = + new NotCompliantMBeanException(e.getMessage()); + ncmbe.initCause(e); + throw ncmbe; + } return new MXBeanSupport(mbean, c, factory); } checkCompliance(mbeanClass); diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java index 1095897d99b..777cd1cce65 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,44 +25,42 @@ package com.sun.jmx.mbeanserver; -import java.util.Iterator; -import java.util.logging.Level; -import java.util.Set; +import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER; +import com.sun.jmx.interceptor.NamespaceDispatchInterceptor; + import java.io.ObjectInputStream; import java.security.AccessController; import java.security.Permission; import java.security.PrivilegedExceptionAction; +import java.util.Iterator; +import java.util.Set; +import java.util.logging.Level; -// RI import -import javax.management.MBeanPermission; -import javax.management.AttributeNotFoundException; -import javax.management.MBeanException; -import javax.management.ReflectionException; -import javax.management.MBeanInfo; -import javax.management.QueryExp; -import javax.management.NotificationListener; -import javax.management.NotificationFilter; -import javax.management.ListenerNotFoundException; -import javax.management.IntrospectionException; -import javax.management.OperationsException; -import javax.management.InstanceNotFoundException; -import javax.management.NotCompliantMBeanException; -import javax.management.MBeanRegistrationException; -import javax.management.InstanceAlreadyExistsException; -import javax.management.InvalidAttributeValueException; -import javax.management.ObjectName; -import javax.management.ObjectInstance; import javax.management.Attribute; import javax.management.AttributeList; -import javax.management.RuntimeOperationsException; +import javax.management.AttributeNotFoundException; +import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; +import javax.management.IntrospectionException; +import javax.management.InvalidAttributeValueException; +import javax.management.ListenerNotFoundException; +import javax.management.MBeanException; +import javax.management.MBeanInfo; +import javax.management.MBeanPermission; +import javax.management.MBeanRegistrationException; import javax.management.MBeanServer; import javax.management.MBeanServerDelegate; +import javax.management.NotCompliantMBeanException; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.ObjectInstance; +import javax.management.ObjectName; +import javax.management.OperationsException; +import javax.management.QueryExp; +import javax.management.ReflectionException; +import javax.management.RuntimeOperationsException; import javax.management.loading.ClassLoaderRepository; -import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER; -import com.sun.jmx.interceptor.DefaultMBeanServerInterceptor; -import com.sun.jmx.interceptor.MBeanServerInterceptor; - /** * This is the base class for MBean manipulation on the agent side. It * contains the methods necessary for the creation, registration, and @@ -102,15 +100,14 @@ public final class JmxMBeanServer /** true if interceptors are enabled **/ private final boolean interceptorsEnabled; - /** Revisit: transient ??? **/ - private final transient MBeanServer outerShell; + private final MBeanServer outerShell; - /** Revisit: transient ??? **/ - private transient MBeanServerInterceptor mbsInterceptor = null; + private volatile MBeanServer mbsInterceptor = null; - /** Revisit: transient ??? **/ /** The MBeanServerDelegate object representing the MBean Server */ - private final transient MBeanServerDelegate mBeanServerDelegateObject; + private final MBeanServerDelegate mBeanServerDelegateObject; + + private final String mbeanServerName; /** * Package: Creates an MBeanServer with the @@ -243,9 +240,10 @@ public final class JmxMBeanServer final Repository repository = new Repository(domain,fairLock); this.mbsInterceptor = - new DefaultMBeanServerInterceptor(outer, delegate, instantiator, + new NamespaceDispatchInterceptor(outer, delegate, instantiator, repository); this.interceptorsEnabled = interceptors; + this.mbeanServerName = Util.getMBeanServerSecurityName(delegate); initialize(); } @@ -941,7 +939,8 @@ public final class JmxMBeanServer throws ReflectionException, MBeanException { /* Permission check */ - checkMBeanPermission(className, null, null, "instantiate"); + checkMBeanPermission(mbeanServerName, className, null, null, + "instantiate"); return instantiator.instantiate(className); } @@ -978,7 +977,8 @@ public final class JmxMBeanServer InstanceNotFoundException { /* Permission check */ - checkMBeanPermission(className, null, null, "instantiate"); + checkMBeanPermission(mbeanServerName, className, null, + null, "instantiate"); ClassLoader myLoader = outerShell.getClass().getClassLoader(); return instantiator.instantiate(className, loaderName, myLoader); @@ -1016,7 +1016,8 @@ public final class JmxMBeanServer throws ReflectionException, MBeanException { /* Permission check */ - checkMBeanPermission(className, null, null, "instantiate"); + checkMBeanPermission(mbeanServerName, className, null, null, + "instantiate"); ClassLoader myLoader = outerShell.getClass().getClassLoader(); return instantiator.instantiate(className, params, signature, @@ -1059,7 +1060,8 @@ public final class JmxMBeanServer InstanceNotFoundException { /* Permission check */ - checkMBeanPermission(className, null, null, "instantiate"); + checkMBeanPermission(mbeanServerName, className, null, + null, "instantiate"); ClassLoader myLoader = outerShell.getClass().getClassLoader(); return instantiator.instantiate(className,loaderName,params,signature, @@ -1236,7 +1238,7 @@ public final class JmxMBeanServer "Unexpected exception occurred", e); } throw new - IllegalStateException("Can't register delegate."); + IllegalStateException("Can't register delegate.",e); } @@ -1278,7 +1280,7 @@ public final class JmxMBeanServer * are not enabled on this object. * @see #interceptorsEnabled **/ - public synchronized MBeanServerInterceptor getMBeanServerInterceptor() { + public synchronized MBeanServer getMBeanServerInterceptor() { if (interceptorsEnabled) return mbsInterceptor; else throw new UnsupportedOperationException( "MBeanServerInterceptors are disabled."); @@ -1292,7 +1294,7 @@ public final class JmxMBeanServer * @see #interceptorsEnabled **/ public synchronized void - setMBeanServerInterceptor(MBeanServerInterceptor interceptor) { + setMBeanServerInterceptor(MBeanServer interceptor) { if (!interceptorsEnabled) throw new UnsupportedOperationException( "MBeanServerInterceptors are disabled."); if (interceptor == null) throw new @@ -1330,7 +1332,8 @@ public final class JmxMBeanServer **/ public ClassLoaderRepository getClassLoaderRepository() { /* Permission check */ - checkMBeanPermission(null, null, null, "getClassLoaderRepository"); + checkMBeanPermission(mbeanServerName, null, null, + null, "getClassLoaderRepository"); return secureClr; } @@ -1484,14 +1487,16 @@ public final class JmxMBeanServer // SECURITY CHECKS //---------------- - private static void checkMBeanPermission(String classname, + private static void checkMBeanPermission(String serverName, + String classname, String member, ObjectName objectName, String actions) throws SecurityException { SecurityManager sm = System.getSecurityManager(); if (sm != null) { - Permission perm = new MBeanPermission(classname, + Permission perm = new MBeanPermission(serverName, + classname, member, objectName, actions); diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInjector.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInjector.java index 4831134f6af..8ef296a1a4c 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInjector.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInjector.java @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -172,7 +172,7 @@ public class MBeanInjector { * reference. * * So we accept a Field if it has a @Resource annotation and either - * (a) its type is ObjectName or a subclass and its @Resource type is + * (a) its type is exactly ObjectName and its @Resource type is * compatible with ObjectName (e.g. it is Object); or * (b) its type is compatible with ObjectName and its @Resource type * is exactly ObjectName. Fields that meet these criteria will not diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java index 725292bca36..99aaa85466d 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java @@ -623,7 +623,7 @@ abstract class MBeanIntrospector { } private static MBeanConstructorInfo[] findConstructors(Class c) { - Constructor[] cons = c.getConstructors(); + Constructor[] cons = c.getConstructors(); MBeanConstructorInfo[] mbc = new MBeanConstructorInfo[cons.length]; for (int i = 0; i < cons.length; i++) { String descr = "Public constructor of the MBean"; diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java index d4f3123fbc5..20a776534ce 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java @@ -25,7 +25,6 @@ package com.sun.jmx.mbeanserver; -import static com.sun.jmx.mbeanserver.Util.*; import javax.management.Attribute; import javax.management.AttributeList; diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanLookup.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanLookup.java index 41b3b989160..227c1eec990 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanLookup.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanLookup.java @@ -224,7 +224,7 @@ public abstract class MXBeanLookup { throws InvalidObjectException { String domain = prefix + name.getDomain(); try { - name = switchDomain(domain, name); + name = name.withDomain(domain); } catch (MalformedObjectNameException e) { throw EnvHelp.initCause( new InvalidObjectException(e.getMessage()), e); @@ -242,7 +242,7 @@ public abstract class MXBeanLookup { "Proxy's name does not start with " + prefix + ": " + name); } try { - name = switchDomain(domain.substring(prefix.length()), name); + name = name.withDomain(domain.substring(prefix.length())); } catch (MalformedObjectNameException e) { throw EnvHelp.initCause(new OpenDataException(e.getMessage()), e); } @@ -269,14 +269,6 @@ public abstract class MXBeanLookup { currentLookup.set(lookup); } - // Method temporarily added until we have ObjectName.switchDomain in the - // public API. Note that this method DOES NOT PRESERVE the order of - // keys in the ObjectName so it must not be used in the final release. - static ObjectName switchDomain(String domain, ObjectName name) - throws MalformedObjectNameException { - return new ObjectName(domain, name.getKeyPropertyList()); - } - private static final ThreadLocal currentLookup = new ThreadLocal(); diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanSupport.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanSupport.java index 594a9733481..7a9c5d2e7a8 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanSupport.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanSupport.java @@ -36,7 +36,6 @@ import javax.management.MBeanServer; import javax.management.NotCompliantMBeanException; import javax.management.ObjectName; import javax.management.openmbean.MXBeanMappingFactory; -import javax.management.openmbean.MXBeanMappingFactoryClass; /** * Base class for MXBeans. diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/NotifySupport.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/NotifySupport.java index 94227370ba2..00fbb027352 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/NotifySupport.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/NotifySupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/PerThreadGroupPool.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/PerThreadGroupPool.java new file mode 100644 index 00000000000..2946f16fa12 --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/PerThreadGroupPool.java @@ -0,0 +1,71 @@ +/* + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.mbeanserver; + +import java.lang.ref.WeakReference; +import java.util.concurrent.ThreadPoolExecutor; + +/** + *

    A factory for ThreadPoolExecutor objects that allows the same object to + * be shared by all users of the factory that are in the same ThreadGroup.

    + */ +// We return a ThreadPoolExecutor rather than the more general ExecutorService +// because we need to be able to call allowCoreThreadTimeout so that threads in +// the pool will eventually be destroyed when the pool is no longer in use. +// Otherwise these threads would keep the ThreadGroup alive forever. +public class PerThreadGroupPool { + private final WeakIdentityHashMap> map = + WeakIdentityHashMap.make(); + + public static interface Create { + public T createThreadPool(ThreadGroup group); + } + + private PerThreadGroupPool() {} + + public static PerThreadGroupPool make() { + return new PerThreadGroupPool(); + } + + public synchronized T getThreadPoolExecutor(Create create) { + // Find out if there's already an existing executor for the calling + // thread and reuse it. Otherwise, create a new one and store it in + // the executors map. If there is a SecurityManager, the group of + // System.getSecurityManager() is used, else the group of the calling + // thread. + SecurityManager s = System.getSecurityManager(); + ThreadGroup group = (s != null) ? s.getThreadGroup() : + Thread.currentThread().getThreadGroup(); + WeakReference wr = map.get(group); + T executor = (wr == null) ? null : wr.get(); + if (executor == null) { + executor = create.createThreadPool(group); + executor.allowCoreThreadTimeOut(true); + map.put(group, new WeakReference(executor)); + } + return executor; + } +} diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Repository.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Repository.java index f41079912fb..03f3e5277bd 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Repository.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Repository.java @@ -45,7 +45,6 @@ import javax.management.QueryExp; import javax.management.RuntimeOperationsException; /** - * The RepositorySupport implements the Repository interface. * This repository does not support persistency. * * @since 1.5 @@ -197,9 +196,9 @@ public class Repository { if (isPropertyValuePattern && pattern.isPropertyValuePattern(keys[i])) { // wildmatch key property values - final char[] val_pattern = values[i].toCharArray(); - final char[] val_string = v.toCharArray(); - if (wildmatch(val_string,val_pattern)) + // values[i] is the pattern; + // v is the string + if (Util.wildmatch(v,values[i])) continue; else return false; @@ -236,86 +235,6 @@ public class Repository { } } - /** Match a string against a shell-style pattern. The only pattern - characters recognised are ?, standing for any one - character, and *, standing for any string of - characters, including the empty string. - - @param str the string to match, as a character array. - @param pat the pattern to match the string against, as a - character array. - - @return true if and only if the string matches the pattern. - */ - /* The algorithm is a classical one. We advance pointers in - parallel through str and pat. If we encounter a star in pat, - we remember its position and continue advancing. If at any - stage we get a mismatch between str and pat, we look to see if - there is a remembered star. If not, we fail. If so, we - retreat pat to just past that star and str to the position - after the last one we tried, and we let the match advance - again. - - Even though there is only one remembered star position, the - algorithm works when there are several stars in the pattern. - When we encounter the second star, we forget the first one. - This is OK, because if we get to the second star in A*B*C - (where A etc are arbitrary strings), we have already seen AXB. - We're therefore setting up a match of *C against the remainder - of the string, which will match if that remainder looks like - YC, so the whole string looks like AXBYC. - */ - public static boolean wildmatch(char[] str, char[] pat) { - int stri; // index in str - int pati; // index in pat - int starstri; // index for backtrack if "*" attempt fails - int starpati; // index for backtrack if "*" attempt fails, +1 - final int strlen = str.length; - final int patlen = pat.length; - - stri = pati = 0; - starstri = starpati = -1; - - /* On each pass through this loop, we either advance pati, - or we backtrack pati and advance starstri. Since starstri - is only ever assigned from pati, the loop must terminate. */ - while (true) { - if (pati < patlen) { - final char patc = pat[pati]; - switch (patc) { - case '?': - if (stri == strlen) - break; - stri++; - pati++; - continue; - case '*': - pati++; - starpati = pati; - starstri = stri; - continue; - default: - if (stri < strlen && str[stri] == patc) { - stri++; - pati++; - continue; - } - break; - } - } else if (stri == strlen) - return true; - - // Mismatched, can we backtrack to a "*"? - if (starpati < 0 || starstri == strlen) - return false; - - // Retry the match one position later in str - pati = starpati; - starstri++; - stri = starstri; - } - } - private void addNewDomMoi(final DynamicMBean object, final String dom, final ObjectName name, @@ -370,7 +289,7 @@ public class Repository { if (name.isPattern()) return null; // Extract the domain name. - String dom= name.getDomain().intern(); + String dom = name.getDomain().intern(); // Default domain case if (dom.length() == 0) { @@ -477,10 +396,10 @@ public class Repository { // Set domain to default if domain is empty and not already set if (dom.length() == 0) - name = Util.newObjectName(domain + name.toString()); + name = ObjectName.valueOf(domain + name.toString()); // Do we have default domain ? - if (dom == domain) { + if (dom == domain) { // ES: OK (dom & domain are interned) to_default_domain = true; dom = domain; } else { @@ -652,10 +571,9 @@ public class Repository { } // Pattern matching in the domain name (*, ?) - char[] dom2Match = name.getDomain().toCharArray(); + final String dom2Match = name.getDomain(); for (String dom : domainTb.keySet()) { - char[] theDom = dom.toCharArray(); - if (wildmatch(theDom, dom2Match)) { + if (Util.wildpathmatch(dom, dom2Match)) { final Map moiTb = domainTb.get(dom); if (allNames) result.addAll(moiTb.values()); @@ -726,7 +644,7 @@ public class Repository { // need to reinstantiate a hashtable because of possible // big buckets array size inside table, never cleared, // thus the new ! - if (dom == domain) + if (dom == domain) // ES: OK dom and domain are interned. domainTb.put(domain, new HashMap()); } diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/StandardMBeanIntrospector.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/StandardMBeanIntrospector.java index aca58c32f11..87aa9301d7a 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/StandardMBeanIntrospector.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/StandardMBeanIntrospector.java @@ -1,5 +1,5 @@ /* - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/SunJmxMBeanServer.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/SunJmxMBeanServer.java index 6c338387d0e..091ad7c66cb 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/SunJmxMBeanServer.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/SunJmxMBeanServer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,17 +28,16 @@ package com.sun.jmx.mbeanserver; import javax.management.MBeanServer; import javax.management.MBeanServerDelegate; -import com.sun.jmx.interceptor.MBeanServerInterceptor; /** - * Extends the MBeanServer and MBeanServerInterceptor interface to + * Extends the MBeanServer interface to * provide methods for getting the MetaData and MBeanServerInstantiator * objects associated with an MBeanServer. * * @since 1.5 */ public interface SunJmxMBeanServer - extends MBeanServerInterceptor, MBeanServer { + extends MBeanServer { /** * Return the MBeanInstantiator associated to this MBeanServer. @@ -68,7 +67,7 @@ public interface SunJmxMBeanServer * are not enabled on this object. * @see #interceptorsEnabled **/ - public MBeanServerInterceptor getMBeanServerInterceptor(); + public MBeanServer getMBeanServerInterceptor(); /** * Set the MBeanServerInterceptor. @@ -77,7 +76,7 @@ public interface SunJmxMBeanServer * are not enabled on this object. * @see #interceptorsEnabled **/ - public void setMBeanServerInterceptor(MBeanServerInterceptor interceptor); + public void setMBeanServerInterceptor(MBeanServer interceptor); /** *

    Return the MBeanServerDelegate representing the MBeanServer. diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java index af427da2887..6307adbf8d9 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java @@ -25,6 +25,8 @@ package com.sun.jmx.mbeanserver; +import com.sun.jmx.defaults.JmxProperties; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -38,12 +40,27 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedMap; +import java.util.SortedSet; import java.util.TreeMap; +import java.util.TreeSet; import java.util.WeakHashMap; +import java.util.logging.Level; +import javax.management.MBeanServer; +import javax.management.MBeanServerDelegate; +import javax.management.MBeanServerFactory; import javax.management.MalformedObjectNameException; +import javax.management.ObjectInstance; import javax.management.ObjectName; +import javax.management.loading.ClassLoaderRepository; +import static javax.management.namespace.JMXNamespaces.NAMESPACE_SEPARATOR; public class Util { + private final static int NAMESPACE_SEPARATOR_LENGTH = + NAMESPACE_SEPARATOR.length(); + public final static char[] ILLEGAL_MBEANSERVER_NAME_CHARS=";:*?". + toCharArray(); + + static Map newMap() { return new HashMap(); } @@ -93,14 +110,6 @@ public class Util { return new ArrayList(c); } - public static ObjectName newObjectName(String s) { - try { - return new ObjectName(s); - } catch (MalformedObjectNameException e) { - throw new IllegalArgumentException(e); - } - } - /* This method can be used by code that is deliberately violating the * allowed checked casts. Rather than marking the whole method containing * the code with @SuppressWarnings, you can use a call to this method for @@ -142,4 +151,552 @@ public class Util { return hash; } + /** Match a part of a string against a shell-style pattern. + The only pattern characters recognized are ?, + standing for any one character, + and *, standing for any string of + characters, including the empty string. For instance, + {@code wildmatch("sandwich","sa?d*ch",1,4,1,4)} will match + {@code "and"} against {@code "a?d"}. + + @param str the string containing the sequence to match. + @param pat a string containing a pattern to match the sub string + against. + @param stri the index in the string at which matching should begin. + @param strend the index in the string at which the matching should + end. + @param pati the index in the pattern at which matching should begin. + @param patend the index in the pattern at which the matching should + end. + + @return true if and only if the string matches the pattern. + */ + /* The algorithm is a classical one. We advance pointers in + parallel through str and pat. If we encounter a star in pat, + we remember its position and continue advancing. If at any + stage we get a mismatch between str and pat, we look to see if + there is a remembered star. If not, we fail. If so, we + retreat pat to just past that star and str to the position + after the last one we tried, and we let the match advance + again. + + Even though there is only one remembered star position, the + algorithm works when there are several stars in the pattern. + When we encounter the second star, we forget the first one. + This is OK, because if we get to the second star in A*B*C + (where A etc are arbitrary strings), we have already seen AXB. + We're therefore setting up a match of *C against the remainder + of the string, which will match if that remainder looks like + YC, so the whole string looks like AXBYC. + */ + private static boolean wildmatch(final String str, final String pat, + int stri, final int strend, int pati, final int patend) { + + // System.out.println("matching "+pat.substring(pati,patend)+ + // " against "+str.substring(stri, strend)); + int starstri; // index for backtrack if "*" attempt fails + int starpati; // index for backtrack if "*" attempt fails, +1 + + starstri = starpati = -1; + + /* On each pass through this loop, we either advance pati, + or we backtrack pati and advance starstri. Since starstri + is only ever assigned from pati, the loop must terminate. */ + while (true) { + if (pati < patend) { + final char patc = pat.charAt(pati); + switch (patc) { + case '?': + if (stri == strend) + break; + stri++; + pati++; + continue; + case '*': + pati++; + starpati = pati; + starstri = stri; + continue; + default: + if (stri < strend && str.charAt(stri) == patc) { + stri++; + pati++; + continue; + } + break; + } + } else if (stri == strend) + return true; + + // Mismatched, can we backtrack to a "*"? + if (starpati < 0 || starstri == strend) + return false; + + // Retry the match one position later in str + pati = starpati; + starstri++; + stri = starstri; + } + } + + /** Match a string against a shell-style pattern. The only pattern + characters recognized are ?, standing for any one + character, and *, standing for any string of + characters, including the empty string. + + @param str the string to match. + @param pat the pattern to match the string against. + + @return true if and only if the string matches the pattern. + */ + public static boolean wildmatch(String str, String pat) { + return wildmatch(str,pat,0,str.length(),0,pat.length()); + } + + /** + * Matches a string against a pattern, as a name space path. + * This is a special matching where * and ?? don't match //. + * The string is split in sub-strings separated by //, and the + * pattern is split in sub-patterns separated by //. Each sub-string + * is matched against its corresponding sub-pattern. + * so ////...// matches ////...// + * only if n==q and for ( i = 1 => n) elt-i matches pat-i. + * + * In addition, if we encounter a pattern element which is exactly + * **, it can match any number of path-elements - but it must match at + * least one element. + * When we encounter such a meta-wildcard, we remember its position + * and the position in the string path, and we advance both the pattern + * and the string. Later, if we encounter a mismatch in pattern & string, + * we rewind the position in pattern to just after the meta-wildcard, + * and we backtrack the string to i+1 element after the position + * we had when we first encountered the meta-wildcard, i being the + * position when we last backtracked the string. + * + * The backtracking logic is an adaptation of the logic in wildmatch + * above. + * See test/javax/mangement/ObjectName/ApplyWildcardTest.java + * + * Note: this thing is called 'wild' - and that's for a reason ;-) + **/ + public static boolean wildpathmatch(String str, String pat) { + final int strlen = str.length(); + final int patlen = pat.length(); + int stri = 0; + int pati = 0; + + int starstri; // index for backtrack if "**" attempt fails + int starpati; // index for backtrack if "**" attempt fails + + starstri = starpati = -1; + + while (true) { + // System.out.println("pati="+pati+", stri="+stri); + final int strend = str.indexOf(NAMESPACE_SEPARATOR, stri); + final int patend = pat.indexOf(NAMESPACE_SEPARATOR, pati); + + // no // remaining in either string or pattern: simple wildmatch + // until end of string. + if (strend == -1 && patend == -1) { + // System.out.println("last sub pattern, last sub element..."); + // System.out.println("wildmatch("+str.substring(stri,strlen)+ + // ","+pat.substring(pati,patlen)+")"); + return wildmatch(str,pat,stri,strlen,pati,patlen); + } + + // no // remaining in string, but at least one remaining in + // pattern + // => no match + if (strend == -1) { + // System.out.println("pattern has more // than string..."); + return false; + } + + // strend is != -1, but patend might. + // detect wildcard ** + if (patend == pati+2 && pat.charAt(pati)=='*' && + pat.charAt(pati+1)=='*') { + // if we reach here we know that neither strend nor patend are + // equals to -1. + stri = strend + NAMESPACE_SEPARATOR_LENGTH; + pati = patend + NAMESPACE_SEPARATOR_LENGTH; + starpati = pati; // position just after **// in pattern + starstri = stri; // we eat 1 element in string, and remember + // the position for backtracking and eating + // one more element if needed. + // System.out.println("starpati="+pati); + continue; + } + + // This is a bit hacky: * can match // when // is at the end + // of the string, so we include the // delimiter in the pattern + // matching. Either we're in the middle of the path, so including + // // both at the end of the pattern and at the end of the string + // has no effect - match(*//,dfsd//) is equivalent to match(*,dfsd) + // or we're at the end of the pattern path, in which case + // including // at the end of the string will have the desired + // effect (provided that we detect the end of matching correctly, + // see further on). + // + final int endpat = + ((patend > -1)?patend+NAMESPACE_SEPARATOR_LENGTH:patlen); + final int endstr = + ((strend > -1)?strend+NAMESPACE_SEPARATOR_LENGTH:strlen); + + // if we reach the end of the pattern, or if elt-i & pat-i + // don't match, we have a mismatch. + + // Note: we know that strend != -1, therefore patend==-1 + // indicates a mismatch unless pattern can match + // a // at the end, and strend+2=strlen. + // System.out.println("wildmatch("+str.substring(stri,endstr)+","+ + // pat.substring(pati,endpat)+")"); + if (!wildmatch(str,pat,stri,endstr,pati,endpat)) { + + // System.out.println("nomatch"); + // if we have a mismatch and didn't encounter any meta-wildcard, + // we return false. String & pattern don't match. + if (starpati < 0) return false; + + // If we reach here, we had a meta-wildcard. + // We need to backtrack to the wildcard, and make it eat an + // additional string element. + // + stri = str.indexOf(NAMESPACE_SEPARATOR, starstri); + // System.out.println("eating one additional element? "+stri); + + // If there's no more elements to eat, string and pattern + // don't match => return false. + if (stri == -1) return false; + + // Backtrack to where we were when we last matched against + // the meta-wildcard, make it eat an additional path element, + // remember the new positions, and continue from there... + // + stri = stri + NAMESPACE_SEPARATOR_LENGTH; + starstri = stri; + pati = starpati; + // System.out.println("skiping to stri="+stri); + continue; + } + + // Here we know that strend > -1 but we can have patend == -1. + // + // So if we reach here, we know pat-i+//? has matched + // elt-i+// + // + // If patend==-1, we know that there was no delimiter + // at the end of the pattern, that we are at the last pattern, + // and therefore that pat-i has matched elt-i+// + // + // In that case we can consider that we have a match only if + // elt-i is also the last path element in the string, which is + // equivalent to saying that strend+2==strlen. + // + if (patend == -1 && starpati == -1) + return (strend+NAMESPACE_SEPARATOR_LENGTH==strlen); + + // patend != -1, or starpati > -1 so there remains something + // to match. + + // go to next pair: elt-(i+1) pat-(i+1); + stri = strend + NAMESPACE_SEPARATOR_LENGTH; + pati = (patend==-1)?pati:(patend + NAMESPACE_SEPARATOR_LENGTH); + } + } + + /** + * Returns true if the ObjectName's {@code domain} is selected by the + * given {@code pattern}. + */ + public static boolean isDomainSelected(String domain, String pattern) { + if (domain == null || pattern == null) + throw new IllegalArgumentException("null"); + return Util.wildpathmatch(domain,pattern); + } + + /** + * Filters a set of ObjectName according to a given pattern. + * + * @param pattern the pattern that the returned names must match. + * @param all the set of names to filter. + * @return a set of ObjectName from which non matching names + * have been removed. + */ + public static Set filterMatchingNames(ObjectName pattern, + Set all) { + // If no pattern, just return all names + if (pattern == null + || all.isEmpty() + || ObjectName.WILDCARD.equals(pattern)) + return all; + + // If there's a pattern, do the matching. + final Set res = equivalentEmptySet(all); + for (ObjectName n : all) if (pattern.apply(n)) res.add(n); + return res; + } + + + /** + * Filters a set of ObjectInstance according to a given pattern. + * + * @param pattern the pattern that the returned names must match. + * @param all the set of instances to filter. + * @return a set of ObjectInstance from which non matching instances + * have been removed. + */ + public static Set + filterMatchingInstances(ObjectName pattern, + Set all) { + // If no pattern, just return all names + if (pattern == null + || all.isEmpty() + || ObjectName.WILDCARD.equals(pattern)) + return all; + + // If there's a pattern, do the matching. + final Set res = equivalentEmptySet(all); + for (ObjectInstance n : all) { + if (n == null) continue; + if (pattern.apply(n.getObjectName())) + res.add(n); + } + return res; + } + + /** + * An abstract ClassLoaderRepository that contains a single class loader. + **/ + private final static class SingleClassLoaderRepository + implements ClassLoaderRepository { + private final ClassLoader singleLoader; + + SingleClassLoaderRepository(ClassLoader loader) { + this.singleLoader = loader; + } + + ClassLoader getSingleClassLoader() { + return singleLoader; + } + + private Class loadClass(String className, ClassLoader loader) + throws ClassNotFoundException { + return Class.forName(className, false, loader); + } + + public Class loadClass(String className) + throws ClassNotFoundException { + return loadClass(className, getSingleClassLoader()); + } + + public Class loadClassWithout(ClassLoader exclude, + String className) throws ClassNotFoundException { + final ClassLoader loader = getSingleClassLoader(); + if (exclude != null && exclude.equals(loader)) + throw new ClassNotFoundException(className); + return loadClass(className, loader); + } + + public Class loadClassBefore(ClassLoader stop, String className) + throws ClassNotFoundException { + return loadClassWithout(stop, className); + } + } + + /** + * Returns a ClassLoaderRepository that contains a single class loader. + * @param loader the class loader contained in the returned repository. + * @return a ClassLoaderRepository that contains the single loader. + */ + public static ClassLoaderRepository getSingleClassLoaderRepository( + final ClassLoader loader) { + return new SingleClassLoaderRepository(loader); + } + + /** + * Returns the name of the given MBeanServer that should be put in a + * permission you need. + * This corresponds to the + * {@code *[;mbeanServerName=[;*]]} property + * embedded in the MBeanServerId attribute of the + * server's {@link MBeanServerDelegate}. + * + * @param server The MBean server + * @return the name of the MBeanServer, or "*" if the name couldn't be + * obtained, or {@value MBeanServerFactory#DEFAULT_MBEANSERVER_NAME} + * if there was no name. + */ + public static String getMBeanServerSecurityName(MBeanServer server) { + final String notfound = "*"; + try { + final String mbeanServerId = (String) + server.getAttribute(MBeanServerDelegate.DELEGATE_NAME, + "MBeanServerId"); + final String found = extractMBeanServerName(mbeanServerId); + if (found.length()==0) + return MBeanServerFactory.DEFAULT_MBEANSERVER_NAME; + return found; + } catch (Exception x) { + logshort("Failed to retrieve MBeanServerName for server, " + + "using \"*\"",x); + return notfound; + } + } + + /** + * Returns the name of the MBeanServer embedded in the given + * mbeanServerId. If the given mbeanServerId doesn't contain any name, + * an empty String is returned. + * The MBeanServerId is expected to be of the form: + * {@code *[;mbeanServerName=[;*]]} + * @param mbeanServerId The MBean server ID + * @return the name of the MBeanServer if found, or "" if the name was + * not present in the mbeanServerId. + */ + public static String extractMBeanServerName(String mbeanServerId) { + if (mbeanServerId==null) return ""; + final String beginMarker=";mbeanServerName="; + final String endMarker=";"; + final int found = mbeanServerId.indexOf(beginMarker); + if (found < 0) return ""; + final int start = found + beginMarker.length(); + final int stop = mbeanServerId.indexOf(endMarker, start); + return mbeanServerId.substring(start, + (stop < 0 ? mbeanServerId.length() : stop)); + } + + /** + * Insert the given mbeanServerName into the given mbeanServerId. + * If mbeanServerName is null, empty, or equals to "-", the returned + * mbeanServerId will not contain any mbeanServerName. + * @param mbeanServerId The mbeanServerId in which to insert + * mbeanServerName + * @param mbeanServerName The mbeanServerName + * @return an mbeanServerId containing the given mbeanServerName + * @throws IllegalArgumentException if mbeanServerId already contains + * a different name, or if the given mbeanServerName is not valid. + */ + public static String insertMBeanServerName(String mbeanServerId, + String mbeanServerName) { + final String found = extractMBeanServerName(mbeanServerId); + if (found.length() > 0 && + found.equals(checkServerName(mbeanServerName))) + return mbeanServerId; + if (found.length() > 0 && !isMBeanServerNameUndefined(found)) + throw new IllegalArgumentException( + "MBeanServerName already defined"); + if (isMBeanServerNameUndefined(mbeanServerName)) + return mbeanServerId; + final String beginMarker=";mbeanServerName="; + return mbeanServerId+beginMarker+checkServerName(mbeanServerName); + } + + /** + * Returns true if the given mbeanServerName corresponds to an + * undefined MBeanServerName. + * The mbeanServerName is considered undefined if it is one of: + * {@code null} or {@value MBeanServerFactory#DEFAULT_MBEANSERVER_NAME}. + * @param mbeanServerName The mbeanServerName, as returned by + * {@link #extractMBeanServerName(String)}. + * @return true if the given name corresponds to one of the forms that + * denotes an undefined MBeanServerName. + */ + public static boolean isMBeanServerNameUndefined(String mbeanServerName) { + return mbeanServerName == null || + MBeanServerFactory.DEFAULT_MBEANSERVER_NAME.equals(mbeanServerName); + } + /** + * Check that the provided mbeanServername is syntactically valid. + * @param mbeanServerName An mbeanServerName, or {@code null}. + * @return mbeanServerName, or {@value + * MBeanServerFactory#DEFAULT_MBEANSERVER_NAME} if {@code mbeanServerName} + * is {@code null}. + * @throws IllegalArgumentException if mbeanServerName contains illegal + * characters, or is empty, or is {@code "-"}. + * Illegal characters are {@link #ILLEGAL_MBEANSERVER_NAME_CHARS}. + */ + public static String checkServerName(String mbeanServerName) { + if ("".equals(mbeanServerName)) + throw new IllegalArgumentException( + "\"\" is not a valid MBean server name"); + if ("-".equals(mbeanServerName)) + throw new IllegalArgumentException( + "\"-\" is not a valid MBean server name"); + if (isMBeanServerNameUndefined(mbeanServerName)) + return MBeanServerFactory.DEFAULT_MBEANSERVER_NAME; + for (char c : ILLEGAL_MBEANSERVER_NAME_CHARS) { + if (mbeanServerName.indexOf(c) >= 0) + throw new IllegalArgumentException( + "invalid character in MBeanServer name: "+c); + } + return mbeanServerName; + } + + /** + * Get the MBeanServer name that should be put in a permission you need. + * + * @param delegate The MBeanServerDelegate + * @return The MBeanServer name - or {@value + * MBeanServerFactory#DEFAULT_MBEANSERVER_NAME} if there was no name. + */ + public static String getMBeanServerSecurityName( + MBeanServerDelegate delegate) { + try { + final String serverName = delegate.getMBeanServerName(); + if (isMBeanServerNameUndefined(serverName)) + return MBeanServerFactory.DEFAULT_MBEANSERVER_NAME; + return serverName; + } catch (Exception x) { + logshort("Failed to retrieve MBeanServerName from delegate, " + + "using \"*\"",x); + return "*"; + } + } + + // Log the exception and its causes without logging the stack trace. + // Use with care - it is usually preferable to log the whole stack trace! + // We don't want to log the whole stack trace here: logshort() is + // called in those cases where the exception might not be abnormal. + private static void logshort(String msg, Throwable t) { + if (JmxProperties.MISC_LOGGER.isLoggable(Level.FINE)) { + StringBuilder toprint = new StringBuilder(msg); + do { + toprint.append("\nCaused By: ").append(String.valueOf(t)); + } while ((t=t.getCause())!=null); + JmxProperties.MISC_LOGGER.fine(toprint.toString()); + } + } + + public static Set cloneSet(Set set) { + if (set instanceof SortedSet) { + @SuppressWarnings("unchecked") + SortedSet sset = (SortedSet) set; + set = new TreeSet(sset.comparator()); + set.addAll(sset); + } else + set = new HashSet(set); + return set; + } + + public static Set equivalentEmptySet(Set set) { + if (set instanceof SortedSet) { + @SuppressWarnings("unchecked") + SortedSet sset = (SortedSet) set; + set = new TreeSet(sset.comparator()); + } else + set = new HashSet(); + return set; + } + + // This exception is used when wrapping a class that throws IOException + // in a class that doesn't. + // The typical example for this are JMXNamespaces, when the sub + // MBeanServer can be remote. + // + public static RuntimeException newRuntimeIOException(IOException io) { + final String msg = "Communication failed with underlying resource: "+ + io.getMessage(); + return new RuntimeException(msg,io); + } } diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/DomainInterceptor.java b/jdk/src/share/classes/com/sun/jmx/namespace/DomainInterceptor.java new file mode 100644 index 00000000000..7b88087a81c --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/namespace/DomainInterceptor.java @@ -0,0 +1,468 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.namespace; + +import com.sun.jmx.defaults.JmxProperties; +import com.sun.jmx.mbeanserver.Util; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Queue; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.InstanceNotFoundException; +import javax.management.ListenerNotFoundException; +import javax.management.MBeanPermission; +import javax.management.MBeanServerDelegate; +import javax.management.MBeanServerNotification; +import javax.management.MalformedObjectNameException; +import javax.management.Notification; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.ObjectInstance; +import javax.management.ObjectName; +import javax.management.QueryExp; +import javax.management.namespace.JMXDomain; + +/** + * A DomainInterceptor wraps a JMXDomain. + *

    + * This API is a Sun internal API and is subject to changes without notice. + *

    + * @since 1.7 + */ +public class DomainInterceptor extends HandlerInterceptor { + + // TODO: Ideally DomainInterceptor should be replaced by + // something at Repository level. + // The problem there will be that we may need to + // reinstantiate the 'queryPerformedByRepos' boolean + // [or we will need to wrap the repository in + // a 'RepositoryInterceptor'?] + // Also there's no real need for a DomainInterceptor to + // extend RewritingMBeanServerConnection. + + + /** + * A logger for this class. + **/ + private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER; + + private final String domainName; + private volatile ObjectName ALL; + private final String serverName; + private volatile NotificationListener mbsListener; + + private static class PatternNotificationFilter + implements NotificationFilter { + + final ObjectName pattern; + public PatternNotificationFilter(ObjectName pattern) { + this.pattern = pattern==null?ObjectName.WILDCARD:pattern; + } + + public boolean isNotificationEnabled(Notification notification) { + if (!(notification instanceof MBeanServerNotification)) + return false; + final MBeanServerNotification mbsn = + (MBeanServerNotification) notification; + if (pattern.apply(mbsn.getMBeanName())) + return true; + return false; + } + + static final long serialVersionUID = 7409950927025262111L; + } + + /** + * Creates a new instance of NamespaceInterceptor + */ + public DomainInterceptor(String serverName, + JMXDomain handler, + String domainName) { + super(handler); + this.domainName = domainName; + this.serverName = serverName; + ALL = ObjectName.valueOf(domainName+":*"); + } + + @Override + public String toString() { + return this.getClass().getName()+"(parent="+serverName+ + ", domain="+this.domainName+")"; + } + + final void connectDelegate(final MBeanServerDelegate delegate) + throws InstanceNotFoundException { + final NotificationFilter filter = + new PatternNotificationFilter(getPatternFor(null)); + synchronized (this) { + if (mbsListener == null) { + mbsListener = new NotificationListener() { + public void handleNotification(Notification notification, + Object handback) { + if (filter.isNotificationEnabled(notification)) + delegate.sendNotification(notification); + } + }; + } + } + + getHandlerInterceptorMBean(). + addMBeanServerNotificationListener(mbsListener, filter); + } + + final void disconnectDelegate() + throws InstanceNotFoundException, ListenerNotFoundException { + final NotificationListener l; + synchronized (this) { + l = mbsListener; + if (l == null) return; + mbsListener = null; + } + getHandlerInterceptorMBean().removeMBeanServerNotificationListener(l); + } + + public final void addPostRegisterTask(Queue queue, + final MBeanServerDelegate delegate) { + if (queue == null) + throw new IllegalArgumentException("task queue must not be null"); + final Runnable task1 = new Runnable() { + public void run() { + try { + connectDelegate(delegate); + } catch (Exception x) { + throw new UnsupportedOperationException( + "notification forwarding",x); + } + } + }; + queue.add(task1); + } + + public final void addPostDeregisterTask(Queue queue, + final MBeanServerDelegate delegate) { + if (queue == null) + throw new IllegalArgumentException("task queue must not be null"); + final Runnable task1 = new Runnable() { + public void run() { + try { + disconnectDelegate(); + } catch (Exception x) { + throw new UnsupportedOperationException( + "notification forwarding",x); + } + } + }; + queue.add(task1); + } + + // No name conversion for JMXDomains... + // Throws IllegalArgumentException if targetName.getDomain() is not + // in the domain handled. + // + @Override + protected ObjectName toSource(ObjectName targetName) { + if (targetName == null) return null; + if (targetName.isDomainPattern()) return targetName; + final String targetDomain = targetName.getDomain(); + + // TODO: revisit this. RuntimeOperationsException may be better? + // + if (!targetDomain.equals(domainName)) + throw new IllegalArgumentException(targetName.toString()); + return targetName; + } + + // No name conversion for JMXDomains... + @Override + protected ObjectName toTarget(ObjectName sourceName) { + return sourceName; + } + + + + /** + * No rewriting: always return sources - stripping instances for which + * the caller doesn't have permissions. + **/ + @Override + Set processOutputInstances(Set sources) { + if (sources == null || sources.isEmpty() || !checkOn()) + return sources; + final Set res = Util.equivalentEmptySet(sources); + for (ObjectInstance o : sources) { + if (checkQuery(o.getObjectName(), "queryMBeans")) + res.add(o); + } + return res; + } + + + /** + * No rewriting: always return sourceNames - stripping names for which + * the caller doesn't have permissions. + **/ + @Override + Set processOutputNames(Set sourceNames) { + if (sourceNames == null || sourceNames.isEmpty() || !checkOn()) + return sourceNames; + final Set res = Util.equivalentEmptySet(sourceNames); + for (ObjectName o : sourceNames) { + if (checkQuery(o, "queryNames")) + res.add(o); + } + return res; + } + + /** No rewriting: always return source **/ + @Override + ObjectInstance processOutputInstance(ObjectInstance source) { + return source; + } + + @Override + public Set queryNames(ObjectName name, QueryExp query) { + try { + // We don't trust the wrapped JMXDomain... + final ObjectName pattern = getPatternFor(name); + final Set res = super.queryNames(pattern,query); + return Util.filterMatchingNames(pattern,res); + } catch (Exception x) { + if (LOG.isLoggable(Level.FINE)) + LOG.fine("Unexpected exception raised in queryNames: "+x); + LOG.log(Level.FINEST,"Unexpected exception raised in queryNames",x); + return Collections.emptySet(); + } + } + + // Compute a new pattern which is a sub pattern of 'name' but only selects + // the MBeans in domain 'domainName' + // When we reach here, it has been verified that 'name' matches our domain + // name (done by DomainDispatchInterceptor) + private ObjectName getPatternFor(final ObjectName name) { + try { + if (name == null) return ALL; + if (name.getDomain().equals(domainName)) return name; + return name.withDomain(domainName); + } catch (MalformedObjectNameException x) { + throw new IllegalArgumentException(String.valueOf(name),x); + } + } + + @Override + public Set queryMBeans(ObjectName name, QueryExp query) { + try { + // We don't trust the wrapped JMXDomain... + final ObjectName pattern = getPatternFor(name); + final Set res = super.queryMBeans(pattern,query); + return Util.filterMatchingInstances(pattern,res); + } catch (Exception x) { + if (LOG.isLoggable(Level.FINE)) + LOG.fine("Unexpected exception raised in queryNames: "+x); + LOG.log(Level.FINEST,"Unexpected exception raised in queryNames",x); + return Collections.emptySet(); + } + } + + @Override + public String getDefaultDomain() { + return domainName; + } + + @Override + public String[] getDomains() { + return new String[] {domainName}; + } + + // We call getMBeanCount() on the namespace rather than on the + // source server in order to avoid counting MBeans which are not + // in the domain. + @Override + public Integer getMBeanCount() { + return getHandlerInterceptorMBean().getMBeanCount(); + } + + private boolean checkOn() { + final SecurityManager sm = System.getSecurityManager(); + return (sm != null); + } + + // + // Implements permission checks. + // + @Override + void check(ObjectName routingName, String member, String action) { + if (!checkOn()) return; + final String act = (action==null)?"-":action; + if("queryMBeans".equals(act) || "queryNames".equals(act)) { + // This is tricky. check with 3 parameters is called + // by queryNames/queryMBeans before performing the query. + // At this point we must check with no class name. + // Therefore we pass a className of "-". + // The filtering will be done later - processOutputNames and + // processOutputInstance will call checkQuery. + // + check(routingName, "-", "-", act); + } else { + // This is also tricky: + // passing null here will cause check to retrieve the classname, + // if needed. + check(routingName, null, member, act); + } + } + + // + // Implements permission checks. + // + @Override + void checkCreate(ObjectName routingName, String className, String action) { + if (!checkOn()) return; + check(routingName,className,"-",action); + } + + // + // Implements permission checks. + // + void check(ObjectName routingName, String className, String member, + String action) { + if (!checkOn()) return; + final MBeanPermission perm; + + final String act = (action==null)?"-":action; + if ("getDomains".equals(act)) { // ES: OK + perm = new MBeanPermission(serverName,"-",member, + routingName,act); + } else { + final String clazz = + (className==null)?getClassName(routingName):className; + perm = new MBeanPermission(serverName,clazz,member, + routingName,act); + } + final SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkPermission(perm); + } + + String getClassName(ObjectName routingName) { + if (routingName == null || routingName.isPattern()) return "-"; + try { + return getHandlerInterceptorMBean().getSourceServer(). + getObjectInstance(routingName).getClassName(); + } catch (InstanceNotFoundException ex) { + LOG.finest("Can't get class name for "+routingName+ + ", using \"-\". Cause is: "+ex); + return "-"; + } + } + + // + // Implements permission filters for attributes... + // + @Override + AttributeList checkAttributes(ObjectName routingName, + AttributeList attributes, String action) { + if (!checkOn()) return attributes; + final String className = getClassName(routingName); + check(routingName,className,"-",action); + if (attributes == null || attributes.isEmpty()) return attributes; + final AttributeList res = new AttributeList(); + for (Attribute at : attributes.asList()) { + try { + check(routingName,className,at.getName(),action); + res.add(at); + } catch (SecurityException x) { // DLS: OK + continue; + } + } + return res; + } + + // + // Implements permission filters for attributes... + // + @Override + String[] checkAttributes(ObjectName routingName, String[] attributes, + String action) { + if (!checkOn()) return attributes; + final String className = getClassName(routingName); + check(routingName,className,"-",action); + if (attributes == null || attributes.length==0) return attributes; + final List res = new ArrayList(attributes.length); + for (String at : attributes) { + try { + check(routingName,className,at,action); + res.add(at); + } catch (SecurityException x) { // DLS: OK + continue; + } + } + return res.toArray(new String[res.size()]); + } + + // + // Implements permission filters for domains... + // + @Override + String[] checkDomains(String[] domains, String action) { + if (domains == null || domains.length==0 || !checkOn()) + return domains; + int count=0; + for (int i=0;i + * This API is a Sun internal API and is subject to changes without notice. + *

    + * @since 1.7 + */ +public abstract class HandlerInterceptor + extends RoutingMBeanServerConnection + implements MBeanServerInterceptor { + + /** + * A logger for this class. + **/ + private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER; + + // The wrapped JMXNamespace + private final T handler; + + /** + * Creates a new instance of HandlerInterceptor + */ + public HandlerInterceptor(T handler) { + if (handler == null) throw new IllegalArgumentException("null"); + this.handler = handler; + } + + // + // The {@code source} connection is a connection to the MBeanServer + // that contains the actual MBeans. + // In the case of cascading, that would be a connection to the sub + // agent. Practically, this is JMXNamespace.getSourceServer(); + // + @Override + protected MBeanServer source() { + return handler.getSourceServer(); + } + + // The MBeanServer on which getClassLoader / getClassLoaderFor + // will be called. + // The NamespaceInterceptor overrides this method - so that it + // getClassLoader / getClassLoaderFor don't trigger the loop + // detection mechanism. + // + MBeanServer getServerForLoading() { + return source(); + } + + // The namespace or domain handler - this either a JMXNamespace or a + // a JMXDomain + T getHandlerInterceptorMBean() { + return handler; + } + + // If the underlying JMXNamespace throws an IO, the IO will be + // wrapped in a RuntimeOperationsException. + RuntimeException handleIOException(IOException x,String fromMethodName, + Object... params) { + // Must do something here? + if (LOG.isLoggable(Level.FINEST)) { + LOG.finest("IO Exception in "+fromMethodName+": "+x+ + " - "+" rethrowing as RuntimeOperationsException."); + } + throw new RuntimeOperationsException( + Util.newRuntimeIOException(x)); + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public AttributeList getAttributes(ObjectName name, String[] attributes) + throws InstanceNotFoundException, ReflectionException { + try { + final String[] authorized = + checkAttributes(name,attributes,"getAttribute"); + final AttributeList attrList = + super.getAttributes(name,authorized); + return attrList; + } catch (IOException ex) { + throw handleIOException(ex,"getAttributes",name,attributes); + } + } + + // From MBeanServer + public ClassLoader getClassLoaderFor(ObjectName mbeanName) + throws InstanceNotFoundException { + final ObjectName sourceName = toSourceOrRuntime(mbeanName); + try { + check(mbeanName,null,"getClassLoaderFor"); + return getServerForLoading().getClassLoaderFor(sourceName); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + + // From MBeanServer + public ClassLoader getClassLoader(ObjectName loaderName) + throws InstanceNotFoundException { + final ObjectName sourceName = toSourceOrRuntime(loaderName); + try { + check(loaderName,null,"getClassLoader"); + return getServerForLoading().getClassLoader(sourceName); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // From MBeanServer + public ObjectInstance registerMBean(Object object, ObjectName name) + throws InstanceAlreadyExistsException, MBeanRegistrationException, + NotCompliantMBeanException { + final ObjectName sourceName = newSourceMBeanName(name); + try { + checkCreate(name,object.getClass().getName(),"registerMBean"); + return processOutputInstance( + source().registerMBean(object,sourceName)); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public void removeNotificationListener(ObjectName name, ObjectName listener) + throws InstanceNotFoundException, ListenerNotFoundException { + try { + check(name,null,"removeNotificationListener"); + super.removeNotificationListener(name,listener); + } catch (IOException ex) { + throw handleIOException(ex,"removeNotificationListener",name,listener); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public String getDefaultDomain() { + try { + return super.getDefaultDomain(); + } catch (IOException ex) { + throw handleIOException(ex,"getDefaultDomain"); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public String[] getDomains() { + try { + check(null,null,"getDomains"); + final String[] domains = super.getDomains(); + return checkDomains(domains,"getDomains"); + } catch (IOException ex) { + throw handleIOException(ex,"getDomains"); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public Integer getMBeanCount() { + try { + return super.getMBeanCount(); + } catch (IOException ex) { + throw handleIOException(ex,"getMBeanCount"); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public void setAttribute(ObjectName name, Attribute attribute) + throws InstanceNotFoundException, AttributeNotFoundException, + InvalidAttributeValueException, MBeanException, + ReflectionException { + try { + check(name, + (attribute==null?null:attribute.getName()), + "setAttribute"); + super.setAttribute(name,attribute); + } catch (IOException ex) { + throw handleIOException(ex,"setAttribute",name, attribute); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public Set queryNames(ObjectName name, QueryExp query) { + if (name == null) name=ObjectName.WILDCARD; + try { + checkPattern(name,null,"queryNames"); + return super.queryNames(name,query); + } catch (IOException ex) { + throw handleIOException(ex,"queryNames",name, query); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public Set queryMBeans(ObjectName name, QueryExp query) { + if (name == null) name=ObjectName.WILDCARD; + try { + checkPattern(name,null,"queryMBeans"); + return super.queryMBeans(name,query); + } catch (IOException ex) { + throw handleIOException(ex,"queryMBeans",name, query); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public boolean isInstanceOf(ObjectName name, String className) + throws InstanceNotFoundException { + try { + check(name, null, "isInstanceOf"); + return super.isInstanceOf(name, className); + } catch (IOException ex) { + throw handleIOException(ex,"isInstanceOf",name, className); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public ObjectInstance createMBean(String className, ObjectName name) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException { + try { + checkCreate(name, className, "instantiate"); + checkCreate(name, className, "registerMBean"); + return super.createMBean(className, name); + } catch (IOException ex) { + throw handleIOException(ex,"createMBean",className, name); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public ObjectInstance createMBean(String className, ObjectName name, + ObjectName loaderName) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, InstanceNotFoundException { + try { + checkCreate(name, className, "instantiate"); + checkCreate(name, className, "registerMBean"); + return super.createMBean(className, name, loaderName); + } catch (IOException ex) { + throw handleIOException(ex,"createMBean",className, name, loaderName); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public Object getAttribute(ObjectName name, String attribute) + throws MBeanException, AttributeNotFoundException, + InstanceNotFoundException, ReflectionException { + try { + check(name, attribute, "getAttribute"); + return super.getAttribute(name, attribute); + } catch (IOException ex) { + throw handleIOException(ex,"getAttribute",name, attribute); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public void removeNotificationListener(ObjectName name, ObjectName listener, + NotificationFilter filter, Object handback) + throws InstanceNotFoundException, ListenerNotFoundException { + try { + check(name,null,"removeNotificationListener"); + super.removeNotificationListener(name, listener, filter, handback); + } catch (IOException ex) { + throw handleIOException(ex,"removeNotificationListener",name, + listener, filter, handback); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public void removeNotificationListener(ObjectName name, + NotificationListener listener, NotificationFilter filter, + Object handback) + throws InstanceNotFoundException, ListenerNotFoundException { + try { + check(name,null,"removeNotificationListener"); + super.removeNotificationListener(name, listener, filter, handback); + } catch (IOException ex) { + throw handleIOException(ex,"removeNotificationListener",name, + listener, filter, handback); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public void removeNotificationListener(ObjectName name, + NotificationListener listener) + throws InstanceNotFoundException, ListenerNotFoundException { + try { + check(name,null,"removeNotificationListener"); + super.removeNotificationListener(name, listener); + } catch (IOException ex) { + throw handleIOException(ex,"removeNotificationListener",name, + listener); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public void addNotificationListener(ObjectName name, + NotificationListener listener, NotificationFilter filter, + Object handback) throws InstanceNotFoundException { + try { + check(name,null,"addNotificationListener"); + super.addNotificationListener(name, listener, filter, handback); + } catch (IOException ex) { + throw handleIOException(ex,"addNotificationListener",name, + listener, filter, handback); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public void addNotificationListener(ObjectName name, ObjectName listener, + NotificationFilter filter, Object handback) + throws InstanceNotFoundException { + try { + check(name,null,"addNotificationListener"); + super.addNotificationListener(name, listener, filter, handback); + } catch (IOException ex) { + throw handleIOException(ex,"addNotificationListener",name, + listener, filter, handback); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public boolean isRegistered(ObjectName name) { + try { + return super.isRegistered(name); + } catch (IOException ex) { + throw handleIOException(ex,"isRegistered",name); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public void unregisterMBean(ObjectName name) + throws InstanceNotFoundException, MBeanRegistrationException { + try { + check(name, null, "unregisterMBean"); + super.unregisterMBean(name); + } catch (IOException ex) { + throw handleIOException(ex,"unregisterMBean",name); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public MBeanInfo getMBeanInfo(ObjectName name) + throws InstanceNotFoundException, IntrospectionException, + ReflectionException { + try { + check(name, null, "getMBeanInfo"); + return super.getMBeanInfo(name); + } catch (IOException ex) { + throw handleIOException(ex,"getMBeanInfo",name); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public ObjectInstance getObjectInstance(ObjectName name) + throws InstanceNotFoundException { + try { + check(name, null, "getObjectInstance"); + return super.getObjectInstance(name); + } catch (IOException ex) { + throw handleIOException(ex,"getObjectInstance",name); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public ObjectInstance createMBean(String className, ObjectName name, + Object[] params, String[] signature) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException { + try { + checkCreate(name, className, "instantiate"); + checkCreate(name, className, "registerMBean"); + return super.createMBean(className, name, params, signature); + } catch (IOException ex) { + throw handleIOException(ex,"createMBean",className, name, + params, signature); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public ObjectInstance createMBean(String className, ObjectName name, + ObjectName loaderName, Object[] params, String[] signature) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, InstanceNotFoundException { + try { + checkCreate(name, className, "instantiate"); + checkCreate(name, className, "registerMBean"); + return super.createMBean(className, name, loaderName, params, + signature); + } catch (IOException ex) { + throw handleIOException(ex,"createMBean",className, name,loaderName, + params, signature); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public AttributeList setAttributes(ObjectName name,AttributeList attributes) + throws InstanceNotFoundException, ReflectionException { + try { + final AttributeList authorized = + checkAttributes(name, attributes, "setAttribute"); + return super.setAttributes(name, authorized); + } catch (IOException ex) { + throw handleIOException(ex,"setAttributes",name, attributes); + } + } + + // From MBeanServerConnection: catch & handles IOException + @Override + public Object invoke(ObjectName name, String operationName, Object[] params, + String[] signature) + throws InstanceNotFoundException, MBeanException, ReflectionException { + try { + check(name, operationName, "invoke"); + return super.invoke(name, operationName, params, signature); + } catch (IOException ex) { + throw handleIOException(ex,"invoke",name, operationName, + params, signature); + } + } + + // + // These methods are inherited from MBeanServer.... + // + + /** + * This method should never be called. + * Throws UnsupportedOperationException. + */ + public Object instantiate(String className) + throws ReflectionException, MBeanException { + if (LOG.isLoggable(Level.FINE)) + LOG.fine("call to unsupported instantiate method: " + + "trowing UnsupportedOperationException"); + throw new UnsupportedOperationException("Not applicable."); + } + + /** + * This method should never be called. + * Throws UnsupportedOperationException. + */ + public Object instantiate(String className, ObjectName loaderName) + throws ReflectionException, MBeanException, + InstanceNotFoundException { + if (LOG.isLoggable(Level.FINE)) + LOG.fine("call to unsupported method: instantiate(...) -" + + "throwing UnsupportedOperationException"); + throw new UnsupportedOperationException("Not applicable."); + } + + /** + * This method should never be called. + * Throws UnsupportedOperationException. + */ + public Object instantiate(String className, Object[] params, + String[] signature) throws ReflectionException, MBeanException { + if (LOG.isLoggable(Level.FINE)) + LOG.fine("call to unsupported method: instantiate(...) -" + + "throwing UnsupportedOperationException"); + throw new UnsupportedOperationException("Not applicable."); + } + + /** + * This method should never be called. + * Throws UnsupportedOperationException. + */ + public Object instantiate(String className, ObjectName loaderName, + Object[] params, String[] signature) + throws ReflectionException, MBeanException, + InstanceNotFoundException { + if (LOG.isLoggable(Level.FINE)) + LOG.fine("call to unsupported method: instantiate(...) -" + + "throwing UnsupportedOperationException"); + throw new UnsupportedOperationException("Not applicable."); + } + + /** + * This method should never be called. + * Throws UnsupportedOperationException. + */ + @Deprecated + public ObjectInputStream deserialize(ObjectName name, byte[] data) + throws InstanceNotFoundException, OperationsException { + if (LOG.isLoggable(Level.FINE)) + LOG.fine("call to unsupported method: deserialize(...) -" + + "throwing UnsupportedOperationException"); + throw new UnsupportedOperationException("Not applicable."); + } + + /** + * This method should never be called. + * Throws UnsupportedOperationException. + */ + @Deprecated + public ObjectInputStream deserialize(String className, byte[] data) + throws OperationsException, ReflectionException { + if (LOG.isLoggable(Level.FINE)) + LOG.fine("call to unsupported method: deserialize(...) -" + + "throwing UnsupportedOperationException"); + throw new UnsupportedOperationException("Not applicable."); + } + + /** + * This method should never be called. + * Throws UnsupportedOperationException. + */ + @Deprecated + public ObjectInputStream deserialize(String className, + ObjectName loaderName, byte[] data) + throws InstanceNotFoundException, OperationsException, + ReflectionException { + if (LOG.isLoggable(Level.FINE)) + LOG.fine("call to unsupported method: deserialize(...) -" + + "throwing UnsupportedOperationException"); + throw new UnsupportedOperationException("Not applicable."); + } + + /** + * This method should never be called. + * Throws UnsupportedOperationException. + */ + public ClassLoaderRepository getClassLoaderRepository() { + if (LOG.isLoggable(Level.FINE)) + LOG.fine("call to unsupported method: getClassLoaderRepository() -" + + "throwing UnsupportedOperationException"); + throw new UnsupportedOperationException("Not applicable."); + } + + static RuntimeException newUnsupportedException(String namespace) { + return new RuntimeOperationsException( + new UnsupportedOperationException( + "Not supported in this namespace: "+namespace)); + } + + /** + * A result might be excluded for security reasons. + */ + @Override + boolean excludesFromResult(ObjectName targetName, String queryMethod) { + return !checkQuery(targetName, queryMethod); + } + + + //---------------------------------------------------------------------- + // Hooks for checking permissions + //---------------------------------------------------------------------- + + /** + * This method is a hook to implement permission checking in subclasses. + * A subclass may override this method and throw a {@link + * SecurityException} if the permission is denied. + * + * @param routingName The name of the MBean in the enclosing context. + * This is of the form {@code //}. + * @param member The {@link + * javax.management.namespace.JMXNamespacePermission#getMember member} + * name. + * @param action The {@link + * javax.management.namespace.JMXNamespacePermission#getActions action} + * name. + * @throws SecurityException if the caller doesn't have the permission + * to perform the given action on the MBean pointed to + * by routingName. + */ + abstract void check(ObjectName routingName, + String member, String action); + + // called in createMBean and registerMBean + abstract void checkCreate(ObjectName routingName, String className, + String action); + + /** + * This is a hook to implement permission checking in subclasses. + * + * Checks that the caller has sufficient permission for returning + * information about {@code sourceName} in {@code action}. + * + * Subclass may override this method and return false if the caller + * doesn't have sufficient permissions. + * + * @param routingName The name of the MBean to include or exclude from + * the query, expressed in the enclosing context. + * This is of the form {@code //}. + * @param action one of "queryNames" or "queryMBeans" + * @return true if {@code sourceName} can be returned. + */ + abstract boolean checkQuery(ObjectName routingName, String action); + + /** + * This method is a hook to implement permission checking in subclasses. + * + * @param routingName The name of the MBean in the enclosing context. + * This is of the form {@code //}. + * @param attributes The list of attributes to check permission for. + * @param action one of "getAttribute" or "setAttribute" + * @return The list of attributes for which the callers has the + * appropriate {@link + * javax.management.namespace.JMXNamespacePermission}. + * @throws SecurityException if the caller doesn't have the permission + * to perform {@code action} on the MBean pointed to by routingName. + */ + abstract String[] checkAttributes(ObjectName routingName, + String[] attributes, String action); + + /** + * This method is a hook to implement permission checking in subclasses. + * + * @param routingName The name of the MBean in the enclosing context. + * This is of the form {@code //}. + * @param attributes The list of attributes to check permission for. + * @param action one of "getAttribute" or "setAttribute" + * @return The list of attributes for which the callers has the + * appropriate {@link + * javax.management.namespace.JMXNamespacePermission}. + * @throws SecurityException if the caller doesn't have the permission + * to perform {@code action} on the MBean pointed to by routingName. + */ + abstract AttributeList checkAttributes(ObjectName routingName, + AttributeList attributes, String action); + + /** + * This method is a hook to implement permission checking in subclasses. + * Checks that the caller as the necessary permissions to view the + * given domain. If not remove the domains for which the caller doesn't + * have permission from the list. + *

    + * By default, this method always returns {@code domains} + * + * @param domains The domains to return. + * @param action "getDomains" + * @return a filtered list of domains. + */ + String[] checkDomains(String[] domains, String action) { + return domains; + } + + // A priori check for queryNames/queryMBeans/ + void checkPattern(ObjectName routingPattern, + String member, String action) { + // pattern is checked only at posteriori by checkQuery. + // checking it a priori usually doesn't work, because ObjectName.apply + // does not work between two patterns. + // We only check that we have the permission requested for 'action'. + check(null,null,action); + } + + + +} diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/JMXNamespaceUtils.java b/jdk/src/share/classes/com/sun/jmx/namespace/JMXNamespaceUtils.java new file mode 100644 index 00000000000..49f875144f2 --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/namespace/JMXNamespaceUtils.java @@ -0,0 +1,354 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.namespace; + +import com.sun.jmx.defaults.JmxProperties; + +import java.io.IOException; +import java.util.Collections; +import java.util.Map; +import java.util.WeakHashMap; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.management.ListenerNotFoundException; +import javax.management.MBeanServerConnection; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.event.EventClient; +import javax.management.event.EventClientDelegateMBean; +import javax.management.namespace.JMXNamespace; +import javax.management.namespace.JMXNamespaces; +import javax.management.remote.JMXAddressable; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXServiceURL; +import javax.security.auth.Subject; + +/** + * A collection of methods that provide JMXConnector wrappers for + * JMXRemoteNamepaces underlying connectors. + *

    + * This API is a Sun internal API and is subject to changes without notice. + *

    + * @since 1.7 + */ +public final class JMXNamespaceUtils { + + /** + * A logger for this class. + **/ + private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER; + + + private static Map newWeakHashMap() { + return new WeakHashMap(); + } + + /** There are no instances of this class */ + private JMXNamespaceUtils() { + } + + // returns un unmodifiable view of a map. + public static Map unmodifiableMap(Map aMap) { + if (aMap == null || aMap.isEmpty()) + return Collections.emptyMap(); + return Collections.unmodifiableMap(aMap); + } + + + /** + * A base class that helps writing JMXConnectors that return + * MBeanServerConnection wrappers. + * This base class wraps an inner JMXConnector (the source), and preserve + * its caching policy. If a connection is cached in the source, its wrapper + * will be cached in this connector too. + * Author's note: rewriting this with java.lang.reflect.Proxy could be + * envisaged. It would avoid the combinatory sub-classing introduced by + * JMXAddressable. + *

    + * Note: all the standard JMXConnector implementations are serializable. + * This implementation here is not. Should it be? + * I believe it must not be serializable unless it becomes + * part of a public API (either standard or officially exposed + * and supported in a documented com.sun package) + **/ + static class JMXCachingConnector + implements JMXConnector { + + // private static final long serialVersionUID = -2279076110599707875L; + + final JMXConnector source; + + // if this object is made serializable, then the variable below + // needs to become volatile transient and be lazyly-created... + private final + Map connectionMap; + + + public JMXCachingConnector(JMXConnector source) { + this.source = checkNonNull(source, "source"); + connectionMap = newWeakHashMap(); + } + + private MBeanServerConnection + getCached(MBeanServerConnection inner) { + return connectionMap.get(inner); + } + + private MBeanServerConnection putCached(final MBeanServerConnection inner, + final MBeanServerConnection wrapper) { + if (inner == wrapper) return wrapper; + synchronized (this) { + final MBeanServerConnection concurrent = + connectionMap.get(inner); + if (concurrent != null) return concurrent; + connectionMap.put(inner,wrapper); + } + return wrapper; + } + + public void addConnectionNotificationListener(NotificationListener + listener, NotificationFilter filter, Object handback) { + source.addConnectionNotificationListener(listener,filter,handback); + } + + public void close() throws IOException { + source.close(); + } + + public void connect() throws IOException { + source.connect(); + } + + public void connect(Map env) throws IOException { + source.connect(env); + } + + public String getConnectionId() throws IOException { + return source.getConnectionId(); + } + + /** + * Preserve caching policy of the underlying connector. + **/ + public MBeanServerConnection + getMBeanServerConnection() throws IOException { + final MBeanServerConnection inner = + source.getMBeanServerConnection(); + final MBeanServerConnection cached = getCached(inner); + if (cached != null) return cached; + final MBeanServerConnection wrapper = wrap(inner); + return putCached(inner,wrapper); + } + + public MBeanServerConnection + getMBeanServerConnection(Subject delegationSubject) + throws IOException { + final MBeanServerConnection wrapped = + source.getMBeanServerConnection(delegationSubject); + synchronized (this) { + final MBeanServerConnection cached = getCached(wrapped); + if (cached != null) return cached; + final MBeanServerConnection wrapper = + wrapWithSubject(wrapped,delegationSubject); + return putCached(wrapped,wrapper); + } + } + + public void removeConnectionNotificationListener( + NotificationListener listener) + throws ListenerNotFoundException { + source.removeConnectionNotificationListener(listener); + } + + public void removeConnectionNotificationListener( + NotificationListener l, NotificationFilter f, + Object handback) throws ListenerNotFoundException { + source.removeConnectionNotificationListener(l,f,handback); + } + + /** + * This is the method that subclass will redefine. This method + * is called by {@code this.getMBeanServerConnection()}. + * {@code inner} is the connection returned by + * {@code source.getMBeanServerConnection()}. + **/ + protected MBeanServerConnection wrap(MBeanServerConnection inner) + throws IOException { + return inner; + } + + /** + * Subclass may also want to redefine this method. + * By default it calls wrap(inner). This method + * is called by {@code this.getMBeanServerConnection(Subject)}. + * {@code inner} is the connection returned by + * {@code source.getMBeanServerConnection(Subject)}. + **/ + protected MBeanServerConnection wrapWithSubject( + MBeanServerConnection inner, Subject delegationSubject) + throws IOException { + return wrap(inner); + } + + @Override + public String toString() { + if (source instanceof JMXAddressable) { + final JMXServiceURL address = + ((JMXAddressable)source).getAddress(); + if (address != null) + return address.toString(); + } + return source.toString(); + } + + } + + + /** + * The name space connector can do 'cd' + **/ + static class JMXNamespaceConnector extends JMXCachingConnector { + + // private static final long serialVersionUID = -4813611540843020867L; + + private final String toDir; + private final boolean closeable; + + public JMXNamespaceConnector(JMXConnector source, String toDir, + boolean closeable) { + super(source); + this.toDir = toDir; + this.closeable = closeable; + } + + @Override + public void close() throws IOException { + if (!closeable) + throw new UnsupportedOperationException("close"); + else super.close(); + } + + @Override + protected MBeanServerConnection wrap(MBeanServerConnection wrapped) + throws IOException { + if (LOG.isLoggable(Level.FINER)) + LOG.finer("Creating name space proxy connection for source: "+ + "namespace="+toDir); + return JMXNamespaces.narrowToNamespace(wrapped,toDir); + } + + @Override + public String toString() { + return "JMXNamespaces.narrowToNamespace("+ + super.toString()+ + ", \""+toDir+"\")"; + } + + } + + static class JMXEventConnector extends JMXCachingConnector { + + // private static final long serialVersionUID = 4742659236340242785L; + + JMXEventConnector(JMXConnector wrapped) { + super(wrapped); + } + + @Override + protected MBeanServerConnection wrap(MBeanServerConnection inner) + throws IOException { + return EventClient.getEventClientConnection(inner); + } + + + @Override + public String toString() { + return "EventClient.withEventClient("+super.toString()+")"; + } + } + + static class JMXAddressableEventConnector extends JMXEventConnector + implements JMXAddressable { + + // private static final long serialVersionUID = -9128520234812124712L; + + JMXAddressableEventConnector(JMXConnector wrapped) { + super(wrapped); + } + + public JMXServiceURL getAddress() { + return ((JMXAddressable)source).getAddress(); + } + } + + /** + * Creates a connector whose MBeamServerConnection will point to the + * given sub name space inside the source connector. + * @see JMXNamespace + **/ + public static JMXConnector cd(final JMXConnector source, + final String toNamespace, + final boolean closeable) + throws IOException { + + checkNonNull(source, "JMXConnector"); + + if (toNamespace == null || toNamespace.equals("")) + return source; + + return new JMXNamespaceConnector(source,toNamespace,closeable); + } + + + /** + * Returns a JMX Connector that will use an {@link EventClient} + * to subscribe for notifications. If the server doesn't have + * an {@link EventClientDelegateMBean}, then the connector will + * use the legacy notification mechanism instead. + * + * @param source The underlying JMX Connector wrapped by the returned + * connector. + * @return A JMX Connector that will uses an {@link EventClient}, if + * available. + * @see EventClient#getEventClientConnection(MBeanServerConnection) + */ + public static JMXConnector withEventClient(final JMXConnector source) { + checkNonNull(source, "JMXConnector"); + if (source instanceof JMXAddressable) + return new JMXAddressableEventConnector(source); + else + return new JMXEventConnector(source); + } + + public static T checkNonNull(T parameter, String name) { + if (parameter == null) + throw new IllegalArgumentException(name+" must not be null"); + return parameter; + } + + +} diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java b/jdk/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java new file mode 100644 index 00000000000..6862066d2bc --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java @@ -0,0 +1,225 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +package com.sun.jmx.namespace; + +import com.sun.jmx.defaults.JmxProperties; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.MBeanServer; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; +import javax.management.namespace.JMXNamespace; +import javax.management.namespace.JMXNamespacePermission; + +/** + * A NamespaceInterceptor wraps a JMXNamespace, performing + * ObjectName rewriting. + *

    + * This API is a Sun internal API and is subject to changes without notice. + *

    + * @since 1.7 + */ +public class NamespaceInterceptor extends HandlerInterceptor { + + + // The target name space in which the NamepsaceHandler is mounted. + private final String targetNs; + + private final String serverName; + + private final ObjectNameRouter proc; + + /** + * Creates a new instance of NamespaceInterceptor + */ + public NamespaceInterceptor( + String serverName, + JMXNamespace handler, + String targetNamespace) { + super(handler); + this.serverName = serverName; + this.targetNs = + ObjectNameRouter.normalizeNamespacePath(targetNamespace, + true, true, false); + proc = new ObjectNameRouter(targetNamespace, ""); + } + + @Override + public String toString() { + return this.getClass().getName()+"(parent="+serverName+ + ", namespace="+this.targetNs+")"; + } + + /** + * This method will send a probe to detect self-linking name spaces. + * A self linking namespace is a namespace that links back directly + * on itslef. Calling a method on such a name space always results + * in an infinite loop going through: + * [1]MBeanServer -> [2]NamespaceDispatcher -> [3]NamespaceInterceptor + * [4]JMXNamespace -> { network // or cd // or ... } -> [5]MBeanServer + * with exactly the same request than [1]... + * + * The namespace interceptor [2] tries to detect such condition the + * *first time* that the connection is used. It does so by setting + * a flag, and sending a queryNames() through the name space. If the + * queryNames comes back, it knows that there's a loop. + * + * The DynamicProbe interface can also be used by a Sun JMXNamespace + * implementation to request the emission of a probe at any time + * (see JMXRemoteNamespace implementation). + */ + private MBeanServer connection() { + final MBeanServer c = super.source(); + if (c != null) return c; + // should not come here + throw new NullPointerException("getMBeanServerConnection"); + } + + + @Override + protected MBeanServer source() { + return connection(); + } + + @Override + protected MBeanServer getServerForLoading() { + // don't want to send probe on getClassLoader/getClassLoaderFor + return super.source(); + } + + @Override + protected ObjectName toSource(ObjectName targetName) + throws MalformedObjectNameException { + return proc.toSourceContext(targetName, true); + } + + @Override + protected ObjectName toTarget(ObjectName sourceName) + throws MalformedObjectNameException { + return proc.toTargetContext(sourceName, false); + } + + // + // Implements permission checks. + // + @Override + void check(ObjectName routingName, String member, String action) { + final SecurityManager sm = System.getSecurityManager(); + if (sm == null) return; + if ("getDomains".equals(action)) return; + final JMXNamespacePermission perm = + new JMXNamespacePermission(serverName,member, + routingName,action); + sm.checkPermission(perm); + } + + @Override + void checkCreate(ObjectName routingName, String className, String action) { + final SecurityManager sm = System.getSecurityManager(); + if (sm == null) return; + final JMXNamespacePermission perm = + new JMXNamespacePermission(serverName,className, + routingName,action); + sm.checkPermission(perm); + } + + // + // Implements permission filters for attributes... + // + @Override + AttributeList checkAttributes(ObjectName routingName, + AttributeList attributes, String action) { + check(routingName,null,action); + if (attributes == null || attributes.isEmpty()) return attributes; + final SecurityManager sm = System.getSecurityManager(); + if (sm == null) return attributes; + final AttributeList res = new AttributeList(); + for (Attribute at : attributes.asList()) { + try { + check(routingName,at.getName(),action); + res.add(at); + } catch (SecurityException x) { // DLS: OK + continue; + } + } + return res; + } + + // + // Implements permission filters for attributes... + // + @Override + String[] checkAttributes(ObjectName routingName, String[] attributes, + String action) { + check(routingName,null,action); + if (attributes == null || attributes.length==0) return attributes; + final SecurityManager sm = System.getSecurityManager(); + if (sm == null) return attributes; + final List res = new ArrayList(attributes.length); + for (String at : attributes) { + try { + check(routingName,at,action); + res.add(at); + } catch (SecurityException x) { // DLS: OK + continue; + } + } + return res.toArray(new String[res.size()]); + } + + // + // Implements permission filters for domains... + // + @Override + String[] checkDomains(String[] domains, String action) { + // in principle, this method is never called because + // getDomains() will never be called - since there's + // no way that MBeanServer.getDomains() can be routed + // to a NamespaceInterceptor. + // + // This is also why there's no getDomains() in a + // JMXNamespacePermission... + // + return super.checkDomains(domains, action); + } + + // + // Implements permission filters for queries... + // + @Override + boolean checkQuery(ObjectName routingName, String action) { + try { + check(routingName,null,action); + return true; + } catch (SecurityException x) { // DLS: OK + return false; + } + } + +} diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/ObjectNameRouter.java b/jdk/src/share/classes/com/sun/jmx/namespace/ObjectNameRouter.java new file mode 100644 index 00000000000..3c7065c478e --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/namespace/ObjectNameRouter.java @@ -0,0 +1,191 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.namespace; + +import static javax.management.namespace.JMXNamespaces.NAMESPACE_SEPARATOR; + +import javax.management.MalformedObjectNameException; +import javax.management.ObjectInstance; +import javax.management.ObjectName; + +/** + * The ObjectNameRouter is used to rewrite routing object names. + *

    + * This API is a Sun internal API and is subject to changes without notice. + *

    + * @since 1.7 + */ +public class ObjectNameRouter { + + private static final int NAMESPACE_SEPARATOR_LENGTH = + NAMESPACE_SEPARATOR.length(); + + final String targetPrefix; + final String sourcePrefix; + final int slen; + final int tlen; + final boolean identity; + + + public ObjectNameRouter(String targetDirName) { + this(targetDirName,null); + } + + /** Creates a new instance of ObjectNameRouter */ + public ObjectNameRouter(final String remove, final String add) { + this.targetPrefix = (remove==null?"":remove); + this.sourcePrefix = (add==null?"":add); + tlen = targetPrefix.length(); + slen = sourcePrefix.length(); + identity = targetPrefix.equals(sourcePrefix); + } + + public final ObjectName toTargetContext(ObjectName sourceName, + boolean removeLeadingSeparators) { + if (sourceName == null) return null; + if (identity) return sourceName; + String srcDomain = sourceName.getDomain(); + + // if the ObjectName starts with // and removeLeadingSeparators is + // true, then recursively strip leading //. + // Otherwise, do not rewrite ObjectName. + // + if (srcDomain.startsWith(NAMESPACE_SEPARATOR)) { + if (!removeLeadingSeparators) return sourceName; + else srcDomain = normalizeDomain(srcDomain,true); + } + if (slen != 0) { + if (!srcDomain.startsWith(sourcePrefix) || + !srcDomain.startsWith(NAMESPACE_SEPARATOR,slen)) + throw new IllegalArgumentException( + "ObjectName does not start with expected prefix " + + sourcePrefix + ": " + + String.valueOf(sourceName)); + srcDomain = srcDomain.substring(slen+NAMESPACE_SEPARATOR_LENGTH); + } + final String targetDomain = + (tlen>0?targetPrefix+NAMESPACE_SEPARATOR+srcDomain:srcDomain); + try { + return sourceName.withDomain(targetDomain); + } catch (MalformedObjectNameException x) { + throw new IllegalArgumentException(String.valueOf(sourceName),x); + } + } + + public final ObjectName toSourceContext(ObjectName targetName, + boolean removeLeadingSeparators) { + if (targetName == null) return null; + if (identity) return targetName; + String targetDomain = targetName.getDomain(); + if (targetDomain.startsWith(NAMESPACE_SEPARATOR)) { + if (!removeLeadingSeparators) return targetName; + else targetDomain = + normalizeDomain(targetDomain,true); + } + if (tlen != 0) { + if (!targetDomain.startsWith(targetPrefix) || + !targetDomain.startsWith(NAMESPACE_SEPARATOR,tlen)) + throw new IllegalArgumentException( + "ObjectName does not start with expected prefix " + + targetPrefix + ": " + + String.valueOf(targetName)); + targetDomain = targetDomain. + substring(tlen+NAMESPACE_SEPARATOR_LENGTH); + } + final String sourceDomain = + (slen>0?sourcePrefix+NAMESPACE_SEPARATOR+targetDomain: + targetDomain); + try { + return targetName.withDomain(sourceDomain); + } catch (MalformedObjectNameException x) { + throw new IllegalArgumentException(String.valueOf(targetName),x); + } + } + + public final ObjectInstance toTargetContext(ObjectInstance sourceMoi, + boolean removeLeadingSeparators) { + if (sourceMoi == null) return null; + if (identity) return sourceMoi; + return new ObjectInstance( + toTargetContext(sourceMoi.getObjectName(), + removeLeadingSeparators), + sourceMoi.getClassName()); + } + + /** + * Removes leading, trailing, or duplicate // in a name space path. + **/ + public static String normalizeDomain(String domain, + boolean removeLeadingSep) { + return normalizeNamespacePath(domain,removeLeadingSep,false,true); + } + + /** + * Removes leading, trailing, or duplicate // in a name space path. + **/ + public static String normalizeNamespacePath(String namespacePath, + boolean removeLeadingSep, + boolean removeTrailingSep, + boolean endsWithDomain) { + if (namespacePath.equals("")) + return ""; + final String[] components = namespacePath.split(NAMESPACE_SEPARATOR); + final StringBuilder b = + new StringBuilder(namespacePath.length()+NAMESPACE_SEPARATOR_LENGTH); + String sep = null; + if (!removeLeadingSep && namespacePath.startsWith(NAMESPACE_SEPARATOR)) + b.append(NAMESPACE_SEPARATOR); + int count = 0; + for (int i=0; i 0) + b.append(NAMESPACE_SEPARATOR); + return b.toString(); + } + + +} diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingConnectionProxy.java b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingConnectionProxy.java new file mode 100644 index 00000000000..443c80f2ae5 --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingConnectionProxy.java @@ -0,0 +1,123 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.namespace; + + +import com.sun.jmx.defaults.JmxProperties; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.management.MBeanServerConnection; +import javax.management.namespace.JMXNamespaces; + + +/** + * A RoutingConnectionProxy is an MBeanServerConnection proxy that proxies a + * source name space in a source MBeanServerConnection. + * It wraps a source MBeanServerConnection, and rewrites routing + * ObjectNames. It is used to implement + * {@code JMXNamespaces.narrowToNamespace(MBeanServerConnection)}. + *

    + * This API is a Sun internal API and is subject to changes without notice. + *

    + * @since 1.7 + */ +// See class hierarchy and detailled explanations in RoutingProxy in this +// package. +// +public class RoutingConnectionProxy + extends RoutingProxy { + + /** + * A logger for this class. + **/ + private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER; + + + /** + * Creates a new instance of RoutingConnectionProxy + */ + public RoutingConnectionProxy(MBeanServerConnection source, + String sourceDir) { + this(source,sourceDir,"",false); + } + + /** + * Creates a new instance of RoutingConnectionProxy + */ + public RoutingConnectionProxy(MBeanServerConnection source, + String sourceDir, + String targetDir, + boolean forwardsContext) { + super(source,sourceDir,targetDir,forwardsContext); + + if (LOG.isLoggable(Level.FINER)) + LOG.finer("RoutingConnectionProxy for " + getSourceNamespace() + + " created"); + } + + @Override + public String toString() { + final String targetNs = getTargetNamespace(); + final String sourceNs = getSourceNamespace(); + String wrapped = String.valueOf(source()); + if ("".equals(targetNs)) { + if (forwardsContext) + wrapped = "ClientContext.withDynamicContext("+wrapped+")"; + return "JMXNamespaces.narrowToNamespace("+ + wrapped+", \""+ + sourceNs+"\")"; + } + return this.getClass().getSimpleName()+"("+wrapped+", \""+ + sourceNs+"\", \""+ + targetNs+"\", "+forwardsContext+")"; + } + + static final RoutingProxyFactory + + FACTORY = new RoutingProxyFactory + () { + + public RoutingConnectionProxy newInstance(MBeanServerConnection source, + String sourcePath, String targetPath, + boolean forwardsContext) { + return new RoutingConnectionProxy(source,sourcePath, + targetPath,forwardsContext); + } + + public RoutingConnectionProxy newInstance( + MBeanServerConnection source, String sourcePath) { + return new RoutingConnectionProxy(source,sourcePath); + } + }; + + public static MBeanServerConnection cd(MBeanServerConnection source, + String sourcePath) { + return RoutingProxy.cd(RoutingConnectionProxy.class, FACTORY, + source, sourcePath); + } + +} diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingMBeanServerConnection.java b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingMBeanServerConnection.java new file mode 100644 index 00000000000..7022e7e2973 --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingMBeanServerConnection.java @@ -0,0 +1,567 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.namespace; + +import com.sun.jmx.defaults.JmxProperties; +import com.sun.jmx.mbeanserver.Util; +import java.io.IOException; +import java.lang.reflect.UndeclaredThrowableException; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.AttributeNotFoundException; +import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; +import javax.management.IntrospectionException; +import javax.management.InvalidAttributeValueException; +import javax.management.JMRuntimeException; +import javax.management.ListenerNotFoundException; +import javax.management.MBeanException; +import javax.management.MBeanInfo; +import javax.management.MBeanRegistrationException; +import javax.management.MBeanServerConnection; +import javax.management.MalformedObjectNameException; +import javax.management.NotCompliantMBeanException; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.ObjectInstance; +import javax.management.ObjectName; +import javax.management.QueryExp; +import javax.management.ReflectionException; +import javax.management.RuntimeMBeanException; +import javax.management.RuntimeOperationsException; + +/** + * A RoutingMBeanServerConnection wraps a MBeanServerConnection, defining + * abstract methods that can be implemented by subclasses to rewrite + * routing ObjectNames. It is used to implement + * HandlerInterceptors (wrapping JMXNamespace instances) and routing + * proxies (used to implement cd operations). + *

    + * This API is a Sun internal API and is subject to changes without notice. + *

    + * @since 1.7 + */ +public abstract class RoutingMBeanServerConnection + implements MBeanServerConnection { + + /** + * A logger for this class. + **/ + private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER; + + /** + * Creates a new instance of RoutingMBeanServerConnection + */ + public RoutingMBeanServerConnection() { + } + + /** + * Returns the wrapped source connection. The {@code source} connection + * is a connection to the MBeanServer that contains the actual MBean. + * In the case of cascading, that would be a connection to the sub + * agent. + **/ + protected abstract T source() throws IOException; + + /** + * Converts a target ObjectName to a source ObjectName. + * The target ObjectName is the name of the MBean in the mount point + * target. In the case of cascading, that would be the name of the + * MBean in the master agent. So if a subagent S containing an MBean + * named "X" is mounted in the target namespace "foo//" of a master agent M, + * the source is S, the target is "foo//" in M, the source name is "X", and + * the target name is "foo//X". + * In the case of cascading - such as in NamespaceInterceptor, this method + * will convert "foo//X" (the targetName) into "X", the source name. + **/ + protected abstract ObjectName toSource(ObjectName targetName) + throws MalformedObjectNameException; + + /** + * Converts a source ObjectName to a target ObjectName. + * (see description of toSource above for explanations) + * In the case of cascading - such as in NamespaceInterceptor, this method + * will convert "X" (the sourceName) into "foo//X", the target name. + **/ + protected abstract ObjectName toTarget(ObjectName sourceName) + throws MalformedObjectNameException; + + /** + * Can be overridden by subclasses to check the validity of a new + * ObjectName used in createMBean or registerMBean. + * This method is typically used by subclasses which might require + * special handling for "null"; + **/ + protected ObjectName newSourceMBeanName(ObjectName targetName) + throws MBeanRegistrationException { + try { + return toSource(targetName); + } catch (Exception x) { + throw new MBeanRegistrationException(x,"Illegal MBean Name"); + } + } + + // Calls toSource(), Wraps MalformedObjectNameException. + ObjectName toSourceOrRuntime(ObjectName targetName) + throws RuntimeOperationsException { + try { + return toSource(targetName); + } catch (MalformedObjectNameException x) { + final IllegalArgumentException x2 = + new IllegalArgumentException(String.valueOf(targetName),x); + final RuntimeOperationsException x3 = + new RuntimeOperationsException(x2); + throw x3; + } + } + + + // Wraps given exception if needed. + RuntimeException makeCompliantRuntimeException(Exception x) { + if (x instanceof SecurityException) return (SecurityException)x; + if (x instanceof JMRuntimeException) return (JMRuntimeException)x; + if (x instanceof RuntimeException) + return new RuntimeOperationsException((RuntimeException)x); + if (x instanceof IOException) + return Util.newRuntimeIOException((IOException)x); + // shouldn't come here... + final RuntimeException x2 = new UndeclaredThrowableException(x); + return new RuntimeOperationsException(x2); + } + + // from MBeanServerConnection + public AttributeList getAttributes(ObjectName name, String[] attributes) + throws InstanceNotFoundException, ReflectionException, IOException { + final ObjectName sourceName = toSourceOrRuntime(name); + try { + return source().getAttributes(sourceName, attributes); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // from MBeanServerConnection + public Object invoke(ObjectName name, String operationName, Object[] params, + String[] signature) + throws InstanceNotFoundException, MBeanException, ReflectionException, + IOException { + final ObjectName sourceName = toSourceOrRuntime(name); + try { + final Object result = + source().invoke(sourceName,operationName,params, + signature); + return result; + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // from MBeanServerConnection + public void unregisterMBean(ObjectName name) + throws InstanceNotFoundException, MBeanRegistrationException, + IOException { + final ObjectName sourceName = toSourceOrRuntime(name); + try { + source().unregisterMBean(sourceName); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // from MBeanServerConnection + public MBeanInfo getMBeanInfo(ObjectName name) + throws InstanceNotFoundException, IntrospectionException, + ReflectionException, IOException { + final ObjectName sourceName = toSourceOrRuntime(name); + try { + return source().getMBeanInfo(sourceName); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // from MBeanServerConnection + public ObjectInstance getObjectInstance(ObjectName name) + throws InstanceNotFoundException, IOException { + final ObjectName sourceName = toSourceOrRuntime(name); + try { + return processOutputInstance( + source().getObjectInstance(sourceName)); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // from MBeanServerConnection + public boolean isRegistered(ObjectName name) throws IOException { + final ObjectName sourceName = toSourceOrRuntime(name); + try { + return source().isRegistered(sourceName); + } catch (RuntimeMBeanException x) { + throw new RuntimeOperationsException(x.getTargetException()); + } catch (RuntimeException x) { + throw makeCompliantRuntimeException(x); + } + } + + // from MBeanServerConnection + public void setAttribute(ObjectName name, Attribute attribute) + throws InstanceNotFoundException, AttributeNotFoundException, + InvalidAttributeValueException, MBeanException, + ReflectionException, IOException { + final ObjectName sourceName = toSourceOrRuntime(name); + try { + source().setAttribute(sourceName,attribute); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // from MBeanServerConnection + public ObjectInstance createMBean(String className, + ObjectName name, ObjectName loaderName, + Object[] params, String[] signature) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, InstanceNotFoundException, IOException { + final ObjectName sourceName = newSourceMBeanName(name); + // Loader Name is already a sourceLoaderName. + final ObjectName sourceLoaderName = loaderName; + try { + final ObjectInstance instance = + source().createMBean(className,sourceName, + sourceLoaderName, + params,signature); + return processOutputInstance(instance); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // from MBeanServerConnection + public ObjectInstance createMBean(String className, ObjectName name, + Object[] params, String[] signature) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, IOException { + final ObjectName sourceName = newSourceMBeanName(name); + try { + return processOutputInstance(source().createMBean(className, + sourceName,params,signature)); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // from MBeanServerConnection + public ObjectInstance createMBean(String className, ObjectName name, + ObjectName loaderName) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, InstanceNotFoundException, IOException { + final ObjectName sourceName = newSourceMBeanName(name); + // Loader Name is already a source Loader Name. + final ObjectName sourceLoaderName = loaderName; + try { + return processOutputInstance(source().createMBean(className, + sourceName,sourceLoaderName)); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // from MBeanServerConnection + public ObjectInstance createMBean(String className, ObjectName name) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, IOException { + final ObjectName sourceName = newSourceMBeanName(name); + try { + return processOutputInstance(source(). + createMBean(className,sourceName)); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // from MBeanServerConnection + public Object getAttribute(ObjectName name, String attribute) + throws MBeanException, AttributeNotFoundException, + InstanceNotFoundException, ReflectionException, IOException { + final ObjectName sourceName = toSourceOrRuntime(name); + try { + return source().getAttribute(sourceName,attribute); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // from MBeanServerConnection + public boolean isInstanceOf(ObjectName name, String className) + throws InstanceNotFoundException, IOException { + final ObjectName sourceName = toSourceOrRuntime(name); + try { + return source().isInstanceOf(sourceName,className); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // from MBeanServerConnection + public AttributeList setAttributes(ObjectName name, AttributeList attributes) + throws InstanceNotFoundException, ReflectionException, IOException { + final ObjectName sourceName = toSourceOrRuntime(name); + try { + return source(). + setAttributes(sourceName,attributes); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // Return names in the target's context. + Set processOutputInstances(Set sources) { + + final Set result = Util.equivalentEmptySet(sources); + for (ObjectInstance i : sources) { + try { + final ObjectInstance target = processOutputInstance(i); + if (excludesFromResult(target.getObjectName(), "queryMBeans")) + continue; + result.add(target); + } catch (Exception x) { + if (LOG.isLoggable(Level.FINE)) { + LOG.fine("Skiping returned item: " + + "Unexpected exception while processing " + + "ObjectInstance: " + x); + } + continue; + } + } + return result; + } + + + // Return names in the target's context. + ObjectInstance processOutputInstance(ObjectInstance source) { + if (source == null) return null; + final ObjectName sourceName = source.getObjectName(); + try { + final ObjectName targetName = toTarget(sourceName); + return new ObjectInstance(targetName,source.getClassName()); + } catch (MalformedObjectNameException x) { + final IllegalArgumentException x2 = + new IllegalArgumentException(String.valueOf(sourceName),x); + final RuntimeOperationsException x3 = + new RuntimeOperationsException(x2); + throw x3; + } + } + + // Returns names in the target's context. + Set processOutputNames(Set sourceNames) { + + final Set names = Util.equivalentEmptySet(sourceNames); + for (ObjectName n : sourceNames) { + try { + final ObjectName targetName = toTarget(n); + if (excludesFromResult(targetName, "queryNames")) continue; + names.add(targetName); + } catch (Exception x) { + if (LOG.isLoggable(Level.FINE)) { + LOG.fine("Skiping returned item: " + + "Unexpected exception while processing " + + "ObjectInstance: " + x); + } + continue; + } + } + return names; + } + + // from MBeanServerConnection + public Set queryMBeans(ObjectName name, + QueryExp query) throws IOException { + if (name == null) name=ObjectName.WILDCARD; + final ObjectName sourceName = toSourceOrRuntime(name); + try { + return processOutputInstances( + source().queryMBeans(sourceName,query)); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // from MBeanServerConnection + + public Set queryNames(ObjectName name, QueryExp query) + throws IOException { + if (name == null) name=ObjectName.WILDCARD; + final ObjectName sourceName = toSourceOrRuntime(name); + try { + final Set tmp = source().queryNames(sourceName,query); + final Set out = processOutputNames(tmp); + //System.err.println("queryNames: out: "+out); + return out; + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // from MBeanServerConnection + public void removeNotificationListener(ObjectName name, + NotificationListener listener) + throws InstanceNotFoundException, + ListenerNotFoundException, IOException { + final ObjectName sourceName = toSourceOrRuntime(name); + try { + source().removeNotificationListener(sourceName,listener); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // from MBeanServerConnection + public void addNotificationListener(ObjectName name, ObjectName listener, + NotificationFilter filter, Object handback) + throws InstanceNotFoundException, IOException { + final ObjectName sourceName = toSourceOrRuntime(name); + // Listener name is already a source listener name. + try { + source().addNotificationListener(sourceName,listener, + filter,handback); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // from MBeanServerConnection + public void addNotificationListener(ObjectName name, + NotificationListener listener, NotificationFilter filter, + Object handback) throws InstanceNotFoundException, IOException { + final ObjectName sourceName = toSourceOrRuntime(name); + try { + source().addNotificationListener(sourceName, listener, filter, + handback); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + + // from MBeanServerConnection + public void removeNotificationListener(ObjectName name, + NotificationListener listener, NotificationFilter filter, + Object handback) + throws InstanceNotFoundException, ListenerNotFoundException, + IOException { + final ObjectName sourceName = toSourceOrRuntime(name); + try { + source().removeNotificationListener(sourceName,listener,filter, + handback); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // from MBeanServerConnection + public void removeNotificationListener(ObjectName name, ObjectName listener, + NotificationFilter filter, Object handback) + throws InstanceNotFoundException, ListenerNotFoundException, + IOException { + final ObjectName sourceName = toSourceOrRuntime(name); + try { + source().removeNotificationListener(sourceName,listener, + filter,handback); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // from MBeanServerConnection + public void removeNotificationListener(ObjectName name, ObjectName listener) + throws InstanceNotFoundException, ListenerNotFoundException, + IOException { + final ObjectName sourceName = toSourceOrRuntime(name); + // listener name is already a source name... + final ObjectName sourceListener = listener; + try { + source().removeNotificationListener(sourceName,sourceListener); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // from MBeanServerConnection + public Integer getMBeanCount() throws IOException { + try { + return source().getMBeanCount(); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // from MBeanServerConnection + public String[] getDomains() throws IOException { + try { + return source().getDomains(); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // from MBeanServerConnection + public String getDefaultDomain() throws IOException { + try { + return source().getDefaultDomain(); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + /** + * Returns true if the given targetName must be excluded from the + * query result. + * In this base class, always return {@code false}. + * By default all object names returned by the sources are + * transmitted to the caller - there is no filtering. + * + * @param name A target object name expressed in the caller's + * context. In the case of cascading, where the source + * is a sub agent mounted on e.g. namespace "foo", + * that would be a name prefixed by "foo//"... + * @param queryMethod either "queryNames" or "queryMBeans". + * @return true if the name must be excluded. + */ + boolean excludesFromResult(ObjectName targetName, String queryMethod) { + return false; + } + +} diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingProxy.java b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingProxy.java new file mode 100644 index 00000000000..aa35c5bdaed --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingProxy.java @@ -0,0 +1,413 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.namespace; + +import com.sun.jmx.defaults.JmxProperties; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.management.MBeanException; +import javax.management.MBeanRegistrationException; + +import javax.management.MBeanServerConnection; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; +import javax.management.namespace.JMXNamespaces; + + +/** + * A RoutingProxy narrows on a given name space in a + * source object implementing MBeanServerConnection. + * It is used to implement + * {@code JMXNamespaces.narrowToNamespace(...)}. + * This abstract class has two concrete subclasses: + *

    {@link RoutingConnectionProxy}: to narrow down into an + * MBeanServerConnection.

    + *

    {@link RoutingServerProxy}: to narrow down into an MBeanServer.

    + * + *

    This class can also be used to "broaden" from a namespace. The same + * class is used for both purposes because in both cases all that happens + * is that ObjectNames are rewritten in one way on the way in (e.g. the + * parameter of getMBeanInfo) and another way on the way out (e.g. the + * return value of queryNames).

    + * + *

    Specifically, if you narrow into "a//" then you want to add the + * "a//" prefix to ObjectNames on the way in and subtract it on the way + * out. But ClientContext uses this class to subtract the + * "jmx.context//foo=bar//" prefix on the way in and add it back on the + * way out.

    + * + *

    + * This API is a Sun internal API and is subject to changes without notice. + *

    + * @since 1.7 + */ +// +// RoutingProxies are client side objects which are used to narrow down +// into a namespace. They are used to perform ObjectName translation, +// adding the namespace to the routing ObjectName before sending it over +// to the source connection, and removing that prefix from results of +// queries, createMBean, registerMBean, and getObjectInstance. +// This translation is the opposite to that which is performed by +// NamespaceInterceptors. +// +// There is however a special case where routing proxies are used on the +// 'server' side to remove a namespace - rather than to add it: +// This the case of ClientContext. +// When an ObjectName like "jmx.context//c1=v1,c2=v2//D:k=v" reaches the +// jmx.context namespace, a routing proxy is used to remove the prefix +// c1=v1,c2=v2// from the routing objectname. +// +// For a RoutingProxy used in a narrowDownToNamespace operation, we have: +// targetNs="" // targetNS is the namespace 'to remove' +// sourceNS= // namespace 'to add' +// +// For a RoutingProxy used in a ClientContext operation, we have: +// targetNs= // context must be removed from object name +// sourceNs="" // nothing to add... +// +// RoutingProxies can also be used on the client side to implement +// "withClientContext" operations. In that case, the boolean parameter +// 'forwards context' is set to true, targetNs is "", and sourceNS may +// also be "". When forwardsContext is true, the RoutingProxy dynamically +// creates an ObjectNameRouter for each operation - in order to dynamically add +// the context attached to the thread to the routing ObjectName. This is +// performed in the getObjectNameRouter() method. +// +// Finally, in order to avoid too many layers of wrapping, +// RoutingConnectionProxy and RoutingServerProxy can be created through a +// factory method that can concatenate namespace pathes in order to +// return a single RoutingProxy - rather than wrapping a RoutingProxy inside +// another RoutingProxy. See RoutingConnectionProxy.cd and +// RoutingServerProxy.cd +// +// The class hierarchy is as follows: +// +// RoutingMBeanServerConnection +// [abstract class for all routing interceptors, +// such as RoutingProxies and HandlerInterceptors] +// / \ +// / \ +// RoutingProxy HandlerInterceptor +// [base class for [base class for server side +// client-side objects used objects, created by +// in narrowDownTo] DispatchInterceptors] +// / \ | \ +// RoutingConnectionProxy \ | NamespaceInterceptor +// [wraps MBeanServerConnection \ | [used to remove +// objects] \ | namespace prefix and +// RoutingServerProxy | wrap JMXNamespace] +// [wraps MBeanServer | +// Objects] | +// DomainInterceptor +// [used to wrap JMXDomain] +// +// RoutingProxies also differ from HandlerInterceptors in that they transform +// calls to MBeanServerConnection operations that do not have any parameters +// into a call to the underlying JMXNamespace MBean. +// So for instance a call to: +// JMXNamespaces.narrowDownToNamespace(conn,"foo").getDomains() +// is transformed into +// conn.getAttribute("foo//type=JMXNamespace","Domains"); +// +public abstract class RoutingProxy + extends RoutingMBeanServerConnection { + + /** + * A logger for this class. + **/ + private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER; + + // The source MBeanServerConnection + private final T source; + + // The name space we're narrowing to (usually some name space in + // the source MBeanServerConnection + private final String sourceNs; + + // The name space we pretend to be mounted in (usually "") + private final String targetNs; + + // The name of the JMXNamespace that handles the source name space + private final ObjectName handlerName; + private final ObjectNameRouter router; + final boolean forwardsContext; + private volatile String defaultDomain = null; + + /** + * Creates a new instance of RoutingProxy + */ + protected RoutingProxy(T source, + String sourceNs, + String targetNs, + boolean forwardsContext) { + if (source == null) throw new IllegalArgumentException("null"); + this.sourceNs = JMXNamespaces.normalizeNamespaceName(sourceNs); + + // Usually sourceNs is not null, except when implementing + // Client Contexts + // + if (sourceNs.equals("")) { + this.handlerName = null; + } else { + // System.err.println("sourceNs: "+sourceNs); + this.handlerName = + JMXNamespaces.getNamespaceObjectName(this.sourceNs); + try { + // System.err.println("handlerName: "+handlerName); + if (!source.isRegistered(handlerName)) + throw new IllegalArgumentException(sourceNs + + ": no such name space"); + } catch (IOException x) { + throw new IllegalArgumentException("source stale: "+x,x); + } + } + this.source = source; + this.targetNs = (targetNs==null?"": + JMXNamespaces.normalizeNamespaceName(targetNs)); + this.router = + new ObjectNameRouter(this.targetNs,this.sourceNs); + this.forwardsContext = forwardsContext; + + if (LOG.isLoggable(Level.FINER)) + LOG.finer("RoutingProxy for " + this.sourceNs + " created"); + } + + @Override + public T source() { return source; } + + ObjectNameRouter getObjectNameRouter() { +// TODO: uncomment this when contexts are added +// if (forwardsContext) +// return ObjectNameRouter.wrapWithContext(router); +// else + return router; + } + + @Override + public ObjectName toSource(ObjectName targetName) + throws MalformedObjectNameException { + if (targetName == null) return null; + if (targetName.getDomain().equals("") && targetNs.equals("")) { + try { + if (defaultDomain == null) + defaultDomain = getDefaultDomain(); + } catch(Exception x) { + LOG.log(Level.FINEST,"Failed to get default domain",x); + } + if (defaultDomain != null) + targetName = targetName.withDomain(defaultDomain); + } + final ObjectNameRouter r = getObjectNameRouter(); + return r.toSourceContext(targetName,true); + } + + @Override + protected ObjectName newSourceMBeanName(ObjectName targetName) + throws MBeanRegistrationException { + if (targetName != null) return super.newSourceMBeanName(targetName); + + // OK => we can accept null if sourceNs is empty. + if (sourceNs.equals("")) return null; + + throw new MBeanRegistrationException( + new IllegalArgumentException( + "Can't use null ObjectName with namespaces")); + } + + @Override + public ObjectName toTarget(ObjectName sourceName) + throws MalformedObjectNameException { + if (sourceName == null) return null; + final ObjectNameRouter r = getObjectNameRouter(); + return r.toTargetContext(sourceName,false); + } + + private Object getAttributeFromHandler(String attributeName) + throws IOException { + + try { + return source().getAttribute(handlerName,attributeName); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } catch (IOException x) { + throw x; + } catch (MBeanException ex) { + throw new IOException("Failed to get "+attributeName+": "+ + ex.getCause(), + ex.getCause()); + } catch (Exception ex) { + throw new IOException("Failed to get "+attributeName+": "+ + ex,ex); + } + } + + // We cannot call getMBeanCount() on the underlying + // MBeanServerConnection, because it would return the number of + // 'top-level' MBeans, not the number of MBeans in the name space + // we are narrowing to. Instead we're calling getMBeanCount() on + // the JMXNamespace that handles the source name space. + // + // There is however one particular case when the sourceNs is empty. + // In that case, there's no handler - and the 'source' is the top + // level namespace. In that particular case, handlerName will be null, + // and we directly invoke the top level source(). + // This later complex case is only used when implementing ClientContexts. + // + @Override + public Integer getMBeanCount() throws IOException { + try { + if (handlerName == null) return source().getMBeanCount(); + return (Integer) getAttributeFromHandler("MBeanCount"); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // We cannot call getDomains() on the underlying + // MBeanServerConnection, because it would return the domains of + // 'top-level' MBeans, not the domains of MBeans in the name space + // we are narrowing to. Instead we're calling getDomains() on + // the JMXNamespace that handles the source name space. + // + // There is however one particular case when the sourceNs is empty. + // In that case, there's no handler - and the 'source' is the top + // level namespace. In that particular case, handlerName will be null, + // and we directly invoke the top level source(). + // This later complex case is only used when implementing ClientContexts. + // + @Override + public String[] getDomains() throws IOException { + try { + if (handlerName == null) return source().getDomains(); + return (String[]) getAttributeFromHandler("Domains"); + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + // We cannot call getDefaultDomain() on the underlying + // MBeanServerConnection, because it would return the default domain of + // 'top-level' namespace, not the default domain in the name space + // we are narrowing to. Instead we're calling getDefaultDomain() on + // the JMXNamespace that handles the source name space. + // + // There is however one particular case when the sourceNs is empty. + // In that case, there's no handler - and the 'source' is the top + // level namespace. In that particular case, handlerName will be null, + // and we directly invoke the top level source(). + // This later complex case is only used when implementing ClientContexts. + // + @Override + public String getDefaultDomain() throws IOException { + try { + if (handlerName == null) { + defaultDomain = source().getDefaultDomain(); + } else { + defaultDomain =(String) + getAttributeFromHandler("DefaultDomain"); + } + return defaultDomain; + } catch (RuntimeException ex) { + throw makeCompliantRuntimeException(ex); + } + } + + public String getSourceNamespace() { + return sourceNs; + } + + public String getTargetNamespace() { + return targetNs; + } + + @Override + public String toString() { + return super.toString()+", sourceNs="+ + sourceNs + (targetNs.equals("")?"": + (" mounted on targetNs="+targetNs)); + } + + // Creates an instance of a subclass 'R' of RoutingProxy + // RoutingServerProxy and RoutingConnectionProxy have their own factory + // instance. + static interface RoutingProxyFactory> { + R newInstance(T source, + String sourcePath, String targetPath, + boolean forwardsContext); + R newInstance(T source, + String sourcePath); + } + + // Performs a narrowDownToNamespace operation. + // This method will attempt to merge two RoutingProxies in a single + // one if they are of the same class. + // + // This method is never called directly - it should be called only by + // subclasses of RoutingProxy. + // + // As for now it is called by: + // RoutingServerProxy.cd and RoutingConnectionProxy.cd. + // + static > + R cd(Class routingProxyClass, + RoutingProxyFactory factory, + T source, String sourcePath) { + if (source == null) throw new IllegalArgumentException("null"); + if (source.getClass().equals(routingProxyClass)) { + // cast is OK here, but findbugs complains unless we use class.cast + final R other = routingProxyClass.cast(source); + final String target = other.getTargetNamespace(); + + // Avoid multiple layers of serialization. + // + // We construct a new proxy from the original source instead of + // stacking a new proxy on top of the old one. + // - that is we replace + // cd ( cd ( x, dir1), dir2); + // by + // cd (x, dir1//dir2); + // + // We can do this only when the source class is exactly + // RoutingServerProxy. + // + if (target == null || target.equals("")) { + final String path = + JMXNamespaces.concat(other.getSourceNamespace(), + sourcePath); + return factory.newInstance(other.source(),path,"", + other.forwardsContext); + } + // Note: we could do possibly something here - but it would involve + // removing part of targetDir, and possibly adding + // something to sourcePath. + // Too complex to bother! => simply default to stacking... + } + return factory.newInstance(source,sourcePath); + } +} diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingServerProxy.java b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingServerProxy.java new file mode 100644 index 00000000000..f58e39816d3 --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingServerProxy.java @@ -0,0 +1,590 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.namespace; + + +import com.sun.jmx.mbeanserver.Util; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.lang.reflect.UndeclaredThrowableException; +import java.util.Collections; +import java.util.Set; + +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.AttributeNotFoundException; +import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; +import javax.management.IntrospectionException; +import javax.management.InvalidAttributeValueException; +import javax.management.ListenerNotFoundException; +import javax.management.MBeanException; +import javax.management.MBeanInfo; +import javax.management.MBeanRegistrationException; +import javax.management.MBeanServer; +import javax.management.NotCompliantMBeanException; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.ObjectInstance; +import javax.management.ObjectName; +import javax.management.OperationsException; +import javax.management.QueryExp; +import javax.management.ReflectionException; +import javax.management.loading.ClassLoaderRepository; +import javax.management.namespace.JMXNamespaces; + +/** + * A RoutingServerProxy is an MBeanServer proxy that proxies a + * source name space in a source MBeanServer. + * It wraps a source MBeanServer, and rewrites routing ObjectNames. + * It is typically use for implementing 'cd' operations, and + * will add the source name space to routing ObjectNames at input, + * and remove it at output. + *

    + * This API is a Sun internal API and is subject to changes without notice. + *

    + * + * @since 1.7 + */ +// See class hierarchy and detailled explanations in RoutingProxy in this +// package. +// +public class RoutingServerProxy + extends RoutingProxy + implements MBeanServer { + + /** + * Creates a new instance of RoutingServerProxy + */ + public RoutingServerProxy(MBeanServer source, + String sourceNs) { + this(source,sourceNs,"",false); + } + + public RoutingServerProxy(MBeanServer source, + String sourceNs, + String targetNs, + boolean forwardsContext) { + super(source,sourceNs,targetNs,forwardsContext); + } + + /** + * This method is called each time an IOException is raised when + * trying to forward an operation to the underlying + * MBeanServerConnection, as a result of calling + * {@link #getMBeanServerConnection()} or as a result of invoking the + * operation on the returned connection. + * Subclasses may redefine this method if they need to perform any + * specific handling of IOException (logging etc...). + * @param x The raised IOException. + * @param method The name of the method in which the exception was + * raised. This is one of the methods of the MBeanServer + * interface. + * @return A RuntimeException that should be thrown by the caller. + * In this default implementation, this is an + * {@link UndeclaredThrowableException} wrapping x. + **/ + protected RuntimeException handleIOException(IOException x, + String method) { + return Util.newRuntimeIOException(x); + } + + + //-------------------------------------------- + //-------------------------------------------- + // + // Implementation of the MBeanServer interface + // + //-------------------------------------------- + //-------------------------------------------- + @Override + public void addNotificationListener(ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException { + try { + super.addNotificationListener(name, listener, + filter, handback); + } catch (IOException x) { + throw handleIOException(x,"addNotificationListener"); + } + } + + @Override + public void addNotificationListener(ObjectName name, + ObjectName listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException { + try { + super.addNotificationListener(name, listener, + filter, handback); + } catch (IOException x) { + throw handleIOException(x,"addNotificationListener"); + } + } + + @Override + public ObjectInstance createMBean(String className, ObjectName name) + throws + ReflectionException, + InstanceAlreadyExistsException, + MBeanRegistrationException, + MBeanException, + NotCompliantMBeanException { + try { + return super.createMBean(className, name); + } catch (IOException x) { + throw handleIOException(x,"createMBean"); + } + } + + @Override + public ObjectInstance createMBean(String className, ObjectName name, + Object params[], String signature[]) + throws + ReflectionException, + InstanceAlreadyExistsException, + MBeanRegistrationException, + MBeanException, + NotCompliantMBeanException { + try { + return super.createMBean(className, name, + params, signature); + } catch (IOException x) { + throw handleIOException(x,"createMBean"); + } + } + + @Override + public ObjectInstance createMBean(String className, + ObjectName name, + ObjectName loaderName) + throws + ReflectionException, + InstanceAlreadyExistsException, + MBeanRegistrationException, + MBeanException, + NotCompliantMBeanException, + InstanceNotFoundException { + try { + return super.createMBean(className, name, loaderName); + } catch (IOException x) { + throw handleIOException(x,"createMBean"); + } + } + + @Override + public ObjectInstance createMBean(String className, + ObjectName name, + ObjectName loaderName, + Object params[], + String signature[]) + throws + ReflectionException, + InstanceAlreadyExistsException, + MBeanRegistrationException, + MBeanException, + NotCompliantMBeanException, + InstanceNotFoundException { + try { + return super.createMBean(className, name, loaderName, + params, signature); + } catch (IOException x) { + throw handleIOException(x,"createMBean"); + } + } + + /** + * @deprecated see {@link MBeanServer#deserialize(ObjectName,byte[]) + * MBeanServer} + **/ + @Deprecated + public ObjectInputStream deserialize(ObjectName name, byte[] data) + throws InstanceNotFoundException, OperationsException { + final ObjectName sourceName = toSourceOrRuntime(name); + try { + return source().deserialize(sourceName,data); + } catch (RuntimeException x) { + throw makeCompliantRuntimeException(x); + } + } + + /** + * @deprecated see {@link MBeanServer#deserialize(String,byte[]) + * MBeanServer} + */ + @Deprecated + public ObjectInputStream deserialize(String className, byte[] data) + throws OperationsException, ReflectionException { + try { + return source().deserialize(className,data); + } catch (RuntimeException x) { + throw makeCompliantRuntimeException(x); + } + } + + /** + * @deprecated see {@link MBeanServer#deserialize(String,ObjectName,byte[]) + * MBeanServer} + */ + @Deprecated + public ObjectInputStream deserialize(String className, + ObjectName loaderName, + byte[] data) + throws + InstanceNotFoundException, + OperationsException, + ReflectionException { + try { + return source().deserialize(className,loaderName,data); + } catch (RuntimeException x) { + throw makeCompliantRuntimeException(x); + } + } + + @Override + public Object getAttribute(ObjectName name, String attribute) + throws + MBeanException, + AttributeNotFoundException, + InstanceNotFoundException, + ReflectionException { + try { + return super.getAttribute(name, attribute); + } catch (IOException x) { + throw handleIOException(x,"getAttribute"); + } + } + + @Override + public AttributeList getAttributes(ObjectName name, String[] attributes) + throws InstanceNotFoundException, ReflectionException { + try { + return super.getAttributes(name, attributes); + } catch (IOException x) { + throw handleIOException(x,"getAttributes"); + } + } + + public ClassLoader getClassLoader(ObjectName loaderName) + throws InstanceNotFoundException { + final ObjectName sourceName = toSourceOrRuntime(loaderName); + try { + return source().getClassLoader(sourceName); + } catch (RuntimeException x) { + throw makeCompliantRuntimeException(x); + } + } + + public ClassLoader getClassLoaderFor(ObjectName mbeanName) + throws InstanceNotFoundException { + final ObjectName sourceName = toSourceOrRuntime(mbeanName); + try { + return source().getClassLoaderFor(sourceName); + } catch (RuntimeException x) { + throw makeCompliantRuntimeException(x); + } + } + + public ClassLoaderRepository getClassLoaderRepository() { + try { + return source().getClassLoaderRepository(); + } catch (RuntimeException x) { + throw makeCompliantRuntimeException(x); + } + } + + @Override + public String getDefaultDomain() { + try { + return super.getDefaultDomain(); + } catch (IOException x) { + throw handleIOException(x,"getDefaultDomain"); + } + } + + @Override + public String[] getDomains() { + try { + return super.getDomains(); + } catch (IOException x) { + throw handleIOException(x,"getDomains"); + } + } + + @Override + public Integer getMBeanCount() { + try { + return super.getMBeanCount(); + } catch (IOException x) { + throw handleIOException(x,"getMBeanCount"); + } + } + + @Override + public MBeanInfo getMBeanInfo(ObjectName name) + throws + InstanceNotFoundException, + IntrospectionException, + ReflectionException { + try { + return super.getMBeanInfo(name); + } catch (IOException x) { + throw handleIOException(x,"getMBeanInfo"); + } + } + + @Override + public ObjectInstance getObjectInstance(ObjectName name) + throws InstanceNotFoundException { + try { + return super.getObjectInstance(name); + } catch (IOException x) { + throw handleIOException(x,"getObjectInstance"); + } + } + + public Object instantiate(String className) + throws ReflectionException, MBeanException { + try { + return source().instantiate(className); + } catch (RuntimeException x) { + throw makeCompliantRuntimeException(x); + } + } + + public Object instantiate(String className, + Object params[], + String signature[]) + throws ReflectionException, MBeanException { + try { + return source().instantiate(className, + params,signature); + } catch (RuntimeException x) { + throw makeCompliantRuntimeException(x); + } + } + + public Object instantiate(String className, ObjectName loaderName) + throws ReflectionException, MBeanException, + InstanceNotFoundException { + final ObjectName srcLoaderName = toSourceOrRuntime(loaderName); + try { + return source().instantiate(className,srcLoaderName); + } catch (RuntimeException x) { + throw makeCompliantRuntimeException(x); + } + } + + public Object instantiate(String className, ObjectName loaderName, + Object params[], String signature[]) + throws ReflectionException, MBeanException, + InstanceNotFoundException { + final ObjectName srcLoaderName = toSourceOrRuntime(loaderName); + try { + return source().instantiate(className,srcLoaderName, + params,signature); + } catch (RuntimeException x) { + throw makeCompliantRuntimeException(x); + } + } + + @Override + public Object invoke(ObjectName name, String operationName, + Object params[], String signature[]) + throws + InstanceNotFoundException, + MBeanException, + ReflectionException { + try { + return super.invoke(name,operationName,params,signature); + } catch (IOException x) { + throw handleIOException(x,"invoke"); + } + } + + @Override + public boolean isInstanceOf(ObjectName name, String className) + throws InstanceNotFoundException { + try { + return super.isInstanceOf(name, className); + } catch (IOException x) { + throw handleIOException(x,"isInstanceOf"); + } + } + + @Override + public boolean isRegistered(ObjectName name) { + try { + return super.isRegistered(name); + } catch (IOException x) { + throw handleIOException(x,"isRegistered"); + } + } + + @Override + public Set queryMBeans(ObjectName name, QueryExp query) { + try { + return super.queryMBeans(name, query); + } catch (IOException x) { + handleIOException(x,"queryMBeans"); + return Collections.emptySet(); + } + } + + @Override + public Set queryNames(ObjectName name, QueryExp query) { + try { + return super.queryNames(name, query); + } catch (IOException x) { + handleIOException(x,"queryNames"); + return Collections.emptySet(); + } + } + + public ObjectInstance registerMBean(Object object, ObjectName name) + throws + InstanceAlreadyExistsException, + MBeanRegistrationException, + NotCompliantMBeanException { + final ObjectName sourceName = newSourceMBeanName(name); + try { + return processOutputInstance( + source().registerMBean(object,sourceName)); + } catch (RuntimeException x) { + throw makeCompliantRuntimeException(x); + } + } + + @Override + public void removeNotificationListener(ObjectName name, + NotificationListener listener) + throws InstanceNotFoundException, ListenerNotFoundException { + try { + super.removeNotificationListener(name, listener); + } catch (IOException x) { + throw handleIOException(x,"removeNotificationListener"); + } + } + + @Override + public void removeNotificationListener(ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException, ListenerNotFoundException { + try { + super.removeNotificationListener(name, listener, + filter, handback); + } catch (IOException x) { + throw handleIOException(x,"removeNotificationListener"); + } + } + + @Override + public void removeNotificationListener(ObjectName name, + ObjectName listener) + throws InstanceNotFoundException, ListenerNotFoundException { + try { + super.removeNotificationListener(name, listener); + } catch (IOException x) { + throw handleIOException(x,"removeNotificationListener"); + } + } + + @Override + public void removeNotificationListener(ObjectName name, + ObjectName listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException, ListenerNotFoundException { + try { + super.removeNotificationListener(name, listener, + filter, handback); + } catch (IOException x) { + throw handleIOException(x,"removeNotificationListener"); + } + } + + @Override + public void setAttribute(ObjectName name, Attribute attribute) + throws + InstanceNotFoundException, + AttributeNotFoundException, + InvalidAttributeValueException, + MBeanException, + ReflectionException { + try { + super.setAttribute(name, attribute); + } catch (IOException x) { + throw handleIOException(x,"setAttribute"); + } + } + + @Override + public AttributeList setAttributes(ObjectName name, + AttributeList attributes) + throws InstanceNotFoundException, ReflectionException { + try { + return super.setAttributes(name, attributes); + } catch (IOException x) { + throw handleIOException(x,"setAttributes"); + } + } + + @Override + public void unregisterMBean(ObjectName name) + throws InstanceNotFoundException, MBeanRegistrationException { + try { + super.unregisterMBean(name); + } catch (IOException x) { + throw handleIOException(x,"unregisterMBean"); + } + } + + static final RoutingProxyFactory + FACTORY = new RoutingProxyFactory() { + + public RoutingServerProxy newInstance(MBeanServer source, + String sourcePath, String targetPath, + boolean forwardsContext) { + return new RoutingServerProxy(source,sourcePath, + targetPath,forwardsContext); + } + + public RoutingServerProxy newInstance( + MBeanServer source, String sourcePath) { + return new RoutingServerProxy(source,sourcePath); + } + }; + + public static MBeanServer cd(MBeanServer source, String sourcePath) { + return RoutingProxy.cd(RoutingServerProxy.class, FACTORY, + source, sourcePath); + } +} diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/package.html b/jdk/src/share/classes/com/sun/jmx/namespace/package.html new file mode 100644 index 00000000000..6677288ca88 --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/namespace/package.html @@ -0,0 +1,45 @@ + + + + + The <code>com.sun.jmx.namespace</code> package + + + +

    The com.sun.jmx.namespace package contains + sun specific implementation classes used to implement the + JMX namespaces. +

    +

    DO NOT USE THESE CLASSES DIRECTLY

    +

    + This API is a Sun internal API and is subject to changes without notice. +

    +

    The public API through wich these proprietary classes can be + invoked is located in javax.management.namespace + package. +

    + + diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/serial/DefaultRewritingProcessor.java b/jdk/src/share/classes/com/sun/jmx/namespace/serial/DefaultRewritingProcessor.java new file mode 100644 index 00000000000..f458378cbcc --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/namespace/serial/DefaultRewritingProcessor.java @@ -0,0 +1,150 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.namespace.serial; + + +import javax.management.ObjectInstance; +import javax.management.ObjectName; + +/** + * Class DefaultRewritingProcessor. Rewrite ObjectName in input & output + * parameters. + *

    + * This API is a Sun internal API and is subject to changes without notice. + *

    + * @since 1.7 + */ +// We know that rewriting using serialization is costly. +// This object tries to determine whether an object needs rewriting prior +// to rewriting, and rewrites by creating a new object in those cases +// where we know how to recreate a new object (e.g. a Notification). +// Rewriting is however usually not used - so this object is just a +// skeleton that eventually uses serialization... +// +class DefaultRewritingProcessor extends RewritingProcessor { + + + private static enum RewriteMode { + INPUT, // Input from target to source (parameters) + OUTPUT // Output from source to target (results) + }; + + private final boolean identity; + + public DefaultRewritingProcessor(String targetDirName) { + this(targetDirName,null); + } + + /** Creates a new instance of SerialParamProcessor */ + public DefaultRewritingProcessor(final String remove, final String add) { + super(new SerialRewritingProcessor(remove, add)); + identity = remove.equals(add); + } + + private ObjectName rewriteObjectName(RewriteMode mode, + ObjectName name) { + return changeContext(mode, name); + } + + private ObjectInstance rewriteObjectInstance(RewriteMode mode, + ObjectInstance moi) { + final ObjectName srcName = moi.getObjectName(); + final ObjectName targetName = changeContext(mode,srcName); + if (targetName == srcName) return moi; + return new ObjectInstance(targetName,moi.getClassName()); + } + + + private Object processObject(RewriteMode mode, Object obj) { + if (obj == null) return null; + + // Some things which will always needs rewriting: + // ObjectName, ObjectInstance, and Notifications. + // Take care of those we can handle here... + // + if (obj instanceof ObjectName) + return rewriteObjectName(mode,(ObjectName) obj); + else if (obj instanceof ObjectInstance) + return rewriteObjectInstance(mode,(ObjectInstance) obj); + + // TODO: add other standard JMX classes - like e.g. MBeanInfo... + // + + // Well, the object may contain an ObjectName => pass it to + // our serial rewriting delegate... + // + return processAnyObject(mode,obj); + } + + + private Object processAnyObject(RewriteMode mode, Object obj) { + switch (mode) { + case INPUT: + return super.rewriteInput(obj); + case OUTPUT: + return super.rewriteOutput(obj); + default: // can't happen. + throw new AssertionError(); + } + } + + private ObjectName changeContext(RewriteMode mode, ObjectName name) { + switch (mode) { + case INPUT: + return toSourceContext(name); + case OUTPUT: + return toTargetContext(name); + default: // can't happen. + throw new AssertionError(); + } + } + + @Override + public ObjectName toTargetContext(ObjectName srcName) { + if (identity) return srcName; + return super.toTargetContext(srcName); + } + + @Override + public ObjectName toSourceContext(ObjectName targetName) { + if (identity) return targetName; + return super.toSourceContext(targetName); + } + + @SuppressWarnings("unchecked") + @Override + public T rewriteInput(T input) { + if (identity) return input; + return (T) processObject(RewriteMode.INPUT,input); + } + + @SuppressWarnings("unchecked") + @Override + public T rewriteOutput(T result) { + if (identity) return result; + return (T) processObject(RewriteMode.OUTPUT,result); + } +} diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/serial/IdentityProcessor.java b/jdk/src/share/classes/com/sun/jmx/namespace/serial/IdentityProcessor.java new file mode 100644 index 00000000000..32cca2d2dc4 --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/namespace/serial/IdentityProcessor.java @@ -0,0 +1,74 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.namespace.serial; + + +import javax.management.ObjectInstance; +import javax.management.ObjectName; + +/** + * Class RoutingOnlyProcessor. A RewritingProcessor that uses + * Java Serialization to rewrite ObjectNames contained in + * input & results... + *

    + * This API is a Sun internal API and is subject to changes without notice. + *

    + * + * @since 1.7 + */ +class IdentityProcessor extends RewritingProcessor { + + + /** Creates a new instance of SerialRewritingProcessor */ + public IdentityProcessor() { + } + + @Override + public T rewriteOutput(T result) { + return result; + } + + @Override + public T rewriteInput(T input) { + return input; + } + + @Override + public final ObjectName toTargetContext(ObjectName sourceName) { + return sourceName; + } + + @Override + public final ObjectInstance toTargetContext(ObjectInstance sourceMoi) { + return sourceMoi; + } + + @Override + public final ObjectName toSourceContext(ObjectName targetName) { + return targetName; + } + +} diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/serial/JMXNamespaceContext.java b/jdk/src/share/classes/com/sun/jmx/namespace/serial/JMXNamespaceContext.java new file mode 100644 index 00000000000..6416bfb9644 --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/namespace/serial/JMXNamespaceContext.java @@ -0,0 +1,145 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.namespace.serial; + +import com.sun.jmx.defaults.JmxProperties; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.logging.Level; +import java.util.logging.Logger; + + +/** + * The JMXNamespaceContext class is used to implement a thread local + * serialization / deserialization context for namespaces. + *

    + * This class is consulted by {@link javax.management.ObjectName} at + * serialization / deserialization time. + * The serialization or deserialization context is established by + * by the {@link SerialRewritingProcessor} defined in this package. + *

    + * These classes are Sun proprietary APIs, subject to change without + * notice. Do not use these classes directly. + * The public API to rewrite ObjectNames embedded in parameters is + * defined in {@link javax.management.namespace.JMXNamespaces}. + * + *

    + * This API is a Sun internal API and is subject to changes without notice. + *

    + * @since 1.7 + */ +public class JMXNamespaceContext { + + private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER; + + public final String prefixToRemove; + public final String prefixToAdd; + + private JMXNamespaceContext(String add, String remove) { + prefixToRemove = (remove==null?"":remove); + prefixToAdd = (add==null?"":add); + } + + private final static class SerialContext { + private JMXNamespaceContext serializationContext; + private JMXNamespaceContext deserializationContext; + public SerialContext(){ + serializationContext = new JMXNamespaceContext("",""); + deserializationContext = new JMXNamespaceContext("",""); + } + } + + private final static ThreadLocal prefix = + new ThreadLocal() { + @Override + protected SerialContext initialValue() { + return new SerialContext(); + } + }; + + public static JMXNamespaceContext getSerializationContext() { + return prefix.get().serializationContext; + } + + public static JMXNamespaceContext getDeserializationContext() { + return prefix.get().deserializationContext; + } + + private static String[] setSerializationContext(String oldPrefix, + String newPrefix) { + final SerialContext c = prefix.get(); + JMXNamespaceContext dc = c.serializationContext; + String[] old = {dc.prefixToRemove, dc.prefixToAdd}; + c.serializationContext = new JMXNamespaceContext(newPrefix,oldPrefix); + return old; + } + + private static String[] setDeserializationContext(String oldPrefix, + String newPrefix) { + final SerialContext c = prefix.get(); + JMXNamespaceContext dc = c.deserializationContext; + String[] old = {dc.prefixToRemove, dc.prefixToAdd}; + c.deserializationContext = new JMXNamespaceContext(newPrefix,oldPrefix); + return old; + } + + static void serialize(ObjectOutputStream stream, Object obj, + String prefixToRemove, String prefixToAdd) + throws IOException { + final String[] old = + setSerializationContext(prefixToRemove,prefixToAdd); + try { + stream.writeObject(obj); + } finally { + try { + setSerializationContext(old[0],old[1]); + } catch (Exception x) { + LOG.log(Level.FINEST, + "failed to restore serialization context",x); + } + } + } + + static Object deserialize(ObjectInputStream stream, + String prefixToRemove, + String prefixToAdd) + throws IOException, ClassNotFoundException { + final String[] old = + setDeserializationContext(prefixToRemove,prefixToAdd); + try { + return stream.readObject(); + } finally { + try { + setDeserializationContext(old[0],old[1]); + } catch (Exception x) { + LOG.log(Level.FINEST, + "failed to restore serialization context",x); + } + } + } + +} diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/serial/RewritingProcessor.java b/jdk/src/share/classes/com/sun/jmx/namespace/serial/RewritingProcessor.java new file mode 100644 index 00000000000..2c81be934c5 --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/namespace/serial/RewritingProcessor.java @@ -0,0 +1,362 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.namespace.serial; + + +import javax.management.ObjectInstance; +import javax.management.ObjectName; + +/** + * An object that can rewrite ObjectNames contained in input/output + * parameters when entering/leaving a {@link javax.management.namespace + * namespace}. + *

    When entering a {@link javax.management.namespace + * namespace}, the {@code namespace} prefix is stripped from + * ObjectNames contained in input parameters. When leaving a + * {@code namespace}, + * the {@code namespace} prefix is prepended to the ObjectNames contained in + * the result parameters returned from that {@code namespace}. + *

    + *

    Objects that need to perform these operations usually use a + * {@code RewritingProcessor} for that purpose.
    + * The {@code RewritingProcessor} allows a somewhat larger + * transformation in which part of a prefix {@link #newRewritingProcessor + * remove} can be replaced by another prefix {@link #newRewritingProcessor + * add}. The transformation described above correspond to the case where + * {@code remove} is the stripped {@link javax.management.namespace + * namespace} prefix (removed when entering the {@code namespace}) and + * {@code add} is the empty String {@code ""}. + *
    + * It is interesting to note that {@link + * javax.management.JMXNamespaces#narrowToNamespace narrowToNamespace} + * operations use the inverse transformation (that is, {@code remove} is + * the empty String {@code ""} and {@code add} is the {@link + * javax.management.namespace namespace} prefix). + *
    + * On a more general scale, {@link #rewriteInput rewriteInput} removes + * {@link #newRewritingProcessor remove} and the prepend {@link + * #newRewritingProcessor add}, and {@link #rewriteOutput rewriteOutput} + * does the opposite, removing {@link #newRewritingProcessor add}, and + * then adding {@link #newRewritingProcessor remove}. + *
    + * An implementation of {@code RewritingProcessor} should make sure that + * rewriteInput(rewriteOutput(x,clp),clp) and + * rewriteOutput(rewriteInput(x,clp),clp) always return + * {@code x} or an exact clone of {@code x}. + *

    + *

    A default implementation of {@code RewritingProcessor} based on + * Java Object Serialization can be + * obtained from {@link #newRewritingProcessor newRewritingProcessor}. + *

    + *

    + * By default, the instances of {@code RewritingProcessor} returned by + * {@link #newRewritingProcessor newRewritingProcessor} will rewrite + * ObjectNames contained in instances of classes they don't know about by + * serializing and then deserializing such object instances. This will + * happen even if such instances don't - or can't contain ObjectNames, + * because the default implementation of {@code RewritingProcessor} will + * not be able to determine whether instances of such classes can/do contain + * instance of ObjectNames before serializing/deserializing them. + *

    + *

    If you are using custom classes that the default implementation of + * {@code RewritingProcessor} don't know about, it can be interesting to + * prevent an instance of {@code RewritingProcessor} to serialize/deserialize + * instances of such classes for nothing. In that case, you could customize + * the behavior of such a {@code RewritingProcessor} by wrapping it in a + * custom subclass of {@code RewritingProcessor} as shown below: + *

    + * public class MyRewritingProcessor extends RewritingProcessor {
    + *      MyRewritingProcessor(String remove, String add) {
    + *          this(RewritingProcessor.newRewritingProcessor(remove,add));
    + *      }
    + *      MyRewritingProcessor(RewritingProcessor delegate) {
    + *          super(delegate);
    + *      }
    + *
    + *   T rewriteInput(T input) {
    + *          if (input == null) return null;
    + *          if (MyClass.equals(input.getClass())) {
    + *              // I know that MyClass doesn't contain any ObjectName
    + *              return (T) input;
    + *          }
    + *          return super.rewriteInput(input);
    + *      }
    + *   T rewriteOutput(T result) {
    + *          if (result == null) return null;
    + *          if (MyClass.equals(result.getClass())) {
    + *              // I know that MyClass doesn't contain any ObjectName
    + *              return (T) result;
    + *          }
    + *          return super.rewriteOutput(result);
    + *      }
    + * }
    + * 
    + *

    + *

    Such a subclass may also provide an alternate way of rewriting + * custom subclasses for which rewriting is needed - for instance: + *

    + * public class MyRewritingProcessor extends RewritingProcessor {
    + *      MyRewritingProcessor(String remove, String add) {
    + *          this(RewritingProcessor.newRewritingProcessor(remove,add));
    + *      }
    + *      MyRewritingProcessor(RewritingProcessor delegate) {
    + *          super(delegate);
    + *      }
    + *
    + *   T rewriteInput(T input) {
    + *          if (input == null) return null;
    + *          if (MyClass.equals(input.getClass())) {
    + *              // I know that MyClass doesn't contain any ObjectName
    + *              return (T) input;
    + *          } else if (MyOtherClass.equals(input.getClass())) {
    + *              // Returns a new instance in which ObjectNames have been
    + *              // replaced.
    + *              final ObjectName aname = ((MyOtherClass)input).getName();
    + *              return (T) (new MyOtherClass(super.rewriteInput(aname)));
    + *          }
    + *          return super.rewriteInput(input,clp);
    + *      }
    + *   T rewriteOutput(T result) {
    + *          if (result == null) return null;
    + *          if (MyClass.equals(result.getClass())) {
    + *              // I know that MyClass doesn't contain any ObjectName
    + *              return (T) result;
    + *          } else if (MyOtherClass.equals(result.getClass())) {
    + *              // Returns a new instance in which ObjectNames have been
    + *              // replaced.
    + *              final ObjectName aname = ((MyOtherClass)result).getName();
    + *              return (T) (new MyOtherClass(super.rewriteOutput(aname)));
    + *          }
    + *          return super.rewriteOutput(result,clp);
    + *      }
    + * }
    + * 
    + *

    + *

    If your application only uses {@link javax.management.MXBean MXBeans}, + * or MBeans using simple types, and doesn't define any custom subclass of + * {@link javax.management.Notification}, you should never write such + * such {@code RewitingProcessor} implementations. + *

    + *

    + * This API is a Sun internal API and is subject to changes without notice. + *

    + * @since 1.7 + */ +public abstract class RewritingProcessor { + /** + * A logger for this class. + **/ + private final RewritingProcessor delegate; + + /** + * Creates a new instance of RewritingProcessor. + *

    This is equivalent to calling {@link + * #RewritingProcessor(RewritingProcessor) RewritingProcessor(null)}. + *

    + **/ + protected RewritingProcessor() { + this(null); + } + + /** + * Creates a new instance of RewritingProcessor, with a delegate. + * @param delegate a {@code RewritingProcessor} to which all the + * calls will be delegated. When implementing a subclass + * of {@code RewritingProcessor}, calling {@link + * #rewriteInput super.rewriteInput} will invoke + * {@code delegate.rewriteInput} and calling {@link + * #rewriteOutput super.rewriteOutput} will invoke + * {@code delegate.rewriteOutput}. + * + **/ + protected RewritingProcessor(RewritingProcessor delegate) { + this.delegate = delegate; + } + + /** + * Rewrites ObjectNames when {@link RewritingProcessor leaving} a {@link + * javax.management.namespace namespace}. + *

    + * Returns {@code obj}, if it is known that {@code obj} doesn't contain + * any ObjectName, or a new copied instance of {@code obj} in which + * ObjectNames (if any) will have been rewritten, if {@code obj} contains + * ObjectNames, or if it is not known whether {@code obj} contains + * ObjectNames or not. + *

    + *

    + * The default implementation of this method is as follows: if the + * {@link #RewritingProcessor(RewritingProcessor) delegate} is {@code + * null}, throws an {@link IllegalArgumentException}. Otherwise, + * returns {@code delegate.rewriteOutput(obj)}. + *

    + *

    This behavior can be overridden by subclasses as shown in this + * class {@link RewritingProcessor description}. + *

    + * @param obj The result to be rewritten if needed. + * + * @return {@code obj}, or a clone of {@code obj} in which ObjectNames + * have been rewritten. See this class {@link RewritingProcessor + * description} for more details. + * @throws IllegalArgumentException if this implementation does not know + * how to rewrite the object. + **/ + public T rewriteOutput(T obj) { + if (obj == null) return null; + if (delegate != null) + return delegate.rewriteOutput(obj); + throw new IllegalArgumentException("can't rewrite "+ + obj.getClass().getName()); + } + + /** + * Rewrites ObjectNames when {@link RewritingProcessor entering} a {@link + * javax.management.namespace namespace}. + *

    + * Returns {@code obj}, if it is known that {@code obj} doesn't contain + * any ObjectName, or a new copied instance of {@code obj} in which + * ObjectNames (if any) will have been rewritten, if {@code obj} contains + * ObjectNames, or if it is not known whether {@code obj} contains + * ObjectNames or not. + *

    + *

    + * The default implementation of this method is as follows: if the + * {@link #RewritingProcessor(RewritingProcessor) delegate} is {@code + * null}, throws an {@link IllegalArgumentException}. Otherwise, + * returns {@code delegate.rewriteInput(obj)}. + *

    + *

    This behavior can be overridden by subclasses as shown in this + * class {@link RewritingProcessor description}. + *

    + * @param obj The result to be rewritten if needed. + * @return {@code obj}, or a clone of {@code obj} in which ObjectNames + * have been rewritten. See this class {@link RewritingProcessor + * description} for more details. + * @throws IllegalArgumentException if this implementation does not know + * how to rewrite the object. + **/ + public T rewriteInput(T obj) { + if (obj == null) return null; + if (delegate != null) + return delegate.rewriteInput(obj); + throw new IllegalArgumentException("can't rewrite "+ + obj.getClass().getName()); + } + + /** + * Translate a routing ObjectName from the target (calling) context to + * the source (called) context when {@link RewritingProcessor entering} a + * {@link javax.management.namespace namespace}. + *

    + * The default implementation of this method is as follows: if the + * {@link #RewritingProcessor(RewritingProcessor) delegate} is {@code + * null}, throws an {@link IllegalArgumentException}. Otherwise, + * returns {@code delegate.toSourceContext(targetName)}. + *

    + *

    This behavior can be overridden by subclasses as shown in this + * class {@link RewritingProcessor description}. + *

    + * @param targetName The routing target ObjectName to translate. + * @return The ObjectName translated to the source context. + * @throws IllegalArgumentException if this implementation does not know + * how to rewrite the object. + **/ + public ObjectName toSourceContext(ObjectName targetName) { + if (delegate != null) + return delegate.toSourceContext(targetName); + throw new IllegalArgumentException("can't rewrite targetName: "+ + " no delegate."); + } + + /** + * Translate an ObjectName returned from the source context into + * the target (calling) context when {@link RewritingProcessor leaving} a + * {@link javax.management.namespace namespace}. + *

    + * The default implementation of this method is as follows: if the + * {@link #RewritingProcessor(RewritingProcessor) delegate} is {@code + * null}, throws an {@link IllegalArgumentException}. Otherwise, + * returns {@code delegate.toTargetContext(sourceName)}. + *

    + *

    This behavior can be overridden by subclasses as shown in this + * class {@link RewritingProcessor description}. + *

    + * @param sourceName The routing source ObjectName to translate to the + * target context. + * @return The ObjectName translated to the target context. + * @throws IllegalArgumentException if this implementation does not know + * how to rewrite the object. + **/ + public ObjectName toTargetContext(ObjectName sourceName) { + if (delegate != null) + return delegate.toTargetContext(sourceName); + throw new IllegalArgumentException("can't rewrite sourceName: "+ + " no delegate."); + } + + /** + * Translate an ObjectInstance returned from the source context into + * the target (calling) context when {@link RewritingProcessor leaving} a + * {@link javax.management.namespace namespace}. + *

    + * The default implementation of this method is as follows: if the + * {@link #RewritingProcessor(RewritingProcessor) delegate} is {@code + * null}, throws an {@link IllegalArgumentException}. Otherwise, + * returns {@code delegate.toTargetContext(sourceMoi)}. + *

    + *

    This behavior can be overridden by subclasses as shown in this + * class {@link RewritingProcessor description}. + *

    + * @param sourceMoi The routing source ObjectInstance to translate. + * @return The ObjectInstance translated to the target context. + * @throws IllegalArgumentException if this implementation does not know + * how to rewrite the object. + **/ + public ObjectInstance toTargetContext(ObjectInstance sourceMoi) { + if (delegate != null) + return delegate.toTargetContext(sourceMoi); + throw new IllegalArgumentException("can't rewrite sourceName: "+ + " no delegate."); + } + + /** + * Creates a new default instance of {@link RewritingProcessor}. + * @param remove The prefix to remove from {@link ObjectName ObjectNames} + * when {@link RewritingProcessor entering} the {@link + * javax.management.namespace namespace}. + * @param add The prefix to add to {@link ObjectName ObjectNames} + * when {@link RewritingProcessor entering} the {@link + * javax.management.namespace namespace} (this is performed + * after having removed the {@code remove} prefix. + * @return A new {@link RewritingProcessor} processor object that will + * perform the requested operation, using Java serialization if + * necessary. + **/ + public static RewritingProcessor newRewritingProcessor(String remove, + String add) { + return new DefaultRewritingProcessor(remove,add); + } + +} diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/serial/RoutingOnlyProcessor.java b/jdk/src/share/classes/com/sun/jmx/namespace/serial/RoutingOnlyProcessor.java new file mode 100644 index 00000000000..1df2e26a9c8 --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/namespace/serial/RoutingOnlyProcessor.java @@ -0,0 +1,74 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.namespace.serial; + +import com.sun.jmx.namespace.ObjectNameRouter; + + +import javax.management.ObjectInstance; +import javax.management.ObjectName; + +/** + * Class RoutingOnlyProcessor. A RewritingProcessor that uses + * Java Serialization to rewrite ObjectNames contained in + * input and results... + * + *

    + * This API is a Sun internal API and is subject to changes without notice. + *

    + * @since 1.7 + */ +class RoutingOnlyProcessor extends RewritingProcessor { + + final ObjectNameRouter router; + + public RoutingOnlyProcessor(String targetDirName) { + this(targetDirName,null); + } + + /** Creates a new instance of RoutingOnlyProcessor */ + public RoutingOnlyProcessor(final String remove, final String add) { + super(new IdentityProcessor()); + if (remove == null || add == null) + throw new IllegalArgumentException("Null argument"); + router = new ObjectNameRouter(remove,add); + } + + @Override + public final ObjectName toTargetContext(ObjectName sourceName) { + return router.toTargetContext(sourceName,false); + } + + @Override + public final ObjectName toSourceContext(ObjectName targetName) { + return router.toSourceContext(targetName,false); + } + + @Override + public final ObjectInstance toTargetContext(ObjectInstance sourceMoi) { + return router.toTargetContext(sourceMoi,false); + } +} diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/serial/SerialRewritingProcessor.java b/jdk/src/share/classes/com/sun/jmx/namespace/serial/SerialRewritingProcessor.java new file mode 100644 index 00000000000..d7e879822e3 --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/namespace/serial/SerialRewritingProcessor.java @@ -0,0 +1,172 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.namespace.serial; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InvalidClassException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamClass; +import java.io.OutputStream; +import java.util.LinkedList; +import java.util.Queue; + +import javax.management.ObjectName; + +/** + * Class SerialRewritingProcessor. A RewritingProcessor that uses + * Java Serialization to rewrite ObjectNames contained in + * input & results... + *

    + * This API is a Sun internal API and is subject to changes without notice. + *

    + * @since 1.7 + */ +class SerialRewritingProcessor extends RewritingProcessor { + + + private static class CloneOutput extends ObjectOutputStream { + Queue> classQueue = new LinkedList>(); + + CloneOutput(OutputStream out) throws IOException { + super(out); + } + + @Override + protected void annotateClass(Class c) { + classQueue.add(c); + } + + @Override + protected void annotateProxyClass(Class c) { + classQueue.add(c); + } + } + + private static class CloneInput extends ObjectInputStream { + private final CloneOutput output; + + CloneInput(InputStream in, CloneOutput output) throws IOException { + super(in); + this.output = output; + } + + @Override + protected Class resolveClass(ObjectStreamClass osc) + throws IOException, ClassNotFoundException { + Class c = output.classQueue.poll(); + String expected = osc.getName(); + String found = (c == null) ? null : c.getName(); + if (!expected.equals(found)) { + throw new InvalidClassException("Classes desynchronized: " + + "found " + found + " when expecting " + expected); + } + return c; + } + + @Override + protected Class resolveProxyClass(String[] interfaceNames) + throws IOException, ClassNotFoundException { + return output.classQueue.poll(); + } + } + + + final String targetPrefix; + final String sourcePrefix; + final boolean identity; + + + public SerialRewritingProcessor(String targetDirName) { + this(targetDirName,null); + } + + /** Creates a new instance of SerialRewritingProcessor */ + public SerialRewritingProcessor(final String remove, final String add) { + super(new RoutingOnlyProcessor(remove,add)); + this.targetPrefix = remove; + this.sourcePrefix = add; + identity = targetPrefix.equals(sourcePrefix); + } + + private T switchContext(T result, String from,String to) + throws IOException, ClassNotFoundException { + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + final CloneOutput ostream = new CloneOutput(baos); + + JMXNamespaceContext.serialize(ostream,result,from,null); + ostream.flush(); + + final byte[] bytes = baos.toByteArray(); + final ByteArrayInputStream bais = new ByteArrayInputStream(bytes); + final CloneInput istream = new CloneInput(bais, ostream); + @SuppressWarnings("unchecked") + final T clone = (T) JMXNamespaceContext.deserialize(istream,null,to); + return clone; + } + + @Override + @SuppressWarnings("unchecked") + public T rewriteOutput(T result) { + if (identity) return result; + return (T) processOutput(result); + } + + private Object processOutput(Object result) { + try { + if (result instanceof ObjectName) + return toTargetContext((ObjectName) result); + return switchContext(result,sourcePrefix,targetPrefix); + } catch (ClassNotFoundException x) { + throw new IllegalArgumentException("Can't process result: "+x,x); + } catch (IOException x) { + throw new IllegalArgumentException("Can't process result: "+x,x); + } + } + + @Override + @SuppressWarnings("unchecked") + public T rewriteInput(T input) { + if (identity) return input; + return (T) processInput(input); + } + + private Object processInput(Object input) { + try { + if (input instanceof ObjectName) + return toSourceContext((ObjectName) input); + return switchContext(input,targetPrefix,sourcePrefix); + } catch (ClassNotFoundException x) { + throw new IllegalArgumentException("Can't process input: "+x,x); + } catch (IOException x) { + throw new IllegalArgumentException("Can't process input: "+x,x); + } + } + +} diff --git a/jdk/src/share/classes/com/sun/jmx/namespace/serial/package.html b/jdk/src/share/classes/com/sun/jmx/namespace/serial/package.html new file mode 100644 index 00000000000..fe2e8c64b94 --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/namespace/serial/package.html @@ -0,0 +1,44 @@ + + + + + The <code>com.sun.jmx.namespace.serial</code> package + + + +

    The com.sun.jmx.namespace.serial package contains + sun specific implementation classes used to switch namespace + prefixes in ObjectName during serialization. +

    +

    NEVER USE THESE CLASSES DIRECTLY

    +

    + This API is a Sun internal API and is subject to changes without notice. +

    +

    The public API through which these proprietary classes can be invoked is + located in javax.management.namespace.JMXNamespaces +

    + + diff --git a/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientCommunicatorAdmin.java b/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientCommunicatorAdmin.java index a6635aad8bd..9bc5cc7e8fe 100644 --- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientCommunicatorAdmin.java +++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientCommunicatorAdmin.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,13 +32,15 @@ import com.sun.jmx.remote.util.ClassLogger; import com.sun.jmx.remote.util.EnvHelp; public abstract class ClientCommunicatorAdmin { + private static volatile long threadNo = 1; + public ClientCommunicatorAdmin(long period) { this.period = period; if (period > 0) { checker = new Checker(); - Thread t = new Thread(checker); + Thread t = new Thread(checker, "JMX client heartbeat " + ++threadNo); t.setDaemon(true); t.start(); } else diff --git a/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java b/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java index a37b75395f8..ab6bd60caf8 100644 --- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java +++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java @@ -290,28 +290,6 @@ public abstract class ClientNotifForwarder { infoList.clear(); - if (currentFetchThread == Thread.currentThread()) { - /* we do not need to stop the fetching thread, because this thread is - used to do restarting and it will not be used to do fetching during - the re-registering the listeners.*/ - return tmp; - } - - while (state == STARTING) { - try { - wait(); - } catch (InterruptedException ire) { - IOException ioe = new IOException(ire.toString()); - EnvHelp.initCause(ioe, ire); - - throw ioe; - } - } - - if (state == STARTED) { - setState(STOPPING); - } - return tmp; } @@ -353,8 +331,9 @@ public abstract class ClientNotifForwarder { beingReconnected = false; notifyAll(); - if (currentFetchThread == Thread.currentThread()) { - // no need to init, simply get the id + if (currentFetchThread == Thread.currentThread() || + state == STARTING || state == STARTED) { // doing or waiting reconnection + // only update mbeanRemovedNotifID try { mbeanRemovedNotifID = addListenerForMBeanRemovedNotif(); } catch (Exception e) { @@ -366,12 +345,23 @@ public abstract class ClientNotifForwarder { logger.trace("init", msg, e); } } - } else if (listenerInfos.length > 0) { // old listeners re-registered - init(true); - } else if (infoList.size() > 0) { - // but new listeners registered during reconnection - init(false); - } + } else { + while (state == STOPPING) { + try { + wait(); + } catch (InterruptedException ire) { + IOException ioe = new IOException(ire.toString()); + EnvHelp.initCause(ioe, ire); + throw ioe; + } + } + + if (listenerInfos.length > 0) { // old listeners are re-added + init(true); // not update clientSequenceNumber + } else if (infoList.size() > 0) { // only new listeners added during reconnection + init(false); // need update clientSequenceNumber + } + } } public synchronized void terminate() { @@ -486,6 +476,15 @@ public abstract class ClientNotifForwarder { if (nr == null || shouldStop()) { // tell that the thread is REALLY stopped setState(STOPPED); + + try { + removeListenerForMBeanRemovedNotif(mbeanRemovedNotifID); + } catch (Exception e) { + if (logger.traceOn()) { + logger.trace("NotifFetcher-run", + "removeListenerForMBeanRemovedNotif", e); + } + } } else { executor.execute(this); } @@ -576,6 +575,7 @@ public abstract class ClientNotifForwarder { int notFoundCount = 0; NotificationResult result = null; + long firstEarliest = -1; while (result == null && !shouldStop()) { NotificationResult nr; @@ -598,6 +598,8 @@ public abstract class ClientNotifForwarder { return null; startSequenceNumber = nr.getNextSequenceNumber(); + if (firstEarliest < 0) + firstEarliest = nr.getEarliestSequenceNumber(); try { // 1 notif to skip possible missing class @@ -628,6 +630,17 @@ public abstract class ClientNotifForwarder { (notFoundCount == 1 ? "" : "s") + " because classes were missing locally"; lostNotifs(msg, notFoundCount); + // Even if result.getEarliestSequenceNumber() is now greater than + // it was initially, meaning some notifs have been dropped + // from the buffer, we don't want the caller to see that + // because it is then likely to renotify about the lost notifs. + // So we put back the first value of earliestSequenceNumber + // that we saw. + if (result != null) { + result = new NotificationResult( + firstEarliest, result.getNextSequenceNumber(), + result.getTargetedNotifications()); + } } return result; diff --git a/jdk/src/share/classes/com/sun/jmx/remote/internal/ProxyInputStream.java b/jdk/src/share/classes/com/sun/jmx/remote/internal/ProxyInputStream.java index cdcdd6159b7..8d57b8f92a6 100644 --- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ProxyInputStream.java +++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ProxyInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,10 +33,8 @@ import org.omg.CORBA.Any; import org.omg.CORBA.Context; import org.omg.CORBA.NO_IMPLEMENT; import org.omg.CORBA.ORB; -import org.omg.CORBA.Principal; import org.omg.CORBA.TypeCode; import org.omg.CORBA.portable.BoxedValueHelper; -import org.omg.CORBA_2_3.portable.InputStream; @SuppressWarnings("deprecation") public class ProxyInputStream extends org.omg.CORBA_2_3.portable.InputStream { @@ -160,54 +158,71 @@ public class ProxyInputStream extends org.omg.CORBA_2_3.portable.InputStream { return in.read_any(); } - public Principal read_Principal() { + /** + * @deprecated + */ + @Override + @Deprecated + public org.omg.CORBA.Principal read_Principal() { return in.read_Principal(); } + @Override public int read() throws IOException { return in.read(); } + @Override public BigDecimal read_fixed() { return in.read_fixed(); } + @Override public Context read_Context() { return in.read_Context(); } + @Override public org.omg.CORBA.Object read_Object(java.lang.Class clz) { return in.read_Object(clz); } + @Override public ORB orb() { return in.orb(); } + @Override public Serializable read_value() { return narrow().read_value(); } + @Override public Serializable read_value(Class clz) { return narrow().read_value(clz); } + @Override public Serializable read_value(BoxedValueHelper factory) { return narrow().read_value(factory); } + @Override public Serializable read_value(String rep_id) { return narrow().read_value(rep_id); } + @Override public Serializable read_value(Serializable value) { return narrow().read_value(value); } + @Override public Object read_abstract_interface() { return narrow().read_abstract_interface(); } + @Override public Object read_abstract_interface(Class clz) { return narrow().read_abstract_interface(clz); } diff --git a/jdk/src/share/classes/com/sun/jmx/remote/internal/ProxyRef.java b/jdk/src/share/classes/com/sun/jmx/remote/internal/ProxyRef.java index 3c16e9e7f4d..e1593266ac4 100644 --- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ProxyRef.java +++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ProxyRef.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,8 +31,6 @@ import java.io.ObjectOutput; import java.lang.reflect.Method; import java.rmi.Remote; import java.rmi.RemoteException; -import java.rmi.server.Operation; -import java.rmi.server.RemoteCall; import java.rmi.server.RemoteObject; import java.rmi.server.RemoteRef; @@ -54,7 +52,11 @@ public class ProxyRef implements RemoteRef { ref.writeExternal(out); } - public void invoke(RemoteCall call) throws Exception { + /** + * @deprecated + */ + @Deprecated + public void invoke(java.rmi.server.RemoteCall call) throws Exception { ref.invoke(call); } @@ -63,7 +65,11 @@ public class ProxyRef implements RemoteRef { return ref.invoke(obj, method, params, opnum); } - public void done(RemoteCall call) throws RemoteException { + /** + * @deprecated + */ + @Deprecated + public void done(java.rmi.server.RemoteCall call) throws RemoteException { ref.done(call); } @@ -71,7 +77,12 @@ public class ProxyRef implements RemoteRef { return ref.getRefClass(out); } - public RemoteCall newCall(RemoteObject obj, Operation[] op, int opnum, + /** + * @deprecated + */ + @Deprecated + public java.rmi.server.RemoteCall newCall(RemoteObject obj, + java.rmi.server.Operation[] op, int opnum, long hash) throws RemoteException { return ref.newCall(obj, op, opnum, hash); } diff --git a/jdk/src/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java b/jdk/src/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java index ae84f4b9d2e..c3542cc1d8a 100644 --- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java +++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java @@ -25,16 +25,16 @@ package com.sun.jmx.remote.internal; +import com.sun.jmx.mbeanserver.Util; import com.sun.jmx.remote.security.NotificationAccessController; import com.sun.jmx.remote.util.ClassLogger; import com.sun.jmx.remote.util.EnvHelp; import java.io.IOException; import java.security.AccessControlContext; import java.security.AccessController; +import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -57,6 +57,7 @@ import javax.security.auth.Subject; public class ServerNotifForwarder { + public ServerNotifForwarder(MBeanServer mbeanServer, Map env, NotificationBuffer notifBuffer, @@ -67,9 +68,9 @@ public class ServerNotifForwarder { connectionTimeout = EnvHelp.getServerConnectionTimeout(env); checkNotificationEmission = EnvHelp.computeBooleanFromString( env, - "jmx.remote.x.check.notification.emission"); - notificationAccessController = (NotificationAccessController) - env.get("com.sun.jmx.remote.notification.access.controller"); + "jmx.remote.x.check.notification.emission",false); + notificationAccessController = + EnvHelp.getNotificationAccessController(env); } public Integer addNotificationListener(final ObjectName name, @@ -85,12 +86,11 @@ public class ServerNotifForwarder { // Explicitly check MBeanPermission for addNotificationListener // - checkMBeanPermission(name, "addNotificationListener"); + checkMBeanPermission(getMBeanServerName(), + mbeanServer, name, "addNotificationListener"); if (notificationAccessController != null) { notificationAccessController.addNotificationListener( - connectionId, - name, - Subject.getSubject(AccessController.getContext())); + connectionId, name, getSubject()); } try { boolean instanceOf = @@ -157,12 +157,11 @@ public class ServerNotifForwarder { // Explicitly check MBeanPermission for removeNotificationListener // - checkMBeanPermission(name, "removeNotificationListener"); + checkMBeanPermission(getMBeanServerName(), + mbeanServer, name, "removeNotificationListener"); if (notificationAccessController != null) { notificationAccessController.removeNotificationListener( - connectionId, - name, - Subject.getSubject(AccessController.getContext())); + connectionId, name, getSubject()); } Exception re = null; @@ -312,6 +311,10 @@ public class ServerNotifForwarder { // PRIVATE METHODS //---------------- + private Subject getSubject() { + return Subject.getSubject(AccessController.getContext()); + } + private void checkState() throws IOException { synchronized(terminationLock) { if (terminated) { @@ -330,9 +333,9 @@ public class ServerNotifForwarder { * Explicitly check the MBeanPermission for * the current access control context. */ - private void checkMBeanPermission(final ObjectName name, - final String actions) - throws InstanceNotFoundException, SecurityException { + public static void checkMBeanPermission(String serverName, + final MBeanServer mbs, final ObjectName name, final String actions) + throws InstanceNotFoundException, SecurityException { SecurityManager sm = System.getSecurityManager(); if (sm != null) { AccessControlContext acc = AccessController.getContext(); @@ -342,14 +345,16 @@ public class ServerNotifForwarder { new PrivilegedExceptionAction() { public ObjectInstance run() throws InstanceNotFoundException { - return mbeanServer.getObjectInstance(name); + return mbs.getObjectInstance(name); } }); } catch (PrivilegedActionException e) { throw (InstanceNotFoundException) extractException(e); } String classname = oi.getClassName(); - MBeanPermission perm = new MBeanPermission(classname, + MBeanPermission perm = new MBeanPermission( + serverName, + classname, null, name, actions); @@ -364,14 +369,12 @@ public class ServerNotifForwarder { TargetedNotification tn) { try { if (checkNotificationEmission) { - checkMBeanPermission(name, "addNotificationListener"); + checkMBeanPermission(getMBeanServerName(), + mbeanServer, name, "addNotificationListener"); } if (notificationAccessController != null) { notificationAccessController.fetchNotification( - connectionId, - name, - tn.getNotification(), - Subject.getSubject(AccessController.getContext())); + connectionId, name, tn.getNotification(), getSubject()); } return true; } catch (SecurityException e) { @@ -429,11 +432,27 @@ public class ServerNotifForwarder { } } + private String getMBeanServerName() { + if (mbeanServerName != null) return mbeanServerName; + else return (mbeanServerName = getMBeanServerName(mbeanServer)); + } + + private static String getMBeanServerName(final MBeanServer server) { + final PrivilegedAction action = new PrivilegedAction() { + public String run() { + return Util.getMBeanServerSecurityName(server); + } + }; + return AccessController.doPrivileged(action); + } + + //------------------ // PRIVATE VARIABLES //------------------ private MBeanServer mbeanServer; + private volatile String mbeanServerName; private final String connectionId; diff --git a/jdk/src/share/classes/com/sun/jmx/remote/security/FileLoginModule.java b/jdk/src/share/classes/com/sun/jmx/remote/security/FileLoginModule.java index 47f3e07ab07..a901a19c8f8 100644 --- a/jdk/src/share/classes/com/sun/jmx/remote/security/FileLoginModule.java +++ b/jdk/src/share/classes/com/sun/jmx/remote/security/FileLoginModule.java @@ -25,6 +25,7 @@ package com.sun.jmx.remote.security; +import com.sun.jmx.mbeanserver.GetPropertyAction; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; @@ -47,8 +48,6 @@ import com.sun.jmx.remote.util.ClassLogger; import com.sun.jmx.remote.util.EnvHelp; import sun.management.jmxremote.ConnectorBootstrap; -import sun.security.action.GetPropertyAction; - /** * This {@link LoginModule} performs file-based authentication. * @@ -479,7 +478,7 @@ public class FileLoginModule implements LoginModule { if (userSuppliedPasswordFile || hasJavaHomePermission) { throw e; } else { - FilePermission fp = + final FilePermission fp = new FilePermission(passwordFileDisplayName, "read"); AccessControlException ace = new AccessControlException( "access denied " + fp.toString()); @@ -488,10 +487,13 @@ public class FileLoginModule implements LoginModule { } } try { - BufferedInputStream bis = new BufferedInputStream(fis); - userCredentials = new Properties(); - userCredentials.load(bis); - bis.close(); + final BufferedInputStream bis = new BufferedInputStream(fis); + try { + userCredentials = new Properties(); + userCredentials.load(bis); + } finally { + bis.close(); + } } finally { fis.close(); } diff --git a/jdk/src/share/classes/com/sun/jmx/remote/util/EnvHelp.java b/jdk/src/share/classes/com/sun/jmx/remote/util/EnvHelp.java index 219559ea531..67b9ea59561 100644 --- a/jdk/src/share/classes/com/sun/jmx/remote/util/EnvHelp.java +++ b/jdk/src/share/classes/com/sun/jmx/remote/util/EnvHelp.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,9 +40,6 @@ import java.util.TreeMap; import java.util.TreeSet; import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import javax.management.ObjectName; import javax.management.MBeanServer; @@ -50,6 +47,9 @@ import javax.management.InstanceNotFoundException; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXConnectorServerFactory; import com.sun.jmx.mbeanserver.GetPropertyAction; +import com.sun.jmx.remote.security.NotificationAccessController; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorServer; public class EnvHelp { @@ -346,7 +346,24 @@ public class EnvHelp { */ public static long getFetchTimeout(Map env) { return getIntegerAttribute(env, FETCH_TIMEOUT, 60000L, 0, - Long.MAX_VALUE); + Long.MAX_VALUE); + } + + /** + *

    Name of the attribute that specifies an object that will check + * accesses to add/removeNotificationListener and also attempts to + * receive notifications. The value associated with this attribute + * should be a NotificationAccessController object. + * The default value is null.

    + * This field is not public because of its com.sun dependency. + */ + public static final String NOTIF_ACCESS_CONTROLLER = + "com.sun.jmx.remote.notification.access.controller"; + + public static NotificationAccessController getNotificationAccessController( + Map env) { + return (env == null) ? null : + (NotificationAccessController) env.get(NOTIF_ACCESS_CONTROLLER); } /** @@ -470,24 +487,24 @@ public class EnvHelp { } /** - The value of this attribute, if present, is a string specifying - what other attributes should not appear in - JMXConnectorServer.getAttributes(). It is a space-separated - list of attribute patterns, where each pattern is either an - attribute name, or an attribute prefix followed by a "*" - character. The "*" has no special significance anywhere except - at the end of a pattern. By default, this list is added to the - list defined by {@link #DEFAULT_HIDDEN_ATTRIBUTES} (which - uses the same format). If the value of this attribute begins - with an "=", then the remainder of the string defines the - complete list of attribute patterns. + * The value of this attribute, if present, is a string specifying + * what other attributes should not appear in + * JMXConnectorServer.getAttributes(). It is a space-separated + * list of attribute patterns, where each pattern is either an + * attribute name, or an attribute prefix followed by a "*" + * character. The "*" has no special significance anywhere except + * at the end of a pattern. By default, this list is added to the + * list defined by {@link #DEFAULT_HIDDEN_ATTRIBUTES} (which + * uses the same format). If the value of this attribute begins + * with an "=", then the remainder of the string defines the + * complete list of attribute patterns. */ public static final String HIDDEN_ATTRIBUTES = "jmx.remote.x.hidden.attributes"; /** - Default list of attributes not to show. - @see #HIDDEN_ATTRIBUTES + * Default list of attributes not to show. + * @see #HIDDEN_ATTRIBUTES */ /* This list is copied directly from the spec, plus java.naming.security.*. Most of the attributes here would have @@ -651,6 +668,8 @@ public class EnvHelp { * @param env the environment map. * @param prop the name of the property in the environment map whose * returned string value must be converted into a boolean value. + * @param systemProperty if true, consult a system property of the + * same name if there is no entry in the environment map. * * @return *
      @@ -671,16 +690,73 @@ public class EnvHelp { * @throws ClassCastException if {@code env.get(prop)} cannot be cast * to {@code String}. */ - public static boolean computeBooleanFromString(Map env, String prop) - throws IllegalArgumentException, ClassCastException { + public static boolean computeBooleanFromString( + Map env, String prop, boolean systemProperty) { + + if (env == null) + throw new IllegalArgumentException("env map cannot be null"); + + // returns a default value of 'false' if no property is found... + return computeBooleanFromString(env,prop,systemProperty,false); + } + + /** + * Computes a boolean value from a string value retrieved from a + * property in the given map. + * + * @param env the environment map. + * @param prop the name of the property in the environment map whose + * returned string value must be converted into a boolean value. + * @param systemProperty if true, consult a system property of the + * same name if there is no entry in the environment map. + * @param defaultValue a default value to return in case no property + * was defined. + * + * @return + *
        + *
      • {@code defaultValue} if {@code env.get(prop)} is {@code null} + * and {@code systemProperty} is {@code false}
      • + *
      • {@code defaultValue} if {@code env.get(prop)} is {@code null} + * and {@code systemProperty} is {@code true} and + * {@code System.getProperty(prop)} is {@code null}
      • + *
      • {@code false} if {@code env.get(prop)} is {@code null} + * and {@code systemProperty} is {@code true} and + * {@code System.getProperty(prop).equalsIgnoreCase("false")} + * is {@code true}
      • + *
      • {@code true} if {@code env.get(prop)} is {@code null} + * and {@code systemProperty} is {@code true} and + * {@code System.getProperty(prop).equalsIgnoreCase("true")} + * is {@code true}
      • + *
      • {@code false} if + * {@code ((String)env.get(prop)).equalsIgnoreCase("false")} + * is {@code true}
      • + *
      • {@code true} if + * {@code ((String)env.get(prop)).equalsIgnoreCase("true")} + * is {@code true}
      • + *
      + * + * @throws IllegalArgumentException if {@code env} is {@code null} or + * {@code env.get(prop)} is not {@code null} and + * {@code ((String)env.get(prop)).equalsIgnoreCase("false")} and + * {@code ((String)env.get(prop)).equalsIgnoreCase("true")} are + * {@code false}. + * @throws ClassCastException if {@code env.get(prop)} cannot be cast + * to {@code String}. + */ + public static boolean computeBooleanFromString( + Map env, String prop, boolean systemProperty, boolean defaultValue) { if (env == null) throw new IllegalArgumentException("env map cannot be null"); String stringBoolean = (String) env.get(prop); + if (stringBoolean == null && systemProperty) { + stringBoolean = + AccessController.doPrivileged(new GetPropertyAction(prop)); + } if (stringBoolean == null) - return false; + return defaultValue; else if (stringBoolean.equalsIgnoreCase("true")) return true; else if (stringBoolean.equalsIgnoreCase("false")) @@ -703,6 +779,65 @@ public class EnvHelp { return new Hashtable(m); } + /** + * Returns true if the parameter JMXConnector.USE_EVENT_SERVICE is set to a + * String equals "true" by ignoring case in the map or in the System. + */ + public static boolean eventServiceEnabled(Map env) { + return computeBooleanFromString(env, JMXConnector.USE_EVENT_SERVICE, true); + } + + /** + * Returns true if the parameter JMXConnectorServer.DELEGATE_TO_EVENT_SERVICE + * is set to a String equals "true" (ignores case). + * If the property DELEGATE_TO_EVENT_SERVICE is not set, returns + * a default value of "true". + */ + public static boolean delegateToEventService(Map env) { + return computeBooleanFromString(env, + JMXConnectorServer.DELEGATE_TO_EVENT_SERVICE, true, true); + } + +// /** +// *

      Name of the attribute that specifies an EventRelay object to use. +// */ +// public static final String EVENT_RELAY = +// "jmx.remote.x.event.relay"; +// +// +// /** +// * Returns an EventRelay object. The default one is FetchingEventRelay. +// * If {@code EVENT_RELAY} is specified in {@code env} as a key, +// * its value will be returned as an EventRelay object, if the value is +// * not of type {@code EventRelay}, the default {@code FetchingEventRelay} +// * will be returned. +// * If {@code EVENT_RELAY} is not specified but {@code ENABLE_EVENT_RELAY} +// * is specified as a key and its value is , the default {@code FetchingEventRelay} +// * will be returned. +// */ +// public static EventRelay getEventRelay(Map env) { +// Map info = env == null ? +// Collections.EMPTY_MAP : env; +// +// Object o = env.get(EVENT_RELAY); +// if (o instanceof EventRelay) { +// return (EventRelay)o; +// } else if (o != null) { +// logger.warning("getEventRelay", +// "The user specified object is not an EventRelay object, " + +// "using the default class FetchingEventRelay."); +// +// return new FetchingEventRelay(); +// } +// +// if (enableEventRelay(env)) { +// return new FetchingEventRelay(); +// } +// +// return null; +// } + + private static final class SinkOutputStream extends OutputStream { public void write(byte[] b, int off, int len) {} public void write(int b) {} diff --git a/jdk/src/share/classes/com/sun/jmx/remote/util/EventClientConnection.java b/jdk/src/share/classes/com/sun/jmx/remote/util/EventClientConnection.java new file mode 100644 index 00000000000..6281b68a574 --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/remote/util/EventClientConnection.java @@ -0,0 +1,471 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.jmx.remote.util; + +import com.sun.jmx.defaults.JmxProperties; +import com.sun.jmx.event.EventClientFactory; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Arrays; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.management.MBeanServerConnection; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.ObjectName; +import javax.management.event.EventClient; +import javax.management.event.EventClientDelegate; +import javax.management.namespace.JMXNamespaces; + +/** + * Class EventClientConnection - a {@link Proxy} that wraps an + * {@link MBeanServerConnection} and an {@link EventClient}. + * All methods are routed to the underlying {@code MBeanServerConnection}, + * except add/remove notification listeners which are routed to the + * {@code EventClient}. + * The caller only sees an {@code MBeanServerConnection} which uses an + * {@code EventClient} behind the scenes. + * + * @author Sun Microsystems, Inc. + */ +public class EventClientConnection implements InvocationHandler, + EventClientFactory { + + /** + * A logger for this class. + **/ + private static final Logger LOG = JmxProperties.NOTIFICATION_LOGGER; + + private static final int NAMESPACE_SEPARATOR_LENGTH = + JMXNamespaces.NAMESPACE_SEPARATOR.length(); + + /** + * Creates a new {@code EventClientConnection}. + * @param connection The underlying MBeanServerConnection. + */ + public EventClientConnection(MBeanServerConnection connection) { + this(connection,null); + } + + /** + * Creates a new {@code EventClientConnection}. + * @param connection The underlying MBeanServerConnection. + * @param eventClientFactory a factory object that will be invoked + * to create an {@link EventClient} when needed. + * The {@code EventClient} is created lazily, when it is needed + * for the first time. If null, a default factory will be used + * (see {@link #createEventClient}). + */ + public EventClientConnection(MBeanServerConnection connection, + Callable eventClientFactory) { + + if (connection == null) { + throw new IllegalArgumentException("Null connection"); + } + this.connection = connection; + if (eventClientFactory == null) { + eventClientFactory = new Callable() { + public final EventClient call() throws Exception { + return createEventClient(EventClientConnection.this.connection); + } + }; + } + this.eventClientFactory = eventClientFactory; + this.lock = new ReentrantLock(); + } + + /** + *

      The MBean server connection through which the methods of + * a proxy using this handler are forwarded.

      + * + * @return the MBean server connection. + * + * @since 1.6 + */ + public MBeanServerConnection getMBeanServerConnection() { + return connection; + } + + + + + /** + * Creates a new EventClientConnection proxy instance. + * + * @param The underlying {@code MBeanServerConnection} - which should + * not be using the Event Service itself. + * @param interfaceClass {@code MBeanServerConnection.class}, or a subclass. + * @param eventClientFactory a factory used to create the EventClient. + * If null, a default factory is used (see {@link + * #createEventClient}). + * @return the new proxy instance, which will route add/remove notification + * listener calls through an {@code EventClient}. + * + */ + private static T + newProxyInstance(T connection, + Class interfaceClass, Callable eventClientFactory) { + final InvocationHandler handler = + new EventClientConnection(connection,eventClientFactory); + final Class[] interfaces = + new Class[] {interfaceClass, EventClientFactory.class}; + + Object proxy = + Proxy.newProxyInstance(interfaceClass.getClassLoader(), + interfaces, + handler); + return interfaceClass.cast(proxy); + } + + + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable { + final String methodName = method.getName(); + + // add/remove notification listener are routed to the EventClient + if (methodName.equals("addNotificationListener") + || methodName.equals("removeNotificationListener")) { + final Class[] sig = method.getParameterTypes(); + if (sig.length>1 && + NotificationListener.class.isAssignableFrom(sig[1])) { + return invokeBroadcasterMethod(proxy,method,args); + } + } + + // subscribe/unsubscribe are also routed to the EventClient. + final Class clazz = method.getDeclaringClass(); + if (clazz.equals(EventClientFactory.class)) { + return invokeEventClientSubscriberMethod(proxy,method,args); + } + + // local or not: equals, toString, hashCode + if (shouldDoLocally(proxy, method)) + return doLocally(proxy, method, args); + + return call(connection,method,args); + } + + // The purpose of this method is to unwrap InvocationTargetException, + // in order to avoid throwing UndeclaredThrowableException for + // declared exceptions. + // + // When calling method.invoke(), any exception thrown by the invoked + // method will be wrapped in InvocationTargetException. If we don't + // unwrap this exception, the proxy will always throw + // UndeclaredThrowableException, even for runtime exceptions. + // + private Object call(final Object obj, final Method m, + final Object[] args) + throws Throwable { + try { + return m.invoke(obj,args); + } catch (InvocationTargetException x) { + final Throwable xx = x.getTargetException(); + if (xx == null) throw x; + else throw xx; + } + } + + /** + * Route add/remove notification listener to the event client. + **/ + private Object invokeBroadcasterMethod(Object proxy, Method method, + Object[] args) throws Exception { + final String methodName = method.getName(); + final int nargs = (args == null) ? 0 : args.length; + + if (nargs < 1) { + final String msg = + "Bad arg count: " + nargs; + throw new IllegalArgumentException(msg); + } + + final ObjectName mbean = (ObjectName) args[0]; + final EventClient evtClient = getEventClient(); + + // Fails if evtClient is null AND the MBean we try to listen to is + // in a subnamespace. We fail here because we know this will not + // work. + // + // Note that if the wrapped MBeanServerConnection points to a an + // earlier agent (JDK 1.6 or earlier), then the EventClient will + // be null (we can't use the event service with earlier JDKs). + // + // In principle a null evtClient indicates that the remote VM is of + // an earlier version, in which case it shouldn't contain any namespace. + // + // So having a null evtClient AND an MBean contained in a namespace is + // clearly an error case. + // + if (evtClient == null) { + final String domain = mbean.getDomain(); + final int index = domain.indexOf(JMXNamespaces.NAMESPACE_SEPARATOR); + if (index > -1 && index < + (domain.length()-NAMESPACE_SEPARATOR_LENGTH)) { + throw new UnsupportedOperationException(method.getName()+ + " on namespace "+domain.substring(0,index+ + NAMESPACE_SEPARATOR_LENGTH)); + } + } + + if (methodName.equals("addNotificationListener")) { + /* The various throws of IllegalArgumentException here + should not happen, since we know what the methods in + NotificationBroadcaster and NotificationEmitter + are. */ + if (nargs != 4) { + final String msg = + "Bad arg count to addNotificationListener: " + nargs; + throw new IllegalArgumentException(msg); + } + /* Other inconsistencies will produce ClassCastException + below. */ + + final NotificationListener listener = (NotificationListener) args[1]; + final NotificationFilter filter = (NotificationFilter) args[2]; + final Object handback = args[3]; + + if (evtClient != null) { + // general case + evtClient.addNotificationListener(mbean,listener,filter,handback); + } else { + // deprecated case. Only works for mbean in local namespace. + connection.addNotificationListener(mbean,listener,filter, + handback); + } + return null; + + } else if (methodName.equals("removeNotificationListener")) { + + /* NullPointerException if method with no args, but that + shouldn't happen because removeNL does have args. */ + NotificationListener listener = (NotificationListener) args[1]; + + switch (nargs) { + case 2: + if (evtClient != null) { + // general case + evtClient.removeNotificationListener(mbean,listener); + } else { + // deprecated case. Only works for mbean in local namespace. + connection.removeNotificationListener(mbean, listener); + } + return null; + + case 4: + NotificationFilter filter = (NotificationFilter) args[2]; + Object handback = args[3]; + if (evtClient != null) { + evtClient.removeNotificationListener(mbean, + listener, + filter, + handback); + } else { + connection.removeNotificationListener(mbean, + listener, + filter, + handback); + } + return null; + + default: + final String msg = + "Bad arg count to removeNotificationListener: " + nargs; + throw new IllegalArgumentException(msg); + } + + } else { + throw new IllegalArgumentException("Bad method name: " + + methodName); + } + } + + private boolean shouldDoLocally(Object proxy, Method method) { + final String methodName = method.getName(); + if ((methodName.equals("hashCode") || methodName.equals("toString")) + && method.getParameterTypes().length == 0 + && isLocal(proxy, method)) + return true; + if (methodName.equals("equals") + && Arrays.equals(method.getParameterTypes(), + new Class[] {Object.class}) + && isLocal(proxy, method)) + return true; + return false; + } + + private Object doLocally(Object proxy, Method method, Object[] args) { + final String methodName = method.getName(); + + if (methodName.equals("equals")) { + + if (this == args[0]) { + return true; + } + + if (!(args[0] instanceof Proxy)) { + return false; + } + + final InvocationHandler ihandler = + Proxy.getInvocationHandler(args[0]); + + if (ihandler == null || + !(ihandler instanceof EventClientConnection)) { + return false; + } + + final EventClientConnection handler = + (EventClientConnection)ihandler; + + return connection.equals(handler.connection) && + proxy.getClass().equals(args[0].getClass()); + } else if (methodName.equals("hashCode")) { + return connection.hashCode(); + } + + throw new RuntimeException("Unexpected method name: " + methodName); + } + + private static boolean isLocal(Object proxy, Method method) { + final Class[] interfaces = proxy.getClass().getInterfaces(); + if(interfaces == null) { + return true; + } + + final String methodName = method.getName(); + final Class[] params = method.getParameterTypes(); + for (Class intf : interfaces) { + try { + intf.getMethod(methodName, params); + return false; // found method in one of our interfaces + } catch (NoSuchMethodException nsme) { + // OK. + } + } + + return true; // did not find in any interface + } + + /** + * Return the EventClient used by this object. Can be null if the + * remote VM is of an earlier JDK version which doesn't have the + * event service.
      + * This method will invoke the event client factory the first time + * it is called. + **/ + public final EventClient getEventClient() { + if (initialized) return client; + try { + if (!lock.tryLock(TRYLOCK_TIMEOUT,TimeUnit.SECONDS)) + throw new IllegalStateException("can't acquire lock"); + try { + client = eventClientFactory.call(); + initialized = true; + } finally { + lock.unlock(); + } + } catch (RuntimeException x) { + throw x; + } catch (Exception x) { + throw new IllegalStateException("Can't create EventClient: "+x,x); + } + return client; + } + + /** + * Returns an event client for the wrapped {@code MBeanServerConnection}. + * This is the method invoked by the default event client factory. + * @param connection the wrapped {@code MBeanServerConnection}. + **/ + protected EventClient createEventClient(MBeanServerConnection connection) + throws Exception { + final ObjectName name = + EventClientDelegate.OBJECT_NAME; + if (connection.isRegistered(name)) { + return new EventClient(connection); + } + return null; + } + + /** + * Creates a new {@link MBeanServerConnection} that goes through an + * {@link EventClient} to receive/subscribe to notifications. + * @param connection the underlying {@link MBeanServerConnection}. + * The given connection shouldn't be already + * using an {@code EventClient}. + * @param eventClientFactory a factory object that will be invoked + * to create an {@link EventClient} when needed. + * The {@code EventClient} is created lazily, when it is needed + * for the first time. If null, a default factory will be used + * (see {@link #createEventClient}). + * @return the + **/ + public static MBeanServerConnection getEventConnectionFor( + MBeanServerConnection connection, + Callable eventClientFactory) { + // if c already uses an EventClient no need to create a new one. + // + if (connection instanceof EventClientFactory + && eventClientFactory != null) + throw new IllegalArgumentException("connection already uses EventClient"); + + if (connection instanceof EventClientFactory) + return connection; + + // create a new proxy using an event client. + // + if (LOG.isLoggable(Level.FINE)) + LOG.fine("Creating EventClient for: "+connection); + return newProxyInstance(connection, + MBeanServerConnection.class, + eventClientFactory); + } + + private Object invokeEventClientSubscriberMethod(Object proxy, + Method method, Object[] args) throws Throwable { + return call(this,method,args); + } + + // Maximum lock timeout in seconds. Obviously arbitrary. + // + private final static short TRYLOCK_TIMEOUT = 3; + + private final MBeanServerConnection connection; + private final Callable eventClientFactory; + private final Lock lock; + private volatile EventClient client = null; + private volatile boolean initialized = false; + +} diff --git a/jdk/src/share/classes/com/sun/jmx/snmp/tasks/ThreadService.java b/jdk/src/share/classes/com/sun/jmx/snmp/tasks/ThreadService.java index 95090412ad4..452500d52aa 100644 --- a/jdk/src/share/classes/com/sun/jmx/snmp/tasks/ThreadService.java +++ b/jdk/src/share/classes/com/sun/jmx/snmp/tasks/ThreadService.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,15 +45,9 @@ public class ThreadService implements TaskServer { minThreads = threadNumber; threadList = new ExecutorThread[threadNumber]; -// for (int i=0; i 0)) { - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Register Resolver: " + JAVACLASS + ": " - + Description); + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Register Resolver: " + JAVACLASS + ": " + Description); } else { - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Register Resolver: " + JAVACLASS - + ": For unknown purposes"); + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Register Resolver: " + JAVACLASS + ": For unknown purposes"); } try { ResourceResolver.register(JAVACLASS); @@ -359,13 +351,11 @@ public final class Init { "DESCRIPTION"); if ((Description != null) && (Description.length() > 0)) { - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Register Resolver: " + JAVACLASS + ": " - + Description); + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Register Resolver: " + JAVACLASS + ": " + Description); } else { - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Register Resolver: " + JAVACLASS - + ": For unknown purposes"); + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Register Resolver: " + JAVACLASS + ": For unknown purposes"); } KeyResolver.register(JAVACLASS); @@ -376,8 +366,8 @@ public final class Init { if (tag.equals("PrefixMappings")){ XX_configure_reg_prefixes_start = System.currentTimeMillis(); - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Now I try to bind prefixes:"); + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Now I try to bind prefixes:"); Element[] nl = XMLUtils.selectNodes(el.getFirstChild(), CONF_NS,"PrefixMapping"); @@ -386,8 +376,8 @@ public final class Init { "namespace"); String prefix = nl[i].getAttributeNS(null, "prefix"); - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Now I try to bind " + prefix + " to " + namespace); + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Now I try to bind " + prefix + " to " + namespace); com.sun.org.apache.xml.internal.security.utils.ElementProxy .setDefaultPrefix(namespace, prefix); } @@ -398,19 +388,19 @@ public final class Init { long XX_init_end = System.currentTimeMillis(); //J- - if (true) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "XX_init " + ((int)(XX_init_end - XX_init_start)) + " ms"); - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, " XX_prng " + ((int)(XX_prng_end - XX_prng_start)) + " ms"); - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, " XX_parsing " + ((int)(XX_parsing_end - XX_parsing_start)) + " ms"); - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, " XX_configure_i18n " + ((int)(XX_configure_i18n_end- XX_configure_i18n_start)) + " ms"); - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, " XX_configure_reg_c14n " + ((int)(XX_configure_reg_c14n_end- XX_configure_reg_c14n_start)) + " ms"); - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, " XX_configure_reg_jcemapper " + ((int)(XX_configure_reg_jcemapper_end- XX_configure_reg_jcemapper_start)) + " ms"); - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, " XX_configure_reg_keyInfo " + ((int)(XX_configure_reg_keyInfo_end- XX_configure_reg_keyInfo_start)) + " ms"); - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, " XX_configure_reg_keyResolver " + ((int)(XX_configure_reg_keyResolver_end- XX_configure_reg_keyResolver_start)) + " ms"); - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, " XX_configure_reg_prefixes " + ((int)(XX_configure_reg_prefixes_end- XX_configure_reg_prefixes_start)) + " ms"); - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, " XX_configure_reg_resourceresolver " + ((int)(XX_configure_reg_resourceresolver_end- XX_configure_reg_resourceresolver_start)) + " ms"); - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, " XX_configure_reg_sigalgos " + ((int)(XX_configure_reg_sigalgos_end- XX_configure_reg_sigalgos_start)) + " ms"); - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, " XX_configure_reg_transforms " + ((int)(XX_configure_reg_transforms_end- XX_configure_reg_transforms_start)) + " ms"); + if (log.isLoggable(java.util.logging.Level.FINE)) { + log.log(java.util.logging.Level.FINE, "XX_init " + ((int)(XX_init_end - XX_init_start)) + " ms"); + log.log(java.util.logging.Level.FINE, " XX_prng " + ((int)(XX_prng_end - XX_prng_start)) + " ms"); + log.log(java.util.logging.Level.FINE, " XX_parsing " + ((int)(XX_parsing_end - XX_parsing_start)) + " ms"); + log.log(java.util.logging.Level.FINE, " XX_configure_i18n " + ((int)(XX_configure_i18n_end- XX_configure_i18n_start)) + " ms"); + log.log(java.util.logging.Level.FINE, " XX_configure_reg_c14n " + ((int)(XX_configure_reg_c14n_end- XX_configure_reg_c14n_start)) + " ms"); + log.log(java.util.logging.Level.FINE, " XX_configure_reg_jcemapper " + ((int)(XX_configure_reg_jcemapper_end- XX_configure_reg_jcemapper_start)) + " ms"); + log.log(java.util.logging.Level.FINE, " XX_configure_reg_keyInfo " + ((int)(XX_configure_reg_keyInfo_end- XX_configure_reg_keyInfo_start)) + " ms"); + log.log(java.util.logging.Level.FINE, " XX_configure_reg_keyResolver " + ((int)(XX_configure_reg_keyResolver_end- XX_configure_reg_keyResolver_start)) + " ms"); + log.log(java.util.logging.Level.FINE, " XX_configure_reg_prefixes " + ((int)(XX_configure_reg_prefixes_end- XX_configure_reg_prefixes_start)) + " ms"); + log.log(java.util.logging.Level.FINE, " XX_configure_reg_resourceresolver " + ((int)(XX_configure_reg_resourceresolver_end- XX_configure_reg_resourceresolver_start)) + " ms"); + log.log(java.util.logging.Level.FINE, " XX_configure_reg_sigalgos " + ((int)(XX_configure_reg_sigalgos_end- XX_configure_reg_sigalgos_start)) + " ms"); + log.log(java.util.logging.Level.FINE, " XX_configure_reg_transforms " + ((int)(XX_configure_reg_transforms_end- XX_configure_reg_transforms_start)) + " ms"); } } catch (Exception e) { log.log(java.util.logging.Level.SEVERE, "Bad: ", e); diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/Algorithm.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/Algorithm.java index 2f326f0a7a4..62fd0fe4964 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/Algorithm.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/Algorithm.java @@ -24,7 +24,7 @@ package com.sun.org.apache.xml.internal.security.algorithms; import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; import com.sun.org.apache.xml.internal.security.utils.Constants; -import com.sun.org.apache.xml.internal.security.utils.ElementProxy; +import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -33,11 +33,7 @@ import org.w3c.dom.Element; * The Algorithm class which stores the Algorithm URI as a string. * */ -public abstract class Algorithm extends ElementProxy { - - /** {@link java.util.logging} logging facility */ - static java.util.logging.Logger log = - java.util.logging.Logger.getLogger(Algorithm.class.getName()); +public abstract class Algorithm extends SignatureElementProxy { /** * @@ -79,7 +75,7 @@ public abstract class Algorithm extends ElementProxy { */ protected void setAlgorithmURI(String algorithmURI) { - if ((this._state == MODE_CREATE) && (algorithmURI != null)) { + if ( (algorithmURI != null)) { this._constructionElement.setAttributeNS(null, Constants._ATT_ALGORITHM, algorithmURI); } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java index 475d4591bcd..7a239135920 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java @@ -35,7 +35,7 @@ import org.w3c.dom.Element; /** * This class maps algorithm identifier URIs to JAVA JCE class names. * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class JCEMapper { @@ -45,9 +45,9 @@ public class JCEMapper { - private static Map uriToJCEName = new HashMap(); + private static Map uriToJCEName; - private static Map algorithmsMap = new HashMap(); + private static Map algorithmsMap; private static String providerName = null; /** @@ -63,6 +63,8 @@ public class JCEMapper { static void loadAlgorithms( Element algorithmsEl) { Element[] algorithms = XMLUtils.selectNodes(algorithmsEl.getFirstChild(),Init.CONF_NS,"Algorithm"); + uriToJCEName = new HashMap( algorithms.length * 2); + algorithmsMap = new HashMap( algorithms.length * 2); for (int i = 0 ;i < algorithms.length ;i ++) { Element el = algorithms[i]; String id = el.getAttribute("URI"); @@ -70,6 +72,7 @@ public class JCEMapper { uriToJCEName.put(id, jceName); algorithmsMap.put(id, new Algorithm(el)); } + } static Algorithm getAlgorithmMapping(String algoURI) { @@ -84,8 +87,8 @@ public class JCEMapper { * */ public static String translateURItoJCEID(String AlgorithmURI) { - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Request for URI " + AlgorithmURI); + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Request for URI " + AlgorithmURI); String jceName = (String) uriToJCEName.get(AlgorithmURI); return jceName; @@ -100,8 +103,8 @@ public class JCEMapper { * */ public static String getAlgorithmClassFromURI(String AlgorithmURI) { - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Request for URI " + AlgorithmURI); + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Request for URI " + AlgorithmURI); return ((Algorithm) algorithmsMap.get(AlgorithmURI)).algorithmClass; } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/MessageDigestAlgorithm.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/MessageDigestAlgorithm.java index 805d061a2e6..fa62ef3518f 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/MessageDigestAlgorithm.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/MessageDigestAlgorithm.java @@ -20,10 +20,10 @@ */ package com.sun.org.apache.xml.internal.security.algorithms; - - import java.security.MessageDigest; import java.security.NoSuchProviderException; +import java.util.HashMap; +import java.util.Map; import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException; import com.sun.org.apache.xml.internal.security.utils.Constants; @@ -41,11 +41,6 @@ import org.w3c.dom.Document; */ public class MessageDigestAlgorithm extends Algorithm { - /** {@link java.util.logging} logging facility */ - static java.util.logging.Logger log = - java.util.logging.Logger.getLogger( - MessageDigestAlgorithm.class.getName()); - /** Message Digest - NOT RECOMMENDED MD5*/ public static final String ALGO_ID_DIGEST_NOT_RECOMMENDED_MD5 = Constants.MoreAlgorithmsSpecNS + "md5"; /** Digest - Required SHA1*/ @@ -76,6 +71,12 @@ public class MessageDigestAlgorithm extends Algorithm { this.algorithm = messageDigest; } + static ThreadLocal instances=new ThreadLocal() { + protected Object initialValue() { + return new HashMap(); + }; + }; + /** * Factory method for constructing a message digest algorithm by name. * @@ -86,8 +87,15 @@ public class MessageDigestAlgorithm extends Algorithm { */ public static MessageDigestAlgorithm getInstance( Document doc, String algorithmURI) throws XMLSignatureException { + MessageDigest md = getDigestInstance(algorithmURI); + return new MessageDigestAlgorithm(doc, md, algorithmURI); + } - String algorithmID = JCEMapper.translateURItoJCEID(algorithmURI); +private static MessageDigest getDigestInstance(String algorithmURI) throws XMLSignatureException { + MessageDigest result=(MessageDigest) ((Map)instances.get()).get(algorithmURI); + if (result!=null) + return result; + String algorithmID = JCEMapper.translateURItoJCEID(algorithmURI); if (algorithmID == null) { Object[] exArgs = { algorithmURI }; @@ -113,8 +121,9 @@ public class MessageDigestAlgorithm extends Algorithm { throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs); } - return new MessageDigestAlgorithm(doc, md, algorithmURI); - } + ((Map)instances.get()).put(algorithmURI, md); + return md; +} /** * Returns the actual {@link java.security.MessageDigest} algorithm object diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java index 3ebb782a3d2..567df3cbbd1 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java @@ -25,6 +25,7 @@ import java.security.Key; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.util.HashMap; +import java.util.Map; import com.sun.org.apache.xml.internal.security.algorithms.implementations.IntegrityHmac; import com.sun.org.apache.xml.internal.security.exceptions.AlgorithmAlreadyRegisteredException; @@ -52,9 +53,35 @@ public class SignatureAlgorithm extends Algorithm { /** All available algorithm classes are registered here */ static HashMap _algorithmHash = null; + static ThreadLocal instancesSigning=new ThreadLocal() { + protected Object initialValue() { + return new HashMap(); + }; + }; + + static ThreadLocal instancesVerify=new ThreadLocal() { + protected Object initialValue() { + return new HashMap(); + }; + }; + + static ThreadLocal keysSigning=new ThreadLocal() { + protected Object initialValue() { + return new HashMap(); + }; + }; + static ThreadLocal keysVerify=new ThreadLocal() { + protected Object initialValue() { + return new HashMap(); + }; + }; +// boolean isForSigning=false; + /** Field _signatureAlgorithm */ protected SignatureAlgorithmSpi _signatureAlgorithm = null; + private String algorithmURI; + /** * Constructor SignatureAlgorithm * @@ -64,18 +91,49 @@ public class SignatureAlgorithm extends Algorithm { */ public SignatureAlgorithm(Document doc, String algorithmURI) throws XMLSecurityException { - super(doc, algorithmURI); + this.algorithmURI = algorithmURI; + } - try { + + private void initializeAlgorithm(boolean isForSigning) throws XMLSignatureException { + if (_signatureAlgorithm!=null) { + return; + } + _signatureAlgorithm=isForSigning ? getInstanceForSigning(algorithmURI) : getInstanceForVerify(algorithmURI); + this._signatureAlgorithm + .engineGetContextFromElement(this._constructionElement); + } + private static SignatureAlgorithmSpi getInstanceForSigning(String algorithmURI) throws XMLSignatureException { + SignatureAlgorithmSpi result=(SignatureAlgorithmSpi) ((Map)instancesSigning.get()).get(algorithmURI); + if (result!=null) { + result.reset(); + return result; + } + result=buildSigner(algorithmURI, result); + ((Map)instancesSigning.get()).put(algorithmURI,result); + return result; + } + private static SignatureAlgorithmSpi getInstanceForVerify(String algorithmURI) throws XMLSignatureException { + SignatureAlgorithmSpi result=(SignatureAlgorithmSpi) ((Map)instancesVerify.get()).get(algorithmURI); + if (result!=null) { + result.reset(); + return result; + } + result=buildSigner(algorithmURI, result); + ((Map)instancesVerify.get()).put(algorithmURI,result); + return result; + } + + private static SignatureAlgorithmSpi buildSigner(String algorithmURI, SignatureAlgorithmSpi result) throws XMLSignatureException { + try { Class implementingClass = SignatureAlgorithm.getImplementingClass(algorithmURI); - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Create URI \"" + algorithmURI + "\" class \"" + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Create URI \"" + algorithmURI + "\" class \"" + implementingClass + "\""); - - this._signatureAlgorithm = - (SignatureAlgorithmSpi) implementingClass.newInstance(); + result=(SignatureAlgorithmSpi) implementingClass.newInstance(); + return result; } catch (IllegalAccessException ex) { Object exArgs[] = { algorithmURI, ex.getMessage() }; @@ -92,7 +150,7 @@ public class SignatureAlgorithm extends Algorithm { throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs, ex); } - } +} /** * Constructor SignatureAlgorithm @@ -107,7 +165,8 @@ public class SignatureAlgorithm extends Algorithm { throws XMLSecurityException { this(doc, algorithmURI); - + this.algorithmURI=algorithmURI; + initializeAlgorithm(true); this._signatureAlgorithm.engineSetHMACOutputLength(HMACOutputLength); ((IntegrityHmac)this._signatureAlgorithm) .engineAddContextToElement(this._constructionElement); @@ -124,37 +183,7 @@ public class SignatureAlgorithm extends Algorithm { throws XMLSecurityException { super(element, BaseURI); - - String algorithmURI = this.getURI(); - - try { - Class implementingClass = - SignatureAlgorithm.getImplementingClass(algorithmURI); - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Create URI \"" + algorithmURI + "\" class \"" - + implementingClass + "\""); - - this._signatureAlgorithm = - (SignatureAlgorithmSpi) implementingClass.newInstance(); - - this._signatureAlgorithm - .engineGetContextFromElement(this._constructionElement); - } catch (IllegalAccessException ex) { - Object exArgs[] = { algorithmURI, ex.getMessage() }; - - throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs, - ex); - } catch (InstantiationException ex) { - Object exArgs[] = { algorithmURI, ex.getMessage() }; - - throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs, - ex); - } catch (NullPointerException ex) { - Object exArgs[] = { algorithmURI, ex.getMessage() }; - - throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs, - ex); - } + algorithmURI = this.getURI(); } /** @@ -175,7 +204,12 @@ public class SignatureAlgorithm extends Algorithm { * @return the result of the {@link java.security.Signature#getAlgorithm} method */ public String getJCEAlgorithmString() { - return this._signatureAlgorithm.engineGetJCEAlgorithmString(); + try { + return getInstanceForVerify(algorithmURI).engineGetJCEAlgorithmString(); + } catch (XMLSignatureException e) { + //Ignore. + return null; + } } /** @@ -184,7 +218,11 @@ public class SignatureAlgorithm extends Algorithm { * @return The Provider of this Signature Alogrithm */ public String getJCEProviderName() { - return this._signatureAlgorithm.engineGetJCEProviderName(); + try { + return getInstanceForVerify(algorithmURI).engineGetJCEProviderName(); + } catch (XMLSignatureException e) { + return null; + } } /** @@ -231,7 +269,13 @@ public class SignatureAlgorithm extends Algorithm { * @throws XMLSignatureException */ public void initSign(Key signingKey) throws XMLSignatureException { - this._signatureAlgorithm.engineInitSign(signingKey); + initializeAlgorithm(true); + Map map=(Map)keysSigning.get(); + if (map.get(this.algorithmURI)==signingKey) { + return; + } + map.put(this.algorithmURI,signingKey); + this._signatureAlgorithm.engineInitSign(signingKey); } /** @@ -244,6 +288,7 @@ public class SignatureAlgorithm extends Algorithm { */ public void initSign(Key signingKey, SecureRandom secureRandom) throws XMLSignatureException { + initializeAlgorithm(true); this._signatureAlgorithm.engineInitSign(signingKey, secureRandom); } @@ -258,6 +303,7 @@ public class SignatureAlgorithm extends Algorithm { public void initSign( Key signingKey, AlgorithmParameterSpec algorithmParameterSpec) throws XMLSignatureException { + initializeAlgorithm(true); this._signatureAlgorithm.engineInitSign(signingKey, algorithmParameterSpec); } @@ -282,7 +328,13 @@ public class SignatureAlgorithm extends Algorithm { * @throws XMLSignatureException */ public void initVerify(Key verificationKey) throws XMLSignatureException { - this._signatureAlgorithm.engineInitVerify(verificationKey); + initializeAlgorithm(false); + Map map=(Map)keysVerify.get(); + if (map.get(this.algorithmURI)==verificationKey) { + return; + } + map.put(this.algorithmURI,verificationKey); + this._signatureAlgorithm.engineInitVerify(verificationKey); } /** @@ -320,7 +372,7 @@ public class SignatureAlgorithm extends Algorithm { .getLogger(SignatureAlgorithm.class.getName()); } - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Init() called"); + log.log(java.util.logging.Level.FINE, "Init() called"); if (!SignatureAlgorithm._alreadyInitialized) { SignatureAlgorithm._algorithmHash = new HashMap(10); @@ -340,8 +392,8 @@ public class SignatureAlgorithm extends Algorithm { throws AlgorithmAlreadyRegisteredException,XMLSignatureException { { - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Try to register " + algorithmURI + " " + implementingClass); + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Try to register " + algorithmURI + " " + implementingClass); // are we already registered? Class registeredClassClass = diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithmSpi.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithmSpi.java index 1ae46db4bb3..c47be7e2c0d 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithmSpi.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithmSpi.java @@ -20,27 +20,20 @@ */ package com.sun.org.apache.xml.internal.security.algorithms; - - import java.security.Key; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException; -import org.w3c.dom.Document; import org.w3c.dom.Element; /** * - * @author $Author: raul $ + * @author $Author: mullan $ */ public abstract class SignatureAlgorithmSpi { - /** {@link java.util.logging} logging facility */ - static java.util.logging.Logger log = - java.util.logging.Logger.getLogger(SignatureAlgorithmSpi.class.getName()); - /** * Returns the URI representation of Transformation algorithm * @@ -167,20 +160,6 @@ public abstract class SignatureAlgorithmSpi { protected abstract void engineSetParameter(AlgorithmParameterSpec params) throws XMLSignatureException; - /** Field _doc */ - Document _doc = null; - - /** - * Method engineSetDocument - * - * @param doc - */ - protected void engineSetDocument(Document doc) { - this._doc = doc; - } - - /** Field _constructionElement */ - Element _constructionElement = null; /** * Method engineGetContextFromElement @@ -188,7 +167,6 @@ public abstract class SignatureAlgorithmSpi { * @param element */ protected void engineGetContextFromElement(Element element) { - this._constructionElement = element; } /** @@ -199,4 +177,7 @@ public abstract class SignatureAlgorithmSpi { */ protected abstract void engineSetHMACOutputLength(int HMACOutputLength) throws XMLSignatureException; + + public void reset() { + } } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java index 0e89024bf26..d3495bb567f 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java @@ -45,7 +45,7 @@ import org.w3c.dom.Text; /** * - * @author $Author: raul $ + * @author $Author: mullan $ */ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { @@ -74,8 +74,8 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { public IntegrityHmac() throws XMLSignatureException { String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI()); - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Created IntegrityHmacSHA1 using " + algorithmID); + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Created IntegrityHmacSHA1 using " + algorithmID); try { this._macAlgorithm = Mac.getInstance(algorithmID); @@ -99,6 +99,10 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { throw new XMLSignatureException("empty"); } + public void reset() { + _HMACOutputLength=0; + } + /** * Proxy method for {@link java.security.Signature#verify(byte[])} * which is executed on the internal {@link java.security.Signature} object. @@ -145,7 +149,20 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { try { this._macAlgorithm.init(secretKey); } catch (InvalidKeyException ex) { - throw new XMLSignatureException("empty", ex); + // reinstantiate Mac object to work around bug in JDK + // see: http://bugs.sun.com/view_bug.do?bug_id=4953555 + Mac mac = this._macAlgorithm; + try { + this._macAlgorithm = Mac.getInstance + (_macAlgorithm.getAlgorithm()); + } catch (Exception e) { + // this shouldn't occur, but if it does, restore previous Mac + if (log.isLoggable(java.util.logging.Level.FINE)) { + log.log(java.util.logging.Level.FINE, "Exception when reinstantiating Mac:" + e); + } + this._macAlgorithm = mac; + } + throw new XMLSignatureException("empty", ex); } } @@ -323,7 +340,7 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { */ protected String engineGetJCEAlgorithmString() { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "engineGetJCEAlgorithmString()"); + log.log(java.util.logging.Level.FINE, "engineGetJCEAlgorithmString()"); return this._macAlgorithm.getAlgorithm(); } @@ -397,7 +414,8 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { /** * Class IntegrityHmacSHA1 * - * @author $Author: raul $ + * @author $Author: mullan $ + * @version $Revision: 1.5 $ */ public static class IntegrityHmacSHA1 extends IntegrityHmac { @@ -423,7 +441,8 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { /** * Class IntegrityHmacSHA256 * - * @author $Author: raul $ + * @author $Author: mullan $ + * @version $Revision: 1.5 $ */ public static class IntegrityHmacSHA256 extends IntegrityHmac { @@ -449,7 +468,8 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { /** * Class IntegrityHmacSHA384 * - * @author $Author: raul $ + * @author $Author: mullan $ + * @version $Revision: 1.5 $ */ public static class IntegrityHmacSHA384 extends IntegrityHmac { @@ -475,7 +495,8 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { /** * Class IntegrityHmacSHA512 * - * @author $Author: raul $ + * @author $Author: mullan $ + * @version $Revision: 1.5 $ */ public static class IntegrityHmacSHA512 extends IntegrityHmac { @@ -501,7 +522,8 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { /** * Class IntegrityHmacRIPEMD160 * - * @author $Author: raul $ + * @author $Author: mullan $ + * @version $Revision: 1.5 $ */ public static class IntegrityHmacRIPEMD160 extends IntegrityHmac { @@ -527,7 +549,8 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { /** * Class IntegrityHmacMD5 * - * @author $Author: raul $ + * @author $Author: mullan $ + * @version $Revision: 1.5 $ */ public static class IntegrityHmacMD5 extends IntegrityHmac { diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureBaseRSA.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureBaseRSA.java index fde23e8fc88..ccc01b01c58 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureBaseRSA.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureBaseRSA.java @@ -3,7 +3,7 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 1999-2004 The Apache Software Foundation. + * Copyright 1999-2007 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,8 +20,6 @@ */ package com.sun.org.apache.xml.internal.security.algorithms.implementations; - - import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; @@ -38,329 +36,344 @@ import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithmSpi import com.sun.org.apache.xml.internal.security.signature.XMLSignature; import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException; - /** * - * @author $Author: raul $ + * @author $Author: mullan $ */ public abstract class SignatureBaseRSA extends SignatureAlgorithmSpi { - /** {@link java.util.logging} logging facility */ + /** {@link java.util.logging} logging facility */ static java.util.logging.Logger log = - java.util.logging.Logger.getLogger(SignatureBaseRSA.class.getName()); + java.util.logging.Logger.getLogger + (SignatureBaseRSA.class.getName()); /** @inheritDoc */ - public abstract String engineGetURI(); + public abstract String engineGetURI(); - /** Field algorithm */ - private java.security.Signature _signatureAlgorithm = null; + /** Field algorithm */ + private java.security.Signature _signatureAlgorithm = null; - /** - * Constructor SignatureRSA - * - * @throws XMLSignatureException - */ - public SignatureBaseRSA() throws XMLSignatureException { + /** + * Constructor SignatureRSA + * + * @throws XMLSignatureException + */ + public SignatureBaseRSA() throws XMLSignatureException { - String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI()); + String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI()); - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Created SignatureDSA using " + algorithmID); - String provider=JCEMapper.getProviderId(); - try { - if (provider==null) { + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Created SignatureRSA using " + algorithmID); + String provider=JCEMapper.getProviderId(); + try { + if (provider==null) { this._signatureAlgorithm = Signature.getInstance(algorithmID); - } else { + } else { this._signatureAlgorithm = Signature.getInstance(algorithmID,provider); - } - } catch (java.security.NoSuchAlgorithmException ex) { - Object[] exArgs = { algorithmID, - ex.getLocalizedMessage() }; + } + } catch (java.security.NoSuchAlgorithmException ex) { + Object[] exArgs = { algorithmID, ex.getLocalizedMessage() }; - throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs); - } catch (NoSuchProviderException ex) { - Object[] exArgs = { algorithmID, - ex.getLocalizedMessage() }; + throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs); + } catch (NoSuchProviderException ex) { + Object[] exArgs = { algorithmID, ex.getLocalizedMessage() }; - throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs); + throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs); } - } + } - /** @inheritDoc */ - protected void engineSetParameter(AlgorithmParameterSpec params) - throws XMLSignatureException { + /** @inheritDoc */ + protected void engineSetParameter(AlgorithmParameterSpec params) + throws XMLSignatureException { - try { - this._signatureAlgorithm.setParameter(params); - } catch (InvalidAlgorithmParameterException ex) { - throw new XMLSignatureException("empty", ex); - } - } + try { + this._signatureAlgorithm.setParameter(params); + } catch (InvalidAlgorithmParameterException ex) { + throw new XMLSignatureException("empty", ex); + } + } - /** @inheritDoc */ - protected boolean engineVerify(byte[] signature) - throws XMLSignatureException { + /** @inheritDoc */ + protected boolean engineVerify(byte[] signature) + throws XMLSignatureException { - try { - return this._signatureAlgorithm.verify(signature); - } catch (SignatureException ex) { - throw new XMLSignatureException("empty", ex); - } - } + try { + return this._signatureAlgorithm.verify(signature); + } catch (SignatureException ex) { + throw new XMLSignatureException("empty", ex); + } + } - /** @inheritDoc */ - protected void engineInitVerify(Key publicKey) throws XMLSignatureException { + /** @inheritDoc */ + protected void engineInitVerify(Key publicKey) throws XMLSignatureException { - if (!(publicKey instanceof PublicKey)) { - String supplied = publicKey.getClass().getName(); - String needed = PublicKey.class.getName(); - Object exArgs[] = { supplied, needed }; + if (!(publicKey instanceof PublicKey)) { + String supplied = publicKey.getClass().getName(); + String needed = PublicKey.class.getName(); + Object exArgs[] = { supplied, needed }; - throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", - exArgs); - } + throw new XMLSignatureException + ("algorithms.WrongKeyForThisOperation", exArgs); + } - try { - this._signatureAlgorithm.initVerify((PublicKey) publicKey); - } catch (InvalidKeyException ex) { - throw new XMLSignatureException("empty", ex); - } - } + try { + this._signatureAlgorithm.initVerify((PublicKey) publicKey); + } catch (InvalidKeyException ex) { + // reinstantiate Signature object to work around bug in JDK + // see: http://bugs.sun.com/view_bug.do?bug_id=4953555 + Signature sig = this._signatureAlgorithm; + try { + this._signatureAlgorithm = Signature.getInstance + (_signatureAlgorithm.getAlgorithm()); + } catch (Exception e) { + // this shouldn't occur, but if it does, restore previous + // Signature + if (log.isLoggable(java.util.logging.Level.FINE)) { + log.log(java.util.logging.Level.FINE, "Exception when reinstantiating Signature:" + e); + } + this._signatureAlgorithm = sig; + } + throw new XMLSignatureException("empty", ex); + } + } - /** @inheritDoc */ - protected byte[] engineSign() throws XMLSignatureException { + /** @inheritDoc */ + protected byte[] engineSign() throws XMLSignatureException { + try { + return this._signatureAlgorithm.sign(); + } catch (SignatureException ex) { + throw new XMLSignatureException("empty", ex); + } + } - try { - return this._signatureAlgorithm.sign(); - } catch (SignatureException ex) { - throw new XMLSignatureException("empty", ex); - } - } + /** @inheritDoc */ + protected void engineInitSign(Key privateKey, SecureRandom secureRandom) + throws XMLSignatureException { - /** @inheritDoc */ - protected void engineInitSign(Key privateKey, SecureRandom secureRandom) - throws XMLSignatureException { + if (!(privateKey instanceof PrivateKey)) { + String supplied = privateKey.getClass().getName(); + String needed = PrivateKey.class.getName(); + Object exArgs[] = { supplied, needed }; - if (!(privateKey instanceof PrivateKey)) { - String supplied = privateKey.getClass().getName(); - String needed = PrivateKey.class.getName(); - Object exArgs[] = { supplied, needed }; + throw new XMLSignatureException + ("algorithms.WrongKeyForThisOperation", exArgs); + } - throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", - exArgs); - } + try { + this._signatureAlgorithm.initSign + ((PrivateKey) privateKey, secureRandom); + } catch (InvalidKeyException ex) { + throw new XMLSignatureException("empty", ex); + } + } - try { - this._signatureAlgorithm.initSign((PrivateKey) privateKey, - secureRandom); - } catch (InvalidKeyException ex) { - throw new XMLSignatureException("empty", ex); - } - } + /** @inheritDoc */ + protected void engineInitSign(Key privateKey) throws XMLSignatureException { - /** @inheritDoc */ - protected void engineInitSign(Key privateKey) throws XMLSignatureException { + if (!(privateKey instanceof PrivateKey)) { + String supplied = privateKey.getClass().getName(); + String needed = PrivateKey.class.getName(); + Object exArgs[] = { supplied, needed }; - if (!(privateKey instanceof PrivateKey)) { - String supplied = privateKey.getClass().getName(); - String needed = PrivateKey.class.getName(); - Object exArgs[] = { supplied, needed }; + throw new XMLSignatureException + ("algorithms.WrongKeyForThisOperation", exArgs); + } - throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", - exArgs); - } + try { + this._signatureAlgorithm.initSign((PrivateKey) privateKey); + } catch (InvalidKeyException ex) { + throw new XMLSignatureException("empty", ex); + } + } - try { - this._signatureAlgorithm.initSign((PrivateKey) privateKey); - } catch (InvalidKeyException ex) { - throw new XMLSignatureException("empty", ex); - } - } + /** @inheritDoc */ + protected void engineUpdate(byte[] input) throws XMLSignatureException { + try { + this._signatureAlgorithm.update(input); + } catch (SignatureException ex) { + throw new XMLSignatureException("empty", ex); + } + } - /** @inheritDoc */ - protected void engineUpdate(byte[] input) throws XMLSignatureException { + /** @inheritDoc */ + protected void engineUpdate(byte input) throws XMLSignatureException { + try { + this._signatureAlgorithm.update(input); + } catch (SignatureException ex) { + throw new XMLSignatureException("empty", ex); + } + } - try { - this._signatureAlgorithm.update(input); - } catch (SignatureException ex) { - throw new XMLSignatureException("empty", ex); - } - } + /** @inheritDoc */ + protected void engineUpdate(byte buf[], int offset, int len) + throws XMLSignatureException { + try { + this._signatureAlgorithm.update(buf, offset, len); + } catch (SignatureException ex) { + throw new XMLSignatureException("empty", ex); + } + } - /** @inheritDoc */ - protected void engineUpdate(byte input) throws XMLSignatureException { + /** @inheritDoc */ + protected String engineGetJCEAlgorithmString() { + return this._signatureAlgorithm.getAlgorithm(); + } - try { - this._signatureAlgorithm.update(input); - } catch (SignatureException ex) { - throw new XMLSignatureException("empty", ex); - } - } + /** @inheritDoc */ + protected String engineGetJCEProviderName() { + return this._signatureAlgorithm.getProvider().getName(); + } - /** @inheritDoc */ - protected void engineUpdate(byte buf[], int offset, int len) - throws XMLSignatureException { + /** @inheritDoc */ + protected void engineSetHMACOutputLength(int HMACOutputLength) + throws XMLSignatureException { + throw new XMLSignatureException + ("algorithms.HMACOutputLengthOnlyForHMAC"); + } - try { - this._signatureAlgorithm.update(buf, offset, len); - } catch (SignatureException ex) { - throw new XMLSignatureException("empty", ex); - } - } + /** @inheritDoc */ + protected void engineInitSign( + Key signingKey, AlgorithmParameterSpec algorithmParameterSpec) + throws XMLSignatureException { + throw new XMLSignatureException( + "algorithms.CannotUseAlgorithmParameterSpecOnRSA"); + } - /** @inheritDoc */ - protected String engineGetJCEAlgorithmString() { - return this._signatureAlgorithm.getAlgorithm(); - } + /** + * Class SignatureRSASHA1 + * + * @author $Author: mullan $ + * @version $Revision: 1.5 $ + */ + public static class SignatureRSASHA1 extends SignatureBaseRSA { - /** @inheritDoc */ - protected String engineGetJCEProviderName() { - return this._signatureAlgorithm.getProvider().getName(); - } + /** + * Constructor SignatureRSASHA1 + * + * @throws XMLSignatureException + */ + public SignatureRSASHA1() throws XMLSignatureException { + super(); + } - /** @inheritDoc */ - protected void engineSetHMACOutputLength(int HMACOutputLength) - throws XMLSignatureException { - throw new XMLSignatureException("algorithms.HMACOutputLengthOnlyForHMAC"); - } + /** @inheritDoc */ + public String engineGetURI() { + return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1; + } + } - /** @inheritDoc */ - protected void engineInitSign( - Key signingKey, AlgorithmParameterSpec algorithmParameterSpec) - throws XMLSignatureException { - throw new XMLSignatureException( - "algorithms.CannotUseAlgorithmParameterSpecOnRSA"); - } + /** + * Class SignatureRSASHA256 + * + * @author $Author: mullan $ + * @version $Revision: 1.5 $ + */ + public static class SignatureRSASHA256 extends SignatureBaseRSA { - /** - * Class SignatureRSASHA1 - * - * @author $Author: raul $ - */ - public static class SignatureRSASHA1 extends SignatureBaseRSA { + /** + * Constructor SignatureRSASHA256 + * + * @throws XMLSignatureException + */ + public SignatureRSASHA256() throws XMLSignatureException { + super(); + } - /** - * Constructor SignatureRSASHA1 - * - * @throws XMLSignatureException - */ - public SignatureRSASHA1() throws XMLSignatureException { - super(); - } + /** @inheritDoc */ + public String engineGetURI() { + return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256; + } + } - /** @inheritDoc */ - public String engineGetURI() { - return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1; - } - } + /** + * Class SignatureRSASHA384 + * + * @author $Author: mullan $ + * @version $Revision: 1.5 $ + */ + public static class SignatureRSASHA384 extends SignatureBaseRSA { - /** - * Class SignatureRSASHA256 - * - * @author $Author: raul $ - */ - public static class SignatureRSASHA256 extends SignatureBaseRSA { + /** + * Constructor SignatureRSASHA384 + * + * @throws XMLSignatureException + */ + public SignatureRSASHA384() throws XMLSignatureException { + super(); + } - /** - * Constructor SignatureRSASHA256 - * - * @throws XMLSignatureException - */ - public SignatureRSASHA256() throws XMLSignatureException { - super(); - } + /** @inheritDoc */ + public String engineGetURI() { + return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA384; + } + } - /** @inheritDoc */ - public String engineGetURI() { - return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256; - } - } + /** + * Class SignatureRSASHA512 + * + * @author $Author: mullan $ + * @version $Revision: 1.5 $ + */ + public static class SignatureRSASHA512 extends SignatureBaseRSA { - /** - * Class SignatureRSASHA384 - * - * @author $Author: raul $ - */ - public static class SignatureRSASHA384 extends SignatureBaseRSA { + /** + * Constructor SignatureRSASHA512 + * + * @throws XMLSignatureException + */ + public SignatureRSASHA512() throws XMLSignatureException { + super(); + } - /** - * Constructor SignatureRSASHA384 - * - * @throws XMLSignatureException - */ - public SignatureRSASHA384() throws XMLSignatureException { - super(); - } + /** @inheritDoc */ + public String engineGetURI() { + return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA512; + } + } - /** @inheritDoc */ - public String engineGetURI() { - return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA384; - } - } + /** + * Class SignatureRSARIPEMD160 + * + * @author $Author: mullan $ + * @version $Revision: 1.5 $ + */ + public static class SignatureRSARIPEMD160 extends SignatureBaseRSA { - /** - * Class SignatureRSASHA512 - * - * @author $Author: raul $ - */ - public static class SignatureRSASHA512 extends SignatureBaseRSA { + /** + * Constructor SignatureRSARIPEMD160 + * + * @throws XMLSignatureException + */ + public SignatureRSARIPEMD160() throws XMLSignatureException { + super(); + } - /** - * Constructor SignatureRSASHA512 - * - * @throws XMLSignatureException - */ - public SignatureRSASHA512() throws XMLSignatureException { - super(); - } + /** @inheritDoc */ + public String engineGetURI() { + return XMLSignature.ALGO_ID_SIGNATURE_RSA_RIPEMD160; + } + } - /** @inheritDoc */ - public String engineGetURI() { - return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA512; - } - } + /** + * Class SignatureRSAMD5 + * + * @author $Author: mullan $ + * @version $Revision: 1.5 $ + */ + public static class SignatureRSAMD5 extends SignatureBaseRSA { - /** - * Class SignatureRSARIPEMD160 - * - * @author $Author: raul $ - */ - public static class SignatureRSARIPEMD160 extends SignatureBaseRSA { + /** + * Constructor SignatureRSAMD5 + * + * @throws XMLSignatureException + */ + public SignatureRSAMD5() throws XMLSignatureException { + super(); + } - /** - * Constructor SignatureRSARIPEMD160 - * - * @throws XMLSignatureException - */ - public SignatureRSARIPEMD160() throws XMLSignatureException { - super(); - } - - /** @inheritDoc */ - public String engineGetURI() { - return XMLSignature.ALGO_ID_SIGNATURE_RSA_RIPEMD160; - } - } - - /** - * Class SignatureRSAMD5 - * - * @author $Author: raul $ - */ - public static class SignatureRSAMD5 extends SignatureBaseRSA { - - /** - * Constructor SignatureRSAMD5 - * - * @throws XMLSignatureException - */ - public SignatureRSAMD5() throws XMLSignatureException { - super(); - } - - /** @inheritDoc */ - public String engineGetURI() { - return XMLSignature.ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5; - } - } + /** @inheritDoc */ + public String engineGetURI() { + return XMLSignature.ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5; + } + } } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureDSA.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureDSA.java index 355579b7e53..615aa436e46 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureDSA.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureDSA.java @@ -20,8 +20,6 @@ */ package com.sun.org.apache.xml.internal.security.algorithms.implementations; - - import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; @@ -39,342 +37,359 @@ import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException; import com.sun.org.apache.xml.internal.security.utils.Base64; import com.sun.org.apache.xml.internal.security.utils.Constants; - /** * - * @author $Author: vishal $ + * @author $Author: mullan $ */ public class SignatureDSA extends SignatureAlgorithmSpi { - /** {@link java.util.logging} logging facility */ + /** {@link java.util.logging} logging facility */ static java.util.logging.Logger log = java.util.logging.Logger.getLogger(SignatureDSA.class.getName()); - /** Field _URI */ - public static final String _URI = Constants.SignatureSpecNS + "dsa-sha1"; + /** Field _URI */ + public static final String _URI = Constants.SignatureSpecNS + "dsa-sha1"; - /** Field algorithm */ - private java.security.Signature _signatureAlgorithm = null; + /** Field algorithm */ + private java.security.Signature _signatureAlgorithm = null; - /** - * Method engineGetURI - * - * @inheritDoc - */ - protected String engineGetURI() { - return SignatureDSA._URI; - } + /** + * Method engineGetURI + * + * @inheritDoc + */ + protected String engineGetURI() { + return SignatureDSA._URI; + } - /** - * Constructor SignatureDSA - * - * @throws XMLSignatureException - */ - public SignatureDSA() throws XMLSignatureException { + /** + * Constructor SignatureDSA + * + * @throws XMLSignatureException + */ + public SignatureDSA() throws XMLSignatureException { - String algorithmID = JCEMapper.translateURItoJCEID(SignatureDSA._URI); - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Created SignatureDSA using " + algorithmID); + String algorithmID = JCEMapper.translateURItoJCEID(SignatureDSA._URI); + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Created SignatureDSA using " + algorithmID); - try { - this._signatureAlgorithm = Signature.getInstance(algorithmID); - } catch (java.security.NoSuchAlgorithmException ex) { - Object[] exArgs = { algorithmID, - ex.getLocalizedMessage() }; + String provider = JCEMapper.getProviderId(); + try { + if (provider == null) { + this._signatureAlgorithm = Signature.getInstance(algorithmID); + } else { + this._signatureAlgorithm = + Signature.getInstance(algorithmID, provider); + } + } catch (java.security.NoSuchAlgorithmException ex) { + Object[] exArgs = { algorithmID, ex.getLocalizedMessage() }; + throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs); + } catch (java.security.NoSuchProviderException ex) { + Object[] exArgs = { algorithmID, ex.getLocalizedMessage() }; + throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs); + } + } - throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs); - } - } + /** + * @inheritDoc + */ + protected void engineSetParameter(AlgorithmParameterSpec params) + throws XMLSignatureException { - /** - * @inheritDoc - */ - protected void engineSetParameter(AlgorithmParameterSpec params) + try { + this._signatureAlgorithm.setParameter(params); + } catch (InvalidAlgorithmParameterException ex) { + throw new XMLSignatureException("empty", ex); + } + } + + /** + * @inheritDoc + */ + protected boolean engineVerify(byte[] signature) throws XMLSignatureException { - try { - this._signatureAlgorithm.setParameter(params); - } catch (InvalidAlgorithmParameterException ex) { - throw new XMLSignatureException("empty", ex); - } - } + try { + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Called DSA.verify() on " + Base64.encode(signature)); - /** - * @inheritDoc - */ - protected boolean engineVerify(byte[] signature) + byte[] jcebytes = SignatureDSA.convertXMLDSIGtoASN1(signature); + + return this._signatureAlgorithm.verify(jcebytes); + } catch (SignatureException ex) { + throw new XMLSignatureException("empty", ex); + } catch (IOException ex) { + throw new XMLSignatureException("empty", ex); + } + } + + /** + * @inheritDoc + */ + protected void engineInitVerify(Key publicKey) throws XMLSignatureException { + + if (!(publicKey instanceof PublicKey)) { + String supplied = publicKey.getClass().getName(); + String needed = PublicKey.class.getName(); + Object exArgs[] = { supplied, needed }; + + throw new XMLSignatureException + ("algorithms.WrongKeyForThisOperation", exArgs); + } + + try { + this._signatureAlgorithm.initVerify((PublicKey) publicKey); + } catch (InvalidKeyException ex) { + // reinstantiate Signature object to work around bug in JDK + // see: http://bugs.sun.com/view_bug.do?bug_id=4953555 + Signature sig = this._signatureAlgorithm; + try { + this._signatureAlgorithm = Signature.getInstance + (_signatureAlgorithm.getAlgorithm()); + } catch (Exception e) { + // this shouldn't occur, but if it does, restore previous + // Signature + if (log.isLoggable(java.util.logging.Level.FINE)) { + log.log(java.util.logging.Level.FINE, "Exception when reinstantiating Signature:" + e); + } + this._signatureAlgorithm = sig; + } + throw new XMLSignatureException("empty", ex); + } + } + + /** + * @inheritDoc + */ + protected byte[] engineSign() throws XMLSignatureException { + + try { + byte jcebytes[] = this._signatureAlgorithm.sign(); + + return SignatureDSA.convertASN1toXMLDSIG(jcebytes); + } catch (IOException ex) { + throw new XMLSignatureException("empty", ex); + } catch (SignatureException ex) { + throw new XMLSignatureException("empty", ex); + } + } + + /** + * @inheritDoc + */ + protected void engineInitSign(Key privateKey, SecureRandom secureRandom) throws XMLSignatureException { - try { - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Called DSA.verify() on " + Base64.encode(signature)); + if (!(privateKey instanceof PrivateKey)) { + String supplied = privateKey.getClass().getName(); + String needed = PrivateKey.class.getName(); + Object exArgs[] = { supplied, needed }; - byte[] jcebytes = SignatureDSA.convertXMLDSIGtoASN1(signature); + throw new XMLSignatureException + ("algorithms.WrongKeyForThisOperation", exArgs); + } - return this._signatureAlgorithm.verify(jcebytes); - } catch (SignatureException ex) { - throw new XMLSignatureException("empty", ex); - } catch (IOException ex) { - throw new XMLSignatureException("empty", ex); - } - } - - /** - * @inheritDoc - */ - protected void engineInitVerify(Key publicKey) throws XMLSignatureException { - - if (!(publicKey instanceof PublicKey)) { - String supplied = publicKey.getClass().getName(); - String needed = PublicKey.class.getName(); - Object exArgs[] = { supplied, needed }; - - throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", - exArgs); - } - - try { - this._signatureAlgorithm.initVerify((PublicKey) publicKey); - } catch (InvalidKeyException ex) { - throw new XMLSignatureException("empty", ex); - } - } - - /** - * @inheritDoc - */ - protected byte[] engineSign() throws XMLSignatureException { - - try { - byte jcebytes[] = this._signatureAlgorithm.sign(); - - return SignatureDSA.convertASN1toXMLDSIG(jcebytes); - } catch (IOException ex) { - throw new XMLSignatureException("empty", ex); - } catch (SignatureException ex) { - throw new XMLSignatureException("empty", ex); - } - } - - /** - * @inheritDoc - */ - protected void engineInitSign(Key privateKey, SecureRandom secureRandom) - throws XMLSignatureException { - - if (!(privateKey instanceof PrivateKey)) { - String supplied = privateKey.getClass().getName(); - String needed = PrivateKey.class.getName(); - Object exArgs[] = { supplied, needed }; - - throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", - exArgs); - } - - try { - this._signatureAlgorithm.initSign((PrivateKey) privateKey, + try { + this._signatureAlgorithm.initSign((PrivateKey) privateKey, secureRandom); - } catch (InvalidKeyException ex) { - throw new XMLSignatureException("empty", ex); - } - } + } catch (InvalidKeyException ex) { + throw new XMLSignatureException("empty", ex); + } + } - /** - * @inheritDoc - */ - protected void engineInitSign(Key privateKey) throws XMLSignatureException { + /** + * @inheritDoc + */ + protected void engineInitSign(Key privateKey) throws XMLSignatureException { - if (!(privateKey instanceof PrivateKey)) { - String supplied = privateKey.getClass().getName(); - String needed = PrivateKey.class.getName(); - Object exArgs[] = { supplied, needed }; + if (!(privateKey instanceof PrivateKey)) { + String supplied = privateKey.getClass().getName(); + String needed = PrivateKey.class.getName(); + Object exArgs[] = { supplied, needed }; - throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", - exArgs); - } + throw new XMLSignatureException + ("algorithms.WrongKeyForThisOperation", exArgs); + } - try { - this._signatureAlgorithm.initSign((PrivateKey) privateKey); - } catch (InvalidKeyException ex) { - throw new XMLSignatureException("empty", ex); - } - } + try { + this._signatureAlgorithm.initSign((PrivateKey) privateKey); + } catch (InvalidKeyException ex) { + throw new XMLSignatureException("empty", ex); + } + } - /** - * @inheritDoc - */ - protected void engineUpdate(byte[] input) throws XMLSignatureException { + /** + * @inheritDoc + */ + protected void engineUpdate(byte[] input) throws XMLSignatureException { + try { + this._signatureAlgorithm.update(input); + } catch (SignatureException ex) { + throw new XMLSignatureException("empty", ex); + } + } - try { - this._signatureAlgorithm.update(input); - } catch (SignatureException ex) { - throw new XMLSignatureException("empty", ex); - } - } + /** + * @inheritDoc + */ + protected void engineUpdate(byte input) throws XMLSignatureException { + try { + this._signatureAlgorithm.update(input); + } catch (SignatureException ex) { + throw new XMLSignatureException("empty", ex); + } + } - /** - * @inheritDoc - */ - protected void engineUpdate(byte input) throws XMLSignatureException { + /** + * @inheritDoc + */ + protected void engineUpdate(byte buf[], int offset, int len) + throws XMLSignatureException { + try { + this._signatureAlgorithm.update(buf, offset, len); + } catch (SignatureException ex) { + throw new XMLSignatureException("empty", ex); + } + } - try { - this._signatureAlgorithm.update(input); - } catch (SignatureException ex) { - throw new XMLSignatureException("empty", ex); - } - } + /** + * Method engineGetJCEAlgorithmString + * + * @inheritDoc + */ + protected String engineGetJCEAlgorithmString() { + return this._signatureAlgorithm.getAlgorithm(); + } - /** - * @inheritDoc - */ - protected void engineUpdate(byte buf[], int offset, int len) - throws XMLSignatureException { + /** + * Method engineGetJCEProviderName + * + * @inheritDoc + */ + protected String engineGetJCEProviderName() { + return this._signatureAlgorithm.getProvider().getName(); + } - try { - this._signatureAlgorithm.update(buf, offset, len); - } catch (SignatureException ex) { - throw new XMLSignatureException("empty", ex); - } - } - - /** - * Method engineGetJCEAlgorithmString - * - * @inheritDoc - */ - protected String engineGetJCEAlgorithmString() { - return this._signatureAlgorithm.getAlgorithm(); - } - - /** - * Method engineGetJCEProviderName - * - * @inheritDoc - */ - protected String engineGetJCEProviderName() { - return this._signatureAlgorithm.getProvider().getName(); - } - - - /** - * Converts an ASN.1 DSA value to a XML Signature DSA Value. - * - * The JAVA JCE DSA Signature algorithm creates ASN.1 encoded (r,s) value - * pairs; the XML Signature requires the core BigInteger values. - * - * @param asn1Bytes - * @return the decode bytes - * - * @throws IOException - * @see 6.4.1 DSA - */ - private static byte[] convertASN1toXMLDSIG(byte asn1Bytes[]) + /** + * Converts an ASN.1 DSA value to a XML Signature DSA Value. + * + * The JAVA JCE DSA Signature algorithm creates ASN.1 encoded (r,s) value + * pairs; the XML Signature requires the core BigInteger values. + * + * @param asn1Bytes + * @return the decode bytes + * + * @throws IOException + * @see 6.4.1 DSA + */ + private static byte[] convertASN1toXMLDSIG(byte asn1Bytes[]) throws IOException { - byte rLength = asn1Bytes[3]; - int i; + byte rLength = asn1Bytes[3]; + int i; - for (i = rLength; (i > 0) && (asn1Bytes[(4 + rLength) - i] == 0); i--); + for (i = rLength; (i > 0) && (asn1Bytes[(4 + rLength) - i] == 0); i--); - byte sLength = asn1Bytes[5 + rLength]; - int j; + byte sLength = asn1Bytes[5 + rLength]; + int j; - for (j = sLength; + for (j = sLength; (j > 0) && (asn1Bytes[(6 + rLength + sLength) - j] == 0); j--); - if ((asn1Bytes[0] != 48) || (asn1Bytes[1] != asn1Bytes.length - 2) + if ((asn1Bytes[0] != 48) || (asn1Bytes[1] != asn1Bytes.length - 2) || (asn1Bytes[2] != 2) || (i > 20) || (asn1Bytes[4 + rLength] != 2) || (j > 20)) { - throw new IOException("Invalid ASN.1 format of DSA signature"); - } - byte xmldsigBytes[] = new byte[40]; + throw new IOException("Invalid ASN.1 format of DSA signature"); + } + byte xmldsigBytes[] = new byte[40]; - System.arraycopy(asn1Bytes, (4 + rLength) - i, xmldsigBytes, 20 - i, + System.arraycopy(asn1Bytes, (4 + rLength) - i, xmldsigBytes, 20 - i, i); - System.arraycopy(asn1Bytes, (6 + rLength + sLength) - j, xmldsigBytes, + System.arraycopy(asn1Bytes, (6 + rLength + sLength) - j, xmldsigBytes, 40 - j, j); - return xmldsigBytes; - } + return xmldsigBytes; + } - /** - * Converts a XML Signature DSA Value to an ASN.1 DSA value. - * - * The JAVA JCE DSA Signature algorithm creates ASN.1 encoded (r,s) value - * pairs; the XML Signature requires the core BigInteger values. - * - * @param xmldsigBytes - * @return the encoded ASN.1 bytes - * - * @throws IOException - * @see 6.4.1 DSA - */ - private static byte[] convertXMLDSIGtoASN1(byte xmldsigBytes[]) + /** + * Converts a XML Signature DSA Value to an ASN.1 DSA value. + * + * The JAVA JCE DSA Signature algorithm creates ASN.1 encoded (r,s) value + * pairs; the XML Signature requires the core BigInteger values. + * + * @param xmldsigBytes + * @return the encoded ASN.1 bytes + * + * @throws IOException + * @see 6.4.1 DSA + */ + private static byte[] convertXMLDSIGtoASN1(byte xmldsigBytes[]) throws IOException { - if (xmldsigBytes.length != 40) { - throw new IOException("Invalid XMLDSIG format of DSA signature"); - } + if (xmldsigBytes.length != 40) { + throw new IOException("Invalid XMLDSIG format of DSA signature"); + } - int i; + int i; - for (i = 20; (i > 0) && (xmldsigBytes[20 - i] == 0); i--); + for (i = 20; (i > 0) && (xmldsigBytes[20 - i] == 0); i--); - int j = i; + int j = i; - if (xmldsigBytes[20 - i] < 0) { + if (xmldsigBytes[20 - i] < 0) { j += 1; - } + } - int k; + int k; - for (k = 20; (k > 0) && (xmldsigBytes[40 - k] == 0); k--); + for (k = 20; (k > 0) && (xmldsigBytes[40 - k] == 0); k--); - int l = k; + int l = k; - if (xmldsigBytes[40 - k] < 0) { - l += 1; - } + if (xmldsigBytes[40 - k] < 0) { + l += 1; + } - byte asn1Bytes[] = new byte[6 + j + l]; + byte asn1Bytes[] = new byte[6 + j + l]; - asn1Bytes[0] = 48; - asn1Bytes[1] = (byte) (4 + j + l); - asn1Bytes[2] = 2; - asn1Bytes[3] = (byte) j; + asn1Bytes[0] = 48; + asn1Bytes[1] = (byte) (4 + j + l); + asn1Bytes[2] = 2; + asn1Bytes[3] = (byte) j; - System.arraycopy(xmldsigBytes, 20 - i, asn1Bytes, (4 + j) - i, i); + System.arraycopy(xmldsigBytes, 20 - i, asn1Bytes, (4 + j) - i, i); - asn1Bytes[4 + j] = 2; - asn1Bytes[5 + j] = (byte) l; + asn1Bytes[4 + j] = 2; + asn1Bytes[5 + j] = (byte) l; - System.arraycopy(xmldsigBytes, 40 - k, asn1Bytes, (6 + j + l) - k, k); + System.arraycopy(xmldsigBytes, 40 - k, asn1Bytes, (6 + j + l) - k, k); - return asn1Bytes; - } + return asn1Bytes; + } - /** - * Method engineSetHMACOutputLength - * - * @param HMACOutputLength - * @throws XMLSignatureException - */ - protected void engineSetHMACOutputLength(int HMACOutputLength) - throws XMLSignatureException { - throw new XMLSignatureException("algorithms.HMACOutputLengthOnlyForHMAC"); - } + /** + * Method engineSetHMACOutputLength + * + * @param HMACOutputLength + * @throws XMLSignatureException + */ + protected void engineSetHMACOutputLength(int HMACOutputLength) + throws XMLSignatureException { + throw new XMLSignatureException( + "algorithms.HMACOutputLengthOnlyForHMAC"); + } - /** - * Method engineInitSign - * - * @param signingKey - * @param algorithmParameterSpec - * @throws XMLSignatureException - */ - protected void engineInitSign( - Key signingKey, AlgorithmParameterSpec algorithmParameterSpec) - throws XMLSignatureException { - throw new XMLSignatureException( - "algorithms.CannotUseAlgorithmParameterSpecOnDSA"); - } + /** + * Method engineInitSign + * + * @param signingKey + * @param algorithmParameterSpec + * @throws XMLSignatureException + */ + protected void engineInitSign( + Key signingKey, AlgorithmParameterSpec algorithmParameterSpec) + throws XMLSignatureException { + throw new XMLSignatureException( + "algorithms.CannotUseAlgorithmParameterSpecOnDSA"); + } } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureECDSA.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureECDSA.java new file mode 100644 index 00000000000..18fdffe28fb --- /dev/null +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureECDSA.java @@ -0,0 +1,384 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Copyright 1999-2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package com.sun.org.apache.xml.internal.security.algorithms.implementations; + + + +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.NoSuchProviderException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.Signature; +import java.security.SignatureException; +import java.security.spec.AlgorithmParameterSpec; + +import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper; +import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithmSpi; +import com.sun.org.apache.xml.internal.security.signature.XMLSignature; +import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException; +import com.sun.org.apache.xml.internal.security.utils.Base64; + + +/** + * + * @author $Author: mullan $ + */ +public abstract class SignatureECDSA extends SignatureAlgorithmSpi { + + /** {@link java.util.logging} logging facility */ + static java.util.logging.Logger log = + java.util.logging.Logger.getLogger(SignatureECDSA.class.getName()); + + /** @inheritDoc */ + public abstract String engineGetURI(); + + /** Field algorithm */ + private java.security.Signature _signatureAlgorithm = null; + + /** + * Converts an ASN.1 ECDSA value to a XML Signature ECDSA Value. + * + * The JAVA JCE ECDSA Signature algorithm creates ASN.1 encoded (r,s) value + * pairs; the XML Signature requires the core BigInteger values. + * + * @param asn1Bytes + * @return the decode bytes + * + * @throws IOException + * @see 6.4.1 DSA + * @see 3.3. ECDSA Signatures + */ + private static byte[] convertASN1toXMLDSIG(byte asn1Bytes[]) + throws IOException { + + byte rLength = asn1Bytes[3]; + int i; + + for (i = rLength; (i > 0) && (asn1Bytes[(4 + rLength) - i] == 0); i--); + + byte sLength = asn1Bytes[5 + rLength]; + int j; + + for (j = sLength; + (j > 0) && (asn1Bytes[(6 + rLength + sLength) - j] == 0); j--); + + if ((asn1Bytes[0] != 48) || (asn1Bytes[1] != asn1Bytes.length - 2) + || (asn1Bytes[2] != 2) || (i > 24) + || (asn1Bytes[4 + rLength] != 2) || (j > 24)) { + throw new IOException("Invalid ASN.1 format of ECDSA signature"); + } + byte xmldsigBytes[] = new byte[48]; + + System.arraycopy(asn1Bytes, (4 + rLength) - i, xmldsigBytes, 24 - i, + i); + System.arraycopy(asn1Bytes, (6 + rLength + sLength) - j, xmldsigBytes, + 48 - j, j); + + return xmldsigBytes; + } + + /** + * Converts a XML Signature ECDSA Value to an ASN.1 DSA value. + * + * The JAVA JCE ECDSA Signature algorithm creates ASN.1 encoded (r,s) value + * pairs; the XML Signature requires the core BigInteger values. + * + * @param xmldsigBytes + * @return the encoded ASN.1 bytes + * + * @throws IOException + * @see 6.4.1 DSA + * @see 3.3. ECDSA Signatures + */ + private static byte[] convertXMLDSIGtoASN1(byte xmldsigBytes[]) + throws IOException { + + if (xmldsigBytes.length != 48) { + throw new IOException("Invalid XMLDSIG format of ECDSA signature"); + } + + int i; + + for (i = 24; (i > 0) && (xmldsigBytes[24 - i] == 0); i--); + + int j = i; + + if (xmldsigBytes[24 - i] < 0) { + j += 1; + } + + int k; + + for (k = 24; (k > 0) && (xmldsigBytes[48 - k] == 0); k--); + + int l = k; + + if (xmldsigBytes[48 - k] < 0) { + l += 1; + } + + byte asn1Bytes[] = new byte[6 + j + l]; + + asn1Bytes[0] = 48; + asn1Bytes[1] = (byte) (4 + j + l); + asn1Bytes[2] = 2; + asn1Bytes[3] = (byte) j; + + System.arraycopy(xmldsigBytes, 24 - i, asn1Bytes, (4 + j) - i, i); + + asn1Bytes[4 + j] = 2; + asn1Bytes[5 + j] = (byte) l; + + System.arraycopy(xmldsigBytes, 48 - k, asn1Bytes, (6 + j + l) - k, k); + + return asn1Bytes; + } + + /** + * Constructor SignatureRSA + * + * @throws XMLSignatureException + */ + public SignatureECDSA() throws XMLSignatureException { + + String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI()); + + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Created SignatureECDSA using " + algorithmID); + String provider=JCEMapper.getProviderId(); + try { + if (provider==null) { + this._signatureAlgorithm = Signature.getInstance(algorithmID); + } else { + this._signatureAlgorithm = Signature.getInstance(algorithmID,provider); + } + } catch (java.security.NoSuchAlgorithmException ex) { + Object[] exArgs = { algorithmID, + ex.getLocalizedMessage() }; + + throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs); + } catch (NoSuchProviderException ex) { + Object[] exArgs = { algorithmID, + ex.getLocalizedMessage() }; + + throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs); + } + } + + /** @inheritDoc */ + protected void engineSetParameter(AlgorithmParameterSpec params) + throws XMLSignatureException { + + try { + this._signatureAlgorithm.setParameter(params); + } catch (InvalidAlgorithmParameterException ex) { + throw new XMLSignatureException("empty", ex); + } + } + + /** @inheritDoc */ + protected boolean engineVerify(byte[] signature) + throws XMLSignatureException { + + try { + byte[] jcebytes = SignatureECDSA.convertXMLDSIGtoASN1(signature); + + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Called ECDSA.verify() on " + Base64.encode(signature)); + + return this._signatureAlgorithm.verify(jcebytes); + } catch (SignatureException ex) { + throw new XMLSignatureException("empty", ex); + } catch (IOException ex) { + throw new XMLSignatureException("empty", ex); + } + } + + /** @inheritDoc */ + protected void engineInitVerify(Key publicKey) throws XMLSignatureException { + + if (!(publicKey instanceof PublicKey)) { + String supplied = publicKey.getClass().getName(); + String needed = PublicKey.class.getName(); + Object exArgs[] = { supplied, needed }; + + throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", + exArgs); + } + + try { + this._signatureAlgorithm.initVerify((PublicKey) publicKey); + } catch (InvalidKeyException ex) { + // reinstantiate Signature object to work around bug in JDK + // see: http://bugs.sun.com/view_bug.do?bug_id=4953555 + Signature sig = this._signatureAlgorithm; + try { + this._signatureAlgorithm = Signature.getInstance + (_signatureAlgorithm.getAlgorithm()); + } catch (Exception e) { + // this shouldn't occur, but if it does, restore previous + // Signature + if (log.isLoggable(java.util.logging.Level.FINE)) { + log.log(java.util.logging.Level.FINE, "Exception when reinstantiating Signature:" + e); + } + this._signatureAlgorithm = sig; + } + throw new XMLSignatureException("empty", ex); + } + } + + /** @inheritDoc */ + protected byte[] engineSign() throws XMLSignatureException { + + try { + byte jcebytes[] = this._signatureAlgorithm.sign(); + + return SignatureECDSA.convertASN1toXMLDSIG(jcebytes); + } catch (SignatureException ex) { + throw new XMLSignatureException("empty", ex); + } catch (IOException ex) { + throw new XMLSignatureException("empty", ex); + } + } + + /** @inheritDoc */ + protected void engineInitSign(Key privateKey, SecureRandom secureRandom) + throws XMLSignatureException { + + if (!(privateKey instanceof PrivateKey)) { + String supplied = privateKey.getClass().getName(); + String needed = PrivateKey.class.getName(); + Object exArgs[] = { supplied, needed }; + + throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", + exArgs); + } + + try { + this._signatureAlgorithm.initSign((PrivateKey) privateKey, + secureRandom); + } catch (InvalidKeyException ex) { + throw new XMLSignatureException("empty", ex); + } + } + + /** @inheritDoc */ + protected void engineInitSign(Key privateKey) throws XMLSignatureException { + + if (!(privateKey instanceof PrivateKey)) { + String supplied = privateKey.getClass().getName(); + String needed = PrivateKey.class.getName(); + Object exArgs[] = { supplied, needed }; + + throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", + exArgs); + } + + try { + this._signatureAlgorithm.initSign((PrivateKey) privateKey); + } catch (InvalidKeyException ex) { + throw new XMLSignatureException("empty", ex); + } + } + + /** @inheritDoc */ + protected void engineUpdate(byte[] input) throws XMLSignatureException { + + try { + this._signatureAlgorithm.update(input); + } catch (SignatureException ex) { + throw new XMLSignatureException("empty", ex); + } + } + + /** @inheritDoc */ + protected void engineUpdate(byte input) throws XMLSignatureException { + + try { + this._signatureAlgorithm.update(input); + } catch (SignatureException ex) { + throw new XMLSignatureException("empty", ex); + } + } + + /** @inheritDoc */ + protected void engineUpdate(byte buf[], int offset, int len) + throws XMLSignatureException { + + try { + this._signatureAlgorithm.update(buf, offset, len); + } catch (SignatureException ex) { + throw new XMLSignatureException("empty", ex); + } + } + + /** @inheritDoc */ + protected String engineGetJCEAlgorithmString() { + return this._signatureAlgorithm.getAlgorithm(); + } + + /** @inheritDoc */ + protected String engineGetJCEProviderName() { + return this._signatureAlgorithm.getProvider().getName(); + } + + /** @inheritDoc */ + protected void engineSetHMACOutputLength(int HMACOutputLength) + throws XMLSignatureException { + throw new XMLSignatureException("algorithms.HMACOutputLengthOnlyForHMAC"); + } + + /** @inheritDoc */ + protected void engineInitSign( + Key signingKey, AlgorithmParameterSpec algorithmParameterSpec) + throws XMLSignatureException { + throw new XMLSignatureException( + "algorithms.CannotUseAlgorithmParameterSpecOnRSA"); + } + + /** + * Class SignatureRSASHA1 + * + * @author $Author: mullan $ + * @version $Revision: 1.2 $ + */ + public static class SignatureECDSASHA1 extends SignatureECDSA { + + /** + * Constructor SignatureRSASHA1 + * + * @throws XMLSignatureException + */ + public SignatureECDSASHA1() throws XMLSignatureException { + super(); + } + + /** @inheritDoc */ + public String engineGetURI() { + return XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA1; + } + } + +} diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/CanonicalizationException.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/CanonicalizationException.java index 732334c3656..36c98cfe790 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/CanonicalizationException.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/CanonicalizationException.java @@ -2,7 +2,6 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ - /* * Copyright 1999-2004 The Apache Software Foundation. * diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java index eb7cb6cad01..a4181233d60 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java @@ -3,7 +3,7 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 1999-2004 The Apache Software Foundation. + * Copyright 1999-2008 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,8 +20,6 @@ */ package com.sun.org.apache.xml.internal.security.c14n; - - import java.io.ByteArrayInputStream; import java.io.OutputStream; import java.util.HashMap; @@ -37,318 +35,326 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; - /** - * * * @author Christian Geuer-Pollmann */ public class Canonicalizer { - //J- - /** The output encoding of canonicalized data */ - public static final String ENCODING = "UTF8"; + /** The output encoding of canonicalized data */ + public static final String ENCODING = "UTF8"; - - /** - * XPath Expresion for selecting every node and continuos comments joined in only one node + /** + * XPath Expresion for selecting every node and continuous comments joined + * in only one node */ - public static final String XPATH_C14N_WITH_COMMENTS_SINGLE_NODE = "(.//. | .//@* | .//namespace::*)"; + public static final String XPATH_C14N_WITH_COMMENTS_SINGLE_NODE = + "(.//. | .//@* | .//namespace::*)"; - - /** + /** * The URL defined in XML-SEC Rec for inclusive c14n without comments. */ - public static final String ALGO_ID_C14N_OMIT_COMMENTS = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"; - /** - * The URL defined in XML-SEC Rec for inclusive c14n with comments. - */ - public static final String ALGO_ID_C14N_WITH_COMMENTS = ALGO_ID_C14N_OMIT_COMMENTS + "#WithComments"; - /** - * The URL defined in XML-SEC Rec for exclusive c14n without comments. - */ - public static final String ALGO_ID_C14N_EXCL_OMIT_COMMENTS = "http://www.w3.org/2001/10/xml-exc-c14n#"; - /** - * The URL defined in XML-SEC Rec for exclusive c14n with comments. - */ - public static final String ALGO_ID_C14N_EXCL_WITH_COMMENTS = ALGO_ID_C14N_EXCL_OMIT_COMMENTS + "WithComments"; + public static final String ALGO_ID_C14N_OMIT_COMMENTS = + "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"; + /** + * The URL defined in XML-SEC Rec for inclusive c14n with comments. + */ + public static final String ALGO_ID_C14N_WITH_COMMENTS = + ALGO_ID_C14N_OMIT_COMMENTS + "#WithComments"; + /** + * The URL defined in XML-SEC Rec for exclusive c14n without comments. + */ + public static final String ALGO_ID_C14N_EXCL_OMIT_COMMENTS = + "http://www.w3.org/2001/10/xml-exc-c14n#"; + /** + * The URL defined in XML-SEC Rec for exclusive c14n with comments. + */ + public static final String ALGO_ID_C14N_EXCL_WITH_COMMENTS = + ALGO_ID_C14N_EXCL_OMIT_COMMENTS + "WithComments"; + /** + * The URI for inclusive c14n 1.1 without comments. + */ + public static final String ALGO_ID_C14N11_OMIT_COMMENTS = + "http://www.w3.org/2006/12/xml-c14n11"; + /** + * The URI for inclusive c14n 1.1 with comments. + */ + public static final String ALGO_ID_C14N11_WITH_COMMENTS = + ALGO_ID_C14N11_OMIT_COMMENTS + "#WithComments"; - static boolean _alreadyInitialized = false; - static Map _canonicalizerHash = null; + static boolean _alreadyInitialized = false; + static Map _canonicalizerHash = null; - protected CanonicalizerSpi canonicalizerSpi = null; - //J+ + protected CanonicalizerSpi canonicalizerSpi = null; - /** - * Method init - * - */ - public static void init() { + /** + * Method init + * + */ + public static void init() { - if (!Canonicalizer._alreadyInitialized) { - Canonicalizer._canonicalizerHash = new HashMap(10); - Canonicalizer._alreadyInitialized = true; - } - } + if (!Canonicalizer._alreadyInitialized) { + Canonicalizer._canonicalizerHash = new HashMap(10); + Canonicalizer._alreadyInitialized = true; + } + } - /** - * Constructor Canonicalizer - * - * @param algorithmURI - * @throws InvalidCanonicalizerException - */ - private Canonicalizer(String algorithmURI) + /** + * Constructor Canonicalizer + * + * @param algorithmURI + * @throws InvalidCanonicalizerException + */ + private Canonicalizer(String algorithmURI) throws InvalidCanonicalizerException { - try { - Class implementingClass = getImplementingClass(algorithmURI); + try { + Class implementingClass = getImplementingClass(algorithmURI); - this.canonicalizerSpi = - (CanonicalizerSpi) implementingClass.newInstance(); - this.canonicalizerSpi.reset=true; - } catch (Exception e) { - Object exArgs[] = { algorithmURI }; + this.canonicalizerSpi = + (CanonicalizerSpi) implementingClass.newInstance(); + this.canonicalizerSpi.reset=true; + } catch (Exception e) { + Object exArgs[] = { algorithmURI }; - throw new InvalidCanonicalizerException( - "signature.Canonicalizer.UnknownCanonicalizer", exArgs); - } - } + throw new InvalidCanonicalizerException( + "signature.Canonicalizer.UnknownCanonicalizer", exArgs); + } + } - /** - * Method getInstance - * - * @param algorithmURI - * @return a Conicicalizer instance ready for the job - * @throws InvalidCanonicalizerException - */ - public static final Canonicalizer getInstance(String algorithmURI) + /** + * Method getInstance + * + * @param algorithmURI + * @return a Conicicalizer instance ready for the job + * @throws InvalidCanonicalizerException + */ + public static final Canonicalizer getInstance(String algorithmURI) throws InvalidCanonicalizerException { - Canonicalizer c14nizer = new Canonicalizer(algorithmURI); + Canonicalizer c14nizer = new Canonicalizer(algorithmURI); - return c14nizer; - } + return c14nizer; + } - /** - * Method register - * - * @param algorithmURI - * @param implementingClass - * @throws AlgorithmAlreadyRegisteredException - */ - public static void register(String algorithmURI, String implementingClass) + /** + * Method register + * + * @param algorithmURI + * @param implementingClass + * @throws AlgorithmAlreadyRegisteredException + */ + public static void register(String algorithmURI, String implementingClass) throws AlgorithmAlreadyRegisteredException { - // check whether URI is already registered - Class registeredClass = getImplementingClass(algorithmURI); + // check whether URI is already registered + Class registeredClass = getImplementingClass(algorithmURI); - if (registeredClass != null) { - Object exArgs[] = { algorithmURI, registeredClass }; + if (registeredClass != null) { + Object exArgs[] = { algorithmURI, registeredClass }; - throw new AlgorithmAlreadyRegisteredException( - "algorithm.alreadyRegistered", exArgs); - } - - try { - _canonicalizerHash.put(algorithmURI, Class.forName(implementingClass)); - } catch (ClassNotFoundException e) { - throw new RuntimeException("c14n class not found"); + throw new AlgorithmAlreadyRegisteredException( + "algorithm.alreadyRegistered", exArgs); } - } - /** - * Method getURI - * - * @return the URI defined for this c14n instance. - */ - public final String getURI() { - return this.canonicalizerSpi.engineGetURI(); - } + try { + _canonicalizerHash.put(algorithmURI, Class.forName(implementingClass)); + } catch (ClassNotFoundException e) { + throw new RuntimeException("c14n class not found"); + } + } - /** - * Method getIncludeComments - * - * @return true if the c14n respect the comments. - */ - public boolean getIncludeComments() { - return this.canonicalizerSpi.engineGetIncludeComments(); - } + /** + * Method getURI + * + * @return the URI defined for this c14n instance. + */ + public final String getURI() { + return this.canonicalizerSpi.engineGetURI(); + } - /** - * This method tries to canonicalize the given bytes. It's possible to even - * canonicalize non-wellformed sequences if they are well-formed after being - * wrapped with a >a<...>/a<. - * - * @param inputBytes - * @return the result of the conicalization. - * @throws CanonicalizationException - * @throws java.io.IOException - * @throws javax.xml.parsers.ParserConfigurationException - * @throws org.xml.sax.SAXException - */ - public byte[] canonicalize(byte[] inputBytes) + /** + * Method getIncludeComments + * + * @return true if the c14n respect the comments. + */ + public boolean getIncludeComments() { + return this.canonicalizerSpi.engineGetIncludeComments(); + } + + /** + * This method tries to canonicalize the given bytes. It's possible to even + * canonicalize non-wellformed sequences if they are well-formed after being + * wrapped with a >a<...>/a<. + * + * @param inputBytes + * @return the result of the conicalization. + * @throws CanonicalizationException + * @throws java.io.IOException + * @throws javax.xml.parsers.ParserConfigurationException + * @throws org.xml.sax.SAXException + */ + public byte[] canonicalize(byte[] inputBytes) throws javax.xml.parsers.ParserConfigurationException, java.io.IOException, org.xml.sax.SAXException, CanonicalizationException { - ByteArrayInputStream bais = new ByteArrayInputStream(inputBytes); - InputSource in = new InputSource(bais); - DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); + ByteArrayInputStream bais = new ByteArrayInputStream(inputBytes); + InputSource in = new InputSource(bais); + DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); - dfactory.setNamespaceAware(true); + dfactory.setNamespaceAware(true); - // needs to validate for ID attribute nomalization - dfactory.setValidating(true); + // needs to validate for ID attribute nomalization + dfactory.setValidating(true); - DocumentBuilder db = dfactory.newDocumentBuilder(); + DocumentBuilder db = dfactory.newDocumentBuilder(); - /* - * for some of the test vectors from the specification, - * there has to be a validatin parser for ID attributes, default - * attribute values, NMTOKENS, etc. - * Unfortunaltely, the test vectors do use different DTDs or - * even no DTD. So Xerces 1.3.1 fires many warnings about using - * ErrorHandlers. - * - * Text from the spec: - * - * The input octet stream MUST contain a well-formed XML document, - * but the input need not be validated. However, the attribute - * value normalization and entity reference resolution MUST be - * performed in accordance with the behaviors of a validating - * XML processor. As well, nodes for default attributes (declared - * in the ATTLIST with an AttValue but not specified) are created - * in each element. Thus, the declarations in the document type - * declaration are used to help create the canonical form, even - * though the document type declaration is not retained in the - * canonical form. - * - */ - db.setErrorHandler(new com.sun.org.apache.xml.internal.security.utils - .IgnoreAllErrorHandler()); + /* + * for some of the test vectors from the specification, + * there has to be a validatin parser for ID attributes, default + * attribute values, NMTOKENS, etc. + * Unfortunaltely, the test vectors do use different DTDs or + * even no DTD. So Xerces 1.3.1 fires many warnings about using + * ErrorHandlers. + * + * Text from the spec: + * + * The input octet stream MUST contain a well-formed XML document, + * but the input need not be validated. However, the attribute + * value normalization and entity reference resolution MUST be + * performed in accordance with the behaviors of a validating + * XML processor. As well, nodes for default attributes (declared + * in the ATTLIST with an AttValue but not specified) are created + * in each element. Thus, the declarations in the document type + * declaration are used to help create the canonical form, even + * though the document type declaration is not retained in the + * canonical form. + * + */ + db.setErrorHandler(new com.sun.org.apache.xml.internal.security.utils + .IgnoreAllErrorHandler()); - Document document = db.parse(in); - byte result[] = this.canonicalizeSubtree(document); + Document document = db.parse(in); + byte result[] = this.canonicalizeSubtree(document); - return result; - } + return result; + } - /** - * Canonicalizes the subtree rooted by node. - * - * @param node The node to canicalize - * @return the result of the c14n. - * - * @throws CanonicalizationException - */ - public byte[] canonicalizeSubtree(Node node) + /** + * Canonicalizes the subtree rooted by node. + * + * @param node The node to canicalize + * @return the result of the c14n. + * + * @throws CanonicalizationException + */ + public byte[] canonicalizeSubtree(Node node) throws CanonicalizationException { - return this.canonicalizerSpi.engineCanonicalizeSubTree(node); - } + return this.canonicalizerSpi.engineCanonicalizeSubTree(node); + } - /** - * Canonicalizes the subtree rooted by node. - * - * @param node - * @param inclusiveNamespaces - * @return the result of the c14n. - * @throws CanonicalizationException - */ - public byte[] canonicalizeSubtree(Node node, String inclusiveNamespaces) + /** + * Canonicalizes the subtree rooted by node. + * + * @param node + * @param inclusiveNamespaces + * @return the result of the c14n. + * @throws CanonicalizationException + */ + public byte[] canonicalizeSubtree(Node node, String inclusiveNamespaces) throws CanonicalizationException { - return this.canonicalizerSpi.engineCanonicalizeSubTree(node, + return this.canonicalizerSpi.engineCanonicalizeSubTree(node, inclusiveNamespaces); - } + } - /** - * Canonicalizes an XPath node set. The xpathNodeSet is treated - * as a list of XPath nodes, not as a list of subtrees. - * - * @param xpathNodeSet - * @return the result of the c14n. - * @throws CanonicalizationException - */ - public byte[] canonicalizeXPathNodeSet(NodeList xpathNodeSet) + /** + * Canonicalizes an XPath node set. The xpathNodeSet is treated + * as a list of XPath nodes, not as a list of subtrees. + * + * @param xpathNodeSet + * @return the result of the c14n. + * @throws CanonicalizationException + */ + public byte[] canonicalizeXPathNodeSet(NodeList xpathNodeSet) throws CanonicalizationException { - return this.canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet); - } + return this.canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet); + } - /** - * Canonicalizes an XPath node set. The xpathNodeSet is treated - * as a list of XPath nodes, not as a list of subtrees. - * - * @param xpathNodeSet - * @param inclusiveNamespaces - * @return the result of the c14n. - * @throws CanonicalizationException - */ - public byte[] canonicalizeXPathNodeSet( + /** + * Canonicalizes an XPath node set. The xpathNodeSet is treated + * as a list of XPath nodes, not as a list of subtrees. + * + * @param xpathNodeSet + * @param inclusiveNamespaces + * @return the result of the c14n. + * @throws CanonicalizationException + */ + public byte[] canonicalizeXPathNodeSet( NodeList xpathNodeSet, String inclusiveNamespaces) throws CanonicalizationException { - return this.canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet, + return this.canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet, inclusiveNamespaces); - } + } - /** - * Canonicalizes an XPath node set. - * - * @param xpathNodeSet - * @return the result of the c14n. - * @throws CanonicalizationException - */ - public byte[] canonicalizeXPathNodeSet(Set xpathNodeSet) + /** + * Canonicalizes an XPath node set. + * + * @param xpathNodeSet + * @return the result of the c14n. + * @throws CanonicalizationException + */ + public byte[] canonicalizeXPathNodeSet(Set xpathNodeSet) throws CanonicalizationException { - return this.canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet); - } + return this.canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet); + } - /** - * Canonicalizes an XPath node set. - * - * @param xpathNodeSet - * @param inclusiveNamespaces - * @return the result of the c14n. - * @throws CanonicalizationException - */ - public byte[] canonicalizeXPathNodeSet( - Set xpathNodeSet, String inclusiveNamespaces) - throws CanonicalizationException { - return this.canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet, - inclusiveNamespaces); - } + /** + * Canonicalizes an XPath node set. + * + * @param xpathNodeSet + * @param inclusiveNamespaces + * @return the result of the c14n. + * @throws CanonicalizationException + */ + public byte[] canonicalizeXPathNodeSet(Set xpathNodeSet, + String inclusiveNamespaces) throws CanonicalizationException { + return this.canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet, + inclusiveNamespaces); + } - /** - * Sets the writter where the cannocalization ends. ByteArrayOutputStream if - * none is setted. - * @param os - */ - public void setWriter(OutputStream os) { - this.canonicalizerSpi.setWriter(os); - } + /** + * Sets the writer where the canonicalization ends. ByteArrayOutputStream + * if none is set. + * @param os + */ + public void setWriter(OutputStream os) { + this.canonicalizerSpi.setWriter(os); + } - /** - * Returns the name of the implementing {@link CanonicalizerSpi} class - * - * @return the name of the implementing {@link CanonicalizerSpi} class - */ - public String getImplementingCanonicalizerClass() { - return this.canonicalizerSpi.getClass().getName(); - } + /** + * Returns the name of the implementing {@link CanonicalizerSpi} class + * + * @return the name of the implementing {@link CanonicalizerSpi} class + */ + public String getImplementingCanonicalizerClass() { + return this.canonicalizerSpi.getClass().getName(); + } - /** - * Method getImplementingClass - * - * @param URI - * @return the name of the class that implements the give URI - */ - private static Class getImplementingClass(String URI) { - return (Class) _canonicalizerHash.get(URI); - } + /** + * Method getImplementingClass + * + * @param URI + * @return the name of the class that implements the given URI + */ + private static Class getImplementingClass(String URI) { + return (Class) _canonicalizerHash.get(URI); + } - /** - * Set the canonicalizator behaviour to not reset. - * - */ - public void notReset() { - this.canonicalizerSpi.reset=false; - } + /** + * Set the canonicalizer behaviour to not reset. + */ + public void notReset() { + this.canonicalizerSpi.reset = false; + } } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/InvalidCanonicalizerException.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/InvalidCanonicalizerException.java index 8af3ed88050..9fb1531b7e9 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/InvalidCanonicalizerException.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/InvalidCanonicalizerException.java @@ -2,7 +2,6 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ - /* * Copyright 1999-2004 The Apache Software Foundation. * diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/helper/AttrCompare.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/helper/AttrCompare.java index 46fdc660338..802abda2862 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/helper/AttrCompare.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/helper/AttrCompare.java @@ -2,7 +2,6 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ - /* * Copyright 1999-2004 The Apache Software Foundation. * @@ -21,17 +20,17 @@ */ package com.sun.org.apache.xml.internal.security.c14n.helper; - - import com.sun.org.apache.xml.internal.security.utils.Constants; import org.w3c.dom.Attr; - +import java.io.Serializable; +import java.util.Comparator; /** * Compares two attributes based on the C14n specification. * *
        - *
      • Namespace nodes have a lesser document order position than attribute nodes. + *
      • Namespace nodes have a lesser document order position than attribute + * nodes. *
      • An element's namespace nodes are sorted lexicographically by * local name (the default namespace node, if one exists, has no * local name and is therefore lexicographically least). @@ -40,104 +39,89 @@ import org.w3c.dom.Attr; * key (an empty namespace URI is lexicographically least). *
      * - * $todo$ Should we implement java.util.Comparator and import java.util.Arrays to use Arrays.sort(intarray); * @author Christian Geuer-Pollmann */ -public class AttrCompare implements java.util.Comparator { +public class AttrCompare implements Comparator, Serializable { - private final int ATTR0_BEFORE_ATTR1 = -1; - private final int ATTR1_BEFORE_ATTR0 = 1; + private final static long serialVersionUID = -7113259629930576230L; + private final static int ATTR0_BEFORE_ATTR1 = -1; + private final static int ATTR1_BEFORE_ATTR0 = 1; + private final static String XMLNS=Constants.NamespaceSpecNS; - private final static String XMLNS=Constants.NamespaceSpecNS; - /** - * Compares two attributes based on the C14n specification. - * - *
        - *
      • Namespace nodes have a lesser document order position than attribute nodes. - *
      • An element's namespace nodes are sorted lexicographically by - * local name (the default namespace node, if one exists, has no - * local name and is therefore lexicographically least). - *
      • An element's attribute nodes are sorted lexicographically with - * namespace URI as the primary key and local name as the secondary - * key (an empty namespace URI is lexicographically least). - *
      - * - * @param obj0 casted Attr - * @param obj1 casted Attr - * @return returns a negative integer, zero, or a positive integer as obj0 is less than, equal to, or greater than obj1 - * - */ - public int compare(Object obj0, Object obj1) { + /** + * Compares two attributes based on the C14n specification. + * + *
        + *
      • Namespace nodes have a lesser document order position than + * attribute nodes. + *
      • An element's namespace nodes are sorted lexicographically by + * local name (the default namespace node, if one exists, has no + * local name and is therefore lexicographically least). + *
      • An element's attribute nodes are sorted lexicographically with + * namespace URI as the primary key and local name as the secondary + * key (an empty namespace URI is lexicographically least). + *
      + * + * @param obj0 casted Attr + * @param obj1 casted Attr + * @return returns a negative integer, zero, or a positive integer as + * obj0 is less than, equal to, or greater than obj1 + * + */ + public int compare(Object obj0, Object obj1) { - Attr attr0 = (Attr) obj0; - Attr attr1 = (Attr) obj1; - String namespaceURI0 = attr0.getNamespaceURI(); - String namespaceURI1 = attr1.getNamespaceURI(); + Attr attr0 = (Attr) obj0; + Attr attr1 = (Attr) obj1; + String namespaceURI0 = attr0.getNamespaceURI(); + String namespaceURI1 = attr1.getNamespaceURI(); - boolean isNamespaceAttr0 = - XMLNS.equals(namespaceURI0); - boolean isNamespaceAttr1 = - XMLNS.equals(namespaceURI1); + boolean isNamespaceAttr0 = XMLNS==namespaceURI0; + boolean isNamespaceAttr1 = XMLNS==namespaceURI1; - if (isNamespaceAttr0) { - if (isNamespaceAttr1) { + if (isNamespaceAttr0) { + if (isNamespaceAttr1) { + // both are namespaces + String localname0 = attr0.getLocalName(); + String localname1 = attr1.getLocalName(); - // both are namespaces - String localname0 = attr0.getLocalName(); - String localname1 = attr1.getLocalName(); + if (localname0.equals("xmlns")) { + localname0 = ""; + } - if (localname0.equals("xmlns")) { - localname0 = ""; + if (localname1.equals("xmlns")) { + localname1 = ""; + } + + return localname0.compareTo(localname1); } + // attr0 is a namespace, attr1 is not + return ATTR0_BEFORE_ATTR1; + } - if (localname1.equals("xmlns")) { - localname1 = ""; - } - - return localname0.compareTo(localname1); - } - // attr0 is a namespace, attr1 is not - return ATTR0_BEFORE_ATTR1; - - } - if (isNamespaceAttr1) { - + if (isNamespaceAttr1) { // attr1 is a namespace, attr0 is not return ATTR1_BEFORE_ATTR0; - } - - // none is a namespae - - if (namespaceURI0 == null) { - if (namespaceURI1 == null) { - /* - String localName0 = attr0.getLocalName(); - String localName1 = attr1.getLocalName(); - return localName0.compareTo(localName1); - */ + } + // none is a namespace + if (namespaceURI0 == null) { + if (namespaceURI1 == null) { String name0 = attr0.getName(); String name1 = attr1.getName(); return name0.compareTo(name1); + } + return ATTR0_BEFORE_ATTR1; } - return ATTR0_BEFORE_ATTR1; - } - if (namespaceURI1 == null) { - return ATTR1_BEFORE_ATTR0; - } - int a = namespaceURI0.compareTo(namespaceURI1); + if (namespaceURI1 == null) { + return ATTR1_BEFORE_ATTR0; + } - if (a != 0) { - return a; - } - /* - String localName0 = ; - String localName1 =;*/ - - return (attr0.getLocalName()) - .compareTo( attr1.getLocalName()); - - } + int a = namespaceURI0.compareTo(namespaceURI1); + if (a != 0) { + return a; + } + return (attr0.getLocalName()).compareTo(attr1.getLocalName()); + } } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11.java new file mode 100644 index 00000000000..4790fd89043 --- /dev/null +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11.java @@ -0,0 +1,684 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Copyright 2008 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package com.sun.org.apache.xml.internal.security.c14n.implementations; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import javax.xml.parsers.ParserConfigurationException; +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.xml.sax.SAXException; + +import java.util.logging.Logger; +import java.util.logging.Logger; +import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException; +import com.sun.org.apache.xml.internal.security.c14n.helper.C14nHelper; +import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput; +import com.sun.org.apache.xml.internal.security.utils.Constants; +import com.sun.org.apache.xml.internal.security.utils.XMLUtils; + +/** + * Implements + * Canonical XML Version 1.1, a W3C Proposed Recommendation from 29 + * January 2008. + * + * @author Sean Mullan + * @author Raul Benito + * @version $Revision: 1.2 $ + */ +public abstract class Canonicalizer11 extends CanonicalizerBase { + boolean firstCall = true; + final SortedSet result = new TreeSet(COMPARE); + static final String XMLNS_URI = Constants.NamespaceSpecNS; + static final String XML_LANG_URI = Constants.XML_LANG_SPACE_SpecNS; + + static Logger log = Logger.getLogger(Canonicalizer11.class.getName()); + + static class XmlAttrStack { + int currentLevel = 0; + int lastlevel = 0; + XmlsStackElement cur; + static class XmlsStackElement { + int level; + boolean rendered = false; + List nodes = new ArrayList(); + }; + List levels = new ArrayList(); + void push(int level) { + currentLevel = level; + if (currentLevel == -1) + return; + cur = null; + while (lastlevel >= currentLevel) { + levels.remove(levels.size() - 1); + if (levels.size() == 0) { + lastlevel = 0; + return; + } + lastlevel=((XmlsStackElement)levels.get(levels.size()-1)).level; + } + } + void addXmlnsAttr(Attr n) { + if (cur == null) { + cur = new XmlsStackElement(); + cur.level = currentLevel; + levels.add(cur); + lastlevel = currentLevel; + } + cur.nodes.add(n); + } + void getXmlnsAttr(Collection col) { + if (cur == null) { + cur = new XmlsStackElement(); + cur.level = currentLevel; + lastlevel = currentLevel; + levels.add(cur); + } + int size = levels.size() - 2; + boolean parentRendered = false; + XmlsStackElement e = null; + if (size == -1) { + parentRendered = true; + } else { + e = (XmlsStackElement) levels.get(size); + if (e.rendered && e.level+1 == currentLevel) + parentRendered = true; + } + if (parentRendered) { + col.addAll(cur.nodes); + cur.rendered = true; + return; + } + + Map loa = new HashMap(); + List baseAttrs = new ArrayList(); + boolean successiveOmitted = true; + for (;size>=0;size--) { + e = (XmlsStackElement) levels.get(size); + if (e.rendered) { + successiveOmitted = false; + } + Iterator it = e.nodes.iterator(); + while (it.hasNext() && successiveOmitted) { + Attr n = (Attr) it.next(); + if (n.getLocalName().equals("base")) { + if (!e.rendered) { + baseAttrs.add(n); + } + } else if (!loa.containsKey(n.getName())) + loa.put(n.getName(), n); + } + } + if (!baseAttrs.isEmpty()) { + Iterator it = cur.nodes.iterator(); + String base = null; + Attr baseAttr = null; + while (it.hasNext()) { + Attr n = (Attr) it.next(); + if (n.getLocalName().equals("base")) { + base = n.getValue(); + baseAttr = n; + break; + } + } + it = baseAttrs.iterator(); + while (it.hasNext()) { + Attr n = (Attr) it.next(); + if (base == null) { + base = n.getValue(); + baseAttr = n; + } else { + try { + base = joinURI(n.getValue(), base); + } catch (URISyntaxException ue) { + ue.printStackTrace(); + } + } + } + if (base != null && base.length() != 0) { + baseAttr.setValue(base); + col.add(baseAttr); + } + } + + cur.rendered = true; + col.addAll(loa.values()); + } + }; + XmlAttrStack xmlattrStack = new XmlAttrStack(); + + /** + * Constructor Canonicalizer11 + * + * @param includeComments + */ + public Canonicalizer11(boolean includeComments) { + super(includeComments); + } + + /** + * Returns the Attr[]s to be outputted for the given element. + *
      + * The code of this method is a copy of {@link #handleAttributes(Element, + * NameSpaceSymbTable)}, + * whereas it takes into account that subtree-c14n is -- well -- + * subtree-based. + * So if the element in question isRoot of c14n, it's parent is not in the + * node set, as well as all other ancestors. + * + * @param E + * @param ns + * @return the Attr[]s to be outputted + * @throws CanonicalizationException + */ + Iterator handleAttributesSubtree(Element E, NameSpaceSymbTable ns) + throws CanonicalizationException { + if (!E.hasAttributes() && !firstCall) { + return null; + } + // result will contain the attrs which have to be outputted + final SortedSet result = this.result; + result.clear(); + NamedNodeMap attrs = E.getAttributes(); + int attrsLength = attrs.getLength(); + + for (int i = 0; i < attrsLength; i++) { + Attr N = (Attr) attrs.item(i); + String NUri = N.getNamespaceURI(); + + if (XMLNS_URI != NUri) { + // It's not a namespace attr node. Add to the result and + // continue. + result.add(N); + continue; + } + + String NName = N.getLocalName(); + String NValue = N.getValue(); + if (XML.equals(NName) + && XML_LANG_URI.equals(NValue)) { + // The default mapping for xml must not be output. + continue; + } + + Node n = ns.addMappingAndRender(NName, NValue, N); + + if (n != null) { + // Render the ns definition + result.add(n); + if (C14nHelper.namespaceIsRelative(N)) { + Object exArgs[] = {E.getTagName(), NName, N.getNodeValue()}; + throw new CanonicalizationException( + "c14n.Canonicalizer.RelativeNamespace", exArgs); + } + } + } + + if (firstCall) { + // It is the first node of the subtree + // Obtain all the namespaces defined in the parents, and added + // to the output. + ns.getUnrenderedNodes(result); + // output the attributes in the xml namespace. + xmlattrStack.getXmlnsAttr(result); + firstCall = false; + } + + return result.iterator(); + } + + /** + * Returns the Attr[]s to be outputted for the given element. + *
      + * IMPORTANT: This method expects to work on a modified DOM tree, i.e. a + * DOM which has been prepared using + * {@link com.sun.org.apache.xml.internal.security.utils.XMLUtils#circumventBug2650( + * org.w3c.dom.Document)}. + * + * @param E + * @param ns + * @return the Attr[]s to be outputted + * @throws CanonicalizationException + */ + Iterator handleAttributes(Element E, NameSpaceSymbTable ns) + throws CanonicalizationException { + // result will contain the attrs which have to be output + xmlattrStack.push(ns.getLevel()); + boolean isRealVisible = isVisibleDO(E, ns.getLevel()) == 1; + NamedNodeMap attrs = null; + int attrsLength = 0; + if (E.hasAttributes()) { + attrs = E.getAttributes(); + attrsLength = attrs.getLength(); + } + + SortedSet result = this.result; + result.clear(); + + for (int i = 0; i < attrsLength; i++) { + Attr N = (Attr) attrs.item(i); + String NUri = N.getNamespaceURI(); + + if (XMLNS_URI != NUri) { + // A non namespace definition node. + if (XML_LANG_URI == NUri) { + if (N.getLocalName().equals("id")) { + if (isRealVisible) { + // treat xml:id like any other attribute + // (emit it, but don't inherit it) + result.add(N); + } + } else { + xmlattrStack.addXmlnsAttr(N); + } + } else if (isRealVisible) { + // The node is visible add the attribute to the list of + // output attributes. + result.add(N); + } + // keep working + continue; + } + + String NName = N.getLocalName(); + String NValue = N.getValue(); + if ("xml".equals(NName) + && XML_LANG_URI.equals(NValue)) { + /* except omit namespace node with local name xml, which defines + * the xml prefix, if its string value is + * http://www.w3.org/XML/1998/namespace. + */ + continue; + } + // add the prefix binding to the ns symb table. + // ns.addInclusiveMapping(NName,NValue,N,isRealVisible); + if (isVisible(N)) { + if (!isRealVisible && ns.removeMappingIfRender(NName)) { + continue; + } + // The xpath select this node output it if needed. + // Node n = ns.addMappingAndRenderXNodeSet + // (NName, NValue, N, isRealVisible); + Node n = ns.addMappingAndRender(NName, NValue, N); + if (n != null) { + result.add(n); + if (C14nHelper.namespaceIsRelative(N)) { + Object exArgs[] = + { E.getTagName(), NName, N.getNodeValue() }; + throw new CanonicalizationException( + "c14n.Canonicalizer.RelativeNamespace", exArgs); + } + } + } else { + if (isRealVisible && NName != XMLNS) { + ns.removeMapping(NName); + } else { + ns.addMapping(NName, NValue, N); + } + } + } + if (isRealVisible) { + // The element is visible, handle the xmlns definition + Attr xmlns = E.getAttributeNodeNS(XMLNS_URI, XMLNS); + Node n = null; + if (xmlns == null) { + // No xmlns def just get the already defined. + n = ns.getMapping(XMLNS); + } else if (!isVisible(xmlns)) { + // There is a defn but the xmlns is not selected by the xpath. + // then xmlns="" + n = ns.addMappingAndRender(XMLNS, "", nullNode); + } + // output the xmlns def if needed. + if (n != null) { + result.add(n); + } + // Float all xml:* attributes of the unselected parent elements to + // this one. addXmlAttributes(E,result); + xmlattrStack.getXmlnsAttr(result); + ns.getUnrenderedNodes(result); + } + + return result.iterator(); + } + + /** + * Always throws a CanonicalizationException because this is inclusive c14n. + * + * @param xpathNodeSet + * @param inclusiveNamespaces + * @return none it always fails + * @throws CanonicalizationException always + */ + public byte[] engineCanonicalizeXPathNodeSet(Set xpathNodeSet, + String inclusiveNamespaces) throws CanonicalizationException { + throw new CanonicalizationException( + "c14n.Canonicalizer.UnsupportedOperation"); + } + + /** + * Always throws a CanonicalizationException because this is inclusive c14n. + * + * @param rootNode + * @param inclusiveNamespaces + * @return none it always fails + * @throws CanonicalizationException + */ + public byte[] engineCanonicalizeSubTree(Node rootNode, + String inclusiveNamespaces) throws CanonicalizationException { + throw new CanonicalizationException( + "c14n.Canonicalizer.UnsupportedOperation"); + } + + void circumventBugIfNeeded(XMLSignatureInput input) + throws CanonicalizationException, ParserConfigurationException, + IOException, SAXException { + if (!input.isNeedsToBeExpanded()) + return; + Document doc = null; + if (input.getSubNode() != null) { + doc = XMLUtils.getOwnerDocument(input.getSubNode()); + } else { + doc = XMLUtils.getOwnerDocument(input.getNodeSet()); + } + XMLUtils.circumventBug2650(doc); + } + + void handleParent(Element e, NameSpaceSymbTable ns) { + if (!e.hasAttributes()) { + return; + } + xmlattrStack.push(-1); + NamedNodeMap attrs = e.getAttributes(); + int attrsLength = attrs.getLength(); + for (int i = 0; i < attrsLength; i++) { + Attr N = (Attr) attrs.item(i); + if (Constants.NamespaceSpecNS != N.getNamespaceURI()) { + // Not a namespace definition, ignore. + if (XML_LANG_URI == N.getNamespaceURI()) { + xmlattrStack.addXmlnsAttr(N); + } + continue; + } + + String NName = N.getLocalName(); + String NValue = N.getNodeValue(); + if (XML.equals(NName) + && Constants.XML_LANG_SPACE_SpecNS.equals(NValue)) { + continue; + } + ns.addMapping(NName,NValue,N); + } + } + + private static String joinURI(String baseURI, String relativeURI) + throws URISyntaxException { + String bscheme = null; + String bauthority = null; + String bpath = ""; + String bquery = null; + String bfragment = null; // Is this correct? + + // pre-parse the baseURI + if (baseURI != null) { + if (baseURI.endsWith("..")) { + baseURI = baseURI + "/"; + } + URI base = new URI(baseURI); + bscheme = base.getScheme(); + bauthority = base.getAuthority(); + bpath = base.getPath(); + bquery = base.getQuery(); + bfragment = base.getFragment(); + } + + URI r = new URI(relativeURI); + String rscheme = r.getScheme(); + String rauthority = r.getAuthority(); + String rpath = r.getPath(); + String rquery = r.getQuery(); + String rfragment = null; + + String tscheme, tauthority, tpath, tquery, tfragment; + if (rscheme != null && rscheme.equals(bscheme)) { + rscheme = null; + } + if (rscheme != null) { + tscheme = rscheme; + tauthority = rauthority; + tpath = removeDotSegments(rpath); + tquery = rquery; + } else { + if (rauthority != null) { + tauthority = rauthority; + tpath = removeDotSegments(rpath); + tquery = rquery; + } else { + if (rpath.length() == 0) { + tpath = bpath; + if (rquery != null) { + tquery = rquery; + } else { + tquery = bquery; + } + } else { + if (rpath.startsWith("/")) { + tpath = removeDotSegments(rpath); + } else { + if (bauthority != null && bpath.length() == 0) { + tpath = "/" + rpath; + } else { + int last = bpath.lastIndexOf('/'); + if (last == -1) { + tpath = rpath; + } else { + tpath = bpath.substring(0, last+1) + rpath; + } + } + tpath = removeDotSegments(tpath); + } + tquery = rquery; + } + tauthority = bauthority; + } + tscheme = bscheme; + } + tfragment = rfragment; + return new URI(tscheme, tauthority, tpath, tquery, tfragment).toString(); + } + + private static String removeDotSegments(String path) { + + log.log(java.util.logging.Level.FINE, "STEP OUTPUT BUFFER\t\tINPUT BUFFER"); + + // 1. The input buffer is initialized with the now-appended path + // components then replace occurrences of "//" in the input buffer + // with "/" until no more occurrences of "//" are in the input buffer. + String input = path; + while (input.indexOf("//") > -1) { + input = input.replaceAll("//", "/"); + } + + // Initialize the output buffer with the empty string. + StringBuffer output = new StringBuffer(); + + // If the input buffer starts with a root slash "/" then move this + // character to the output buffer. + if (input.charAt(0) == '/') { + output.append("/"); + input = input.substring(1); + } + + printStep("1 ", output.toString(), input); + + // While the input buffer is not empty, loop as follows + while (input.length() != 0) { + // 2A. If the input buffer begins with a prefix of "./", + // then remove that prefix from the input buffer + // else if the input buffer begins with a prefix of "../", then + // if also the output does not contain the root slash "/" only, + // then move this prefix to the end of the output buffer else + // remove that prefix + if (input.startsWith("./")) { + input = input.substring(2); + printStep("2A", output.toString(), input); + } else if (input.startsWith("../")) { + input = input.substring(3); + if (!output.toString().equals("/")) { + output.append("../"); + } + printStep("2A", output.toString(), input); + // 2B. if the input buffer begins with a prefix of "/./" or "/.", + // where "." is a complete path segment, then replace that prefix + // with "/" in the input buffer; otherwise, + } else if (input.startsWith("/./")) { + input = input.substring(2); + printStep("2B", output.toString(), input); + } else if (input.equals("/.")) { + // FIXME: what is complete path segment? + input = input.replaceFirst("/.", "/"); + printStep("2B", output.toString(), input); + // 2C. if the input buffer begins with a prefix of "/../" or "/..", + // where ".." is a complete path segment, then replace that prefix + // with "/" in the input buffer and if also the output buffer is + // empty, last segment in the output buffer equals "../" or "..", + // where ".." is a complete path segment, then append ".." or "/.." + // for the latter case respectively to the output buffer else + // remove the last segment and its preceding "/" (if any) from the + // output buffer and if hereby the first character in the output + // buffer was removed and it was not the root slash then delete a + // leading slash from the input buffer; otherwise, + } else if (input.startsWith("/../")) { + input = input.substring(3); + if (output.length() == 0) { + output.append("/"); + } else if (output.toString().endsWith("../")) { + output.append(".."); + } else if (output.toString().endsWith("..")) { + output.append("/.."); + } else { + int index = output.lastIndexOf("/"); + if (index == -1) { + output = new StringBuffer(); + if (input.charAt(0) == '/') { + input = input.substring(1); + } + } else { + output = output.delete(index, output.length()); + } + } + printStep("2C", output.toString(), input); + } else if (input.equals("/..")) { + // FIXME: what is complete path segment? + input = input.replaceFirst("/..", "/"); + if (output.length() == 0) { + output.append("/"); + } else if (output.toString().endsWith("../")) { + output.append(".."); + } else if (output.toString().endsWith("..")) { + output.append("/.."); + } else { + int index = output.lastIndexOf("/"); + if (index == -1) { + output = new StringBuffer(); + if (input.charAt(0) == '/') { + input = input.substring(1); + } + } else { + output = output.delete(index, output.length()); + } + } + printStep("2C", output.toString(), input); + // 2D. if the input buffer consists only of ".", then remove + // that from the input buffer else if the input buffer consists + // only of ".." and if the output buffer does not contain only + // the root slash "/", then move the ".." to the output buffer + // else delte it.; otherwise, + } else if (input.equals(".")) { + input = ""; + printStep("2D", output.toString(), input); + } else if (input.equals("..")) { + if (!output.toString().equals("/")) + output.append(".."); + input = ""; + printStep("2D", output.toString(), input); + // 2E. move the first path segment (if any) in the input buffer + // to the end of the output buffer, including the initial "/" + // character (if any) and any subsequent characters up to, but not + // including, the next "/" character or the end of the input buffer. + } else { + int end = -1; + int begin = input.indexOf('/'); + if (begin == 0) { + end = input.indexOf('/', 1); + } else { + end = begin; + begin = 0; + } + String segment; + if (end == -1) { + segment = input.substring(begin); + input = ""; + } else { + segment = input.substring(begin, end); + input = input.substring(end); + } + output.append(segment); + printStep("2E", output.toString(), input); + } + } + + // 3. Finally, if the only or last segment of the output buffer is + // "..", where ".." is a complete path segment not followed by a slash + // then append a slash "/". The output buffer is returned as the result + // of remove_dot_segments + if (output.toString().endsWith("..")) { + output.append("/"); + printStep("3 ", output.toString(), input); + } + + return output.toString(); + } + + private static void printStep(String step, String output, String input) { + if (log.isLoggable(java.util.logging.Level.FINE)) { + log.log(java.util.logging.Level.FINE, " " + step + ": " + output); + if (output.length() == 0) { + log.log(java.util.logging.Level.FINE, "\t\t\t\t" + input); + } else { + log.log(java.util.logging.Level.FINE, "\t\t\t" + input); + } + } + } +} diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11_OmitComments.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11_OmitComments.java new file mode 100644 index 00000000000..31903667f60 --- /dev/null +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11_OmitComments.java @@ -0,0 +1,41 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Copyright 2008 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package com.sun.org.apache.xml.internal.security.c14n.implementations; + +import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer; + +/** + * @author Sean Mullan + */ +public class Canonicalizer11_OmitComments extends Canonicalizer11 { + + public Canonicalizer11_OmitComments() { + super(false); + } + + public final String engineGetURI() { + return Canonicalizer.ALGO_ID_C14N11_OMIT_COMMENTS; + } + + public final boolean engineGetIncludeComments() { + return false; + } +} diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11_WithComments.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11_WithComments.java new file mode 100644 index 00000000000..ba650c10872 --- /dev/null +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11_WithComments.java @@ -0,0 +1,41 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Copyright 2008 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package com.sun.org.apache.xml.internal.security.c14n.implementations; + +import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer; + +/** + * @author Sean Mullan + */ +public class Canonicalizer11_WithComments extends Canonicalizer11 { + + public Canonicalizer11_WithComments() { + super(true); + } + + public final String engineGetURI() { + return Canonicalizer.ALGO_ID_C14N11_WITH_COMMENTS; + } + + public final boolean engineGetIncludeComments() { + return true; + } +} diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java index 5dbeb60f985..541c2d63c99 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java @@ -2,7 +2,6 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ - /* * Copyright 1999-2004 The Apache Software Foundation. * @@ -23,20 +22,30 @@ package com.sun.org.apache.xml.internal.security.c14n.implementations; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; +import javax.xml.parsers.ParserConfigurationException; + import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException; import com.sun.org.apache.xml.internal.security.c14n.helper.C14nHelper; +import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput; import com.sun.org.apache.xml.internal.security.utils.Constants; +import com.sun.org.apache.xml.internal.security.utils.XMLUtils; import org.w3c.dom.Attr; +import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; +import org.xml.sax.SAXException; /** @@ -44,13 +53,92 @@ import org.w3c.dom.Node; * XML Version 1.0, a W3C Recommendation from 15 March 2001. * * @author Christian Geuer-Pollmann + * @version $Revision: 1.5 $ */ public abstract class Canonicalizer20010315 extends CanonicalizerBase { boolean firstCall=true; final SortedSet result= new TreeSet(COMPARE); static final String XMLNS_URI=Constants.NamespaceSpecNS; static final String XML_LANG_URI=Constants.XML_LANG_SPACE_SpecNS; - /** + static class XmlAttrStack { + int currentLevel=0; + int lastlevel=0; + XmlsStackElement cur; + static class XmlsStackElement { + int level; + boolean rendered=false; + List nodes=new ArrayList(); + }; + List levels=new ArrayList(); + void push(int level) { + currentLevel=level; + if (currentLevel==-1) + return; + cur=null; + while (lastlevel>=currentLevel) { + levels.remove(levels.size()-1); + if (levels.size()==0) { + lastlevel=0; + return; + } + lastlevel=((XmlsStackElement)levels.get(levels.size()-1)).level; + } + } + void addXmlnsAttr(Attr n) { + if (cur==null) { + cur=new XmlsStackElement(); + cur.level=currentLevel; + levels.add(cur); + lastlevel=currentLevel; + } + cur.nodes.add(n); + } + void getXmlnsAttr(Collection col) { + int size=levels.size()-1; + if (cur==null) { + cur=new XmlsStackElement(); + cur.level=currentLevel; + lastlevel=currentLevel; + levels.add(cur); + } + boolean parentRendered=false; + XmlsStackElement e=null; + if (size==-1) { + parentRendered=true; + } else { + e=(XmlsStackElement)levels.get(size); + if (e.rendered && e.level+1==currentLevel) + parentRendered=true; + + } + if (parentRendered) { + col.addAll(cur.nodes); + cur.rendered=true; + return; + } + + Map loa = new HashMap(); + for (;size>=0;size--) { + e=(XmlsStackElement)levels.get(size); + Iterator it=e.nodes.iterator(); + while (it.hasNext()) { + Attr n=(Attr)it.next(); + if (!loa.containsKey(n.getName())) + loa.put(n.getName(),n); + } + //if (e.rendered) + //break; + + }; + //cur.nodes.clear(); + //cur.nodes.addAll(loa.values()); + cur.rendered=true; + col.addAll(loa.values()); + } + + } + XmlAttrStack xmlattrStack=new XmlAttrStack(); + /** * Constructor Canonicalizer20010315 * * @param includeComments @@ -86,16 +174,16 @@ public abstract class Canonicalizer20010315 extends CanonicalizerBase { for (int i = 0; i < attrsLength; i++) { Attr N = (Attr) attrs.item(i); - String NName=N.getLocalName(); - String NValue=N.getValue(); String NUri =N.getNamespaceURI(); - if (!XMLNS_URI.equals(NUri)) { + if (XMLNS_URI!=NUri) { //It's not a namespace attr node. Add to the result and continue. result.add(N); continue; } + String NName=N.getLocalName(); + String NValue=N.getValue(); if (XML.equals(NName) && XML_LANG_URI.equals(NValue)) { //The default mapping for xml must not be output. @@ -120,64 +208,13 @@ public abstract class Canonicalizer20010315 extends CanonicalizerBase { //Obtain all the namespaces defined in the parents, and added to the output. ns.getUnrenderedNodes(result); //output the attributes in the xml namespace. - addXmlAttributesSubtree(E, result); - firstCall=false; + xmlattrStack.getXmlnsAttr(result); + firstCall=false; } return result.iterator(); } - /** - * Float the xml:* attributes of the parent nodes to the root node of c14n - * @param E the root node. - * @param result the xml:* attributes to output. - */ - private void addXmlAttributesSubtree(Element E, SortedSet result) { - // E is in the node-set - Node parent = E.getParentNode(); - Map loa = new HashMap(); - - if ((parent != null) && (parent.getNodeType() == Node.ELEMENT_NODE)) { - - // parent element is not in node set - for (Node ancestor = parent; - (ancestor != null) - && (ancestor.getNodeType() == Node.ELEMENT_NODE); - ancestor = ancestor.getParentNode()) { - Element el=((Element) ancestor); - if (!el.hasAttributes()) { - continue; - } - // for all ancestor elements - NamedNodeMap ancestorAttrs = el.getAttributes(); - - for (int i = 0; i < ancestorAttrs.getLength(); i++) { - // for all attributes in the ancestor element - Attr currentAncestorAttr = (Attr) ancestorAttrs.item(i); - - if (XML_LANG_URI.equals( - currentAncestorAttr.getNamespaceURI())) { - - // do we have an xml:* ? - if (!E.hasAttributeNS( - XML_LANG_URI, - currentAncestorAttr.getLocalName())) { - - // the xml:* attr is not in E - if (!loa.containsKey(currentAncestorAttr.getName())) { - loa.put(currentAncestorAttr.getName(), - currentAncestorAttr); - } - } - } - } - } - } - - result.addAll( loa.values()); - - } - /** * Returns the Attr[]s to be outputted for the given element. *
      @@ -192,7 +229,8 @@ public abstract class Canonicalizer20010315 extends CanonicalizerBase { */ Iterator handleAttributes(Element E, NameSpaceSymbTable ns ) throws CanonicalizationException { // result will contain the attrs which have to be outputted - boolean isRealVisible=isVisible(E); + xmlattrStack.push(ns.getLevel()); + boolean isRealVisible=isVisibleDO(E,ns.getLevel())==1; NamedNodeMap attrs = null; int attrsLength = 0; if (E.hasAttributes()) { @@ -204,16 +242,15 @@ public abstract class Canonicalizer20010315 extends CanonicalizerBase { SortedSet result = this.result; result.clear(); - for (int i = 0; i < attrsLength; i++) { Attr N = (Attr) attrs.item(i); - String NName=N.getLocalName(); - String NValue=N.getValue(); String NUri =N.getNamespaceURI(); - if (!XMLNS_URI.equals(NUri)) { + if (XMLNS_URI!=NUri) { //A non namespace definition node. - if (isRealVisible){ + if (XML_LANG_URI==NUri) { + xmlattrStack.addXmlnsAttr(N); + } else if (isRealVisible){ //The node is visible add the attribute to the list of output attributes. result.add(N); } @@ -221,7 +258,8 @@ public abstract class Canonicalizer20010315 extends CanonicalizerBase { continue; } - + String NName=N.getLocalName(); + String NValue=N.getValue(); if ("xml".equals(NName) && XML_LANG_URI.equals(NValue)) { /* except omit namespace node with local name xml, which defines @@ -232,16 +270,26 @@ public abstract class Canonicalizer20010315 extends CanonicalizerBase { //add the prefix binding to the ns symb table. //ns.addInclusiveMapping(NName,NValue,N,isRealVisible); if (isVisible(N)) { - //The xpath select this node output it if needed. - Node n=ns.addMappingAndRenderXNodeSet(NName,NValue,N,isRealVisible); - if (n!=null) { + if (!isRealVisible && ns.removeMappingIfRender(NName)) { + continue; + } + //The xpath select this node output it if needed. + //Node n=ns.addMappingAndRenderXNodeSet(NName,NValue,N,isRealVisible); + Node n=ns.addMappingAndRender(NName,NValue,N); + if (n!=null) { result.add(n); if (C14nHelper.namespaceIsRelative(N)) { Object exArgs[] = { E.getTagName(), NName, N.getNodeValue() }; throw new CanonicalizationException( "c14n.Canonicalizer.RelativeNamespace", exArgs); - } - } + } + } + } else { + if (isRealVisible && NName!=XMLNS) { + ns.removeMapping(NName); + } else { + ns.addMapping(NName,NValue,N); + } } } if (isRealVisible) { @@ -254,84 +302,21 @@ public abstract class Canonicalizer20010315 extends CanonicalizerBase { } else if ( !isVisible(xmlns)) { //There is a definition but the xmlns is not selected by the xpath. //then xmlns="" - n=ns.addMappingAndRenderXNodeSet(XMLNS,"",nullNode,true); + n=ns.addMappingAndRender(XMLNS,"",nullNode); } //output the xmlns def if needed. if (n!=null) { result.add(n); } //Float all xml:* attributes of the unselected parent elements to this one. - addXmlAttributes(E,result); + //addXmlAttributes(E,result); + xmlattrStack.getXmlnsAttr(result); + ns.getUnrenderedNodes(result); + } return result.iterator(); } - /** - * Float the xml:* attributes of the unselected parent nodes to the ciurrent node. - * @param E - * @param result - */ - private void addXmlAttributes(Element E, SortedSet result) { - /* The processing of an element node E MUST be modified slightly when an - * XPath node-set is given as input and the element's parent is omitted - * from the node-set. The method for processing the attribute axis of an - * element E in the node-set is enhanced. All element nodes along E's - * ancestor axis are examined for nearest occurrences of attributes in - * the xml namespace, such as xml:lang and xml:space (whether or not they - * are in the node-set). From this list of attributes, remove any that are - * in E's attribute axis (whether or not they are in the node-set). Then, - * lexicographically merge this attribute list with the nodes of E's - * attribute axis that are in the node-set. The result of visiting the - * attribute axis is computed by processing the attribute nodes in this - * merged attribute list. - */ - - // E is in the node-set - Node parent = E.getParentNode(); - Map loa = new HashMap(); - - if ((parent != null) && (parent.getNodeType() == Node.ELEMENT_NODE) - &&!isVisible(parent)) { - - // parent element is not in node set - for (Node ancestor = parent; - (ancestor != null) - && (ancestor.getNodeType() == Node.ELEMENT_NODE); - ancestor = ancestor.getParentNode()) { - Element el=((Element) ancestor); - if (!el.hasAttributes()) { - continue; - } - // for all ancestor elements - NamedNodeMap ancestorAttrs =el.getAttributes(); - - for (int i = 0; i < ancestorAttrs.getLength(); i++) { - - // for all attributes in the ancestor element - Attr currentAncestorAttr = (Attr) ancestorAttrs.item(i); - - if (XML_LANG_URI.equals( - currentAncestorAttr.getNamespaceURI())) { - - // do we have an xml:* ? - if (!E.hasAttributeNS( - XML_LANG_URI, - currentAncestorAttr.getLocalName())) { - - // the xml:* attr is not in E - if (!loa.containsKey(currentAncestorAttr.getName())) { - loa.put(currentAncestorAttr.getName(), - currentAncestorAttr); - } - } - } - } - } - } - result.addAll(loa.values()); - -} - /** * Always throws a CanonicalizationException because this is inclusive c14n. * @@ -363,4 +348,43 @@ public abstract class Canonicalizer20010315 extends CanonicalizerBase { throw new CanonicalizationException( "c14n.Canonicalizer.UnsupportedOperation"); } + void circumventBugIfNeeded(XMLSignatureInput input) throws CanonicalizationException, ParserConfigurationException, IOException, SAXException { + if (!input.isNeedsToBeExpanded()) + return; + Document doc = null; + if (input.getSubNode() != null) { + doc=XMLUtils.getOwnerDocument(input.getSubNode()); + } else { + doc=XMLUtils.getOwnerDocument(input.getNodeSet()); + } + XMLUtils.circumventBug2650(doc); + + } + + void handleParent(Element e, NameSpaceSymbTable ns) { + if (!e.hasAttributes()) { + return; + } + xmlattrStack.push(-1); + NamedNodeMap attrs = e.getAttributes(); + int attrsLength = attrs.getLength(); + for (int i = 0; i < attrsLength; i++) { + Attr N = (Attr) attrs.item(i); + if (Constants.NamespaceSpecNS!=N.getNamespaceURI()) { + //Not a namespace definition, ignore. + if (XML_LANG_URI==N.getNamespaceURI()) { + xmlattrStack.addXmlnsAttr(N); + } + continue; + } + + String NName=N.getLocalName(); + String NValue=N.getNodeValue(); + if (XML.equals(NName) + && Constants.XML_LANG_SPACE_SpecNS.equals(NValue)) { + continue; + } + ns.addMapping(NName,NValue,N); + } + } } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315Excl.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315Excl.java index 18f697366cf..679c7b5088b 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315Excl.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315Excl.java @@ -2,7 +2,6 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ - /* * Copyright 1999-2004 The Apache Software Foundation. * @@ -21,20 +20,26 @@ */ package com.sun.org.apache.xml.internal.security.c14n.implementations; +import java.io.IOException; import java.util.Iterator; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; +import javax.xml.parsers.ParserConfigurationException; + import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException; import com.sun.org.apache.xml.internal.security.c14n.helper.C14nHelper; import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput; import com.sun.org.apache.xml.internal.security.transforms.params.InclusiveNamespaces; import com.sun.org.apache.xml.internal.security.utils.Constants; +import com.sun.org.apache.xml.internal.security.utils.XMLUtils; import org.w3c.dom.Attr; +import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; +import org.xml.sax.SAXException; /** * Implements " Exclusive XML @@ -47,6 +52,7 @@ import org.w3c.dom.Node; * THIS implementation is a complete rewrite of the algorithm. * * @author Christian Geuer-Pollmann + * @version $Revision: 1.5 $ * @see * XML Canonicalization, Version 1.0 */ @@ -55,7 +61,7 @@ public abstract class Canonicalizer20010315Excl extends CanonicalizerBase { * This Set contains the names (Strings like "xmlns" or "xmlns:foo") of * the inclusive namespaces. */ - TreeSet _inclusiveNSSet = null; + TreeSet _inclusiveNSSet = new TreeSet(); static final String XMLNS_URI=Constants.NamespaceSpecNS; final SortedSet result = new TreeSet(COMPARE); /** @@ -143,10 +149,8 @@ public abstract class Canonicalizer20010315Excl extends CanonicalizerBase { for (int i = 0; i < attrsLength; i++) { Attr N = (Attr) attrs.item(i); - String NName=N.getLocalName(); - String NNodeValue=N.getNodeValue(); - if (!XMLNS_URI.equals(N.getNamespaceURI())) { + if (XMLNS_URI!=N.getNamespaceURI()) { //Not a namespace definition. //The Element is output element, add his prefix(if used) to visibyUtilized String prefix = N.getPrefix(); @@ -157,6 +161,8 @@ public abstract class Canonicalizer20010315Excl extends CanonicalizerBase { result.add(N); continue; } + String NName=N.getLocalName(); + String NNodeValue=N.getNodeValue(); if (ns.addMapping(NName, NNodeValue,N)) { //New definition check if it is relative. @@ -168,17 +174,17 @@ public abstract class Canonicalizer20010315Excl extends CanonicalizerBase { } } } - + String prefix; if (E.getNamespaceURI() != null) { - String prefix = E.getPrefix(); + prefix = E.getPrefix(); if ((prefix == null) || (prefix.length() == 0)) { - visiblyUtilized.add(XMLNS); - } else { - visiblyUtilized.add(prefix); + prefix=XMLNS; } + } else { - visiblyUtilized.add(XMLNS); + prefix=XMLNS; } + visiblyUtilized.add(prefix); //This can be optimezed by I don't have time Iterator it=visiblyUtilized.iterator(); @@ -211,12 +217,6 @@ public abstract class Canonicalizer20010315Excl extends CanonicalizerBase { } - /** @inheritDoc */ - public byte[] engineCanonicalizeXPathNodeSet(Set xpathNodeSet - ) throws CanonicalizationException { - return engineCanonicalizeXPathNodeSet(xpathNodeSet,""); - } - /** * @inheritDoc * @param E @@ -236,21 +236,20 @@ public abstract class Canonicalizer20010315Excl extends CanonicalizerBase { //The prefix visibly utilized(in the attribute or in the name) in the element Set visiblyUtilized =null; //It's the output selected. - boolean isOutputElement = isVisible(E); + boolean isOutputElement=isVisibleDO(E,ns.getLevel())==1; if (isOutputElement) { visiblyUtilized = (Set) this._inclusiveNSSet.clone(); } for (int i = 0; i < attrsLength; i++) { Attr N = (Attr) attrs.item(i); - String NName=N.getLocalName(); - String NNodeValue=N.getNodeValue(); - if ( !isVisible(N) ) { - //The node is not in the nodeset(if there is a nodeset) - continue; - } - if (!XMLNS_URI.equals(N.getNamespaceURI())) { + + if (XMLNS_URI!=N.getNamespaceURI()) { + if ( !isVisible(N) ) { + //The node is not in the nodeset(if there is a nodeset) + continue; + } //Not a namespace definition. if (isOutputElement) { //The Element is output element, add his prefix(if used) to visibyUtilized @@ -263,6 +262,25 @@ public abstract class Canonicalizer20010315Excl extends CanonicalizerBase { } continue; } + String NName=N.getLocalName(); + if (isOutputElement && !isVisible(N) && NName!=XMLNS) { + ns.removeMappingIfNotRender(NName); + continue; + } + String NNodeValue=N.getNodeValue(); + + if (!isOutputElement && isVisible(N) && _inclusiveNSSet.contains(NName) && !ns.removeMappingIfRender(NName)) { + Node n=ns.addMappingAndRender(NName,NNodeValue,N); + if (n!=null) { + result.add(n); + if (C14nHelper.namespaceIsRelative(N)) { + Object exArgs[] = { E.getTagName(), NName, N.getNodeValue() }; + throw new CanonicalizationException( + "c14n.Canonicalizer.RelativeNamespace", exArgs); + } + } + } + if (ns.addMapping(NName, NNodeValue,N)) { @@ -306,18 +324,20 @@ public abstract class Canonicalizer20010315Excl extends CanonicalizerBase { } result.add(key); } - } else /*if (_circunvented)*/ { - Iterator it=this._inclusiveNSSet.iterator(); - while (it.hasNext()) { - String s=(String)it.next(); - Attr key=ns.getMappingWithoutRendered(s); - if (key==null) { - continue; - } - result.add(key); - } } return result.iterator(); } + void circumventBugIfNeeded(XMLSignatureInput input) throws CanonicalizationException, ParserConfigurationException, IOException, SAXException { + if (!input.isNeedsToBeExpanded() || _inclusiveNSSet.isEmpty()) + return; + Document doc = null; + if (input.getSubNode() != null) { + doc=XMLUtils.getOwnerDocument(input.getSubNode()); + } else { + doc=XMLUtils.getOwnerDocument(input.getNodeSet()); + } + + XMLUtils.circumventBug2650(doc); + } } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315ExclWithComments.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315ExclWithComments.java index 025502bd5fe..37550124879 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315ExclWithComments.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315ExclWithComments.java @@ -28,6 +28,7 @@ import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer; /** * Class Canonicalizer20010315ExclWithComments * + * @version $Revision: 1.5 $ */ public class Canonicalizer20010315ExclWithComments extends Canonicalizer20010315Excl { diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315WithComments.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315WithComments.java index 539bb3a3957..4714e165bba 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315WithComments.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315WithComments.java @@ -2,7 +2,6 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ - /* * Copyright 1999-2004 The Apache Software Foundation. * diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerBase.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerBase.java index 8108763750f..05f22d8c1e8 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerBase.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerBase.java @@ -27,9 +27,11 @@ import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.ListIterator; +import java.util.Map; import java.util.Set; import javax.xml.parsers.DocumentBuilderFactory; @@ -45,7 +47,6 @@ import com.sun.org.apache.xml.internal.security.utils.UnsyncByteArrayOutputStrea import com.sun.org.apache.xml.internal.security.utils.XMLUtils; import org.w3c.dom.Attr; import org.w3c.dom.Comment; -import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; @@ -57,6 +58,7 @@ import org.xml.sax.SAXException; * Abstract base class for canonicalization algorithms. * * @author Christian Geuer-Pollmann + * @version $Revision: 1.5 $ */ public abstract class CanonicalizerBase extends CanonicalizerSpi { //Constants to be outputed, In char array form, so @@ -122,6 +124,18 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { throws CanonicalizationException { return engineCanonicalizeSubTree(rootNode,(Node)null); } + /** + * Method engineCanonicalizeXPathNodeSet + * @inheritDoc + * @param xpathNodeSet + * @throws CanonicalizationException + */ + public byte[] engineCanonicalizeXPathNodeSet(Set xpathNodeSet) + throws CanonicalizationException { + this._xpathNodeSet = xpathNodeSet; + return engineCanonicalizeXPathNodeSetInternal(XMLUtils.getOwnerDocument(this._xpathNodeSet)); + } + /** * Canonicalizes a Subtree node. * @param input the root of the subtree to canicalize @@ -143,15 +157,8 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { return bytes; } else if (input.isNodeSet()) { nodeFilter=input.getNodeFilters(); - Document doc = null; - if (input.getSubNode() != null) { - doc=XMLUtils.getOwnerDocument(input.getSubNode()); - } else { - doc=XMLUtils.getOwnerDocument(input.getNodeSet()); - } - if (input.isNeedsToBeExpanded()) { - XMLUtils.circumventBug2650(doc); - } + + circumventBugIfNeeded(input); if (input.getSubNode() != null) { bytes = engineCanonicalizeXPathNodeSetInternal(input.getSubNode()); @@ -173,6 +180,13 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { } } /** + * @param _writer The _writer to set. + */ + public void setWriter(OutputStream _writer) { + this._writer = _writer; + } + + /** * Canonicalizes a Subtree node. * * @param rootNode @@ -187,11 +201,13 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { this._excludeNode = excludeNode; try { NameSpaceSymbTable ns=new NameSpaceSymbTable(); + int nodeLevel=NODE_BEFORE_DOCUMENT_ELEMENT; if (rootNode instanceof Element) { //Fills the nssymbtable with the definitions of the parent of the root subnode getParentNameSpaces((Element)rootNode,ns); + nodeLevel=NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT; } - this.canonicalizeSubTree(rootNode,ns,rootNode); + this.canonicalizeSubTree(rootNode,ns,rootNode,nodeLevel); this._writer.close(); if (this._writer instanceof ByteArrayOutputStream) { byte []result=((ByteArrayOutputStream)this._writer).toByteArray(); @@ -199,6 +215,12 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { ((ByteArrayOutputStream)this._writer).reset(); } return result; + } else if (this._writer instanceof UnsyncByteArrayOutputStream) { + byte []result=((UnsyncByteArrayOutputStream)this._writer).toByteArray(); + if (reset) { + ((UnsyncByteArrayOutputStream)this._writer).reset(); + } + return result; } return null; @@ -219,13 +241,17 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { * @throws CanonicalizationException * @throws IOException */ - final void canonicalizeSubTree(Node currentNode, NameSpaceSymbTable ns,Node endnode) + final void canonicalizeSubTree(Node currentNode, NameSpaceSymbTable ns,Node endnode, + int documentLevel) throws CanonicalizationException, IOException { + if (isVisibleInt(currentNode)==-1) + return; Node sibling=null; Node parentNode=null; final OutputStream writer=this._writer; final Node excludeNode=this._excludeNode; final boolean includeComments=this._includeComments; + Map cache=new HashMap(); do { switch (currentNode.getNodeType()) { @@ -242,18 +268,17 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { case Node.DOCUMENT_FRAGMENT_NODE : case Node.DOCUMENT_NODE : ns.outputNodePush(); - //currentNode = currentNode.getFirstChild(); sibling= currentNode.getFirstChild(); break; case Node.COMMENT_NODE : if (includeComments) { - outputCommentToWriter((Comment) currentNode, writer); + outputCommentToWriter((Comment) currentNode, writer, documentLevel); } break; case Node.PROCESSING_INSTRUCTION_NODE : - outputPItoWriter((ProcessingInstruction) currentNode, writer); + outputPItoWriter((ProcessingInstruction) currentNode, writer, documentLevel); break; case Node.TEXT_NODE : @@ -262,6 +287,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { break; case Node.ELEMENT_NODE : + documentLevel=NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT; if (currentNode==excludeNode) { break; } @@ -270,27 +296,27 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { ns.outputNodePush(); writer.write('<'); String name=currentElement.getTagName(); - writeStringToUtf8(name,writer); + UtfHelpper.writeByte(name,writer,cache); Iterator attrs = this.handleAttributesSubtree(currentElement,ns); if (attrs!=null) { //we output all Attrs which are available while (attrs.hasNext()) { Attr attr = (Attr) attrs.next(); - outputAttrToWriter(attr.getNodeName(),attr.getNodeValue(), writer); + outputAttrToWriter(attr.getNodeName(),attr.getNodeValue(), writer,cache); } } writer.write('>'); sibling= currentNode.getFirstChild(); if (sibling==null) { writer.write(_END_TAG); - writeStringToUtf8(name,writer); + UtfHelpper.writeStringToUtf8(name,writer); writer.write('>'); //We fineshed with this level, pop to the previous definitions. ns.outputNodePop(); - if (parentNode != null) { + if (parentNode != null) { sibling= currentNode.getNextSibling(); - } + } } else { parentNode=currentElement; } @@ -298,7 +324,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { } while (sibling==null && parentNode!=null) { writer.write(_END_TAG); - writeStringToUtf8(((Element)parentNode).getTagName(),writer); + UtfHelpper.writeByte(((Element)parentNode).getTagName(),writer,cache); writer.write('>'); //We fineshed with this level, pop to the previous definitions. ns.outputNodePop(); @@ -307,6 +333,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { sibling=parentNode.getNextSibling(); parentNode=parentNode.getParentNode(); if (!(parentNode instanceof Element)) { + documentLevel=NODE_AFTER_DOCUMENT_ELEMENT; parentNode=null; } } @@ -317,47 +344,8 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { } while(true); } - /** - * Checks whether a Comment or ProcessingInstruction is before or after the - * document element. This is needed for prepending or appending "\n"s. - * - * @param currentNode comment or pi to check - * @return NODE_BEFORE_DOCUMENT_ELEMENT, NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT or NODE_AFTER_DOCUMENT_ELEMENT - * @see #NODE_BEFORE_DOCUMENT_ELEMENT - * @see #NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT - * @see #NODE_AFTER_DOCUMENT_ELEMENT - */ - final static int getPositionRelativeToDocumentElement(Node currentNode) { - if ((currentNode == null) || - (currentNode.getParentNode().getNodeType() != Node.DOCUMENT_NODE) ) { - return CanonicalizerBase.NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT; - } - Element documentElement = currentNode.getOwnerDocument().getDocumentElement(); - if ( (documentElement == null) || (documentElement == currentNode) ){ - return CanonicalizerBase.NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT; - } - for (Node x = currentNode; x != null; x = x.getNextSibling()) { - if (x == documentElement) { - return CanonicalizerBase.NODE_BEFORE_DOCUMENT_ELEMENT; - } - } - - return CanonicalizerBase.NODE_AFTER_DOCUMENT_ELEMENT; - } - - /** - * Method engineCanonicalizeXPathNodeSet - * @inheritDoc - * @param xpathNodeSet - * @throws CanonicalizationException - */ - public byte[] engineCanonicalizeXPathNodeSet(Set xpathNodeSet) - throws CanonicalizationException { - this._xpathNodeSet = xpathNodeSet; - return engineCanonicalizeXPathNodeSetInternal(XMLUtils.getOwnerDocument(this._xpathNodeSet)); - } private byte[] engineCanonicalizeXPathNodeSetInternal(Node doc) throws CanonicalizationException { @@ -370,6 +358,12 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { ((ByteArrayOutputStream)this._writer).reset(); } return sol; + } else if (this._writer instanceof UnsyncByteArrayOutputStream) { + byte []result=((UnsyncByteArrayOutputStream)this._writer).toByteArray(); + if (reset) { + ((UnsyncByteArrayOutputStream)this._writer).reset(); + } + return result; } return null; } catch (UnsupportedEncodingException ex) { @@ -390,11 +384,17 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { */ final void canonicalizeXPathNodeSet(Node currentNode,Node endnode ) throws CanonicalizationException, IOException { - boolean currentNodeIsVisible = false; - NameSpaceSymbTable ns=new NameSpaceSymbTable(); + if (isVisibleInt(currentNode)==-1) + return; + boolean currentNodeIsVisible = false; + NameSpaceSymbTable ns=new NameSpaceSymbTable(); + if (currentNode instanceof Element) + getParentNameSpaces((Element)currentNode,ns); Node sibling=null; Node parentNode=null; OutputStream writer=this._writer; + int documentLevel=NODE_BEFORE_DOCUMENT_ELEMENT; + Map cache=new HashMap(); do { switch (currentNode.getNodeType()) { @@ -416,14 +416,14 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { break; case Node.COMMENT_NODE : - if (this._includeComments && isVisible(currentNode)) { - outputCommentToWriter((Comment) currentNode, writer); + if (this._includeComments && (isVisibleDO(currentNode,ns.getLevel())==1)) { + outputCommentToWriter((Comment) currentNode, writer, documentLevel); } break; case Node.PROCESSING_INSTRUCTION_NODE : if (isVisible(currentNode)) - outputPItoWriter((ProcessingInstruction) currentNode, writer); + outputPItoWriter((ProcessingInstruction) currentNode, writer, documentLevel); break; case Node.TEXT_NODE : @@ -436,12 +436,6 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { || (nextSibling.getNodeType() == Node.CDATA_SECTION_NODE)); nextSibling = nextSibling.getNextSibling()) { - /* The XPath data model allows to select only the first of a - * sequence of mixed text and CDATA nodes. But we must output - * them all, so we must search: - * - * @see http://nagoya.apache.org/bugzilla/show_bug.cgi?id=6329 - */ outputTextToWriter(nextSibling.getNodeValue(), writer); currentNode=nextSibling; sibling=currentNode.getNextSibling(); @@ -451,15 +445,21 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { break; case Node.ELEMENT_NODE : + documentLevel=NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT; Element currentElement = (Element) currentNode; //Add a level to the nssymbtable. So latter can be pop-back. String name=null; - currentNodeIsVisible=isVisible(currentNode); + int i=isVisibleDO(currentNode,ns.getLevel()); + if (i==-1) { + sibling= currentNode.getNextSibling(); + break; + } + currentNodeIsVisible=(i==1); if (currentNodeIsVisible) { ns.outputNodePush(); writer.write('<'); name=currentElement.getTagName(); - writeStringToUtf8(name,writer); + UtfHelpper.writeByte(name,writer,cache); } else { ns.push(); } @@ -469,7 +469,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { //we output all Attrs which are available while (attrs.hasNext()) { Attr attr = (Attr) attrs.next(); - outputAttrToWriter(attr.getNodeName(),attr.getNodeValue(), writer); + outputAttrToWriter(attr.getNodeName(),attr.getNodeValue(), writer,cache); } } if (currentNodeIsVisible) { @@ -480,7 +480,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { if (sibling==null) { if (currentNodeIsVisible) { writer.write(_END_TAG); - writeStringToUtf8(name,writer); + UtfHelpper.writeByte(name,writer,cache); writer.write('>'); //We fineshed with this level, pop to the previous definitions. ns.outputNodePop(); @@ -498,7 +498,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { while (sibling==null && parentNode!=null) { if (isVisible(parentNode)) { writer.write(_END_TAG); - writeStringToUtf8(((Element)parentNode).getTagName(),writer); + UtfHelpper.writeByte(((Element)parentNode).getTagName(),writer,cache); writer.write('>'); //We fineshed with this level, pop to the previous definitions. ns.outputNodePop(); @@ -511,6 +511,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { parentNode=parentNode.getParentNode(); if (!(parentNode instanceof Element)) { parentNode=null; + documentLevel=NODE_AFTER_DOCUMENT_ELEMENT; } } if (sibling==null) @@ -519,12 +520,38 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { sibling=currentNode.getNextSibling(); } while(true); } + int isVisibleDO(Node currentNode,int level) { + if (nodeFilter!=null) { + Iterator it=nodeFilter.iterator(); + while (it.hasNext()) { + int i=((NodeFilter)it.next()).isNodeIncludeDO(currentNode,level); + if (i!=1) + return i; + } + } + if ((this._xpathNodeSet!=null) && !this._xpathNodeSet.contains(currentNode)) + return 0; + return 1; + } + int isVisibleInt(Node currentNode) { + if (nodeFilter!=null) { + Iterator it=nodeFilter.iterator(); + while (it.hasNext()) { + int i=((NodeFilter)it.next()).isNodeInclude(currentNode); + if (i!=1) + return i; + } + } + if ((this._xpathNodeSet!=null) && !this._xpathNodeSet.contains(currentNode)) + return 0; + return 1; + } boolean isVisible(Node currentNode) { if (nodeFilter!=null) { Iterator it=nodeFilter.iterator(); while (it.hasNext()) { - if (!((NodeFilter)it.next()).isNodeInclude(currentNode)) + if (((NodeFilter)it.next()).isNodeInclude(currentNode)!=1) return false; } } @@ -533,19 +560,42 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { return true; } + void handleParent(Element e,NameSpaceSymbTable ns) { + if (!e.hasAttributes()) { + return; + } + NamedNodeMap attrs = e.getAttributes(); + int attrsLength = attrs.getLength(); + for (int i = 0; i < attrsLength; i++) { + Attr N = (Attr) attrs.item(i); + if (Constants.NamespaceSpecNS!=N.getNamespaceURI()) { + //Not a namespace definition, ignore. + continue; + } + + String NName=N.getLocalName(); + String NValue=N.getNodeValue(); + if (XML.equals(NName) + && Constants.XML_LANG_SPACE_SpecNS.equals(NValue)) { + continue; + } + ns.addMapping(NName,NValue,N); + } + } + /** * Adds to ns the definitons from the parent elements of el * @param el * @param ns */ - final static void getParentNameSpaces(Element el,NameSpaceSymbTable ns) { - List parents=new ArrayList(); + final void getParentNameSpaces(Element el,NameSpaceSymbTable ns) { + List parents=new ArrayList(10); Node n1=el.getParentNode(); if (!(n1 instanceof Element)) { return; } //Obtain all the parents of the elemnt - Element parent=(Element) el.getParentNode(); + Element parent=(Element) n1; while (parent!=null) { parents.add(parent); Node n=parent.getParentNode(); @@ -557,297 +607,15 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { //Visit them in reverse order. ListIterator it=parents.listIterator(parents.size()); while (it.hasPrevious()) { - Element ele=(Element)it.previous(); - if (!ele.hasAttributes()) { - continue; + Element ele=(Element)it.previous(); + handleParent(ele, ns); } - NamedNodeMap attrs = ele.getAttributes(); - int attrsLength = attrs.getLength(); - for (int i = 0; i < attrsLength; i++) { - Attr N = (Attr) attrs.item(i); - if (!Constants.NamespaceSpecNS.equals(N.getNamespaceURI())) { - //Not a namespace definition, ignore. - continue; - } - - String NName=N.getLocalName(); - String NValue=N.getNodeValue(); - if (XML.equals(NName) - && Constants.XML_LANG_SPACE_SpecNS.equals(NValue)) { - continue; - } - ns.addMapping(NName,NValue,N); - } - } Attr nsprefix; if (((nsprefix=ns.getMappingWithoutRendered("xmlns"))!=null) && "".equals(nsprefix.getValue())) { ns.addMappingAndRender("xmlns","",nullNode); } } - /** - * Outputs an Attribute to the internal Writer. - * - * The string value of the node is modified by replacing - *
        - *
      • all ampersands (&) with &amp;
      • - *
      • all open angle brackets (<) with &lt;
      • - *
      • all quotation mark characters with &quot;
      • - *
      • and the whitespace characters #x9, #xA, and #xD, with character - * references. The character references are written in uppercase - * hexadecimal with no leading zeroes (for example, #xD is represented - * by the character reference &#xD;)
      • - *
      - * - * @param name - * @param value - * @param writer - * @throws IOException - */ - static final void outputAttrToWriter(final String name, final String value, final OutputStream writer) throws IOException { - writer.write(' '); - writeStringToUtf8(name,writer); - writer.write(equalsStr); - byte []toWrite; - final int length = value.length(); - for (int i=0;i < length; i++) { - char c = value.charAt(i); - - switch (c) { - - case '&' : - toWrite=_AMP_; - //writer.write(_AMP_); - break; - - case '<' : - toWrite=_LT_; - //writer.write(_LT_); - break; - - case '"' : - toWrite=_QUOT_; - //writer.write(_QUOT_); - break; - - case 0x09 : // '\t' - toWrite=__X9_; - //writer.write(__X9_); - break; - - case 0x0A : // '\n' - toWrite=__XA_; - //writer.write(__XA_); - break; - - case 0x0D : // '\r' - toWrite=__XD_; - //writer.write(__XD_); - break; - - default : - writeCharToUtf8(c,writer); - //this._writer.write(c); - continue; - } - writer.write(toWrite); - } - - writer.write('\"'); - } - - final static void writeCharToUtf8(final char c,final OutputStream out) throws IOException{ - char ch; - if (/*(c >= 0x0001) &&*/ (c <= 0x007F)) { - out.write(c); - return; - } - int bias; - int write; - if (c > 0x07FF) { - ch=(char)(c>>>12); - write=0xE0; - if (ch>0) { - write |= ( ch & 0x0F); - } - out.write(write); - write=0x80; - bias=0x3F; - } else { - write=0xC0; - bias=0x1F; - } - ch=(char)(c>>>6); - if (ch>0) { - write|= (ch & bias); - } - out.write(write); - out.write(0x80 | ((c) & 0x3F)); - - } - - final static void writeStringToUtf8(final String str,final OutputStream out) throws IOException{ - final int length=str.length(); - int i=0; - char c; - while (i= 0x0001) &&*/ (c <= 0x007F)) { - out.write(c); - continue; - } - char ch; - int bias; - int write; - if (c > 0x07FF) { - ch=(char)(c>>>12); - write=0xE0; - if (ch>0) { - write |= ( ch & 0x0F); - } - out.write(write); - write=0x80; - bias=0x3F; - } else { - write=0xC0; - bias=0x1F; - } - ch=(char)(c>>>6); - if (ch>0) { - write|= (ch & bias); - } - out.write(write); - out.write(0x80 | ((c) & 0x3F)); - continue; - - } - - } - /** - * Outputs a PI to the internal Writer. - * - * @param currentPI - * @param writer where to write the things - * @throws IOException - */ - static final void outputPItoWriter(ProcessingInstruction currentPI, OutputStream writer) throws IOException { - final int position = getPositionRelativeToDocumentElement(currentPI); - - if (position == NODE_AFTER_DOCUMENT_ELEMENT) { - writer.write('\n'); - } - writer.write(_BEGIN_PI); - - final String target = currentPI.getTarget(); - int length = target.length(); - - for (int i = 0; i < length; i++) { - char c=target.charAt(i); - if (c==0x0D) { - writer.write(__XD_); - } else { - writeCharToUtf8(c,writer); - } - } - - final String data = currentPI.getData(); - - length = data.length(); - - if (length > 0) { - writer.write(' '); - - for (int i = 0; i < length; i++) { - char c=data.charAt(i); - if (c==0x0D) { - writer.write(__XD_); - } else { - writeCharToUtf8(c,writer); - } - } - } - - writer.write(_END_PI); - if (position == NODE_BEFORE_DOCUMENT_ELEMENT) { - writer.write('\n'); - } - } - - /** - * Method outputCommentToWriter - * - * @param currentComment - * @param writer writer where to write the things - * @throws IOException - */ - static final void outputCommentToWriter(Comment currentComment, OutputStream writer) throws IOException { - final int position = getPositionRelativeToDocumentElement(currentComment); - if (position == NODE_AFTER_DOCUMENT_ELEMENT) { - writer.write('\n'); - } - writer.write(_BEGIN_COMM); - - final String data = currentComment.getData(); - final int length = data.length(); - - for (int i = 0; i < length; i++) { - char c=data.charAt(i); - if (c==0x0D) { - writer.write(__XD_); - } else { - writeCharToUtf8(c,writer); - } - } - - writer.write(_END_COMM); - if (position == NODE_BEFORE_DOCUMENT_ELEMENT) { - writer.write('\n'); - } - } - - /** - * Outputs a Text of CDATA section to the internal Writer. - * - * @param text - * @param writer writer where to write the things - * @throws IOException - */ - static final void outputTextToWriter(final String text, final OutputStream writer) throws IOException { - final int length = text.length(); - byte []toWrite; - for (int i = 0; i < length; i++) { - char c = text.charAt(i); - - switch (c) { - - case '&' : - toWrite=_AMP_; - //writer.write(_AMP_); - break; - - case '<' : - toWrite=_LT_; - //writer.write(_LT_); - break; - - case '>' : - toWrite=_GT_; - //writer.write(_GT_); - break; - - case 0xD : - toWrite=__XD_; - //writer.write(__XD_); - break; - - default : - writeCharToUtf8(c,writer); - continue; - } - writer.write(toWrite); - } - } - /** * Obtain the attributes to output for this node in XPathNodeSet c14n. * @@ -870,13 +638,207 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { abstract Iterator handleAttributesSubtree(Element E, NameSpaceSymbTable ns) throws CanonicalizationException; + abstract void circumventBugIfNeeded(XMLSignatureInput input) throws CanonicalizationException, ParserConfigurationException, IOException, SAXException; + /** + * Outputs an Attribute to the internal Writer. + * + * The string value of the node is modified by replacing + *
        + *
      • all ampersands (&) with &amp;
      • + *
      • all open angle brackets (<) with &lt;
      • + *
      • all quotation mark characters with &quot;
      • + *
      • and the whitespace characters #x9, #xA, and #xD, with character + * references. The character references are written in uppercase + * hexadecimal with no leading zeroes (for example, #xD is represented + * by the character reference &#xD;)
      • + *
      + * + * @param name + * @param value + * @param writer + * @throws IOException + */ + static final void outputAttrToWriter(final String name, final String value, final OutputStream writer, + final Map cache) throws IOException { + writer.write(' '); + UtfHelpper.writeByte(name,writer,cache); + writer.write(equalsStr); + byte []toWrite; + final int length = value.length(); + int i=0; + while (i < length) { + char c = value.charAt(i++); - /** - * @param _writer The _writer to set. - */ - public void setWriter(OutputStream _writer) { - this._writer = _writer; - } + switch (c) { + + case '&' : + toWrite=_AMP_; + break; + + case '<' : + toWrite=_LT_; + break; + + case '"' : + toWrite=_QUOT_; + break; + + case 0x09 : // '\t' + toWrite=__X9_; + break; + + case 0x0A : // '\n' + toWrite=__XA_; + break; + + case 0x0D : // '\r' + toWrite=__XD_; + break; + + default : + if (c < 0x80 ) { + writer.write(c); + } else { + UtfHelpper.writeCharToUtf8(c,writer); + }; + continue; + } + writer.write(toWrite); + } + + writer.write('\"'); + } + + /** + * Outputs a PI to the internal Writer. + * + * @param currentPI + * @param writer where to write the things + * @throws IOException + */ + static final void outputPItoWriter(ProcessingInstruction currentPI, OutputStream writer,int position) throws IOException { + + if (position == NODE_AFTER_DOCUMENT_ELEMENT) { + writer.write('\n'); + } + writer.write(_BEGIN_PI); + + final String target = currentPI.getTarget(); + int length = target.length(); + + for (int i = 0; i < length; i++) { + char c=target.charAt(i); + if (c==0x0D) { + writer.write(__XD_); + } else { + if (c < 0x80) { + writer.write(c); + } else { + UtfHelpper.writeCharToUtf8(c,writer); + }; + } + } + + final String data = currentPI.getData(); + + length = data.length(); + + if (length > 0) { + writer.write(' '); + + for (int i = 0; i < length; i++) { + char c=data.charAt(i); + if (c==0x0D) { + writer.write(__XD_); + } else { + UtfHelpper.writeCharToUtf8(c,writer); + } + } + } + + writer.write(_END_PI); + if (position == NODE_BEFORE_DOCUMENT_ELEMENT) { + writer.write('\n'); + } + } + + /** + * Method outputCommentToWriter + * + * @param currentComment + * @param writer writer where to write the things + * @throws IOException + */ + static final void outputCommentToWriter(Comment currentComment, OutputStream writer,int position) throws IOException { + if (position == NODE_AFTER_DOCUMENT_ELEMENT) { + writer.write('\n'); + } + writer.write(_BEGIN_COMM); + + final String data = currentComment.getData(); + final int length = data.length(); + + for (int i = 0; i < length; i++) { + char c=data.charAt(i); + if (c==0x0D) { + writer.write(__XD_); + } else { + if (c < 0x80) { + writer.write(c); + } else { + UtfHelpper.writeCharToUtf8(c,writer); + }; + } + } + + writer.write(_END_COMM); + if (position == NODE_BEFORE_DOCUMENT_ELEMENT) { + writer.write('\n'); + } + } + + /** + * Outputs a Text of CDATA section to the internal Writer. + * + * @param text + * @param writer writer where to write the things + * @throws IOException + */ + static final void outputTextToWriter(final String text, final OutputStream writer) throws IOException { + final int length = text.length(); + byte []toWrite; + for (int i = 0; i < length; i++) { + char c = text.charAt(i); + + switch (c) { + + case '&' : + toWrite=_AMP_; + break; + + case '<' : + toWrite=_LT_; + break; + + case '>' : + toWrite=_GT_; + break; + + case 0xD : + toWrite=__XD_; + break; + + default : + if (c < 0x80) { + writer.write(c); + } else { + UtfHelpper.writeCharToUtf8(c,writer); + }; + continue; + } + writer.write(toWrite); + } + } } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/NameSpaceSymbTable.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/NameSpaceSymbTable.java index bad23010f11..538d369748c 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/NameSpaceSymbTable.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/NameSpaceSymbTable.java @@ -20,16 +20,10 @@ */ package com.sun.org.apache.xml.internal.security.c14n.implementations; -import java.lang.reflect.Array; -import java.util.AbstractList; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; import java.util.Iterator; import java.util.List; -import java.util.Map; - import org.w3c.dom.Attr; @@ -46,21 +40,26 @@ import org.w3c.dom.Node; public class NameSpaceSymbTable { /**The map betwen prefix-> entry table. */ - SymbMap symb = new SymbMap(); + SymbMap symb; /**The level of nameSpaces (for Inclusive visibility).*/ int nameSpaces=0; /**The stacks for removing the definitions when doing pop.*/ - List level = new ArrayList(); + List level; boolean cloned=true; static final String XMLNS="xmlns"; + final static SymbMap initialMap=new SymbMap(); + static { + NameSpaceSymbEntry ne=new NameSpaceSymbEntry("",null,true,XMLNS); + ne.lastrendered=""; + initialMap.put(XMLNS,ne); + } /** * Default constractor **/ public NameSpaceSymbTable() { + level = new ArrayList(10); //Insert the default binding for xmlns. - NameSpaceSymbEntry ne=new NameSpaceSymbEntry("",null,true); - ne.lastrendered=""; - symb.put(XMLNS,ne); + symb=(SymbMap) initialMap.clone(); } /** @@ -75,8 +74,14 @@ public class NameSpaceSymbTable { NameSpaceSymbEntry n=(NameSpaceSymbEntry)(it.next()); //put them rendered? if ((!n.rendered) && (n.n!=null)) { + n=(NameSpaceSymbEntry) n.clone(); + needsClone(); + symb.put(n.prefix,n); + n.lastrendered=n.uri; + n.rendered=true; + result.add(n.n); - n.rendered=true; + } } } @@ -104,10 +109,6 @@ public class NameSpaceSymbTable { **/ public void push() { //Put the number of namespace definitions in the stack. - /**if (cloned) { - Object ob[]= {symb,cloned ? symb : null}; - level.add(ob); - } **/ level.add(null); cloned=false; } @@ -124,7 +125,7 @@ public class NameSpaceSymbTable { if (size==0) { cloned=false; } else - cloned=(level.get(size-1)!=symb); + cloned=(level.get(size-1)!=symb); } else { cloned=false; } @@ -134,8 +135,7 @@ public class NameSpaceSymbTable { final void needsClone() { if (!cloned) { - level.remove(level.size()-1); - level.add(symb); + level.set(level.size()-1,symb); symb=(SymbMap) symb.clone(); cloned=true; } @@ -200,7 +200,7 @@ public class NameSpaceSymbTable { return false; } //Creates and entry in the table for this new definition. - NameSpaceSymbEntry ne=new NameSpaceSymbEntry(uri,n,false); + NameSpaceSymbEntry ne=new NameSpaceSymbEntry(uri,n,false,prefix); needsClone(); symb.put(prefix, ne); if (ob != null) { @@ -238,7 +238,7 @@ public class NameSpaceSymbTable { return null; } - NameSpaceSymbEntry ne=new NameSpaceSymbEntry(uri,n,true); + NameSpaceSymbEntry ne=new NameSpaceSymbEntry(uri,n,true,prefix); ne.lastrendered=uri; needsClone(); symb.put(prefix, ne); @@ -251,53 +251,38 @@ public class NameSpaceSymbTable { } return ne.n; } - /** - * Adds & gets(if needed) the attribute node that defines the binding for the prefix. - * Take on account if the rules of rendering in the inclusive c14n. - * For inclusive c14n. - * @param prefix the prefix to obtain the attribute. - * @param outputNode the container element is an output element. - * @param uri the Uri of the definition - * @param n the attribute that have the definition - * @return null if there is no need to render the prefix. Otherwise the node of - * definition. - **/ - public Node addMappingAndRenderXNodeSet(String prefix, String uri,Attr n,boolean outputNode) { + + public int getLevel() { + // TODO Auto-generated method stub + return level.size(); + } + + public void removeMapping(String prefix) { NameSpaceSymbEntry ob = symb.get(prefix); - int visibleNameSpaces=nameSpaces; - if ((ob!=null) && uri.equals(ob.uri)) { - if (!ob.rendered) { - ob=(NameSpaceSymbEntry)ob.clone(); - needsClone(); - symb.put(prefix,ob); - ob.rendered=true; - ob.level=visibleNameSpaces; - return ob.n; - } - ob=(NameSpaceSymbEntry)ob.clone(); + + if (ob!=null) { needsClone(); - symb.put(prefix,ob); - if (outputNode && (((visibleNameSpaces-ob.level)<2) || XMLNS.equals(prefix)) ) { - ob.level=visibleNameSpaces; - return null; //Already rendered, just return nulll - } - ob.level=visibleNameSpaces; - return ob.n; - } + symb.put(prefix,null); + } + } - NameSpaceSymbEntry ne=new NameSpaceSymbEntry(uri,n,true); - ne.level=nameSpaces; - ne.rendered=true; - needsClone(); - symb.put(prefix, ne); - if (ob != null) { - ne.lastrendered=ob.lastrendered; + public void removeMappingIfNotRender(String prefix) { + NameSpaceSymbEntry ob = symb.get(prefix); - if ((ob.lastrendered!=null)&& (ob.lastrendered.equals(uri))) { - ne.rendered=true; - } - } - return ne.n; + if (ob!=null && !ob.rendered) { + needsClone(); + symb.put(prefix,null); + } + } + + public boolean removeMappingIfRender(String prefix) { + NameSpaceSymbEntry ob = symb.get(prefix); + + if (ob!=null && ob.rendered) { + needsClone(); + symb.put(prefix,null); + } + return false; } } @@ -305,10 +290,11 @@ public class NameSpaceSymbTable { * The internal structure of NameSpaceSymbTable. **/ class NameSpaceSymbEntry implements Cloneable { - NameSpaceSymbEntry(String name,Attr n,boolean rendered) { + NameSpaceSymbEntry(String name,Attr n,boolean rendered,String prefix) { this.uri=name; this.rendered=rendered; this.n=n; + this.prefix=prefix; } /** @inheritDoc */ public Object clone() { @@ -320,6 +306,7 @@ class NameSpaceSymbEntry implements Cloneable { } /** The level where the definition was rendered(Only for inclusive) */ int level=0; + String prefix; /**The URI that the prefix defines */ String uri; /**The last output in the URI for this prefix (This for speed reason).*/ @@ -330,53 +317,57 @@ class NameSpaceSymbEntry implements Cloneable { Attr n; }; -class SymbMap implements Cloneable{ - int free=23; - NameSpaceSymbEntry[] entries=new NameSpaceSymbEntry[free]; - String[] keys=new String[free]; - - void put(String key, NameSpaceSymbEntry value) { +class SymbMap implements Cloneable { + int free=23; + NameSpaceSymbEntry[] entries; + String[] keys; + SymbMap() { + entries=new NameSpaceSymbEntry[free]; + keys=new String[free]; + } + void put(String key, NameSpaceSymbEntry value) { int index = index(key); - Object oldKey = keys[index]; - keys[index] = key; - entries[index] = value; + Object oldKey = keys[index]; + keys[index] = key; + entries[index] = value; if (oldKey==null || !oldKey.equals(key)) { - if (--free == 0) { - free=entries.length; - int newCapacity = free<<2; - rehash(newCapacity); - } + if (--free == 0) { + free=entries.length; + int newCapacity = free<<2; + rehash(newCapacity); + } } } List entrySet() { - List a=new ArrayList(); - for (int i=0;iint
      value @@ -384,37 +375,38 @@ class SymbMap implements Cloneable{ protected void rehash(int newCapacity) { int oldCapacity = keys.length; String oldKeys[] = keys; - NameSpaceSymbEntry oldVals[] = entries; + NameSpaceSymbEntry oldVals[] = entries; - keys = new String[newCapacity]; - entries = new NameSpaceSymbEntry[newCapacity]; + keys = new String[newCapacity]; + entries = new NameSpaceSymbEntry[newCapacity]; for (int i = oldCapacity; i-- > 0;) { if(oldKeys[i] != null) { String o = oldKeys[i]; int index = index(o); - keys[index] = o; - entries[index] = oldVals[i]; + keys[index] = o; + entries[index] = oldVals[i]; } } } - NameSpaceSymbEntry get(String key) { - return entries[index(key)]; - } - protected Object clone() { - // TODO Auto-generated method stub - try { - SymbMap copy=(SymbMap) super.clone(); - copy.entries=new NameSpaceSymbEntry[entries.length]; - System.arraycopy(entries,0,copy.entries,0,entries.length); - copy.keys=new String[keys.length]; - System.arraycopy(keys,0,copy.keys,0,keys.length); - return copy; - } catch (CloneNotSupportedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return null; + NameSpaceSymbEntry get(String key) { + return entries[index(key)]; + } + + protected Object clone() { + try { + SymbMap copy=(SymbMap) super.clone(); + copy.entries=new NameSpaceSymbEntry[entries.length]; + System.arraycopy(entries,0,copy.entries,0,entries.length); + copy.keys=new String[keys.length]; + System.arraycopy(keys,0,copy.keys,0,keys.length); + + return copy; + } catch (CloneNotSupportedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } + return null; + } } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/UtfHelpper.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/UtfHelpper.java new file mode 100644 index 00000000000..cfcc06dd2c4 --- /dev/null +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/UtfHelpper.java @@ -0,0 +1,155 @@ +package com.sun.org.apache.xml.internal.security.c14n.implementations; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Map; + +public class UtfHelpper { + + final static void writeByte(final String str,final OutputStream out,Map cache) throws IOException { + byte []result=(byte[]) cache.get(str); + if (result==null) { + result=getStringInUtf8(str); + cache.put(str,result); + } + + out.write(result); + + } + + final static void writeCharToUtf8(final char c,final OutputStream out) throws IOException{ + if (c < 0x80) { + out.write(c); + return; + } + if ((c >= 0xD800 && c <= 0xDBFF) || (c >= 0xDC00 && c <= 0xDFFF) ){ + //No Surrogates in sun java + out.write(0x3f); + return; + } + int bias; + int write; + char ch; + if (c > 0x07FF) { + ch=(char)(c>>>12); + write=0xE0; + if (ch>0) { + write |= ( ch & 0x0F); + } + out.write(write); + write=0x80; + bias=0x3F; + } else { + write=0xC0; + bias=0x1F; + } + ch=(char)(c>>>6); + if (ch>0) { + write|= (ch & bias); + } + out.write(write); + out.write(0x80 | ((c) & 0x3F)); + + } + + final static void writeStringToUtf8(final String str,final OutputStream out) throws IOException{ + final int length=str.length(); + int i=0; + char c; + while (i= 0xD800 && c <= 0xDBFF) || (c >= 0xDC00 && c <= 0xDFFF) ){ + //No Surrogates in sun java + out.write(0x3f); + continue; + } + char ch; + int bias; + int write; + if (c > 0x07FF) { + ch=(char)(c>>>12); + write=0xE0; + if (ch>0) { + write |= ( ch & 0x0F); + } + out.write(write); + write=0x80; + bias=0x3F; + } else { + write=0xC0; + bias=0x1F; + } + ch=(char)(c>>>6); + if (ch>0) { + write|= (ch & bias); + } + out.write(write); + out.write(0x80 | ((c) & 0x3F)); + + } + + } + public final static byte[] getStringInUtf8(final String str) { + final int length=str.length(); + boolean expanded=false; + byte []result=new byte[length]; + int i=0; + int out=0; + char c; + while (i= 0xD800 && c <= 0xDBFF) || (c >= 0xDC00 && c <= 0xDFFF) ){ + //No Surrogates in sun java + result[out++]=0x3f; + + continue; + } + if (!expanded) { + byte newResult[]=new byte[3*length]; + System.arraycopy(result, 0, newResult, 0, out); + result=newResult; + expanded=true; + } + char ch; + int bias; + byte write; + if (c > 0x07FF) { + ch=(char)(c>>>12); + write=(byte)0xE0; + if (ch>0) { + write |= ( ch & 0x0F); + } + result[out++]=write; + write=(byte)0x80; + bias=0x3F; + } else { + write=(byte)0xC0; + bias=0x1F; + } + ch=(char)(c>>>6); + if (ch>0) { + write|= (ch & bias); + } + result[out++]=write; + result[out++]=(byte)(0x80 | ((c) & 0x3F));/**/ + + } + if (expanded) { + byte newResult[]=new byte[out]; + System.arraycopy(result, 0, newResult, 0, out); + result=newResult; + } + return result; + } + + + +} diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/XMLCipher.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/XMLCipher.java index 7814216496d..683acdbf003 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/XMLCipher.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/XMLCipher.java @@ -22,6 +22,7 @@ package com.sun.org.apache.xml.internal.security.encryption; import java.io.ByteArrayOutputStream; +import java.io.InputStream; import java.io.IOException; import java.io.StringReader; import java.io.UnsupportedEncodingException; @@ -30,6 +31,7 @@ import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; +import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; @@ -204,7 +206,7 @@ public class XMLCipher { * @since 1.0. */ private XMLCipher() { - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Constructing XMLCipher..."); + logger.log(java.util.logging.Level.FINE, "Constructing XMLCipher..."); _factory = new Factory(); _serializer = new Serializer(); @@ -266,7 +268,7 @@ public class XMLCipher { public static XMLCipher getInstance(String transformation) throws XMLEncryptionException { // sanity checks - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Getting XMLCipher..."); + logger.log(java.util.logging.Level.FINE, "Getting XMLCipher..."); if (null == transformation) logger.log(java.util.logging.Level.SEVERE, "Transformation unexpectedly null..."); if(!isValidEncryptionAlgorithm(transformation)) @@ -294,7 +296,7 @@ public class XMLCipher { try { instance._contextCipher = Cipher.getInstance(jceAlgorithm); - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "cihper.algoritm = " + + logger.log(java.util.logging.Level.FINE, "cihper.algoritm = " + instance._contextCipher.getAlgorithm()); } catch (NoSuchAlgorithmException nsae) { throw new XMLEncryptionException("empty", nsae); @@ -305,49 +307,6 @@ public class XMLCipher { return (instance); } - public static XMLCipher getInstance(String transformation,Cipher cipher) throws - XMLEncryptionException { - // sanity checks - logger.log(java.util.logging.Level.FINE, "Getting XMLCipher..."); - if (null == transformation) - logger.log(java.util.logging.Level.SEVERE, "Transformation unexpectedly null..."); - if(!isValidEncryptionAlgorithm(transformation)) - logger.log(java.util.logging.Level.WARNING, "Algorithm non-standard, expected one of " + ENC_ALGORITHMS); - - XMLCipher instance = new XMLCipher(); - - instance._algorithm = transformation; - instance._key = null; - instance._kek = null; - - - /* Create a canonicaliser - used when serialising DOM to octets - * prior to encryption (and for the reverse) */ - - try { - instance._canon = Canonicalizer.getInstance - (Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS); - - } catch (InvalidCanonicalizerException ice) { - throw new XMLEncryptionException("empty", ice); - } - - String jceAlgorithm = JCEMapper.translateURItoJCEID(transformation); - - try { - instance._contextCipher = cipher; - //Cipher.getInstance(jceAlgorithm); - logger.log(java.util.logging.Level.FINE, "cihper.algoritm = " + - instance._contextCipher.getAlgorithm()); - }catch(Exception ex) { - throw new XMLEncryptionException("empty", ex); - } - - return (instance); - } - - - /** * Returns an XMLCipher that implements the specified * transformation, operates on the specified context document and serializes @@ -380,6 +339,45 @@ public class XMLCipher { return instance; } + public static XMLCipher getInstance(String transformation,Cipher cipher) throws XMLEncryptionException { + // sanity checks + logger.log(java.util.logging.Level.FINE, "Getting XMLCipher..."); + if (null == transformation) + logger.log(java.util.logging.Level.SEVERE, "Transformation unexpectedly null..."); + if(!isValidEncryptionAlgorithm(transformation)) + logger.log(java.util.logging.Level.WARNING, "Algorithm non-standard, expected one of " + ENC_ALGORITHMS); + + XMLCipher instance = new XMLCipher(); + + instance._algorithm = transformation; + instance._key = null; + instance._kek = null; + + + /* Create a canonicaliser - used when serialising DOM to octets + * prior to encryption (and for the reverse) */ + + try { + instance._canon = Canonicalizer.getInstance + (Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS); + + } catch (InvalidCanonicalizerException ice) { + throw new XMLEncryptionException("empty", ice); + } + + String jceAlgorithm = JCEMapper.translateURItoJCEID(transformation); + + try { + instance._contextCipher = cipher; + //Cipher.getInstance(jceAlgorithm); + logger.log(java.util.logging.Level.FINE, "cihper.algoritm = " + + instance._contextCipher.getAlgorithm()); + }catch(Exception ex) { + throw new XMLEncryptionException("empty", ex); + } + + return (instance); + } /** * Returns an XMLCipher that implements the specified @@ -396,7 +394,7 @@ public class XMLCipher { public static XMLCipher getProviderInstance(String transformation, String provider) throws XMLEncryptionException { // sanity checks - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Getting XMLCipher..."); + logger.log(java.util.logging.Level.FINE, "Getting XMLCipher..."); if (null == transformation) logger.log(java.util.logging.Level.SEVERE, "Transformation unexpectedly null..."); if(null == provider) @@ -429,9 +427,9 @@ public class XMLCipher { instance._contextCipher = Cipher.getInstance(jceAlgorithm, provider); - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "cipher._algorithm = " + + logger.log(java.util.logging.Level.FINE, "cipher._algorithm = " + instance._contextCipher.getAlgorithm()); - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "provider.name = " + provider); + logger.log(java.util.logging.Level.FINE, "provider.name = " + provider); } catch (NoSuchAlgorithmException nsae) { throw new XMLEncryptionException("empty", nsae); } catch (NoSuchProviderException nspre) { @@ -490,7 +488,7 @@ public class XMLCipher { public static XMLCipher getInstance() throws XMLEncryptionException { // sanity checks - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Getting XMLCipher for no transformation..."); + logger.log(java.util.logging.Level.FINE, "Getting XMLCipher for no transformation..."); XMLCipher instance = new XMLCipher(); @@ -532,7 +530,7 @@ public class XMLCipher { throws XMLEncryptionException { // sanity checks - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Getting XMLCipher, provider but no transformation"); + logger.log(java.util.logging.Level.FINE, "Getting XMLCipher, provider but no transformation"); if(null == provider) logger.log(java.util.logging.Level.SEVERE, "Provider unexpectedly null.."); if("" == provider) @@ -578,7 +576,7 @@ public class XMLCipher { */ public void init(int opmode, Key key) throws XMLEncryptionException { // sanity checks - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Initializing XMLCipher..."); + logger.log(java.util.logging.Level.FINE, "Initializing XMLCipher..."); _ek = null; _ed = null; @@ -586,18 +584,18 @@ public class XMLCipher { switch (opmode) { case ENCRYPT_MODE : - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "opmode = ENCRYPT_MODE"); + logger.log(java.util.logging.Level.FINE, "opmode = ENCRYPT_MODE"); _ed = createEncryptedData(CipherData.VALUE_TYPE, "NO VALUE YET"); break; case DECRYPT_MODE : - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "opmode = DECRYPT_MODE"); + logger.log(java.util.logging.Level.FINE, "opmode = DECRYPT_MODE"); break; case WRAP_MODE : - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "opmode = WRAP_MODE"); + logger.log(java.util.logging.Level.FINE, "opmode = WRAP_MODE"); _ek = createEncryptedKey(CipherData.VALUE_TYPE, "NO VALUE YET"); break; case UNWRAP_MODE : - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "opmode = UNWRAP_MODE"); + logger.log(java.util.logging.Level.FINE, "opmode = UNWRAP_MODE"); break; default : logger.log(java.util.logging.Level.SEVERE, "Mode unexpectedly invalid"); @@ -622,7 +620,7 @@ public class XMLCipher { public EncryptedData getEncryptedData() { // Sanity checks - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Returning EncryptedData"); + logger.log(java.util.logging.Level.FINE, "Returning EncryptedData"); return _ed; } @@ -640,7 +638,7 @@ public class XMLCipher { public EncryptedKey getEncryptedKey() { // Sanity checks - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Returning EncryptedKey"); + logger.log(java.util.logging.Level.FINE, "Returning EncryptedKey"); return _ek; } @@ -750,11 +748,11 @@ public class XMLCipher { */ private Document encryptElement(Element element) throws Exception{ - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypting element..."); + logger.log(java.util.logging.Level.FINE, "Encrypting element..."); if(null == element) logger.log(java.util.logging.Level.SEVERE, "Element unexpectedly null..."); if(_cipherMode != ENCRYPT_MODE) - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in ENCRYPT_MODE..."); + logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in ENCRYPT_MODE..."); if (_algorithm == null) { throw new XMLEncryptionException("XMLCipher instance without transformation specified"); @@ -785,11 +783,11 @@ public class XMLCipher { */ private Document encryptElementContent(Element element) throws /* XMLEncryption */Exception { - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypting element content..."); + logger.log(java.util.logging.Level.FINE, "Encrypting element content..."); if(null == element) logger.log(java.util.logging.Level.SEVERE, "Element unexpectedly null..."); if(_cipherMode != ENCRYPT_MODE) - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in ENCRYPT_MODE..."); + logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in ENCRYPT_MODE..."); if (_algorithm == null) { throw new XMLEncryptionException("XMLCipher instance without transformation specified"); @@ -815,7 +813,7 @@ public class XMLCipher { */ public Document doFinal(Document context, Document source) throws /* XMLEncryption */Exception { - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Processing source document..."); + logger.log(java.util.logging.Level.FINE, "Processing source document..."); if(null == context) logger.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null..."); if(null == source) @@ -855,7 +853,7 @@ public class XMLCipher { */ public Document doFinal(Document context, Element element) throws /* XMLEncryption */Exception { - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Processing source element..."); + logger.log(java.util.logging.Level.FINE, "Processing source element..."); if(null == context) logger.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null..."); if(null == element) @@ -898,7 +896,7 @@ public class XMLCipher { */ public Document doFinal(Document context, Element element, boolean content) throws /* XMLEncryption*/ Exception { - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Processing source element..."); + logger.log(java.util.logging.Level.FINE, "Processing source element..."); if(null == context) logger.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null..."); if(null == element) @@ -952,6 +950,34 @@ public class XMLCipher { return encryptData(context, element, false); } + /** + * Returns an EncryptedData interface. Use this operation if + * you want to have full control over the serialization of the element + * or element content. + * + * This does not change the source document in any way. + * + * @param context the context Document. + * @param type a URI identifying type information about the plaintext form + * of the encrypted content (may be null) + * @param serializedData the serialized data + * @return the EncryptedData + * @throws Exception + */ + public EncryptedData encryptData(Document context, String type, + InputStream serializedData) throws Exception { + + logger.log(java.util.logging.Level.FINE, "Encrypting element..."); + if (null == context) + logger.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null..."); + if (null == serializedData) + logger.log(java.util.logging.Level.SEVERE, "Serialized data unexpectedly null..."); + if (_cipherMode != ENCRYPT_MODE) + logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in ENCRYPT_MODE..."); + + return encryptData(context, null, type, serializedData); + } + /** * Returns an EncryptedData interface. Use this operation if * you want to have full control over the contents of the @@ -966,160 +992,60 @@ public class XMLCipher { * @return the EncryptedData * @throws Exception */ - public EncryptedData encryptData(Document context, Element element, boolean contentMode) throws - /* XMLEncryption */ Exception { - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypting element..."); - if (null == context) - logger.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null..."); - if (null == element) - logger.log(java.util.logging.Level.SEVERE, "Element unexpectedly null..."); - if (_cipherMode != ENCRYPT_MODE) - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in ENCRYPT_MODE..."); + public EncryptedData encryptData( + Document context, Element element, boolean contentMode) + throws /* XMLEncryption */ Exception { - _contextDocument = context; - - if (_algorithm == null) { - throw new XMLEncryptionException("XMLCipher instance without transformation specified"); - } - - String serializedOctets = null; - if (contentMode) { - NodeList children = element.getChildNodes(); - if ((null != children)) { - serializedOctets = _serializer.serialize(children); - } else { - Object exArgs[] = { "Element has no content." }; - throw new XMLEncryptionException("empty", exArgs); - } - } else { - serializedOctets = _serializer.serialize(element); - } - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Serialized octets:\n" + serializedOctets); - - byte[] encryptedBytes = null; - - // Now create the working cipher if none was created already - Cipher c; - if (_contextCipher == null) { - String jceAlgorithm = - JCEMapper.translateURItoJCEID(_algorithm); - - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "alg = " + jceAlgorithm); - - try { - if (_requestedJCEProvider == null) - c = Cipher.getInstance(jceAlgorithm); - else - c = Cipher.getInstance(jceAlgorithm, _requestedJCEProvider); - } catch (NoSuchAlgorithmException nsae) { - throw new XMLEncryptionException("empty", nsae); - } catch (NoSuchProviderException nspre) { - throw new XMLEncryptionException("empty", nspre); - } catch (NoSuchPaddingException nspae) { - throw new XMLEncryptionException("empty", nspae); - } - } - else { - c = _contextCipher; - } - // Now perform the encryption - - try { - // Should internally generate an IV - // todo - allow user to set an IV - c.init(_cipherMode, _key); - } catch (InvalidKeyException ike) { - throw new XMLEncryptionException("empty", ike); - } - - try { - encryptedBytes = - c.doFinal(serializedOctets.getBytes("UTF-8")); - - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Expected cipher.outputSize = " + - Integer.toString(c.getOutputSize( - serializedOctets.getBytes().length))); - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Actual cipher.outputSize = " + - Integer.toString(encryptedBytes.length)); - } catch (IllegalStateException ise) { - throw new XMLEncryptionException("empty", ise); - } catch (IllegalBlockSizeException ibse) { - throw new XMLEncryptionException("empty", ibse); - } catch (BadPaddingException bpe) { - throw new XMLEncryptionException("empty", bpe); - } catch (UnsupportedEncodingException uee) { - throw new XMLEncryptionException("empty", uee); - } - - // Now build up to a properly XML Encryption encoded octet stream - // IvParameterSpec iv; - - byte[] iv = c.getIV(); - byte[] finalEncryptedBytes = - new byte[iv.length + encryptedBytes.length]; - System.arraycopy(iv, 0, finalEncryptedBytes, 0, - iv.length); - System.arraycopy(encryptedBytes, 0, finalEncryptedBytes, - iv.length, - encryptedBytes.length); - - String base64EncodedEncryptedOctets = Base64.encode(finalEncryptedBytes); - - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypted octets:\n" + base64EncodedEncryptedOctets); - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypted octets length = " + - base64EncodedEncryptedOctets.length()); - - try { - CipherData cd = _ed.getCipherData(); - CipherValue cv = cd.getCipherValue(); - // cv.setValue(base64EncodedEncryptedOctets.getBytes()); - cv.setValue(base64EncodedEncryptedOctets); - - if (contentMode) { - _ed.setType( - new URI(EncryptionConstants.TYPE_CONTENT).toString()); - } else { - _ed.setType( - new URI(EncryptionConstants.TYPE_ELEMENT).toString()); - } - EncryptionMethod method = - _factory.newEncryptionMethod(new URI(_algorithm).toString()); - _ed.setEncryptionMethod(method); - } catch (URI.MalformedURIException mfue) { - throw new XMLEncryptionException("empty", mfue); - } - return (_ed); - } - - - - public EncryptedData encryptData(Document context, byte [] serializedOctets, boolean contentMode) throws - /* XMLEncryption */ Exception { logger.log(java.util.logging.Level.FINE, "Encrypting element..."); if (null == context) logger.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null..."); - if (null == serializedOctets) - logger.log(java.util.logging.Level.SEVERE, "Canonicalized Data is unexpectedly null..."); + if (null == element) + logger.log(java.util.logging.Level.SEVERE, "Element unexpectedly null..."); if (_cipherMode != ENCRYPT_MODE) logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in ENCRYPT_MODE..."); + if (contentMode) { + return encryptData + (context, element, EncryptionConstants.TYPE_CONTENT, null); + } else { + return encryptData + (context, element, EncryptionConstants.TYPE_ELEMENT, null); + } + } + + private EncryptedData encryptData( + Document context, Element element, String type, + InputStream serializedData) throws /* XMLEncryption */ Exception { + _contextDocument = context; if (_algorithm == null) { - throw new XMLEncryptionException("XMLCipher instance without transformation specified"); + throw new XMLEncryptionException + ("XMLCipher instance without transformation specified"); } - - logger.log(java.util.logging.Level.FINE, "Serialized octets:\n" + serializedOctets); + String serializedOctets = null; + if (serializedData == null) { + if (type == EncryptionConstants.TYPE_CONTENT) { + NodeList children = element.getChildNodes(); + if (null != children) { + serializedOctets = _serializer.serialize(children); + } else { + Object exArgs[] = { "Element has no content." }; + throw new XMLEncryptionException("empty", exArgs); + } + } else { + serializedOctets = _serializer.serialize(element); + } + logger.log(java.util.logging.Level.FINE, "Serialized octets:\n" + serializedOctets); + } byte[] encryptedBytes = null; // Now create the working cipher if none was created already Cipher c; if (_contextCipher == null) { - String jceAlgorithm = - JCEMapper.translateURItoJCEID(_algorithm); - + String jceAlgorithm = JCEMapper.translateURItoJCEID(_algorithm); logger.log(java.util.logging.Level.FINE, "alg = " + jceAlgorithm); try { @@ -1148,41 +1074,47 @@ public class XMLCipher { } try { - encryptedBytes = - c.doFinal(serializedOctets); - - logger.log(java.util.logging.Level.FINE, "Expected cipher.outputSize = " + + if (serializedData != null) { + int numBytes; + byte[] buf = new byte[8192]; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + while ((numBytes = serializedData.read(buf)) != -1) { + byte[] data = c.update(buf, 0, numBytes); + baos.write(data); + } + baos.write(c.doFinal()); + encryptedBytes = baos.toByteArray(); + } else { + encryptedBytes = c.doFinal(serializedOctets.getBytes("UTF-8")); + logger.log(java.util.logging.Level.FINE, "Expected cipher.outputSize = " + Integer.toString(c.getOutputSize( - serializedOctets.length))); + serializedOctets.getBytes().length))); + } logger.log(java.util.logging.Level.FINE, "Actual cipher.outputSize = " + - Integer.toString(encryptedBytes.length)); + Integer.toString(encryptedBytes.length)); } catch (IllegalStateException ise) { throw new XMLEncryptionException("empty", ise); } catch (IllegalBlockSizeException ibse) { throw new XMLEncryptionException("empty", ibse); } catch (BadPaddingException bpe) { throw new XMLEncryptionException("empty", bpe); - } catch (Exception uee) { + } catch (UnsupportedEncodingException uee) { throw new XMLEncryptionException("empty", uee); } // Now build up to a properly XML Encryption encoded octet stream // IvParameterSpec iv; - byte[] iv = c.getIV(); byte[] finalEncryptedBytes = new byte[iv.length + encryptedBytes.length]; - System.arraycopy(iv, 0, finalEncryptedBytes, 0, - iv.length); - System.arraycopy(encryptedBytes, 0, finalEncryptedBytes, - iv.length, - encryptedBytes.length); - + System.arraycopy(iv, 0, finalEncryptedBytes, 0, iv.length); + System.arraycopy(encryptedBytes, 0, finalEncryptedBytes, iv.length, + encryptedBytes.length); String base64EncodedEncryptedOctets = Base64.encode(finalEncryptedBytes); logger.log(java.util.logging.Level.FINE, "Encrypted octets:\n" + base64EncodedEncryptedOctets); logger.log(java.util.logging.Level.FINE, "Encrypted octets length = " + - base64EncodedEncryptedOctets.length()); + base64EncodedEncryptedOctets.length()); try { CipherData cd = _ed.getCipherData(); @@ -1190,15 +1122,11 @@ public class XMLCipher { // cv.setValue(base64EncodedEncryptedOctets.getBytes()); cv.setValue(base64EncodedEncryptedOctets); - if (contentMode) { - _ed.setType( - new URI(EncryptionConstants.TYPE_CONTENT).toString()); - } else { - _ed.setType( - new URI(EncryptionConstants.TYPE_ELEMENT).toString()); + if (type != null) { + _ed.setType(new URI(type).toString()); } EncryptionMethod method = - _factory.newEncryptionMethod(new URI(_algorithm).toString()); + _factory.newEncryptionMethod(new URI(_algorithm).toString()); _ed.setEncryptionMethod(method); } catch (URI.MalformedURIException mfue) { throw new XMLEncryptionException("empty", mfue); @@ -1206,7 +1134,6 @@ public class XMLCipher { return (_ed); } - /** * Returns an EncryptedData interface. Use this operation if * you want to load an EncryptedData structure from a DOM @@ -1219,7 +1146,7 @@ public class XMLCipher { */ public EncryptedData loadEncryptedData(Document context, Element element) throws XMLEncryptionException { - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Loading encrypted element..."); + logger.log(java.util.logging.Level.FINE, "Loading encrypted element..."); if(null == context) logger.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null..."); if(null == element) @@ -1246,13 +1173,13 @@ public class XMLCipher { public EncryptedKey loadEncryptedKey(Document context, Element element) throws XMLEncryptionException { - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Loading encrypted key..."); + logger.log(java.util.logging.Level.FINE, "Loading encrypted key..."); if(null == context) logger.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null..."); if(null == element) logger.log(java.util.logging.Level.SEVERE, "Element unexpectedly null..."); if(_cipherMode != UNWRAP_MODE && _cipherMode != DECRYPT_MODE) - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in UNWRAP_MODE or DECRYPT_MODE..."); + logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in UNWRAP_MODE or DECRYPT_MODE..."); _contextDocument = context; _ek = _factory.newEncryptedKey(element); @@ -1290,12 +1217,12 @@ public class XMLCipher { public EncryptedKey encryptKey(Document doc, Key key) throws XMLEncryptionException { - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypting key ..."); + logger.log(java.util.logging.Level.FINE, "Encrypting key ..."); if(null == key) logger.log(java.util.logging.Level.SEVERE, "Key unexpectedly null..."); if(_cipherMode != WRAP_MODE) - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in WRAP_MODE..."); + logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in WRAP_MODE..."); if (_algorithm == null) { @@ -1313,7 +1240,7 @@ public class XMLCipher { String jceAlgorithm = JCEMapper.translateURItoJCEID(_algorithm); - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "alg = " + jceAlgorithm); + logger.log(java.util.logging.Level.FINE, "alg = " + jceAlgorithm); try { if (_requestedJCEProvider == null) @@ -1345,8 +1272,8 @@ public class XMLCipher { String base64EncodedEncryptedOctets = Base64.encode(encryptedBytes); - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypted key octets:\n" + base64EncodedEncryptedOctets); - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypted key octets length = " + + logger.log(java.util.logging.Level.FINE, "Encrypted key octets:\n" + base64EncodedEncryptedOctets); + logger.log(java.util.logging.Level.FINE, "Encrypted key octets length = " + base64EncodedEncryptedOctets.length()); CipherValue cv = _ek.getCipherData().getCipherValue(); @@ -1376,10 +1303,10 @@ public class XMLCipher { public Key decryptKey(EncryptedKey encryptedKey, String algorithm) throws XMLEncryptionException { - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Decrypting key from previously loaded EncryptedKey..."); + logger.log(java.util.logging.Level.FINE, "Decrypting key from previously loaded EncryptedKey..."); if(_cipherMode != UNWRAP_MODE) - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in UNWRAP_MODE..."); + logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in UNWRAP_MODE..."); if (algorithm == null) { throw new XMLEncryptionException("Cannot decrypt a key without knowing the algorithm"); @@ -1387,7 +1314,7 @@ public class XMLCipher { if (_key == null) { - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Trying to find a KEK via key resolvers"); + logger.log(java.util.logging.Level.FINE, "Trying to find a KEK via key resolvers"); KeyInfo ki = encryptedKey.getKeyInfo(); if (ki != null) { @@ -1418,7 +1345,7 @@ public class XMLCipher { JCEMapper.translateURItoJCEID( encryptedKey.getEncryptionMethod().getAlgorithm()); - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "JCE Algorithm = " + jceAlgorithm); + logger.log(java.util.logging.Level.FINE, "JCE Algorithm = " + jceAlgorithm); try { if (_requestedJCEProvider == null) @@ -1448,7 +1375,7 @@ public class XMLCipher { throw new XMLEncryptionException("empty", nsae); } - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Decryption of key type " + algorithm + " OK"); + logger.log(java.util.logging.Level.FINE, "Decryption of key type " + algorithm + " OK"); return ret; @@ -1478,14 +1405,9 @@ public class XMLCipher { * * @param node the Node to clear. */ - private void removeContent(Node node) { - NodeList list = node.getChildNodes(); - if (list.getLength() > 0) { - Node n = list.item(0); - if (null != n) { - n.getParentNode().removeChild(n); - } - removeContent(node); + private static void removeContent(Node node) { + while (node.hasChildNodes()) { + node.removeChild(node.getFirstChild()); } } @@ -1499,7 +1421,7 @@ public class XMLCipher { private Document decryptElement(Element element) throws XMLEncryptionException { - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Decrypting element..."); + logger.log(java.util.logging.Level.FINE, "Decrypting element..."); if(_cipherMode != DECRYPT_MODE) logger.log(java.util.logging.Level.SEVERE, "XMLCipher unexpectedly not in DECRYPT_MODE..."); @@ -1512,7 +1434,7 @@ public class XMLCipher { } - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Decrypted octets:\n" + octets); + logger.log(java.util.logging.Level.FINE, "Decrypted octets:\n" + octets); Node sourceParent = element.getParentNode(); @@ -1573,7 +1495,7 @@ public class XMLCipher { public byte[] decryptToByteArray(Element element) throws XMLEncryptionException { - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Decrypting to ByteArray..."); + logger.log(java.util.logging.Level.FINE, "Decrypting to ByteArray..."); if(_cipherMode != DECRYPT_MODE) logger.log(java.util.logging.Level.SEVERE, "XMLCipher unexpectedly not in DECRYPT_MODE..."); @@ -2226,7 +2148,7 @@ public class XMLCipher { AgreementMethod newAgreementMethod(Element element) throws XMLEncryptionException { if (null == element) { - //complain + throw new NullPointerException("element is null"); } String algorithm = element.getAttributeNS(null, @@ -2292,7 +2214,7 @@ public class XMLCipher { CipherData newCipherData(Element element) throws XMLEncryptionException { if (null == element) { - // complain + throw new NullPointerException("element is null"); } int type = 0; @@ -2352,7 +2274,7 @@ public class XMLCipher { (Element) transformsElements.item(0); if (transformsElement != null) { - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Creating a DSIG based Transforms element"); + logger.log(java.util.logging.Level.FINE, "Creating a DSIG based Transforms element"); try { result.setTransforms(new TransformsImpl(transformsElement)); } @@ -2411,34 +2333,28 @@ public class XMLCipher { XMLEncryptionException { EncryptedData result = null; - NodeList dataElements = element.getElementsByTagNameNS( - EncryptionConstants.EncryptionSpecNS, - EncryptionConstants._TAG_CIPHERDATA); + NodeList dataElements = element.getElementsByTagNameNS( + EncryptionConstants.EncryptionSpecNS, + EncryptionConstants._TAG_CIPHERDATA); - // Need to get the last CipherData found, as earlier ones will - // be for elements in the KeyInfo lists + // Need to get the last CipherData found, as earlier ones will + // be for elements in the KeyInfo lists Element dataElement = - (Element) dataElements.item(dataElements.getLength() - 1); + (Element) dataElements.item(dataElements.getLength() - 1); CipherData data = newCipherData(dataElement); result = newEncryptedData(data); - try { - result.setId(element.getAttributeNS( - null, EncryptionConstants._ATT_ID)); - result.setType(new URI( - element.getAttributeNS( - null, EncryptionConstants._ATT_TYPE)).toString()); - result.setMimeType(element.getAttributeNS( - null, EncryptionConstants._ATT_MIMETYPE)); - result.setEncoding(new URI( - element.getAttributeNS( - null, Constants._ATT_ENCODING)).toString()); - } catch (URI.MalformedURIException mfue) { - // do nothing - } + result.setId(element.getAttributeNS( + null, EncryptionConstants._ATT_ID)); + result.setType( + element.getAttributeNS(null, EncryptionConstants._ATT_TYPE)); + result.setMimeType(element.getAttributeNS( + null, EncryptionConstants._ATT_MIMETYPE)); + result.setEncoding( + element.getAttributeNS(null, Constants._ATT_ENCODING)); Element encryptionMethodElement = (Element) element.getElementsByTagNameNS( @@ -2450,18 +2366,18 @@ public class XMLCipher { } // BFL 16/7/03 - simple implementation - // TODO: Work out how to handle relative URI + // TODO: Work out how to handle relative URI Element keyInfoElement = (Element) element.getElementsByTagNameNS( Constants.SignatureSpecNS, Constants._TAG_KEYINFO).item(0); if (null != keyInfoElement) { - try { - result.setKeyInfo(new KeyInfo(keyInfoElement, null)); - } catch (XMLSecurityException xse) { - throw new XMLEncryptionException("Error loading Key Info", - xse); - } + try { + result.setKeyInfo(new KeyInfo(keyInfoElement, null)); + } catch (XMLSecurityException xse) { + throw new XMLEncryptionException("Error loading Key Info", + xse); + } } // TODO: Implement @@ -2511,31 +2427,25 @@ public class XMLCipher { EncryptedKey newEncryptedKey(Element element) throws XMLEncryptionException { EncryptedKey result = null; - NodeList dataElements = element.getElementsByTagNameNS( - EncryptionConstants.EncryptionSpecNS, - EncryptionConstants._TAG_CIPHERDATA); + NodeList dataElements = element.getElementsByTagNameNS( + EncryptionConstants.EncryptionSpecNS, + EncryptionConstants._TAG_CIPHERDATA); Element dataElement = - (Element) dataElements.item(dataElements.getLength() - 1); + (Element) dataElements.item(dataElements.getLength() - 1); CipherData data = newCipherData(dataElement); result = newEncryptedKey(data); - try { - result.setId(element.getAttributeNS( - null, EncryptionConstants._ATT_ID)); - result.setType(new URI( - element.getAttributeNS( - null, EncryptionConstants._ATT_TYPE)).toString()); - result.setMimeType(element.getAttributeNS( - null, EncryptionConstants._ATT_MIMETYPE)); - result.setEncoding(new URI( - element.getAttributeNS( - null, Constants._ATT_ENCODING)).toString()); - result.setRecipient(element.getAttributeNS( - null, EncryptionConstants._ATT_RECIPIENT)); - } catch (URI.MalformedURIException mfue) { - // do nothing - } + result.setId(element.getAttributeNS( + null, EncryptionConstants._ATT_ID)); + result.setType( + element.getAttributeNS(null, EncryptionConstants._ATT_TYPE)); + result.setMimeType(element.getAttributeNS( + null, EncryptionConstants._ATT_MIMETYPE)); + result.setEncoding( + element.getAttributeNS(null, Constants._ATT_ENCODING)); + result.setRecipient(element.getAttributeNS( + null, EncryptionConstants._ATT_RECIPIENT)); Element encryptionMethodElement = (Element) element.getElementsByTagNameNS( @@ -2550,12 +2460,12 @@ public class XMLCipher { (Element) element.getElementsByTagNameNS( Constants.SignatureSpecNS, Constants._TAG_KEYINFO).item(0); if (null != keyInfoElement) { - try { - result.setKeyInfo(new KeyInfo(keyInfoElement, null)); - } catch (XMLSecurityException xse) { - throw new XMLEncryptionException("Error loading Key Info", - xse); - } + try { + result.setKeyInfo(new KeyInfo(keyInfoElement, null)); + } catch (XMLSecurityException xse) { + throw new XMLEncryptionException + ("Error loading Key Info", xse); + } } // TODO: Implement @@ -2581,7 +2491,8 @@ public class XMLCipher { EncryptionConstants.EncryptionSpecNS, EncryptionConstants._TAG_CARRIEDKEYNAME).item(0); if (null != carriedNameElement) { - result.setCarriedName(carriedNameElement.getNodeValue()); + result.setCarriedName + (carriedNameElement.getFirstChild().getNodeValue()); } return (result); @@ -2680,13 +2591,8 @@ public class XMLCipher { EncryptionProperty newEncryptionProperty(Element element) { EncryptionProperty result = newEncryptionProperty(); - try { - result.setTarget(new URI( - element.getAttributeNS( - null, EncryptionConstants._ATT_TARGET)).toString()); - } catch (URI.MalformedURIException mfue) { - // do nothing - } + result.setTarget( + element.getAttributeNS(null, EncryptionConstants._ATT_TARGET)); result.setId(element.getAttributeNS( null, EncryptionConstants._ATT_ID)); // TODO: Make this lot work... @@ -2943,7 +2849,7 @@ public class XMLCipher { } catch (URI.MalformedURIException mfue) { //complain } - algorithm = tmpAlgorithm.toString(); + algorithmURI = tmpAlgorithm.toString(); } // @@ -3183,7 +3089,7 @@ public class XMLCipher { _contextDocument, EncryptionConstants.EncryptionSpecNS, EncryptionConstants._TAG_CIPHERVALUE); result.appendChild(_contextDocument.createTextNode( - new String(cipherValue))); + cipherValue)); return (result); } @@ -3247,8 +3153,7 @@ public class XMLCipher { } if (null != super.getType()) { result.setAttributeNS( - null, EncryptionConstants._ATT_TYPE, - super.getType().toString()); + null, EncryptionConstants._ATT_TYPE, super.getType()); } if (null != super.getMimeType()) { result.setAttributeNS( @@ -3258,7 +3163,7 @@ public class XMLCipher { if (null != super.getEncoding()) { result.setAttributeNS( null, EncryptionConstants._ATT_ENCODING, - super.getEncoding().toString()); + super.getEncoding()); } if (null != super.getEncryptionMethod()) { result.appendChild(((EncryptionMethodImpl) @@ -3383,8 +3288,7 @@ public class XMLCipher { } if (null != super.getType()) { result.setAttributeNS( - null, EncryptionConstants._ATT_TYPE, - super.getType().toString()); + null, EncryptionConstants._ATT_TYPE, super.getType()); } if (null != super.getMimeType()) { result.setAttributeNS(null, @@ -3392,7 +3296,7 @@ public class XMLCipher { } if (null != super.getEncoding()) { result.setAttributeNS(null, Constants._ATT_ENCODING, - super.getEncoding().toString()); + super.getEncoding()); } if (null != getRecipient()) { result.setAttributeNS(null, @@ -3468,13 +3372,17 @@ public class XMLCipher { * @param type */ public void setType(String type) { - URI tmpType = null; - try { - tmpType = new URI(type); - } catch (URI.MalformedURIException mfue) { - // complain + if (type == null || type.length() == 0) { + this.type = null; + } else { + URI tmpType = null; + try { + tmpType = new URI(type); + } catch (URI.MalformedURIException mfue) { + // complain + } + this.type = tmpType.toString(); } - this.type = tmpType.toString(); } /** * @@ -3502,13 +3410,17 @@ public class XMLCipher { * @param encoding */ public void setEncoding(String encoding) { - URI tmpEncoding = null; - try { - tmpEncoding = new URI(encoding); - } catch (URI.MalformedURIException mfue) { - // complain + if (encoding == null || encoding.length() == 0) { + this.encoding = null; + } else { + URI tmpEncoding = null; + try { + tmpEncoding = new URI(encoding); + } catch (URI.MalformedURIException mfue) { + // complain + } + this.encoding = tmpEncoding.toString(); } - this.encoding = tmpEncoding.toString(); } /** * @@ -3635,7 +3547,7 @@ public class XMLCipher { _contextDocument, EncryptionConstants.EncryptionSpecNS, EncryptionConstants._TAG_ENCRYPTIONMETHOD); result.setAttributeNS(null, EncryptionConstants._ATT_ALGORITHM, - algorithm.toString()); + algorithm); if (keySize > 0) { result.appendChild( ElementProxy.createElementForFamily(_contextDocument, @@ -3735,8 +3647,7 @@ public class XMLCipher { private class EncryptionPropertyImpl implements EncryptionProperty { private String target = null; private String id = null; - private String attributeName = null; - private String attributeValue = null; + private HashMap attributeMap = new HashMap(); private List encryptionInformation = null; /** @@ -3752,13 +3663,24 @@ public class XMLCipher { } /** @inheritDoc */ public void setTarget(String target) { - URI tmpTarget = null; - try { - tmpTarget = new URI(target); - } catch (URI.MalformedURIException mfue) { - // complain + if (target == null || target.length() == 0) { + this.target = null; + } else if (target.startsWith("#")) { + /* + * This is a same document URI reference. Do not parse, + * because com.sun.org.apache.xml.internal.utils.URI considers this an + * illegal URI because it has no scheme. + */ + this.target = target; + } else { + URI tmpTarget = null; + try { + tmpTarget = new URI(target); + } catch (URI.MalformedURIException mfue) { + // complain + } + this.target = tmpTarget.toString(); } - this.target = tmpTarget.toString(); } /** @inheritDoc */ public String getId() { @@ -3770,12 +3692,11 @@ public class XMLCipher { } /** @inheritDoc */ public String getAttribute(String attribute) { - return (attributeValue); + return (String) attributeMap.get(attribute); } /** @inheritDoc */ public void setAttribute(String attribute, String value) { - attributeName = attribute; - attributeValue = value; + attributeMap.put(attribute, value); } /** @inheritDoc */ public Iterator getEncryptionInformation() { @@ -3805,7 +3726,7 @@ public class XMLCipher { EncryptionConstants._TAG_ENCRYPTIONPROPERTY); if (null != target) { result.setAttributeNS(null, EncryptionConstants._ATT_TARGET, - target.toString()); + target); } if (null != id) { result.setAttributeNS(null, EncryptionConstants._ATT_ID, @@ -3839,7 +3760,13 @@ public class XMLCipher { * @param doc */ public TransformsImpl(Document doc) { - super(doc); + if (doc == null) { + throw new RuntimeException("Document is null"); + } + + this._doc = doc; + this._constructionElement = createElementForFamilyLocal(this._doc, + this.getBaseNamespace(), this.getBaseLocalName()); } /** * diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/XMLCipherInput.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/XMLCipherInput.java index 9d1db588eb6..65b9a604b66 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/XMLCipherInput.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/XMLCipherInput.java @@ -108,84 +108,78 @@ public class XMLCipherInput { return null; } - /** - * Internal method to get bytes in decryption mode + /** + * Internal method to get bytes in decryption mode * @return the decripted bytes * @throws XMLEncryptionException - */ + */ + private byte[] getDecryptBytes() throws XMLEncryptionException { - private byte[] getDecryptBytes() throws XMLEncryptionException { - - String base64EncodedEncryptedOctets = null; + String base64EncodedEncryptedOctets = null; if (_cipherData.getDataType() == CipherData.REFERENCE_TYPE) { - // Fun time! - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Found a reference type CipherData"); - CipherReference cr = _cipherData.getCipherReference(); + // Fun time! + logger.log(java.util.logging.Level.FINE, "Found a reference type CipherData"); + CipherReference cr = _cipherData.getCipherReference(); - // Need to wrap the uri in an Attribute node so that we can - // Pass to the resource resolvers + // Need to wrap the uri in an Attribute node so that we can + // Pass to the resource resolvers - Attr uriAttr = cr.getURIAsAttr(); - XMLSignatureInput input = null; + Attr uriAttr = cr.getURIAsAttr(); + XMLSignatureInput input = null; - try { - ResourceResolver resolver = - ResourceResolver.getInstance(uriAttr, null); - input = resolver.resolve(uriAttr, null); - } catch (ResourceResolverException ex) { - throw new XMLEncryptionException("empty", ex); - } + try { + ResourceResolver resolver = + ResourceResolver.getInstance(uriAttr, null); + input = resolver.resolve(uriAttr, null); + } catch (ResourceResolverException ex) { + throw new XMLEncryptionException("empty", ex); + } - if (input != null) { - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Managed to resolve URI \"" + cr.getURI() + "\""); - } - else { - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Failed to resolve URI \"" + cr.getURI() + "\""); - } + if (input != null) { + logger.log(java.util.logging.Level.FINE, "Managed to resolve URI \"" + cr.getURI() + "\""); + } else { + logger.log(java.util.logging.Level.FINE, "Failed to resolve URI \"" + cr.getURI() + "\""); + } - // Lets see if there are any transforms - Transforms transforms = cr.getTransforms(); - if (transforms != null) { - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Have transforms in cipher reference"); - try { - com.sun.org.apache.xml.internal.security.transforms.Transforms dsTransforms = - transforms.getDSTransforms(); - input = dsTransforms.performTransforms(input); - } catch (TransformationException ex) { - throw new XMLEncryptionException("empty", ex); - } - } - - try { - return input.getBytes(); - } - catch (IOException ex) { - throw new XMLEncryptionException("empty", ex); - } catch (CanonicalizationException ex) { - throw new XMLEncryptionException("empty", ex); - } - - // retrieve the cipher text - } else if (_cipherData.getDataType() == CipherData.VALUE_TYPE) { - CipherValue cv = _cipherData.getCipherValue(); - base64EncodedEncryptedOctets = new String(cv.getValue()); - } else { - throw new XMLEncryptionException("CipherData.getDataType() returned unexpected value"); + // Lets see if there are any transforms + Transforms transforms = cr.getTransforms(); + if (transforms != null) { + logger.log(java.util.logging.Level.FINE, "Have transforms in cipher reference"); + try { + com.sun.org.apache.xml.internal.security.transforms.Transforms dsTransforms = + transforms.getDSTransforms(); + input = dsTransforms.performTransforms(input); + } catch (TransformationException ex) { + throw new XMLEncryptionException("empty", ex); } + } - if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypted octets:\n" + base64EncodedEncryptedOctets); + try { + return input.getBytes(); + } catch (IOException ex) { + throw new XMLEncryptionException("empty", ex); + } catch (CanonicalizationException ex) { + throw new XMLEncryptionException("empty", ex); + } + + // retrieve the cipher text + } else if (_cipherData.getDataType() == CipherData.VALUE_TYPE) { + base64EncodedEncryptedOctets = + _cipherData.getCipherValue().getValue(); + } else { + throw new XMLEncryptionException("CipherData.getDataType() returned unexpected value"); + } + + logger.log(java.util.logging.Level.FINE, "Encrypted octets:\n" + base64EncodedEncryptedOctets); byte[] encryptedBytes = null; - try { - encryptedBytes = Base64.decode(base64EncodedEncryptedOctets); + encryptedBytes = Base64.decode(base64EncodedEncryptedOctets); } catch (Base64DecodingException bde) { throw new XMLEncryptionException("empty", bde); } - return (encryptedBytes); - - } - + return (encryptedBytes); + } } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/ContentHandlerAlreadyRegisteredException.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/ContentHandlerAlreadyRegisteredException.java index e071b1474c6..6477d9bba2c 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/ContentHandlerAlreadyRegisteredException.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/ContentHandlerAlreadyRegisteredException.java @@ -2,7 +2,6 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ - /* * Copyright 1999-2004 The Apache Software Foundation. * @@ -28,7 +27,7 @@ import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; /** * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class ContentHandlerAlreadyRegisteredException extends XMLSecurityException { diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/KeyInfo.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/KeyInfo.java index 1750257f625..cf588b8d488 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/KeyInfo.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/KeyInfo.java @@ -25,6 +25,8 @@ package com.sun.org.apache.xml.internal.security.keys; import java.security.PublicKey; import java.security.cert.X509Certificate; import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; import java.util.List; import javax.crypto.SecretKey; @@ -88,15 +90,22 @@ import org.w3c.dom.NodeList; * The containsXXX() methods return whether the KeyInfo * contains the corresponding type. * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class KeyInfo extends SignatureElementProxy { /** {@link java.util.logging} logging facility */ static java.util.logging.Logger log = java.util.logging.Logger.getLogger(KeyInfo.class.getName()); + List x509Datas=null; + List encryptedKeys=null; - + static final List nullList; + static { + List list = new ArrayList(); + list.add(null); + nullList = Collections.unmodifiableList(list); + } /** * Constructor KeyInfo @@ -108,7 +117,6 @@ public class KeyInfo extends SignatureElementProxy { XMLUtils.addReturnToElement(this._constructionElement); - } /** @@ -119,8 +127,8 @@ public class KeyInfo extends SignatureElementProxy { * @throws XMLSecurityException */ public KeyInfo(Element element, String BaseURI) throws XMLSecurityException { - super(element, BaseURI); + // _storageResolvers.add(null); } @@ -131,7 +139,7 @@ public class KeyInfo extends SignatureElementProxy { */ public void setId(String Id) { - if ((this._state == MODE_SIGN) && (Id != null)) { + if ((Id != null)) { this._constructionElement.setAttributeNS(null, Constants._ATT_ID, Id); IdResolver.registerElementById(this._constructionElement, Id); } @@ -162,10 +170,8 @@ public class KeyInfo extends SignatureElementProxy { */ public void add(KeyName keyname) { - if (this._state == MODE_SIGN) { this._constructionElement.appendChild(keyname.getElement()); XMLUtils.addReturnToElement(this._constructionElement); - } } /** @@ -219,11 +225,8 @@ public class KeyInfo extends SignatureElementProxy { * @param keyvalue */ public void add(KeyValue keyvalue) { - - if (this._state == MODE_SIGN) { this._constructionElement.appendChild(keyvalue.getElement()); XMLUtils.addReturnToElement(this._constructionElement); - } } /** @@ -241,11 +244,8 @@ public class KeyInfo extends SignatureElementProxy { * @param mgmtdata */ public void add(MgmtData mgmtdata) { - - if (this._state == MODE_SIGN) { this._constructionElement.appendChild(mgmtdata.getElement()); XMLUtils.addReturnToElement(this._constructionElement); - } } /** @@ -254,11 +254,8 @@ public class KeyInfo extends SignatureElementProxy { * @param pgpdata */ public void add(PGPData pgpdata) { - - if (this._state == MODE_SIGN) { this._constructionElement.appendChild(pgpdata.getElement()); XMLUtils.addReturnToElement(this._constructionElement); - } } /** @@ -279,11 +276,8 @@ public class KeyInfo extends SignatureElementProxy { * @param retrievalmethod */ public void add(RetrievalMethod retrievalmethod) { - - if (this._state == MODE_SIGN) { this._constructionElement.appendChild(retrievalmethod.getElement()); XMLUtils.addReturnToElement(this._constructionElement); - } } /** @@ -292,11 +286,8 @@ public class KeyInfo extends SignatureElementProxy { * @param spkidata */ public void add(SPKIData spkidata) { - - if (this._state == MODE_SIGN) { this._constructionElement.appendChild(spkidata.getElement()); XMLUtils.addReturnToElement(this._constructionElement); - } } /** @@ -305,11 +296,11 @@ public class KeyInfo extends SignatureElementProxy { * @param x509data */ public void add(X509Data x509data) { - - if (this._state == MODE_SIGN) { + if (x509Datas==null) + x509Datas=new ArrayList(); + x509Datas.add(x509data); this._constructionElement.appendChild(x509data.getElement()); XMLUtils.addReturnToElement(this._constructionElement); - } } /** @@ -321,12 +312,11 @@ public class KeyInfo extends SignatureElementProxy { public void add(EncryptedKey encryptedKey) throws XMLEncryptionException { - - if (this._state == MODE_SIGN) { + if (encryptedKeys==null) + encryptedKeys=new ArrayList(); + encryptedKeys.add(encryptedKey); XMLCipher cipher = XMLCipher.getInstance(); this._constructionElement.appendChild(cipher.martial(encryptedKey)); - } - } /** @@ -335,11 +325,8 @@ public class KeyInfo extends SignatureElementProxy { * @param element */ public void addUnknownElement(Element element) { - - if (this._state == MODE_SIGN) { this._constructionElement.appendChild(element); XMLUtils.addReturnToElement(this._constructionElement); - } } /** @@ -403,6 +390,9 @@ public class KeyInfo extends SignatureElementProxy { *@return the number of the X509Data tags */ public int lengthX509Data() { + if (x509Datas!=null) { + return x509Datas.size(); + } return this.length(Constants.SignatureSpecNS, Constants._TAG_X509DATA); } @@ -550,7 +540,9 @@ public class KeyInfo extends SignatureElementProxy { * @throws XMLSecurityException */ public X509Data itemX509Data(int i) throws XMLSecurityException { - + if (x509Datas!=null) { + return (X509Data) x509Datas.get(i); + } Element e = XMLUtils.selectDsNode(this._constructionElement.getFirstChild(), Constants._TAG_X509DATA,i); @@ -569,7 +561,9 @@ public class KeyInfo extends SignatureElementProxy { */ public EncryptedKey itemEncryptedKey(int i) throws XMLSecurityException { - + if (encryptedKeys!=null) { + return (EncryptedKey) encryptedKeys.get(i); + } Element e = XMLUtils.selectXencNode(this._constructionElement.getFirstChild(), EncryptionConstants._TAG_ENCRYPTEDKEY,i); @@ -707,20 +701,20 @@ public class KeyInfo extends SignatureElementProxy { PublicKey pk = this.getPublicKeyFromInternalResolvers(); if (pk != null) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "I could find a key using the per-KeyInfo key resolvers"); + log.log(java.util.logging.Level.FINE, "I could find a key using the per-KeyInfo key resolvers"); return pk; } - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "I couldn't find a key using the per-KeyInfo key resolvers"); + log.log(java.util.logging.Level.FINE, "I couldn't find a key using the per-KeyInfo key resolvers"); pk = this.getPublicKeyFromStaticResolvers(); if (pk != null) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "I could find a key using the system-wide key resolvers"); + log.log(java.util.logging.Level.FINE, "I could find a key using the system-wide key resolvers"); return pk; } - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "I couldn't find a key using the system-wide key resolvers"); + log.log(java.util.logging.Level.FINE, "I couldn't find a key using the system-wide key resolvers"); return null; } @@ -732,46 +726,29 @@ public class KeyInfo extends SignatureElementProxy { * @throws KeyResolverException */ PublicKey getPublicKeyFromStaticResolvers() throws KeyResolverException { - - for (int i = 0; i < KeyResolver.length(); i++) { - KeyResolver keyResolver = KeyResolver.item(i); + int length=KeyResolver.length(); + int storageLength=this._storageResolvers.size(); + Iterator it= KeyResolver.iterator(); + for (int i = 0; i < length; i++) { + KeyResolverSpi keyResolver = (KeyResolverSpi) it.next(); Node currentChild=this._constructionElement.getFirstChild(); + String uri= this.getBaseURI(); while (currentChild!=null) { if (currentChild.getNodeType() == Node.ELEMENT_NODE) { - if (this._storageResolvers.size() == 0) { - - // if we do not have storage resolvers, we verify with null - StorageResolver storage = null; - - if (keyResolver.canResolve((Element) currentChild, - this.getBaseURI(), storage)) { - PublicKey pk = - keyResolver.resolvePublicKey((Element) currentChild, - this.getBaseURI(), - storage); - - if (pk != null) { - return pk; - } - } - } else { - for (int k = 0; k < this._storageResolvers.size(); k++) { + for (int k = 0; k < storageLength; k++) { StorageResolver storage = (StorageResolver) this._storageResolvers.get(k); - if (keyResolver.canResolve((Element) currentChild, - this.getBaseURI(), storage)) { - PublicKey pk = - keyResolver.resolvePublicKey((Element) currentChild, - this.getBaseURI(), + PublicKey pk = + keyResolver.engineLookupAndResolvePublicKey((Element) currentChild, + uri, storage); - if (pk != null) { - return pk; - } + if (pk != null) { + KeyResolver.hit(it); + return pk; } } - } } currentChild=currentChild.getNextSibling(); } @@ -786,50 +763,27 @@ public class KeyInfo extends SignatureElementProxy { * @throws KeyResolverException */ PublicKey getPublicKeyFromInternalResolvers() throws KeyResolverException { - - for (int i = 0; i < this.lengthInternalKeyResolver(); i++) { + int length=lengthInternalKeyResolver(); + int storageLength=this._storageResolvers.size(); + for (int i = 0; i < length; i++) { KeyResolverSpi keyResolver = this.itemInternalKeyResolver(i); - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Try " + keyResolver.getClass().getName()); + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Try " + keyResolver.getClass().getName()); Node currentChild=this._constructionElement.getFirstChild(); + String uri=this.getBaseURI(); while (currentChild!=null) { if (currentChild.getNodeType() == Node.ELEMENT_NODE) { - if (this._storageResolvers.size() == 0) { - - // if we do not have storage resolvers, we verify with null - StorageResolver storage = null; - - if (keyResolver.engineCanResolve((Element) currentChild, - this.getBaseURI(), - storage)) { - PublicKey pk = - keyResolver - .engineResolvePublicKey((Element) currentChild, this - .getBaseURI(), storage); + for (int k = 0; k < storageLength; k++) { + StorageResolver storage = + (StorageResolver) this._storageResolvers.get(k); + PublicKey pk = keyResolver + .engineLookupAndResolvePublicKey((Element) currentChild, uri, storage); if (pk != null) { - return pk; + return pk; } } - } else { - for (int k = 0; k < this._storageResolvers.size(); k++) { - StorageResolver storage = - (StorageResolver) this._storageResolvers.get(k); - - if (keyResolver.engineCanResolve((Element) currentChild, - this.getBaseURI(), - storage)) { - PublicKey pk = keyResolver - .engineResolvePublicKey((Element) currentChild, this - .getBaseURI(), storage); - - if (pk != null) { - return pk; - } - } - } - } } currentChild=currentChild.getNextSibling(); } @@ -850,12 +804,12 @@ public class KeyInfo extends SignatureElementProxy { X509Certificate cert = this.getX509CertificateFromInternalResolvers(); if (cert != null) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, + log.log(java.util.logging.Level.FINE, "I could find a X509Certificate using the per-KeyInfo key resolvers"); return cert; } - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, + log.log(java.util.logging.Level.FINE, "I couldn't find a X509Certificate using the per-KeyInfo key resolvers"); @@ -863,12 +817,12 @@ public class KeyInfo extends SignatureElementProxy { cert = this.getX509CertificateFromStaticResolvers(); if (cert != null) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, + log.log(java.util.logging.Level.FINE, "I could find a X509Certificate using the system-wide key resolvers"); return cert; } - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, + log.log(java.util.logging.Level.FINE, "I couldn't find a X509Certificate using the system-wide key resolvers"); @@ -885,53 +839,44 @@ public class KeyInfo extends SignatureElementProxy { */ X509Certificate getX509CertificateFromStaticResolvers() throws KeyResolverException { - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Start getX509CertificateFromStaticResolvers() with " + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Start getX509CertificateFromStaticResolvers() with " + KeyResolver.length() + " resolvers"); + String uri=this.getBaseURI(); + int length= KeyResolver.length(); + int storageLength=this._storageResolvers.size(); + Iterator it = KeyResolver.iterator(); + for (int i = 0; i com.sun.org.apache.xml.internal.security.keys package. * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class KeyUtils { diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyInfoContent.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyInfoContent.java index ba9769043a3..4d5a7a6b975 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyInfoContent.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyInfoContent.java @@ -2,7 +2,6 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ - /* * Copyright 1999-2004 The Apache Software Foundation. * @@ -28,7 +27,7 @@ package com.sun.org.apache.xml.internal.security.keys.content; /** * Empty interface just to identify Elements that can be cildren of ds:KeyInfo. * - * @author $Author: blautenb $ + * @author $Author: mullan $ */ public interface KeyInfoContent { } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyName.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyName.java index dfff3c32211..6794ea67586 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyName.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyName.java @@ -20,25 +20,18 @@ */ package com.sun.org.apache.xml.internal.security.keys.content; - - import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; import com.sun.org.apache.xml.internal.security.utils.Constants; import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy; import org.w3c.dom.Document; import org.w3c.dom.Element; - /** * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class KeyName extends SignatureElementProxy implements KeyInfoContent { - /** {@link java.util.logging} logging facility */ - static java.util.logging.Logger log = - java.util.logging.Logger.getLogger(KeyName.class.getName()); - /** * Constructor KeyName * diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyValue.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyValue.java index ab8b959f75c..0d3ee810d23 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyValue.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyValue.java @@ -20,11 +20,8 @@ */ package com.sun.org.apache.xml.internal.security.keys.content; - - import java.security.PublicKey; - import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; import com.sun.org.apache.xml.internal.security.keys.content.keyvalues.DSAKeyValue; import com.sun.org.apache.xml.internal.security.keys.content.keyvalues.RSAKeyValue; @@ -34,140 +31,131 @@ import com.sun.org.apache.xml.internal.security.utils.XMLUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; - /** * The KeyValue element contains a single public key that may be useful in * validating the signature. Structured formats for defining DSA (REQUIRED) * and RSA (RECOMMENDED) public keys are defined in Signature Algorithms * (section 6.4). The KeyValue element may include externally defined public - * keys values represented as PCDATA or element types from an external namespace. + * keys values represented as PCDATA or element types from an external + * namespace. * - * @author $Author: vishal $ + * @author $Author: mullan $ */ public class KeyValue extends SignatureElementProxy implements KeyInfoContent { - /** {@link java.util.logging} logging facility */ - static java.util.logging.Logger log = - java.util.logging.Logger.getLogger(KeyValue.class.getName()); + /** + * Constructor KeyValue + * + * @param doc + * @param dsaKeyValue + */ + public KeyValue(Document doc, DSAKeyValue dsaKeyValue) { - /** - * Constructor KeyValue - * - * @param doc - * @param dsaKeyValue - */ - public KeyValue(Document doc, DSAKeyValue dsaKeyValue) { + super(doc); - super(doc); + XMLUtils.addReturnToElement(this._constructionElement); + this._constructionElement.appendChild(dsaKeyValue.getElement()); + XMLUtils.addReturnToElement(this._constructionElement); + } - XMLUtils.addReturnToElement(this._constructionElement); - this._constructionElement.appendChild(dsaKeyValue.getElement()); - XMLUtils.addReturnToElement(this._constructionElement); - } + /** + * Constructor KeyValue + * + * @param doc + * @param rsaKeyValue + */ + public KeyValue(Document doc, RSAKeyValue rsaKeyValue) { - /** - * Constructor KeyValue - * - * @param doc - * @param rsaKeyValue - */ - public KeyValue(Document doc, RSAKeyValue rsaKeyValue) { + super(doc); - super(doc); + XMLUtils.addReturnToElement(this._constructionElement); + this._constructionElement.appendChild(rsaKeyValue.getElement()); + XMLUtils.addReturnToElement(this._constructionElement); + } - XMLUtils.addReturnToElement(this._constructionElement); - this._constructionElement.appendChild(rsaKeyValue.getElement()); - XMLUtils.addReturnToElement(this._constructionElement); - } + /** + * Constructor KeyValue + * + * @param doc + * @param unknownKeyValue + */ + public KeyValue(Document doc, Element unknownKeyValue) { - /** - * Constructor KeyValue - * - * @param doc - * @param unknownKeyValue - */ - public KeyValue(Document doc, Element unknownKeyValue) { + super(doc); - super(doc); + XMLUtils.addReturnToElement(this._constructionElement); + this._constructionElement.appendChild(unknownKeyValue); + XMLUtils.addReturnToElement(this._constructionElement); + } - XMLUtils.addReturnToElement(this._constructionElement); - this._constructionElement.appendChild(unknownKeyValue); - XMLUtils.addReturnToElement(this._constructionElement); - } + /** + * Constructor KeyValue + * + * @param doc + * @param pk + */ + public KeyValue(Document doc, PublicKey pk) { - /** - * Constructor KeyValue - * - * @param doc - * @param pk - */ - public KeyValue(Document doc, PublicKey pk) { + super(doc); - super(doc); + XMLUtils.addReturnToElement(this._constructionElement); - XMLUtils.addReturnToElement(this._constructionElement); + if (pk instanceof java.security.interfaces.DSAPublicKey) { + DSAKeyValue dsa = new DSAKeyValue(this._doc, pk); - if (pk instanceof java.security.interfaces.DSAPublicKey) { - DSAKeyValue dsa = new DSAKeyValue(this._doc, pk); + this._constructionElement.appendChild(dsa.getElement()); + XMLUtils.addReturnToElement(this._constructionElement); + } else if (pk instanceof java.security.interfaces.RSAPublicKey) { + RSAKeyValue rsa = new RSAKeyValue(this._doc, pk); - this._constructionElement.appendChild(dsa.getElement()); - XMLUtils.addReturnToElement(this._constructionElement); - } else if (pk instanceof java.security.interfaces.RSAPublicKey) { - RSAKeyValue rsa = new RSAKeyValue(this._doc, pk); + this._constructionElement.appendChild(rsa.getElement()); + XMLUtils.addReturnToElement(this._constructionElement); + } + } - this._constructionElement.appendChild(rsa.getElement()); - XMLUtils.addReturnToElement(this._constructionElement); - } - } - - /** - * Constructor KeyValue - * - * @param element - * @param BaseURI - * @throws XMLSecurityException - */ - public KeyValue(Element element, String BaseURI) + /** + * Constructor KeyValue + * + * @param element + * @param BaseURI + * @throws XMLSecurityException + */ + public KeyValue(Element element, String BaseURI) throws XMLSecurityException { - super(element, BaseURI); - } + super(element, BaseURI); + } - /** - * Method getPublicKey - * - * @return the public key - * @throws XMLSecurityException - */ - public PublicKey getPublicKey() throws XMLSecurityException { + /** + * Method getPublicKey + * + * @return the public key + * @throws XMLSecurityException + */ + public PublicKey getPublicKey() throws XMLSecurityException { + Element rsa = XMLUtils.selectDsNode + (this._constructionElement.getFirstChild(), + Constants._TAG_RSAKEYVALUE,0); - Element rsa = XMLUtils.selectDsNode(this._constructionElement.getFirstChild(), - Constants._TAG_RSAKEYVALUE,0); - - if (rsa != null) { - RSAKeyValue kv = new RSAKeyValue(rsa, - this._baseURI); - + if (rsa != null) { + RSAKeyValue kv = new RSAKeyValue(rsa, this._baseURI); return kv.getPublicKey(); - } + } - Element dsa = XMLUtils.selectDsNode(this._constructionElement, - Constants._TAG_DSAKEYVALUE,0); - - - if (dsa != null) { - DSAKeyValue kv = new DSAKeyValue(dsa, - this._baseURI); + Element dsa = XMLUtils.selectDsNode + (this._constructionElement.getFirstChild(), + Constants._TAG_DSAKEYVALUE,0); + if (dsa != null) { + DSAKeyValue kv = new DSAKeyValue(dsa, this._baseURI); return kv.getPublicKey(); - } + } + return null; + } - return null; - } - - /** @inheritDoc */ - public String getBaseLocalName() { - return Constants._TAG_KEYVALUE; - } + /** @inheritDoc */ + public String getBaseLocalName() { + return Constants._TAG_KEYVALUE; + } } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/MgmtData.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/MgmtData.java index 52662d9129b..185e3557170 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/MgmtData.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/MgmtData.java @@ -20,25 +20,18 @@ */ package com.sun.org.apache.xml.internal.security.keys.content; - - import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; import com.sun.org.apache.xml.internal.security.utils.Constants; import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy; import org.w3c.dom.Document; import org.w3c.dom.Element; - /** * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class MgmtData extends SignatureElementProxy implements KeyInfoContent { - /** {@link java.util.logging} logging facility */ - static java.util.logging.Logger log = - java.util.logging.Logger.getLogger(MgmtData.class.getName()); - /** * Constructor MgmtData * diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/PGPData.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/PGPData.java index 7829c36527f..010c907a8d9 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/PGPData.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/PGPData.java @@ -20,25 +20,18 @@ */ package com.sun.org.apache.xml.internal.security.keys.content; - - import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; import com.sun.org.apache.xml.internal.security.utils.Constants; import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy; import org.w3c.dom.Element; - /** * - * @author $Author: raul $ + * @author $Author: mullan $ * $todo$ Implement */ public class PGPData extends SignatureElementProxy implements KeyInfoContent { - /** {@link java.util.logging} logging facility */ - static java.util.logging.Logger log = - java.util.logging.Logger.getLogger(PGPData.class.getName()); - /** * Constructor PGPData * diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/RetrievalMethod.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/RetrievalMethod.java index feb8b26d3b5..3c4956b7787 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/RetrievalMethod.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/RetrievalMethod.java @@ -20,9 +20,6 @@ */ package com.sun.org.apache.xml.internal.security.keys.content; - - - import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException; import com.sun.org.apache.xml.internal.security.transforms.Transforms; @@ -33,17 +30,13 @@ import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; - /** * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class RetrievalMethod extends SignatureElementProxy implements KeyInfoContent { - /** {@link java.util.logging} logging facility */ - static java.util.logging.Logger log = - java.util.logging.Logger.getLogger(RetrievalMethod.class.getName()); //J- /** DSA retrieval */ public static final String TYPE_DSA = Constants.SignatureSpecNS + "DSAKeyValue"; @@ -133,7 +126,7 @@ public class RetrievalMethod extends SignatureElementProxy try { Element transformsElem = - XMLUtils.selectDsNode(this._constructionElement, + XMLUtils.selectDsNode(this._constructionElement.getFirstChild(), Constants ._TAG_TRANSFORMS, 0); diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/SPKIData.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/SPKIData.java index 64bb23c6231..95cef8d5491 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/SPKIData.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/SPKIData.java @@ -20,25 +20,18 @@ */ package com.sun.org.apache.xml.internal.security.keys.content; - - import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; import com.sun.org.apache.xml.internal.security.utils.Constants; import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy; import org.w3c.dom.Element; - /** * - * @author $Author: raul $ + * @author $Author: mullan $ * $todo$ implement */ public class SPKIData extends SignatureElementProxy implements KeyInfoContent { - /** {@link java.util.logging} logging facility */ - static java.util.logging.Logger log = - java.util.logging.Logger.getLogger(SPKIData.class.getName()); - /** * Constructor SPKIData * diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/X509Data.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/X509Data.java index d60f3ad6518..199b1dcb020 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/X509Data.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/X509Data.java @@ -41,7 +41,7 @@ import org.w3c.dom.Node; /** * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class X509Data extends SignatureElementProxy implements KeyInfoContent { @@ -72,60 +72,17 @@ public class X509Data extends SignatureElementProxy implements KeyInfoContent { throws XMLSecurityException { super(element, BaseURI); - - boolean noElements=true; Node sibling=this._constructionElement.getFirstChild(); while (sibling!=null) { if (sibling.getNodeType()!=Node.ELEMENT_NODE) { sibling=sibling.getNextSibling(); continue; } - noElements=false; - Element currentElem = (Element) sibling; - sibling=sibling.getNextSibling(); - String localname = currentElem.getLocalName(); - - if (currentElem.getNamespaceURI().equals(Constants.SignatureSpecNS)) { - if (localname.equals(Constants._TAG_X509ISSUERSERIAL)) { - XMLX509IssuerSerial is = new XMLX509IssuerSerial(currentElem, - BaseURI); - - this.add(is); - } else if (localname.equals(Constants._TAG_X509SKI)) { - XMLX509SKI ski = new XMLX509SKI(currentElem, BaseURI); - - this.add(ski); - } else if (localname.equals(Constants._TAG_X509SUBJECTNAME)) { - XMLX509SubjectName sn = new XMLX509SubjectName(currentElem, - BaseURI); - - this.add(sn); - } else if (localname.equals(Constants._TAG_X509CERTIFICATE)) { - XMLX509Certificate cert = new XMLX509Certificate(currentElem, - BaseURI); - - this.add(cert); - } else if (localname.equals(Constants._TAG_X509CRL)) { - XMLX509CRL crl = new XMLX509CRL(currentElem, BaseURI); - - this.add(crl); - } else { - log.log(java.util.logging.Level.WARNING, "Found a " + currentElem.getTagName() + " element in " - + Constants._TAG_X509DATA); - this.addUnknownElement(currentElem); - } - } else { - log.log(java.util.logging.Level.WARNING, "Found a " + currentElem.getTagName() + " element in " - + Constants._TAG_X509DATA); - this.addUnknownElement(currentElem); - } + return; } - if (noElements) { - Object exArgs[] = { "Elements", Constants._TAG_X509DATA }; - - throw new XMLSecurityException("xml.WrongContent", exArgs); - } - + /* No Elements found */ + Object exArgs[] = { "Elements", Constants._TAG_X509DATA }; + throw new XMLSecurityException("xml.WrongContent", exArgs); } /** @@ -169,11 +126,9 @@ public class X509Data extends SignatureElementProxy implements KeyInfoContent { */ public void add(XMLX509IssuerSerial xmlX509IssuerSerial) { - if (this._state == MODE_SIGN) { this._constructionElement .appendChild(xmlX509IssuerSerial.getElement()); XMLUtils.addReturnToElement(this._constructionElement); - } } /** @@ -202,11 +157,8 @@ public class X509Data extends SignatureElementProxy implements KeyInfoContent { * @param xmlX509SKI */ public void add(XMLX509SKI xmlX509SKI) { - - if (this._state == MODE_SIGN) { this._constructionElement.appendChild(xmlX509SKI.getElement()); XMLUtils.addReturnToElement(this._constructionElement); - } } /** @@ -233,11 +185,8 @@ public class X509Data extends SignatureElementProxy implements KeyInfoContent { * @param xmlX509SubjectName */ public void add(XMLX509SubjectName xmlX509SubjectName) { - - if (this._state == MODE_SIGN) { this._constructionElement.appendChild(xmlX509SubjectName.getElement()); XMLUtils.addReturnToElement(this._constructionElement); - } } /** @@ -266,11 +215,8 @@ public class X509Data extends SignatureElementProxy implements KeyInfoContent { * @param xmlX509Certificate */ public void add(XMLX509Certificate xmlX509Certificate) { - - if (this._state == MODE_SIGN) { this._constructionElement.appendChild(xmlX509Certificate.getElement()); XMLUtils.addReturnToElement(this._constructionElement); - } } /** @@ -288,11 +234,8 @@ public class X509Data extends SignatureElementProxy implements KeyInfoContent { * @param xmlX509CRL */ public void add(XMLX509CRL xmlX509CRL) { - - if (this._state == MODE_SIGN) { this._constructionElement.appendChild(xmlX509CRL.getElement()); XMLUtils.addReturnToElement(this._constructionElement); - } } /** @@ -301,11 +244,8 @@ public class X509Data extends SignatureElementProxy implements KeyInfoContent { * @param element */ public void addUnknownElement(Element element) { - - if (this._state == MODE_SIGN) { this._constructionElement.appendChild(element); XMLUtils.addReturnToElement(this._constructionElement); - } } /** @@ -479,7 +419,7 @@ public class X509Data extends SignatureElementProxy implements KeyInfoContent { * TODO implement **/ public Element itemUnknownElement(int i) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "itemUnknownElement not implemented:"+i); + log.log(java.util.logging.Level.FINE, "itemUnknownElement not implemented:"+i); return null; } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/DSAKeyValue.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/DSAKeyValue.java index 19fb7758f62..ef735c3dad6 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/DSAKeyValue.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/DSAKeyValue.java @@ -20,8 +20,6 @@ */ package com.sun.org.apache.xml.internal.security.keys.content.keyvalues; - - import java.math.BigInteger; import java.security.Key; import java.security.KeyFactory; @@ -39,18 +37,13 @@ import com.sun.org.apache.xml.internal.security.utils.XMLUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; - /** * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class DSAKeyValue extends SignatureElementProxy implements KeyValueContent { - /** {@link java.util.logging} logging facility */ - static java.util.logging.Logger log = - java.util.logging.Logger.getLogger(DSAKeyValue.class.getName()); - /** * Constructor DSAKeyValue * diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/KeyValueContent.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/KeyValueContent.java index 608758e16ce..31e761443c5 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/KeyValueContent.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/KeyValueContent.java @@ -2,7 +2,6 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ - /* * Copyright 1999-2004 The Apache Software Foundation. * @@ -32,7 +31,7 @@ import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; * * * - * @author $Author: raul $ + * @author $Author: mullan $ * */ public interface KeyValueContent { diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/RSAKeyValue.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/RSAKeyValue.java index 6fc33aded20..71b23cda593 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/RSAKeyValue.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/RSAKeyValue.java @@ -20,8 +20,6 @@ */ package com.sun.org.apache.xml.internal.security.keys.content.keyvalues; - - import java.math.BigInteger; import java.security.Key; import java.security.KeyFactory; @@ -39,19 +37,13 @@ import com.sun.org.apache.xml.internal.security.utils.XMLUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; - /** * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class RSAKeyValue extends SignatureElementProxy implements KeyValueContent { - /** {@link java.util.logging} logging facility */ - static java.util.logging.Logger log = - java.util.logging.Logger.getLogger( - RSAKeyValue.class.getName()); - /** * Constructor RSAKeyValue * diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509CRL.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509CRL.java index 7c9f5be1f69..b68c444dc08 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509CRL.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509CRL.java @@ -20,30 +20,20 @@ */ package com.sun.org.apache.xml.internal.security.keys.content.x509; - - import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; import com.sun.org.apache.xml.internal.security.utils.Constants; import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy; import org.w3c.dom.Document; import org.w3c.dom.Element; - /** * - * - * - * - * @author $Author: raul $ + * @author $Author: mullan $ * */ public class XMLX509CRL extends SignatureElementProxy implements XMLX509DataContent { - /** {@link java.util.logging} logging facility */ - static java.util.logging.Logger log = - java.util.logging.Logger.getLogger(XMLX509CRL.class.getName()); - /** * Constructor XMLX509CRL * diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509Certificate.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509Certificate.java index 51f81e52901..630d9ccc279 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509Certificate.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509Certificate.java @@ -20,8 +20,6 @@ */ package com.sun.org.apache.xml.internal.security.keys.content.x509; - - import java.io.ByteArrayInputStream; import java.security.PublicKey; import java.security.cert.CertificateException; @@ -34,18 +32,13 @@ import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy; import org.w3c.dom.Document; import org.w3c.dom.Element; - /** * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class XMLX509Certificate extends SignatureElementProxy implements XMLX509DataContent { - /** {@link java.util.logging} logging facility */ - static java.util.logging.Logger log = - java.util.logging.Logger.getLogger(XMLX509Certificate.class.getName()); - /** Field JCA_CERT_ID */ public static final String JCA_CERT_ID = "X.509"; @@ -146,23 +139,25 @@ public class XMLX509Certificate extends SignatureElementProxy return null; } - /** @inheritDoc */ - public boolean equals(Object obj) { + /** @inheritDoc */ + public boolean equals(Object obj) { - try { - if (!obj.getClass().getName().equals(this.getClass().getName())) { + if (obj == null) { return false; - } + } + if (!this.getClass().getName().equals(obj.getClass().getName())) { + return false; + } + XMLX509Certificate other = (XMLX509Certificate) obj; + try { - XMLX509Certificate other = (XMLX509Certificate) obj; - - /** $todo$ or should be create X509Certificates and use the equals() from the Certs */ - return java.security.MessageDigest.isEqual(other.getCertificateBytes(), - this.getCertificateBytes()); - } catch (XMLSecurityException ex) { - return false; - } - } + /** $todo$ or should be create X509Certificates and use the equals() from the Certs */ + return java.security.MessageDigest.isEqual + (other.getCertificateBytes(), this.getCertificateBytes()); + } catch (XMLSecurityException ex) { + return false; + } + } /** @inheritDoc */ public String getBaseLocalName() { diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509DataContent.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509DataContent.java index adbf4978fec..02bf9f82d39 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509DataContent.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509DataContent.java @@ -2,7 +2,6 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ - /* * Copyright 1999-2004 The Apache Software Foundation. * @@ -28,7 +27,7 @@ package com.sun.org.apache.xml.internal.security.keys.content.x509; /** * Just used for tagging contents that are allowed inside a ds:X509Data Element. * - * @author $Author: blautenb $ + * @author $Author: mullan $ */ public interface XMLX509DataContent { } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509IssuerSerial.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509IssuerSerial.java index d0701592d54..1d16b2b622f 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509IssuerSerial.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509IssuerSerial.java @@ -20,8 +20,6 @@ */ package com.sun.org.apache.xml.internal.security.keys.content.x509; - - import java.math.BigInteger; import java.security.cert.X509Certificate; @@ -33,148 +31,139 @@ import com.sun.org.apache.xml.internal.security.utils.XMLUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; - /** * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class XMLX509IssuerSerial extends SignatureElementProxy implements XMLX509DataContent { - /** {@link java.util.logging} logging facility */ + /** {@link java.util.logging} logging facility */ static java.util.logging.Logger log = java.util.logging.Logger.getLogger( XMLX509IssuerSerial.class.getName()); - /** - * Constructor XMLX509IssuerSerial - * - * @param element - * @param BaseURI - * @throws XMLSecurityException - */ - public XMLX509IssuerSerial(Element element, String BaseURI) + /** + * Constructor XMLX509IssuerSerial + * + * @param element + * @param baseURI + * @throws XMLSecurityException + */ + public XMLX509IssuerSerial(Element element, String baseURI) throws XMLSecurityException { - super(element, BaseURI); - } + super(element, baseURI); + } - /** - * Constructor XMLX509IssuerSerial - * - * @param doc - * @param X509IssuerName - * @param X509SerialNumber - */ - public XMLX509IssuerSerial(Document doc, String X509IssuerName, - BigInteger X509SerialNumber) { + /** + * Constructor XMLX509IssuerSerial + * + * @param doc + * @param x509IssuerName + * @param x509SerialNumber + */ + public XMLX509IssuerSerial(Document doc, String x509IssuerName, + BigInteger x509SerialNumber) { - super(doc); + super(doc); + XMLUtils.addReturnToElement(this._constructionElement); + addTextElement(x509IssuerName, Constants._TAG_X509ISSUERNAME); + addTextElement(x509SerialNumber.toString(), Constants._TAG_X509SERIALNUMBER); + } - XMLUtils.addReturnToElement(this._constructionElement); - this.addTextElement(X509IssuerName, Constants._TAG_X509ISSUERNAME); - XMLUtils.addReturnToElement(this._constructionElement); - this.addTextElement(X509SerialNumber.toString(), Constants._TAG_X509SERIALNUMBER); - } + /** + * Constructor XMLX509IssuerSerial + * + * @param doc + * @param x509IssuerName + * @param x509SerialNumber + */ + public XMLX509IssuerSerial(Document doc, String x509IssuerName, + String x509SerialNumber) { + this(doc, x509IssuerName, new BigInteger(x509SerialNumber)); + } - /** - * Constructor XMLX509IssuerSerial - * - * @param doc - * @param X509IssuerName - * @param X509SerialNumber - */ - public XMLX509IssuerSerial(Document doc, String X509IssuerName, - String X509SerialNumber) { - this(doc, X509IssuerName, new BigInteger(X509SerialNumber)); - } + /** + * Constructor XMLX509IssuerSerial + * + * @param doc + * @param x509IssuerName + * @param x509SerialNumber + */ + public XMLX509IssuerSerial(Document doc, String x509IssuerName, + int x509SerialNumber) { + this(doc, x509IssuerName, + new BigInteger(Integer.toString(x509SerialNumber))); + } - /** - * Constructor XMLX509IssuerSerial - * - * @param doc - * @param X509IssuerName - * @param X509SerialNumber - */ - public XMLX509IssuerSerial(Document doc, String X509IssuerName, - int X509SerialNumber) { - this(doc, X509IssuerName, - new BigInteger(Integer.toString(X509SerialNumber))); - } + /** + * Constructor XMLX509IssuerSerial + * + * @param doc + * @param x509certificate + */ + public XMLX509IssuerSerial(Document doc, X509Certificate x509certificate) { - /** - * Constructor XMLX509IssuerSerial - * - * @param doc - * @param x509certificate - */ - public XMLX509IssuerSerial(Document doc, X509Certificate x509certificate) { + this(doc, + RFC2253Parser.normalize(x509certificate.getIssuerDN().getName()), + x509certificate.getSerialNumber()); + } - this(doc, - RFC2253Parser.normalize(x509certificate.getIssuerDN().getName()), - x509certificate.getSerialNumber()); - } + /** + * Method getSerialNumber + * + * @return the serial number + */ + public BigInteger getSerialNumber() { - /** - * Method getSerialNumber - * - * - * @return the serial number - */ - public BigInteger getSerialNumber() { + String text = this.getTextFromChildElement + (Constants._TAG_X509SERIALNUMBER, Constants.SignatureSpecNS); + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "X509SerialNumber text: " + text); - String text = - this.getTextFromChildElement(Constants._TAG_X509SERIALNUMBER, - Constants.SignatureSpecNS); - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "In dem X509SerialNumber wurde gefunden: " + text); + return new BigInteger(text); + } - return new BigInteger(text); - } + /** + * Method getSerialNumberInteger + * + * @return the serial number as plain int + */ + public int getSerialNumberInteger() { + return this.getSerialNumber().intValue(); + } - /** - * Method getSerialNumberInteger - * - * - * @return the serial number as plain int - */ - public int getSerialNumberInteger() { - return this.getSerialNumber().intValue(); - } + /** + * Method getIssuerName + * + * @return the issuer name + */ + public String getIssuerName() { - /** - * Method getIssuerName - * - * - * @return the issuer name - */ - public String getIssuerName() { + return RFC2253Parser + .normalize(this + .getTextFromChildElement(Constants._TAG_X509ISSUERNAME, + Constants.SignatureSpecNS)); + } - return RFC2253Parser - .normalize(this - .getTextFromChildElement(Constants._TAG_X509ISSUERNAME, - Constants.SignatureSpecNS)); - } + /** @inheritDoc */ + public boolean equals(Object obj) { - /** @inheritDoc */ - public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (!this.getClass().getName().equals(obj.getClass().getName())) { + return false; + } - if (!obj.getClass().getName().equals(this.getClass().getName())) { - return false; - } + XMLX509IssuerSerial other = (XMLX509IssuerSerial) obj; - XMLX509IssuerSerial other = (XMLX509IssuerSerial) obj; + return this.getSerialNumber().equals(other.getSerialNumber()) + && this.getIssuerName().equals(other.getIssuerName()); + } - - if (other.getSerialNumber().equals(this.getSerialNumber()) - && other.getIssuerName().equals(this.getIssuerName())) { - return true; - } - - return false; - } - - /** @inheritDoc */ - public String getBaseLocalName() { - return Constants._TAG_X509ISSUERSERIAL; - } + /** @inheritDoc */ + public String getBaseLocalName() { + return Constants._TAG_X509ISSUERSERIAL; + } } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SKI.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SKI.java index fcbb19e245a..fbbb17e6a54 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SKI.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SKI.java @@ -20,8 +20,6 @@ */ package com.sun.org.apache.xml.internal.security.keys.content.x509; - - import java.io.IOException; import java.io.ByteArrayInputStream; import java.io.InputStream; @@ -36,192 +34,143 @@ import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy; import org.w3c.dom.Document; import org.w3c.dom.Element; -import sun.security.util.DerValue; - - /** * Handles SubjectKeyIdentifier (SKI) for X.509v3. * - * @author $Author: raul $ - * @see Interface X509Extension + * @author $Author: mullan $ + * @see Interface X509Extension */ public class XMLX509SKI extends SignatureElementProxy implements XMLX509DataContent { - /** {@link java.util.logging} logging facility */ + /** {@link java.util.logging} logging facility */ static java.util.logging.Logger log = java.util.logging.Logger.getLogger(XMLX509SKI.class.getName()); - /** - * SubjectKeyIdentifier (id-ce-subjectKeyIdentifier) (2.5.29.14): - * This extension identifies the public key being certified. It enables - * distinct keys used by the same subject to be differentiated - * (e.g., as key updating occurs). - *
      - * A key identifer shall be unique with respect to all key identifiers - * for the subject with which it is used. This extension is always non-critical. - */ - public static final String SKI_OID = "2.5.29.14"; + /** + * SubjectKeyIdentifier (id-ce-subjectKeyIdentifier) (2.5.29.14): + * This extension identifies the public key being certified. It enables + * distinct keys used by the same subject to be differentiated + * (e.g., as key updating occurs). + *
      + * A key identifer shall be unique with respect to all key identifiers + * for the subject with which it is used. This extension is always non-critical. + */ + public static final String SKI_OID = "2.5.29.14"; - /** - * Constructor X509SKI - * - * @param doc - * @param skiBytes - */ - public XMLX509SKI(Document doc, byte[] skiBytes) { + /** + * Constructor X509SKI + * + * @param doc + * @param skiBytes + */ + public XMLX509SKI(Document doc, byte[] skiBytes) { + super(doc); + this.addBase64Text(skiBytes); + } - super(doc); - - this.addBase64Text(skiBytes); - } - - /** - * Constructor XMLX509SKI - * - * @param doc - * @param x509certificate - * @throws XMLSecurityException - */ - public XMLX509SKI(Document doc, X509Certificate x509certificate) + /** + * Constructor XMLX509SKI + * + * @param doc + * @param x509certificate + * @throws XMLSecurityException + */ + public XMLX509SKI(Document doc, X509Certificate x509certificate) throws XMLSecurityException { + super(doc); + this.addBase64Text(XMLX509SKI.getSKIBytesFromCert(x509certificate)); + } - super(doc); - - this.addBase64Text(XMLX509SKI.getSKIBytesFromCert(x509certificate)); - } - - /** - * Constructor XMLX509SKI - * - * @param element - * @param BaseURI - * @throws XMLSecurityException - */ - public XMLX509SKI(Element element, String BaseURI) + /** + * Constructor XMLX509SKI + * + * @param element + * @param BaseURI + * @throws XMLSecurityException + */ + public XMLX509SKI(Element element, String BaseURI) throws XMLSecurityException { - super(element, BaseURI); - } + super(element, BaseURI); + } - /** - * Method getSKIBytes - * - * @return the skibytes - * @throws XMLSecurityException - */ - public byte[] getSKIBytes() throws XMLSecurityException { - return this.getBytesFromTextChild(); - } + /** + * Method getSKIBytes + * + * @return the skibytes + * @throws XMLSecurityException + */ + public byte[] getSKIBytes() throws XMLSecurityException { + return this.getBytesFromTextChild(); + } - /** - * Method getSKIBytesFromCert - * - * @param cert - * @return sky bytes from the given certificate - * - * @throws XMLSecurityException - * @see java.security.cert.X509Extension#getExtensionValue(java.lang.String) - */ - public static byte[] getSKIBytesFromCert(X509Certificate cert) - throws XMLSecurityException { + /** + * Method getSKIBytesFromCert + * + * @param cert + * @return ski bytes from the given certificate + * + * @throws XMLSecurityException + * @see java.security.cert.X509Extension#getExtensionValue(java.lang.String) + */ + public static byte[] getSKIBytesFromCert(X509Certificate cert) + throws XMLSecurityException { - try { - - /* - * Gets the DER-encoded OCTET string for the extension value (extnValue) - * identified by the passed-in oid String. The oid string is - * represented by a set of positive whole numbers separated by periods. - */ - byte[] derEncodedValue = cert.getExtensionValue(XMLX509SKI.SKI_OID); - - if (cert.getVersion() < 3) { + if (cert.getVersion() < 3) { Object exArgs[] = { new Integer(cert.getVersion()) }; - throw new XMLSecurityException("certificate.noSki.lowVersion", exArgs); - } + } - byte[] extensionValue = null; - - /** - * Use sun.security.util.DerValue if it is present. - */ - try { - DerValue dervalue = new DerValue(derEncodedValue); - if (dervalue == null) { - throw new XMLSecurityException("certificate.noSki.null"); - } - if (dervalue.tag != DerValue.tag_OctetString) { - throw new XMLSecurityException("certificate.noSki.notOctetString"); - } - extensionValue = dervalue.getOctetString(); - } catch (NoClassDefFoundError e) { - } - - /** - * Fall back to org.bouncycastle.asn1.DERInputStream - */ - if (extensionValue == null) { - try { - Class clazz = Class.forName("org.bouncycastle.asn1.DERInputStream"); - if (clazz != null) { - Constructor constructor = clazz.getConstructor(new Class[]{InputStream.class}); - InputStream is = (InputStream) constructor.newInstance(new Object[]{new ByteArrayInputStream(derEncodedValue)}); - Method method = clazz.getMethod("readObject", new Class[]{}); - Object obj = method.invoke(is, new Object[]{}); - if (obj == null) { - throw new XMLSecurityException("certificate.noSki.null"); - } - Class clazz2 = Class.forName("org.bouncycastle.asn1.ASN1OctetString"); - if (!clazz2.isInstance(obj)) { - throw new XMLSecurityException("certificate.noSki.notOctetString"); - } - Method method2 = clazz2.getMethod("getOctets", new Class[]{}); - extensionValue = (byte[]) method2.invoke(obj, new Object[]{}); - } - } catch (Throwable t) { - } - } - - /** - * Strip away first two bytes from the DerValue (tag and length) - */ - byte abyte0[] = new byte[extensionValue.length - 2]; - - System.arraycopy(extensionValue, 2, abyte0, 0, abyte0.length); - - /* - byte abyte0[] = new byte[derEncodedValue.length - 4]; - System.arraycopy(derEncodedValue, 4, abyte0, 0, abyte0.length); + /* + * Gets the DER-encoded OCTET string for the extension value + * (extnValue) identified by the passed-in oid String. The oid + * string is represented by a set of positive whole numbers + * separated by periods. */ - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Base64 of SKI is " + Base64.encode(abyte0)); + byte[] extensionValue = cert.getExtensionValue(XMLX509SKI.SKI_OID); + if (extensionValue == null) { + throw new XMLSecurityException("certificate.noSki.null"); + } - return abyte0; - } catch (IOException ex) { - throw new XMLSecurityException("generic.EmptyMessage", ex); - } - } + /** + * Strip away first four bytes from the extensionValue + * The first two bytes are the tag and length of the extensionValue + * OCTET STRING, and the next two bytes are the tag and length of + * the skid OCTET STRING. + */ + byte skidValue[] = new byte[extensionValue.length - 4]; - /** @inheritDoc */ - public boolean equals(Object obj) { + System.arraycopy(extensionValue, 4, skidValue, 0, skidValue.length); - if (!obj.getClass().getName().equals(this.getClass().getName())) { - return false; - } + if (log.isLoggable(java.util.logging.Level.FINE)) { + log.log(java.util.logging.Level.FINE, "Base64 of SKI is " + Base64.encode(skidValue)); + } - XMLX509SKI other = (XMLX509SKI) obj; + return skidValue; + } - try { - return java.security.MessageDigest.isEqual(other.getSKIBytes(), + /** @inheritDoc */ + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (!this.getClass().getName().equals(obj.getClass().getName())) { + return false; + } + + XMLX509SKI other = (XMLX509SKI) obj; + + try { + return java.security.MessageDigest.isEqual(other.getSKIBytes(), this.getSKIBytes()); - } catch (XMLSecurityException ex) { - return false; - } - } + } catch (XMLSecurityException ex) { + return false; + } + } - /** @inheritDoc */ - public String getBaseLocalName() { - return Constants._TAG_X509SKI; - } + /** @inheritDoc */ + public String getBaseLocalName() { + return Constants._TAG_X509SKI; + } } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SubjectName.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SubjectName.java index 548ec7ba57d..8d51da2e2fd 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SubjectName.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SubjectName.java @@ -20,8 +20,6 @@ */ package com.sun.org.apache.xml.internal.security.keys.content.x509; - - import java.security.cert.X509Certificate; import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; @@ -33,15 +31,11 @@ import org.w3c.dom.Element; /** * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class XMLX509SubjectName extends SignatureElementProxy implements XMLX509DataContent { - /** {@link java.util.logging} logging facility */ - static java.util.logging.Logger log = - java.util.logging.Logger.getLogger(XMLX509SubjectName.class.getName()); - /** * Constructor X509SubjectName * @@ -88,23 +82,21 @@ public class XMLX509SubjectName extends SignatureElementProxy return RFC2253Parser.normalize(this.getTextFromTextChild()); } - /** @inheritDoc */ - public boolean equals(Object obj) { + /** @inheritDoc */ + public boolean equals(Object obj) { + if (obj == null) { + return false; + } - if (!obj.getClass().getName().equals(this.getClass().getName())) { - return false; - } + if (!this.getClass().getName().equals(obj.getClass().getName())) { + return false; + } - XMLX509SubjectName other = (XMLX509SubjectName) obj; - String otherSubject = other.getSubjectName(); - String thisSubject = this.getSubjectName(); - - if (otherSubject.equals(thisSubject)) { - return true; - } - - return false; + XMLX509SubjectName other = (XMLX509SubjectName) obj; + String otherSubject = other.getSubjectName(); + String thisSubject = this.getSubjectName(); + return thisSubject.equals(otherSubject); } /** @inheritDoc */ diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/InvalidKeyResolverException.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/InvalidKeyResolverException.java index 6e3d408d43d..3b3508005cb 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/InvalidKeyResolverException.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/InvalidKeyResolverException.java @@ -2,7 +2,6 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ - /* * Copyright 1999-2004 The Apache Software Foundation. * @@ -29,7 +28,7 @@ import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; /** * * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class InvalidKeyResolverException extends XMLSecurityException { diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java index 488a59731c4..1da9dbb362f 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java @@ -2,7 +2,6 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ - /* * Copyright 1999-2004 The Apache Software Foundation. * @@ -26,6 +25,7 @@ package com.sun.org.apache.xml.internal.security.keys.keyresolver; import java.security.PublicKey; import java.security.cert.X509Certificate; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import javax.crypto.SecretKey; @@ -39,7 +39,8 @@ import org.w3c.dom.Node; * KeyResolver is factory class for subclass of KeyResolverSpi that * represent child element of KeyInfo. * - * @author $Author: raul $ + * @author $Author: mullan $ + * @version %I%, %G% */ public class KeyResolver { @@ -72,6 +73,7 @@ public class KeyResolver { InstantiationException { this._resolverSpi = (KeyResolverSpi) Class.forName(className).newInstance(); + this._resolverSpi.setGlobalResolver(true); } /** @@ -83,21 +85,17 @@ public class KeyResolver { return KeyResolver._resolverVector.size(); } - /** - * Method item - * - * @param i - * @return the number i resolver registerd - * @throws KeyResolverException - */ - public static KeyResolver item(int i) throws KeyResolverException { - - KeyResolver resolver = (KeyResolver) KeyResolver._resolverVector.get(i); - if (resolver==null) { - throw new KeyResolverException("utils.resolver.noClass"); - } - - return resolver; + public static void hit(Iterator hintI) { + ResolverIterator hint = (ResolverIterator) hintI; + int i = hint.i; + if (i!=1 && hint.res ==_resolverVector) { + List resolverVector=(List)((ArrayList)_resolverVector).clone(); + Object ob=resolverVector.remove(i-1); + resolverVector.add(0,ob); + _resolverVector=resolverVector; + } else { + //System.out.println("KeyResolver hitting"); + } } /** @@ -106,17 +104,19 @@ public class KeyResolver { * @param element * @param BaseURI * @param storage - * @return the instance that happends to implement the thing. + * @return The certificate represented by the element. * * @throws KeyResolverException */ - public static final KeyResolver getInstance( + public static final X509Certificate getX509Certificate( Element element, String BaseURI, StorageResolver storage) throws KeyResolverException { - for (int i = 0; i < KeyResolver._resolverVector.size(); i++) { + // use the old vector to not be hit by updates + List resolverVector = KeyResolver._resolverVector; + for (int i = 0; i < resolverVector.size(); i++) { KeyResolver resolver= - (KeyResolver) KeyResolver._resolverVector.get(i); + (KeyResolver) resolverVector.get(i); if (resolver==null) { Object exArgs[] = { @@ -127,11 +127,63 @@ public class KeyResolver { throw new KeyResolverException("utils.resolver.noClass", exArgs); } - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "check resolvability by class " + resolver.getClass()); + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "check resolvability by class " + resolver.getClass()); - if (resolver.canResolve(element, BaseURI, storage)) { - return resolver; + X509Certificate cert=resolver.resolveX509Certificate(element, BaseURI, storage); + if (cert!=null) { + return cert; + } + } + + Object exArgs[] = { + (((element != null) && (element.getNodeType() == Node.ELEMENT_NODE)) + ? element.getTagName() + : "null") }; + + throw new KeyResolverException("utils.resolver.noClass", exArgs); + } + /** + * Method getInstance + * + * @param element + * @param BaseURI + * @param storage + * @return the public key contained in the element + * + * @throws KeyResolverException + */ + public static final PublicKey getPublicKey( + Element element, String BaseURI, StorageResolver storage) + throws KeyResolverException { + + List resolverVector = KeyResolver._resolverVector; + for (int i = 0; i < resolverVector.size(); i++) { + KeyResolver resolver= + (KeyResolver) resolverVector.get(i); + + if (resolver==null) { + Object exArgs[] = { + (((element != null) + && (element.getNodeType() == Node.ELEMENT_NODE)) + ? element.getTagName() + : "null") }; + + throw new KeyResolverException("utils.resolver.noClass", exArgs); + } + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "check resolvability by class " + resolver.getClass()); + + PublicKey cert=resolver.resolvePublicKey(element, BaseURI, storage); + if (cert!=null) { + if (i!=0 && resolverVector==_resolverVector) { + //update resolver. + resolverVector=(List)((ArrayList)_resolverVector).clone(); + Object ob=resolverVector.remove(i); + resolverVector.add(0,ob); + _resolverVector=resolverVector; + } + return cert; } } @@ -182,34 +234,6 @@ public class KeyResolver { KeyResolver._resolverVector.add(0, className); } - /* - * Method resolve - * - * @param element - * - * @throws KeyResolverException - */ - - /** - * Method resolveStatic - * - * @param element - * @param BaseURI - * @param storage - * @return resolve from the static register an element - * - * @throws KeyResolverException - */ - public static PublicKey resolveStatic( - Element element, String BaseURI, StorageResolver storage) - throws KeyResolverException { - - KeyResolver myResolver = KeyResolver.getInstance(element, BaseURI, - storage); - - return myResolver.resolvePublicKey(element, BaseURI, storage); - } - /** * Method resolve * @@ -223,7 +247,7 @@ public class KeyResolver { public PublicKey resolvePublicKey( Element element, String BaseURI, StorageResolver storage) throws KeyResolverException { - return this._resolverSpi.engineResolvePublicKey(element, BaseURI, storage); + return this._resolverSpi.engineLookupAndResolvePublicKey(element, BaseURI, storage); } /** @@ -239,7 +263,7 @@ public class KeyResolver { public X509Certificate resolveX509Certificate( Element element, String BaseURI, StorageResolver storage) throws KeyResolverException { - return this._resolverSpi.engineResolveX509Certificate(element, BaseURI, + return this._resolverSpi.engineLookupResolveX509Certificate(element, BaseURI, storage); } @@ -253,7 +277,7 @@ public class KeyResolver { public SecretKey resolveSecretKey( Element element, String BaseURI, StorageResolver storage) throws KeyResolverException { - return this._resolverSpi.engineResolveSecretKey(element, BaseURI, + return this._resolverSpi.engineLookupAndResolveSecretKey(element, BaseURI, storage); } @@ -277,14 +301,6 @@ public class KeyResolver { return this._resolverSpi.engineGetProperty(key); } - /** - * Method getPropertyKeys - * - * @return the properties key registerd in this resolver - */ - public String[] getPropertyKeys() { - return this._resolverSpi.engineGetPropertyKeys(); - } /** * Method understandsProperty @@ -296,18 +312,6 @@ public class KeyResolver { return this._resolverSpi.understandsProperty(propertyToTest); } - /** - * Method canResolve - * - * @param element - * @param BaseURI - * @param storage - * @return true if can resolve the key in the element - */ - public boolean canResolve(Element element, String BaseURI, - StorageResolver storage) { - return this._resolverSpi.engineCanResolve(element, BaseURI, storage); - } /** * Method resolverClassName @@ -317,4 +321,37 @@ public class KeyResolver { public String resolverClassName() { return this._resolverSpi.getClass().getName(); } + + static class ResolverIterator implements Iterator { + List res; + Iterator it; + int i; + public ResolverIterator(List list) { + res = list; + it = res.iterator(); + } + public boolean hasNext() { + // TODO Auto-generated method stub + return it.hasNext(); + } + + public Object next() { + i++; + KeyResolver resolver = (KeyResolver) it.next(); + if (resolver==null) { + throw new RuntimeException("utils.resolver.noClass"); + } + + return resolver._resolverSpi; + } + + public void remove() { + // TODO Auto-generated method stub + + } + + }; + public static Iterator iterator() { + return new ResolverIterator(_resolverVector); + } } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolverException.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolverException.java index 4248c8dfa6b..f0069949b2f 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolverException.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolverException.java @@ -2,7 +2,6 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ - /* * Copyright 1999-2004 The Apache Software Foundation. * @@ -31,7 +30,7 @@ import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; * * * - * @author $Author: raul $ + * @author $Author: mullan $ * */ public class KeyResolverException extends XMLSecurityException { diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolverSpi.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolverSpi.java index a6b99825ebc..dc2865bcfc4 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolverSpi.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolverSpi.java @@ -20,17 +20,15 @@ */ package com.sun.org.apache.xml.internal.security.keys.keyresolver; - - import java.security.PublicKey; import java.security.cert.X509Certificate; +import java.util.HashMap; import javax.crypto.SecretKey; import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolver; import org.w3c.dom.Element; - /** * This class is abstract class for a child KeyInfo Elemnet. * @@ -41,14 +39,10 @@ import org.w3c.dom.Element; * JAVACLASS="MyPackage.MyKeyValueImpl"//gt; * * - * @author $Author: raul $ + * @author $Author: mullan $ + * @version $Revision: 1.5 $ */ public abstract class KeyResolverSpi { - - /** {@link java.util.logging} logging facility */ - static java.util.logging.Logger log = - java.util.logging.Logger.getLogger(KeyResolverSpi.class.getName()); - /** * This method helps the {@link com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver} to decide whether a * {@link com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverSpi} is able to perform the requested action. @@ -56,10 +50,12 @@ public abstract class KeyResolverSpi { * @param element * @param BaseURI * @param storage - * @return true if can resolve the key in the element + * @return */ - abstract public boolean engineCanResolve(Element element, String BaseURI, - StorageResolver storage); + public boolean engineCanResolve(Element element, String BaseURI, + StorageResolver storage) { + throw new UnsupportedOperationException(); + } /** * Method engineResolvePublicKey @@ -71,9 +67,60 @@ public abstract class KeyResolverSpi { * * @throws KeyResolverException */ - abstract public PublicKey engineResolvePublicKey( + public PublicKey engineResolvePublicKey( Element element, String BaseURI, StorageResolver storage) - throws KeyResolverException; + throws KeyResolverException { + throw new UnsupportedOperationException(); + }; + + /** + * Method engineResolvePublicKey + * + * @param element + * @param BaseURI + * @param storage + * @return resolved public key from the registered from the element. + * + * @throws KeyResolverException + */ + public PublicKey engineLookupAndResolvePublicKey( + Element element, String BaseURI, StorageResolver storage) + throws KeyResolverException { + KeyResolverSpi tmp = cloneIfNeeded(); + if (!tmp.engineCanResolve(element, BaseURI, storage)) + return null; + return tmp.engineResolvePublicKey(element, BaseURI, storage); + } + + private KeyResolverSpi cloneIfNeeded() throws KeyResolverException { + KeyResolverSpi tmp=this; + if (globalResolver) { + try { + tmp = (KeyResolverSpi) getClass().newInstance(); + } catch (InstantiationException e) { + throw new KeyResolverException("",e); + } catch (IllegalAccessException e) { + throw new KeyResolverException("",e); + } + } + return tmp; + } + + /** + * Method engineResolveCertificate + * + * @param element + * @param BaseURI + * @param storage + * @return resolved X509Certificate key from the registered from the elements + * + * @throws KeyResolverException + */ + public X509Certificate engineResolveX509Certificate( + Element element, String BaseURI, StorageResolver storage) + throws KeyResolverException{ + throw new UnsupportedOperationException(); + }; /** * Method engineResolveCertificate @@ -85,9 +132,30 @@ public abstract class KeyResolverSpi { * * @throws KeyResolverException */ - abstract public X509Certificate engineResolveX509Certificate( + public X509Certificate engineLookupResolveX509Certificate( Element element, String BaseURI, StorageResolver storage) - throws KeyResolverException; + throws KeyResolverException { + KeyResolverSpi tmp = cloneIfNeeded(); + if (!tmp.engineCanResolve(element, BaseURI, storage)) + return null; + return tmp.engineResolveX509Certificate(element, BaseURI, storage); + + } + /** + * Method engineResolveSecretKey + * + * @param element + * @param BaseURI + * @param storage + * @return resolved SecretKey key from the registered from the elements + * + * @throws KeyResolverException + */ + public SecretKey engineResolveSecretKey( + Element element, String BaseURI, StorageResolver storage) + throws KeyResolverException{ + throw new UnsupportedOperationException(); + }; /** * Method engineResolveSecretKey @@ -99,12 +167,19 @@ public abstract class KeyResolverSpi { * * @throws KeyResolverException */ - abstract public SecretKey engineResolveSecretKey( + public SecretKey engineLookupAndResolveSecretKey( Element element, String BaseURI, StorageResolver storage) - throws KeyResolverException; + throws KeyResolverException { + KeyResolverSpi tmp = cloneIfNeeded(); + if (!tmp.engineCanResolve(element, BaseURI, storage)) + return null; + return tmp.engineResolveSecretKey(element, BaseURI, storage); + } /** Field _properties */ - protected java.util.Map _properties = new java.util.HashMap(10); + protected java.util.Map _properties = null; + + protected boolean globalResolver=false; /** * Method engineSetProperty @@ -113,19 +188,8 @@ public abstract class KeyResolverSpi { * @param value */ public void engineSetProperty(String key, String value) { - - java.util.Iterator i = this._properties.keySet().iterator(); - - while (i.hasNext()) { - String c = (String) i.next(); - - if (c.equals(key)) { - key = c; - - break; - } - } - + if (_properties==null) + _properties=new HashMap(); this._properties.put(key, value); } @@ -136,31 +200,12 @@ public abstract class KeyResolverSpi { * @return obtain the property appointed by key */ public String engineGetProperty(String key) { - - java.util.Iterator i = this._properties.keySet().iterator(); - - while (i.hasNext()) { - String c = (String) i.next(); - - if (c.equals(key)) { - key = c; - - break; - } - } + if (_properties==null) + return null; return (String) this._properties.get(key); } - /** - * Method engineGetPropertyKeys - * - * @return the keys of properties known by this resolver - */ - public String[] engineGetPropertyKeys() { - return new String[0]; - } - /** * Method understandsProperty * @@ -168,17 +213,13 @@ public abstract class KeyResolverSpi { * @return true if understood the property */ public boolean understandsProperty(String propertyToTest) { + if (_properties==null) + return false; - String[] understood = this.engineGetPropertyKeys(); - - if (understood != null) { - for (int i = 0; i < understood.length; i++) { - if (understood[i].equals(propertyToTest)) { - return true; - } - } - } - - return false; + return this._properties.get(propertyToTest)!=null; } + public void setGlobalResolver(boolean globalResolver) { + this.globalResolver = globalResolver; + } + } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/DSAKeyValueResolver.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/DSAKeyValueResolver.java index efda14c1a4a..20bf7bad777 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/DSAKeyValueResolver.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/DSAKeyValueResolver.java @@ -37,46 +37,10 @@ import org.w3c.dom.Element; /** * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class DSAKeyValueResolver extends KeyResolverSpi { - /** Field _dsaKeyElement */ - private Element _dsaKeyElement = null; - - /** @inheritDoc */ - public boolean engineCanResolve(Element element, String BaseURI, - StorageResolver storage) { - - if (element == null) { - return false; - } - - boolean isKeyValue = XMLUtils.elementIsInSignatureSpace(element, - Constants._TAG_KEYVALUE); - boolean isDSAKeyValue = XMLUtils.elementIsInSignatureSpace(element, - Constants._TAG_DSAKEYVALUE); - - if (isKeyValue) { - - this._dsaKeyElement = - XMLUtils.selectDsNode(element.getFirstChild(),Constants._TAG_DSAKEYVALUE,0); - - if (this._dsaKeyElement != null) { - return true; - } - } else if (isDSAKeyValue) { - - // this trick is needed to allow the RetrievalMethodResolver to eat a - // ds:DSAKeyValue directly (without KeyValue) - this._dsaKeyElement = element; - - return true; - } - - return false; - } - /** * Method engineResolvePublicKey * @@ -85,20 +49,30 @@ public class DSAKeyValueResolver extends KeyResolverSpi { * @param storage * @return null if no {@link PublicKey} could be obtained */ - public PublicKey engineResolvePublicKey( + public PublicKey engineLookupAndResolvePublicKey( Element element, String BaseURI, StorageResolver storage) { + if (element == null) { + return null; + } + Element dsaKeyElement=null; + boolean isKeyValue = XMLUtils.elementIsInSignatureSpace(element, + Constants._TAG_KEYVALUE); + if (isKeyValue) { + dsaKeyElement = + XMLUtils.selectDsNode(element.getFirstChild(),Constants._TAG_DSAKEYVALUE,0); + } else if (XMLUtils.elementIsInSignatureSpace(element, + Constants._TAG_DSAKEYVALUE)) { + // this trick is needed to allow the RetrievalMethodResolver to eat a + // ds:DSAKeyValue directly (without KeyValue) + dsaKeyElement = element; + } - if (this._dsaKeyElement == null) { - boolean weCanResolve = this.engineCanResolve(element, BaseURI, - storage); - - if (!weCanResolve || (this._dsaKeyElement == null)) { - return null; - } + if (dsaKeyElement == null) { + return null; } try { - DSAKeyValue dsaKeyValue = new DSAKeyValue(this._dsaKeyElement, + DSAKeyValue dsaKeyValue = new DSAKeyValue(dsaKeyElement, BaseURI); PublicKey pk = dsaKeyValue.getPublicKey(); @@ -112,13 +86,13 @@ public class DSAKeyValueResolver extends KeyResolverSpi { /** @inheritDoc */ - public X509Certificate engineResolveX509Certificate( + public X509Certificate engineLookupResolveX509Certificate( Element element, String BaseURI, StorageResolver storage) { return null; } /** @inheritDoc */ - public javax.crypto.SecretKey engineResolveSecretKey( + public javax.crypto.SecretKey engineLookupAndResolveSecretKey( Element element, String BaseURI, StorageResolver storage){ return null; } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/EncryptedKeyResolver.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/EncryptedKeyResolver.java index 4b44f1c50d1..6adc050e893 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/EncryptedKeyResolver.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/EncryptedKeyResolver.java @@ -56,7 +56,6 @@ public class EncryptedKeyResolver extends KeyResolverSpi { RSAKeyValueResolver.class.getName()); - Key _key; Key _kek; String _algorithm; @@ -66,7 +65,6 @@ public class EncryptedKeyResolver extends KeyResolverSpi { * @param algorithm */ public EncryptedKeyResolver(String algorithm) { - _key = null; _kek = null; _algorithm=algorithm; } @@ -78,64 +76,49 @@ public class EncryptedKeyResolver extends KeyResolverSpi { */ public EncryptedKeyResolver(String algorithm, Key kek) { - _key = null; _algorithm = algorithm; _kek = kek; } - /** - * Method engineCanResolve - * - * @param element - * @param BaseURI - * @param storage - * @return true if can resolve the key in the element - * - */ - - public boolean engineCanResolve(Element element, String BaseURI, - StorageResolver storage) { - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "EncryptedKeyResolver - Can I resolve " + element.getTagName()); - - if (element == null) { - return false; - } - - boolean isEncryptedKey = XMLUtils.elementIsInEncryptionSpace(element, - EncryptionConstants._TAG_ENCRYPTEDKEY); - - if (isEncryptedKey) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Passed an Encrypted Key"); - try { - XMLCipher cipher = XMLCipher.getInstance(); - cipher.init(XMLCipher.UNWRAP_MODE, _kek); - EncryptedKey ek = cipher.loadEncryptedKey(element); - _key = cipher.decryptKey(ek, _algorithm); - } - catch (Exception e) {} - } - - return (_key != null); - } - /** @inheritDoc */ - public PublicKey engineResolvePublicKey( + public PublicKey engineLookupAndResolvePublicKey( Element element, String BaseURI, StorageResolver storage) { return null; } /** @inheritDoc */ - public X509Certificate engineResolveX509Certificate( + public X509Certificate engineLookupResolveX509Certificate( Element element, String BaseURI, StorageResolver storage) { return null; } /** @inheritDoc */ - public javax.crypto.SecretKey engineResolveSecretKey( + public javax.crypto.SecretKey engineLookupAndResolveSecretKey( Element element, String BaseURI, StorageResolver storage) { - return (SecretKey) _key; + SecretKey key=null; + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "EncryptedKeyResolver - Can I resolve " + element.getTagName()); + + if (element == null) { + return null; + } + + boolean isEncryptedKey = XMLUtils.elementIsInEncryptionSpace(element, + EncryptionConstants._TAG_ENCRYPTEDKEY); + + if (isEncryptedKey) { + log.log(java.util.logging.Level.FINE, "Passed an Encrypted Key"); + try { + XMLCipher cipher = XMLCipher.getInstance(); + cipher.init(XMLCipher.UNWRAP_MODE, _kek); + EncryptedKey ek = cipher.loadEncryptedKey(element); + key = (SecretKey) cipher.decryptKey(ek, _algorithm); + } + catch (Exception e) {} + } + + return key; } } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RSAKeyValueResolver.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RSAKeyValueResolver.java index 541de7307f4..fb38e872590 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RSAKeyValueResolver.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RSAKeyValueResolver.java @@ -2,7 +2,6 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ - /* * Copyright 1999-2004 The Apache Software Foundation. * @@ -38,7 +37,7 @@ import org.w3c.dom.Element; /** * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class RSAKeyValueResolver extends KeyResolverSpi { @@ -48,75 +47,55 @@ public class RSAKeyValueResolver extends KeyResolverSpi { RSAKeyValueResolver.class.getName()); /** Field _rsaKeyElement */ - private Element _rsaKeyElement = null; + /** @inheritDoc */ - public boolean engineCanResolve(Element element, String BaseURI, - StorageResolver storage) { - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName()); - + public PublicKey engineLookupAndResolvePublicKey( + Element element, String BaseURI, StorageResolver storage) { + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName()); if (element == null) { - return false; + return null; } - boolean isKeyValue = XMLUtils.elementIsInSignatureSpace(element, - Constants._TAG_KEYVALUE); - boolean isRSAKeyValue = XMLUtils.elementIsInSignatureSpace(element, - Constants._TAG_RSAKEYVALUE); - - if (isKeyValue) { - this._rsaKeyElement = XMLUtils.selectDsNode(element.getFirstChild(), - Constants._TAG_RSAKEYVALUE, 0); - - if (this._rsaKeyElement != null) { - return true; - } - } else if (isRSAKeyValue) { - + boolean isKeyValue = XMLUtils.elementIsInSignatureSpace(element, + Constants._TAG_KEYVALUE); + Element rsaKeyElement=null; + if (isKeyValue) { + rsaKeyElement = XMLUtils.selectDsNode(element.getFirstChild(), + Constants._TAG_RSAKEYVALUE, 0); + } else if (XMLUtils.elementIsInSignatureSpace(element, + Constants._TAG_RSAKEYVALUE)) { // this trick is needed to allow the RetrievalMethodResolver to eat a // ds:RSAKeyValue directly (without KeyValue) - this._rsaKeyElement = element; + rsaKeyElement = element; + } - return true; - } - return false; - } - - /** @inheritDoc */ - public PublicKey engineResolvePublicKey( - Element element, String BaseURI, StorageResolver storage) { - - if (this._rsaKeyElement == null) { - boolean weCanResolve = this.engineCanResolve(element, BaseURI, - storage); - - if (!weCanResolve || (this._rsaKeyElement == null)) { - return null; - } + if (rsaKeyElement == null) { + return null; } try { - RSAKeyValue rsaKeyValue = new RSAKeyValue(this._rsaKeyElement, + RSAKeyValue rsaKeyValue = new RSAKeyValue(rsaKeyElement, BaseURI); return rsaKeyValue.getPublicKey(); } catch (XMLSecurityException ex) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "XMLSecurityException", ex); + log.log(java.util.logging.Level.FINE, "XMLSecurityException", ex); } return null; } /** @inheritDoc */ - public X509Certificate engineResolveX509Certificate( + public X509Certificate engineLookupResolveX509Certificate( Element element, String BaseURI, StorageResolver storage) { return null; } /** @inheritDoc */ - public javax.crypto.SecretKey engineResolveSecretKey( + public javax.crypto.SecretKey engineLookupAndResolveSecretKey( Element element, String BaseURI, StorageResolver storage) { return null; } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RetrievalMethodResolver.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RetrievalMethodResolver.java index d8d98bdb9e9..3dff2182445 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RetrievalMethodResolver.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RetrievalMethodResolver.java @@ -28,7 +28,15 @@ import java.security.PublicKey; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Set; +import javax.xml.parsers.ParserConfigurationException; + +import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException; import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; import com.sun.org.apache.xml.internal.security.keys.content.RetrievalMethod; import com.sun.org.apache.xml.internal.security.keys.content.x509.XMLX509Certificate; @@ -44,6 +52,7 @@ import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver; import org.w3c.dom.Attr; import org.w3c.dom.Element; import org.w3c.dom.Node; +import org.xml.sax.SAXException; /** @@ -55,7 +64,7 @@ import org.w3c.dom.Node; * RetrievalMethodResolver cannot handle itself, resolving of the extracted * element is delegated back to the KeyResolver mechanism. * - * @author $Author: raul $ + * @author $Author: mullan $ modified by Dave Garcia */ public class RetrievalMethodResolver extends KeyResolverSpi { @@ -64,26 +73,6 @@ public class RetrievalMethodResolver extends KeyResolverSpi { java.util.logging.Logger.getLogger( RetrievalMethodResolver.class.getName()); - /** - * Method engineCanResolve - * @inheritDoc - * @param element - * @param BaseURI - * @param storage - * - */ - public boolean engineCanResolve(Element element, String BaseURI, - StorageResolver storage) { - - if - (!XMLUtils.elementIsInSignatureSpace(element, - Constants._TAG_RETRIEVALMETHOD)) { - return false; - } - - return true; - } - /** * Method engineResolvePublicKey * @inheritDoc @@ -92,84 +81,61 @@ public class RetrievalMethodResolver extends KeyResolverSpi { * @param storage * */ - public PublicKey engineResolvePublicKey( + public PublicKey engineLookupAndResolvePublicKey( Element element, String BaseURI, StorageResolver storage) { + if (!XMLUtils.elementIsInSignatureSpace(element, + Constants._TAG_RETRIEVALMETHOD)) { + return null; + } try { - RetrievalMethod rm = new RetrievalMethod(element, BaseURI); - Attr uri = rm.getURIAttr(); - - // type can be null because it's optional - String type = rm.getType(); - Transforms transforms = rm.getTransforms(); - ResourceResolver resRes = ResourceResolver.getInstance(uri, BaseURI); - - if (resRes != null) { - XMLSignatureInput resource = resRes.resolve(uri, BaseURI); - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Before applying Transforms, resource has " - + resource.getBytes().length + "bytes"); - - if (transforms != null) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "We have Transforms"); - - resource = transforms.performTransforms(resource); - } - if (true) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "After applying Transforms, resource has " - + resource.getBytes().length + "bytes"); - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Resolved to resource " + resource.getSourceURI()); - } - - byte inputBytes[] = resource.getBytes(); - - if ((type != null) && type.equals(RetrievalMethod.TYPE_RAWX509)) { - - // if the resource stores a raw certificate, we have to handle it - CertificateFactory certFact = - CertificateFactory - .getInstance(XMLX509Certificate.JCA_CERT_ID); - X509Certificate cert = - (X509Certificate) certFact - .generateCertificate(new ByteArrayInputStream(inputBytes)); - - if (cert != null) { - return cert.getPublicKey(); - } - } else { - - // otherwise, we parse the resource, create an Element and delegate - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "we have to parse " + inputBytes.length + " bytes"); - - Element e = this.getDocFromBytes(inputBytes); - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Now we have a {" + e.getNamespaceURI() + "}" - + e.getLocalName() + " Element"); - - if (e != null) { - KeyResolver newKeyResolver = KeyResolver.getInstance(getFirstElementChild(e), - BaseURI, storage); - - if (newKeyResolver != null) { - return newKeyResolver.resolvePublicKey(getFirstElementChild(e), BaseURI, - storage); - } - } - } - } - } catch (XMLSecurityException ex) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "XMLSecurityException", ex); + //Create a retrieval method over the given element + RetrievalMethod rm = new RetrievalMethod(element, BaseURI); + String type = rm.getType(); + XMLSignatureInput resource=resolveInput(rm,BaseURI); + if (RetrievalMethod.TYPE_RAWX509.equals(type)) { + //a raw certificate, direct parsing is done! + X509Certificate cert=getRawCertificate(resource); + if (cert != null) { + return cert.getPublicKey(); + } + return null; + }; + Element e = obtainRefrenceElement(resource); + return resolveKey(e,BaseURI,storage); + } catch (XMLSecurityException ex) { + log.log(java.util.logging.Level.FINE, "XMLSecurityException", ex); } catch (CertificateException ex) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "CertificateException", ex); + log.log(java.util.logging.Level.FINE, "CertificateException", ex); } catch (IOException ex) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "IOException", ex); - } - + log.log(java.util.logging.Level.FINE, "IOException", ex); + } catch (ParserConfigurationException e) { + log.log(java.util.logging.Level.FINE, "ParserConfigurationException", e); + } catch (SAXException e) { + log.log(java.util.logging.Level.FINE, "SAXException", e); + } return null; } + static private Element obtainRefrenceElement(XMLSignatureInput resource) throws CanonicalizationException, ParserConfigurationException, IOException, SAXException, KeyResolverException { + Element e; + if (resource.isElement()){ + e=(Element) resource.getSubNode(); + } else if (resource.isNodeSet()) { + //Retrieved resource is a nodeSet + e=getDocumentElement(resource.getNodeSet()); + } else { + //Retrieved resource is an inputStream + byte inputBytes[] = resource.getBytes(); + e = getDocFromBytes(inputBytes); + //otherwise, we parse the resource, create an Element and delegate + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "we have to parse " + inputBytes.length + " bytes"); + } + return e; + } + /** * Method engineResolveX509Certificate * @inheritDoc @@ -178,87 +144,102 @@ public class RetrievalMethodResolver extends KeyResolverSpi { * @param storage * */ - public X509Certificate engineResolveX509Certificate( + public X509Certificate engineLookupResolveX509Certificate( Element element, String BaseURI, StorageResolver storage) { + if (!XMLUtils.elementIsInSignatureSpace(element, + Constants._TAG_RETRIEVALMETHOD)) { + return null; + } - try { + try { RetrievalMethod rm = new RetrievalMethod(element, BaseURI); - Attr uri = rm.getURIAttr(); - Transforms transforms = rm.getTransforms(); - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Asked to resolve URI " + uri); - - ResourceResolver resRes = ResourceResolver.getInstance(uri, BaseURI); - - if (resRes != null) { - XMLSignatureInput resource = resRes.resolve(uri, BaseURI); - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Before applying Transforms, resource has " - + resource.getBytes().length + "bytes"); - - if (transforms != null) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "We have Transforms"); - - resource = transforms.performTransforms(resource); - } - - if (true) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "After applying Transforms, resource has " - + resource.getBytes().length + "bytes"); - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Resolved to resource " + resource.getSourceURI()); - } - - byte inputBytes[] = resource.getBytes(); - - if ((rm.getType() != null) - && rm.getType().equals(RetrievalMethod.TYPE_RAWX509)) { - - // if the resource stores a raw certificate, we have to handle it - CertificateFactory certFact = - CertificateFactory - .getInstance(XMLX509Certificate.JCA_CERT_ID); - X509Certificate cert = - (X509Certificate) certFact - .generateCertificate(new ByteArrayInputStream(inputBytes)); - - if (cert != null) { - return cert; - } - } else { - - // otherwise, we parse the resource, create an Element and delegate - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "we have to parse " + inputBytes.length + " bytes"); - - Element e = this.getDocFromBytes(inputBytes); - - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Now we have a {" + e.getNamespaceURI() + "}" - + e.getLocalName() + " Element"); - - if (e != null) { - KeyResolver newKeyResolver = KeyResolver.getInstance(getFirstElementChild(e), - BaseURI, storage); - - if (newKeyResolver != null) { - return newKeyResolver.resolveX509Certificate(getFirstElementChild(e), BaseURI, - storage); - } - } - } - } + String type = rm.getType(); + XMLSignatureInput resource=resolveInput(rm,BaseURI); + if (RetrievalMethod.TYPE_RAWX509.equals(type)) { + X509Certificate cert=getRawCertificate(resource); + return cert; + } + Element e = obtainRefrenceElement(resource); + return resolveCertificate(e,BaseURI,storage); } catch (XMLSecurityException ex) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "XMLSecurityException", ex); + log.log(java.util.logging.Level.FINE, "XMLSecurityException", ex); } catch (CertificateException ex) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "CertificateException", ex); + log.log(java.util.logging.Level.FINE, "CertificateException", ex); } catch (IOException ex) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "IOException", ex); - } - + log.log(java.util.logging.Level.FINE, "IOException", ex); + } catch (ParserConfigurationException e) { + log.log(java.util.logging.Level.FINE, "ParserConfigurationException", e); + } catch (SAXException e) { + log.log(java.util.logging.Level.FINE, "SAXException", e); + } return null; } + /** + * Retrieves a x509Certificate from the given information + * @param e + * @param BaseURI + * @param storage + * @return + * @throws KeyResolverException + */ + static private X509Certificate resolveCertificate(Element e,String BaseURI,StorageResolver storage) throws KeyResolverException{ + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Now we have a {" + e.getNamespaceURI() + "}"+ e.getLocalName() + " Element"); + //An element has been provided + if (e != null) { + return KeyResolver.getX509Certificate(e,BaseURI, storage); + } + return null; + } + + /** + * Retrieves a x509Certificate from the given information + * @param e + * @param BaseURI + * @param storage + * @return + * @throws KeyResolverException + */ + static private PublicKey resolveKey(Element e,String BaseURI,StorageResolver storage) throws KeyResolverException{ + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Now we have a {" + e.getNamespaceURI() + "}"+ e.getLocalName() + " Element"); + //An element has been provided + if (e != null) { + return KeyResolver.getPublicKey(e,BaseURI, storage); + } + return null; + } + + static private X509Certificate getRawCertificate(XMLSignatureInput resource) throws CanonicalizationException, IOException, CertificateException{ + byte inputBytes[] = resource.getBytes(); + // if the resource stores a raw certificate, we have to handle it + CertificateFactory certFact =CertificateFactory.getInstance(XMLX509Certificate.JCA_CERT_ID); + X509Certificate cert =(X509Certificate) certFact.generateCertificate(new ByteArrayInputStream(inputBytes)); + return cert; + } + /** + * Resolves the input from the given retrieval method + * @return + * @throws XMLSecurityException + */ + static private XMLSignatureInput resolveInput(RetrievalMethod rm,String BaseURI) throws XMLSecurityException{ + Attr uri = rm.getURIAttr(); + //Apply the trnasforms + Transforms transforms = rm.getTransforms(); + ResourceResolver resRes = ResourceResolver.getInstance(uri, BaseURI); + if (resRes != null) { + XMLSignatureInput resource = resRes.resolve(uri, BaseURI); + if (transforms != null) { + log.log(java.util.logging.Level.FINE, "We have Transforms"); + resource = transforms.performTransforms(resource); + } + return resource; + } + return null; + } + /** * Parses a byte array and returns the parsed Element. * @@ -266,18 +247,13 @@ public class RetrievalMethodResolver extends KeyResolverSpi { * @return the Document Element after parsing bytes * @throws KeyResolverException if something goes wrong */ - Element getDocFromBytes(byte[] bytes) throws KeyResolverException { - + static Element getDocFromBytes(byte[] bytes) throws KeyResolverException { try { - javax.xml.parsers.DocumentBuilderFactory dbf = - javax.xml.parsers.DocumentBuilderFactory.newInstance(); - + javax.xml.parsers.DocumentBuilderFactory dbf =javax.xml.parsers.DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); - javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder(); org.w3c.dom.Document doc = db.parse(new java.io.ByteArrayInputStream(bytes)); - return doc.getDocumentElement(); } catch (org.xml.sax.SAXException ex) { throw new KeyResolverException("empty", ex); @@ -296,16 +272,43 @@ public class RetrievalMethodResolver extends KeyResolverSpi { * @param storage * */ - public javax.crypto.SecretKey engineResolveSecretKey( + public javax.crypto.SecretKey engineLookupAndResolveSecretKey( Element element, String BaseURI, StorageResolver storage) { return null; } - static Element getFirstElementChild(Element e){ - Node n=e.getFirstChild(); - while (n!=null && n.getNodeType()!=Node.ELEMENT_NODE) { - n=n.getNextSibling(); - } - return (Element)n; + + static Element getDocumentElement(Set set) { + Iterator it=set.iterator(); + Element e=null; + while (it.hasNext()) { + Node currentNode=(Node)it.next(); + if (currentNode instanceof Element) { + e=(Element)currentNode; + break; + } + + } + List parents=new ArrayList(10); + + //Obtain all the parents of the elemnt + do { + parents.add(e); + Node n=e.getParentNode(); + if (!(n instanceof Element )) { + break; + } + e=(Element)n; + } while (e!=null); + //Visit them in reverse order. + ListIterator it2=parents.listIterator(parents.size()-1); + Element ele=null; + while (it2.hasPrevious()) { + ele=(Element)it2.previous(); + if (set.contains(ele)) { + return ele; + } + } + return null; } } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509CertificateResolver.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509CertificateResolver.java index 16264c99868..06a49c6708e 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509CertificateResolver.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509CertificateResolver.java @@ -2,7 +2,6 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ - /* * Copyright 1999-2004 The Apache Software Foundation. * @@ -41,7 +40,7 @@ import org.w3c.dom.Element; * Resolves Certificates which are directly contained inside a * ds:X509Certificate Element. * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class X509CertificateResolver extends KeyResolverSpi { @@ -49,47 +48,7 @@ public class X509CertificateResolver extends KeyResolverSpi { static java.util.logging.Logger log = java.util.logging.Logger.getLogger(X509CertificateResolver.class.getName()); - /** Field _dsaKeyElement */ - Element[] _x509CertKeyElements = null; - /** - * Method engineCanResolve - * @inheritDoc - * @param element - * @param BaseURI - * @param storage - * - */ - public boolean engineCanResolve(Element element, String BaseURI, - StorageResolver storage) { - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName() + "?"); - - if (!XMLUtils.elementIsInSignatureSpace(element, - Constants._TAG_X509DATA)) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "I can't"); - - return false; - } - - - this._x509CertKeyElements = XMLUtils.selectDsNodes(element.getFirstChild(), - Constants._TAG_X509CERTIFICATE); - - if ((this._x509CertKeyElements != null) - && (this._x509CertKeyElements.length > 0)) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Yes Sir, I can"); - - return true; - } - - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "I can't"); - - return false; - } - - /** Field _x509certObject[] */ - XMLX509Certificate _x509certObject[] = null; /** * Method engineResolvePublicKey @@ -100,11 +59,11 @@ public class X509CertificateResolver extends KeyResolverSpi { * * @throws KeyResolverException */ - public PublicKey engineResolvePublicKey( + public PublicKey engineLookupAndResolvePublicKey( Element element, String BaseURI, StorageResolver storage) throws KeyResolverException { - X509Certificate cert = this.engineResolveX509Certificate(element, + X509Certificate cert = this.engineLookupResolveX509Certificate(element, BaseURI, storage); if (cert != null) { @@ -123,43 +82,33 @@ public class X509CertificateResolver extends KeyResolverSpi { * * @throws KeyResolverException */ - public X509Certificate engineResolveX509Certificate( + public X509Certificate engineLookupResolveX509Certificate( Element element, String BaseURI, StorageResolver storage) throws KeyResolverException { try { - if ((this._x509CertKeyElements == null) - || (this._x509CertKeyElements.length == 0)) { - boolean weCanResolve = this.engineCanResolve(element, BaseURI, - storage); - - if (!weCanResolve || (this._x509CertKeyElements == null) - || (this._x509CertKeyElements.length == 0)) { - return null; - } + Element[] els=XMLUtils.selectDsNodes(element.getFirstChild(), + Constants._TAG_X509CERTIFICATE); + if ((els == null) || (els.length == 0)) { + Element el=XMLUtils.selectDsNode(element.getFirstChild(), + Constants._TAG_X509DATA,0); + if (el!=null) { + return engineLookupResolveX509Certificate(el, BaseURI, storage); + } + return null; } - this._x509certObject = - new XMLX509Certificate[this._x509CertKeyElements.length]; - // populate Object array - for (int i = 0; i < this._x509CertKeyElements.length; i++) { - this._x509certObject[i] = - new XMLX509Certificate(this._x509CertKeyElements[i] - , BaseURI); - } - - for (int i = 0; i < this._x509certObject.length; i++) { - X509Certificate cert = this._x509certObject[i].getX509Certificate(); - - if (cert != null) { - return cert; + for (int i = 0; i < els.length; i++) { + XMLX509Certificate xmlCert=new XMLX509Certificate(els[i], BaseURI); + X509Certificate cert = xmlCert.getX509Certificate(); + if (cert!=null) { + return cert; } } - return null; } catch (XMLSecurityException ex) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "XMLSecurityException", ex); + log.log(java.util.logging.Level.FINE, "XMLSecurityException", ex); throw new KeyResolverException("generic.EmptyMessage", ex); } @@ -173,7 +122,7 @@ public class X509CertificateResolver extends KeyResolverSpi { * @param storage * */ - public javax.crypto.SecretKey engineResolveSecretKey( + public javax.crypto.SecretKey engineLookupAndResolveSecretKey( Element element, String BaseURI, StorageResolver storage) { return null; diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509IssuerSerialResolver.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509IssuerSerialResolver.java index c4e824747ba..8f717e71689 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509IssuerSerialResolver.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509IssuerSerialResolver.java @@ -2,7 +2,6 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ - /* * Copyright 1999-2004 The Apache Software Foundation. * @@ -39,7 +38,7 @@ import org.w3c.dom.Element; /** * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class X509IssuerSerialResolver extends KeyResolverSpi { @@ -48,44 +47,13 @@ public class X509IssuerSerialResolver extends KeyResolverSpi { java.util.logging.Logger.getLogger( X509IssuerSerialResolver.class.getName()); - /** @inheritDoc */ - public boolean engineCanResolve(Element element, String BaseURI, - StorageResolver storage) { - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName() + "?"); - - X509Data x509data = null; - try { - x509data = new X509Data(element, BaseURI); - } catch (XMLSignatureException ex) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "I can't"); - - return false; - } catch (XMLSecurityException ex) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "I can't"); - - return false; - } - - if (x509data == null) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "I can't"); - return false; - } - - if (x509data.containsIssuerSerial()) { - return true; - } - - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "I can't"); - return false; - } /** @inheritDoc */ - public PublicKey engineResolvePublicKey( + public PublicKey engineLookupAndResolvePublicKey( Element element, String BaseURI, StorageResolver storage) throws KeyResolverException { - X509Certificate cert = this.engineResolveX509Certificate(element, + X509Certificate cert = this.engineLookupResolveX509Certificate(element, BaseURI, storage); if (cert != null) { @@ -96,10 +64,31 @@ public class X509IssuerSerialResolver extends KeyResolverSpi { } /** @inheritDoc */ - public X509Certificate engineResolveX509Certificate( + public X509Certificate engineLookupResolveX509Certificate( Element element, String BaseURI, StorageResolver storage) throws KeyResolverException { + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName() + "?"); + X509Data x509data = null; + try { + x509data = new X509Data(element, BaseURI); + } catch (XMLSignatureException ex) { + log.log(java.util.logging.Level.FINE, "I can't"); + return null; + } catch (XMLSecurityException ex) { + log.log(java.util.logging.Level.FINE, "I can't"); + return null; + } + + if (x509data == null) { + log.log(java.util.logging.Level.FINE, "I can't"); + return null; + } + + if (!x509data.containsIssuerSerial()) { + return null; + } try { if (storage == null) { Object exArgs[] = { Constants._TAG_X509ISSUERSERIAL }; @@ -107,53 +96,52 @@ public class X509IssuerSerialResolver extends KeyResolverSpi { new KeyResolverException("KeyResolver.needStorageResolver", exArgs); - if (log.isLoggable(java.util.logging.Level.INFO)) log.log(java.util.logging.Level.INFO, "", ex); + log.log(java.util.logging.Level.INFO, "", ex); throw ex; } - X509Data x509data = new X509Data(element, BaseURI); int noOfISS = x509data.lengthIssuerSerial(); while (storage.hasNext()) { X509Certificate cert = storage.next(); XMLX509IssuerSerial certSerial = new XMLX509IssuerSerial(element.getOwnerDocument(), cert); - if (true) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Found Certificate Issuer: " + if (log.isLoggable(java.util.logging.Level.FINE)) { + log.log(java.util.logging.Level.FINE, "Found Certificate Issuer: " + certSerial.getIssuerName()); - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Found Certificate Serial: " + log.log(java.util.logging.Level.FINE, "Found Certificate Serial: " + certSerial.getSerialNumber().toString()); } for (int i=0; i 0)) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Yes Sir, I can"); - - return true; - } - - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "I can't"); - - return false; - } /** * Method engineResolvePublicKey @@ -102,11 +57,11 @@ public class X509SKIResolver extends KeyResolverSpi { * @return null if no {@link PublicKey} could be obtained * @throws KeyResolverException */ - public PublicKey engineResolvePublicKey( + public PublicKey engineLookupAndResolvePublicKey( Element element, String BaseURI, StorageResolver storage) throws KeyResolverException { - X509Certificate cert = this.engineResolveX509Certificate(element, + X509Certificate cert = this.engineLookupResolveX509Certificate(element, BaseURI, storage); if (cert != null) { @@ -125,46 +80,55 @@ public class X509SKIResolver extends KeyResolverSpi { * * @throws KeyResolverException */ - public X509Certificate engineResolveX509Certificate( + public X509Certificate engineLookupResolveX509Certificate( Element element, String BaseURI, StorageResolver storage) throws KeyResolverException { + if (log.isLoggable(java.util.logging.Level.FINE)) { + log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName() + "?"); + } + if (!XMLUtils.elementIsInSignatureSpace(element, + Constants._TAG_X509DATA)) { + log.log(java.util.logging.Level.FINE, "I can't"); + return null; + } + /** Field _x509childObject[] */ + XMLX509SKI x509childObject[] = null; - try { - if (this._x509childNodes == null) { - boolean weCanResolve = this.engineCanResolve(element, BaseURI, - storage); - - if (!weCanResolve || (this._x509childNodes == null)) { - return null; - } - } + Element x509childNodes[] = null; + x509childNodes = XMLUtils.selectDsNodes(element.getFirstChild(), + Constants._TAG_X509SKI); + if (!((x509childNodes != null) + && (x509childNodes.length > 0))) { + log.log(java.util.logging.Level.FINE, "I can't"); + return null; + } + try { if (storage == null) { Object exArgs[] = { Constants._TAG_X509SKI }; KeyResolverException ex = new KeyResolverException("KeyResolver.needStorageResolver", exArgs); - if (log.isLoggable(java.util.logging.Level.INFO)) log.log(java.util.logging.Level.INFO, "", ex); + log.log(java.util.logging.Level.INFO, "", ex); throw ex; } - this._x509childObject = - new XMLX509SKI[this._x509childNodes.length]; + x509childObject = new XMLX509SKI[x509childNodes.length]; - for (int i = 0; i < this._x509childNodes.length; i++) { - this._x509childObject[i] = - new XMLX509SKI(this._x509childNodes[i], BaseURI); + for (int i = 0; i < x509childNodes.length; i++) { + x509childObject[i] = + new XMLX509SKI(x509childNodes[i], BaseURI); } while (storage.hasNext()) { X509Certificate cert = storage.next(); XMLX509SKI certSKI = new XMLX509SKI(element.getOwnerDocument(), cert); - for (int i = 0; i < this._x509childObject.length; i++) { - if (certSKI.equals(this._x509childObject[i])) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Return PublicKey from " + for (int i = 0; i < x509childObject.length; i++) { + if (certSKI.equals(x509childObject[i])) { + log.log(java.util.logging.Level.FINE, "Return PublicKey from " + cert.getSubjectDN().getName()); return cert; @@ -186,7 +150,7 @@ public class X509SKIResolver extends KeyResolverSpi { * @param storage * */ - public javax.crypto.SecretKey engineResolveSecretKey( + public javax.crypto.SecretKey engineLookupAndResolveSecretKey( Element element, String BaseURI, StorageResolver storage) { return null; diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509SubjectNameResolver.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509SubjectNameResolver.java index 5da6a7d8fd7..05e82226c4c 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509SubjectNameResolver.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509SubjectNameResolver.java @@ -38,7 +38,7 @@ import org.w3c.dom.Element; /** * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class X509SubjectNameResolver extends KeyResolverSpi { @@ -47,50 +47,6 @@ public class X509SubjectNameResolver extends KeyResolverSpi { java.util.logging.Logger.getLogger( X509SubjectNameResolver.class.getName()); - /** Field _x509childNodes */ - private Element[] _x509childNodes = null; - - /** Field _x509childObject[] */ - private XMLX509SubjectName _x509childObject[] = null; - - /** - * Method engineCanResolve - * @inheritDoc - * @param element - * @param BaseURI - * @param storage - * - */ - public boolean engineCanResolve(Element element, String BaseURI, - StorageResolver storage) { - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName() + "?"); - - - if (!XMLUtils.elementIsInSignatureSpace(element, - Constants._TAG_X509DATA) ) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "I can't"); - - return false; - } - - - - this._x509childNodes = XMLUtils.selectDsNodes(element, - Constants._TAG_X509SUBJECTNAME); - - if ((this._x509childNodes != null) - && (this._x509childNodes.length > 0)) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Yes Sir, I can"); - - return true; - } - - - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "I can't"); - - return false; - } /** * Method engineResolvePublicKey @@ -101,11 +57,11 @@ public class X509SubjectNameResolver extends KeyResolverSpi { * @return null if no {@link PublicKey} could be obtained * @throws KeyResolverException */ - public PublicKey engineResolvePublicKey( + public PublicKey engineLookupAndResolvePublicKey( Element element, String BaseURI, StorageResolver storage) throws KeyResolverException { - X509Certificate cert = this.engineResolveX509Certificate(element, + X509Certificate cert = this.engineLookupResolveX509Certificate(element, BaseURI, storage); if (cert != null) { @@ -124,37 +80,46 @@ public class X509SubjectNameResolver extends KeyResolverSpi { * * @throws KeyResolverException */ - public X509Certificate engineResolveX509Certificate( + public X509Certificate engineLookupResolveX509Certificate( Element element, String BaseURI, StorageResolver storage) throws KeyResolverException { + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName() + "?"); + Element[] x509childNodes = null; + XMLX509SubjectName x509childObject[] = null; + + if (!XMLUtils.elementIsInSignatureSpace(element, + Constants._TAG_X509DATA) ) { + log.log(java.util.logging.Level.FINE, "I can't"); + return null; + } + x509childNodes = XMLUtils.selectDsNodes(element.getFirstChild(), + Constants._TAG_X509SUBJECTNAME); + + if (!((x509childNodes != null) + && (x509childNodes.length > 0))) { + log.log(java.util.logging.Level.FINE, "I can't"); + return null; + } try { - if (this._x509childNodes == null) { - boolean weCanResolve = this.engineCanResolve(element, BaseURI, - storage); - - if (!weCanResolve || (this._x509childNodes == null)) { - return null; - } - } - if (storage == null) { Object exArgs[] = { Constants._TAG_X509SUBJECTNAME }; KeyResolverException ex = new KeyResolverException("KeyResolver.needStorageResolver", exArgs); - if (log.isLoggable(java.util.logging.Level.INFO)) log.log(java.util.logging.Level.INFO, "", ex); + log.log(java.util.logging.Level.INFO, "", ex); throw ex; } - this._x509childObject = - new XMLX509SubjectName[this._x509childNodes.length]; + x509childObject = + new XMLX509SubjectName[x509childNodes.length]; - for (int i = 0; i < this._x509childNodes.length; i++) { - this._x509childObject[i] = - new XMLX509SubjectName(this._x509childNodes[i], + for (int i = 0; i < x509childNodes.length; i++) { + x509childObject[i] = + new XMLX509SubjectName(x509childNodes[i], BaseURI); } @@ -163,24 +128,24 @@ public class X509SubjectNameResolver extends KeyResolverSpi { XMLX509SubjectName certSN = new XMLX509SubjectName(element.getOwnerDocument(), cert); - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Found Certificate SN: " + certSN.getSubjectName()); + log.log(java.util.logging.Level.FINE, "Found Certificate SN: " + certSN.getSubjectName()); - for (int i = 0; i < this._x509childObject.length; i++) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Found Element SN: " - + this._x509childObject[i].getSubjectName()); + for (int i = 0; i < x509childObject.length; i++) { + log.log(java.util.logging.Level.FINE, "Found Element SN: " + + x509childObject[i].getSubjectName()); - if (certSN.equals(this._x509childObject[i])) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "match !!! "); + if (certSN.equals(x509childObject[i])) { + log.log(java.util.logging.Level.FINE, "match !!! "); return cert; } - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "no match..."); + log.log(java.util.logging.Level.FINE, "no match..."); } } return null; } catch (XMLSecurityException ex) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "XMLSecurityException", ex); + log.log(java.util.logging.Level.FINE, "XMLSecurityException", ex); throw new KeyResolverException("generic.EmptyMessage", ex); } @@ -194,7 +159,7 @@ public class X509SubjectNameResolver extends KeyResolverSpi { * @param storage * */ - public javax.crypto.SecretKey engineResolveSecretKey( + public javax.crypto.SecretKey engineLookupAndResolveSecretKey( Element element, String BaseURI, StorageResolver storage) { return null; diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/StorageResolver.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/StorageResolver.java index 46fee3d4240..f1a8dd3400d 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/StorageResolver.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/StorageResolver.java @@ -2,7 +2,6 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ - /* * Copyright 1999-2004 The Apache Software Foundation. * @@ -21,8 +20,6 @@ */ package com.sun.org.apache.xml.internal.security.keys.storage; - - import java.security.KeyStore; import java.security.cert.X509Certificate; import java.util.ArrayList; @@ -36,7 +33,7 @@ import com.sun.org.apache.xml.internal.security.keys.storage.implementations.Sin /** * This class collects customized resolvers for Certificates. * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class StorageResolver { @@ -45,7 +42,7 @@ public class StorageResolver { java.util.logging.Logger.getLogger(StorageResolver.class.getName()); /** Field _storageResolvers */ - List _storageResolvers = new ArrayList(); + List _storageResolvers = null; /** Field _iterator */ Iterator _iterator = null; @@ -71,7 +68,8 @@ public class StorageResolver { * @param resolver */ public void add(StorageResolverSpi resolver) { - + if (_storageResolvers==null) + _storageResolvers=new ArrayList(); this._storageResolvers.add(resolver); this._iterator = null; @@ -126,6 +124,8 @@ public class StorageResolver { public Iterator getIterator() { if (this._iterator == null) { + if (_storageResolvers==null) + _storageResolvers=new ArrayList(); this._iterator = new StorageResolverIterator(this._storageResolvers.iterator()); } @@ -140,6 +140,8 @@ public class StorageResolver { public boolean hasNext() { if (this._iterator == null) { + if (_storageResolvers==null) + _storageResolvers=new ArrayList(); this._iterator = new StorageResolverIterator(this._storageResolvers.iterator()); } @@ -158,15 +160,13 @@ public class StorageResolver { /** * Class StorageResolverIterator * - * @author $Author: raul $ + * @author $Author: mullan $ + * @version $Revision: 1.5 $ */ - class StorageResolverIterator implements Iterator { + static class StorageResolverIterator implements Iterator { /** Field _resolvers */ - Iterator _resolvers = null; - - /** Field _currentResolver */ - int _currentResolver = 0; + Iterator _resolvers = null; /** * Constructor FilesystemIterator @@ -179,17 +179,16 @@ public class StorageResolver { /** @inheritDoc */ public boolean hasNext() { - return _resolvers.hasNext(); + return _resolvers.hasNext(); } /** @inheritDoc */ public Object next() { - return _resolvers.next(); + return _resolvers.next(); } /** * Method remove - * */ public void remove() { throw new UnsupportedOperationException( diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/StorageResolverException.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/StorageResolverException.java index 2388ef19bc8..29dff030f78 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/StorageResolverException.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/StorageResolverException.java @@ -2,7 +2,6 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ - /* * Copyright 1999-2004 The Apache Software Foundation. * @@ -28,7 +27,7 @@ import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; /** * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class StorageResolverException extends XMLSecurityException { diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/StorageResolverSpi.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/StorageResolverSpi.java index dc95e60407f..25f3e2828d2 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/StorageResolverSpi.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/StorageResolverSpi.java @@ -2,7 +2,6 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ - /* * Copyright 1999-2004 The Apache Software Foundation. * @@ -28,7 +27,7 @@ import java.util.Iterator; /** * - * @author $Author: raul $ + * @author $Author: mullan $ */ public abstract class StorageResolverSpi { diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/CertsInFilesystemDirectoryResolver.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/CertsInFilesystemDirectoryResolver.java index 6c6909665c3..06fb5694bef 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/CertsInFilesystemDirectoryResolver.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/CertsInFilesystemDirectoryResolver.java @@ -2,7 +2,6 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ - /* * Copyright 1999-2004 The Apache Software Foundation. * @@ -21,8 +20,6 @@ */ package com.sun.org.apache.xml.internal.security.keys.storage.implementations; - - import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -40,12 +37,11 @@ import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolverExce import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolverSpi; import com.sun.org.apache.xml.internal.security.utils.Base64; - /** * This {@link StorageResolverSpi} makes all raw (binary) {@link X509Certificate}s * which reside as files in a single directory available to the {@link com.sun.org.apache.xml.internal.security.keys.storage.StorageResolver}. * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class CertsInFilesystemDirectoryResolver extends StorageResolverSpi { @@ -131,20 +127,20 @@ public class CertsInFilesystemDirectoryResolver extends StorageResolverSpi { dn = cert.getSubjectDN().getName(); added = true; } catch (FileNotFoundException ex) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Could not add certificate from file " + filename, ex); + log.log(java.util.logging.Level.FINE, "Could not add certificate from file " + filename, ex); } catch (IOException ex) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Could not add certificate from file " + filename, ex); + log.log(java.util.logging.Level.FINE, "Could not add certificate from file " + filename, ex); } catch (CertificateNotYetValidException ex) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Could not add certificate from file " + filename, ex); + log.log(java.util.logging.Level.FINE, "Could not add certificate from file " + filename, ex); } catch (CertificateExpiredException ex) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Could not add certificate from file " + filename, ex); + log.log(java.util.logging.Level.FINE, "Could not add certificate from file " + filename, ex); } catch (CertificateException ex) { - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Could not add certificate from file " + filename, ex); + log.log(java.util.logging.Level.FINE, "Could not add certificate from file " + filename, ex); } if (added) { - if (true) - if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Added certificate: " + dn); + if (log.isLoggable(java.util.logging.Level.FINE)) + log.log(java.util.logging.Level.FINE, "Added certificate: " + dn); } } } @@ -157,9 +153,10 @@ public class CertsInFilesystemDirectoryResolver extends StorageResolverSpi { /** * Class FilesystemIterator * - * @author $Author: raul $ + * @author $Author: mullan $ + * @version $Revision: 1.5 $ */ - class FilesystemIterator implements Iterator { + private static class FilesystemIterator implements Iterator { /** Field _certs */ List _certs = null; diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/KeyStoreResolver.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/KeyStoreResolver.java index ad1eb6b1494..18632433ca5 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/KeyStoreResolver.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/KeyStoreResolver.java @@ -2,7 +2,6 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ - /* * Copyright 1999-2004 The Apache Software Foundation. * @@ -21,8 +20,6 @@ */ package com.sun.org.apache.xml.internal.security.keys.storage.implementations; - - import java.security.KeyStore; import java.security.KeyStoreException; import java.security.cert.X509Certificate; @@ -37,7 +34,7 @@ import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolverSpi; * Makes the Certificates from a JAVA {@link KeyStore} object available to the * {@link com.sun.org.apache.xml.internal.security.keys.storage.StorageResolver}. * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class KeyStoreResolver extends StorageResolverSpi { @@ -66,9 +63,10 @@ public class KeyStoreResolver extends StorageResolverSpi { /** * Class KeyStoreIterator * - * @author $Author: raul $ + * @author $Author: mullan $ + * @version $Revision: 1.5 $ */ - class KeyStoreIterator implements Iterator { + static class KeyStoreIterator implements Iterator { /** Field _keyStore */ KeyStore _keyStore = null; diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/SingleCertificateResolver.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/SingleCertificateResolver.java index 6c4f260b9d1..7e61b2a244d 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/SingleCertificateResolver.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/SingleCertificateResolver.java @@ -2,7 +2,6 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ - /* * Copyright 1999-2004 The Apache Software Foundation. * @@ -21,8 +20,6 @@ */ package com.sun.org.apache.xml.internal.security.keys.storage.implementations; - - import java.security.cert.X509Certificate; import java.util.Iterator; @@ -33,7 +30,7 @@ import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolverSpi; * This {@link StorageResolverSpi} makes a single {@link X509Certificate} * available to the {@link com.sun.org.apache.xml.internal.security.keys.storage.StorageResolver}. * - * @author $Author: raul $ + * @author $Author: mullan $ */ public class SingleCertificateResolver extends StorageResolverSpi { @@ -61,9 +58,10 @@ public class SingleCertificateResolver extends StorageResolverSpi { /** * Class InternalIterator * - * @author $Author: raul $ + * @author $Author: mullan $ + * @version $Revision: 1.5 $ */ - class InternalIterator implements Iterator { + static class InternalIterator implements Iterator { /** Field _alreadyReturned */ boolean _alreadyReturned = false; diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/config.dtd b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/config.dtd index 1e886bf1776..f57b9fabe4d 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/config.dtd +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/config.dtd @@ -1,73 +1,73 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml index d0d6edcee69..aea1595741b 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml @@ -1,380 +1,399 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/etsi.xsd b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/etsi.xsd index 3a08c64f4b6..d69852ff842 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/etsi.xsd +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/etsi.xsd @@ -1,347 +1,347 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.dtd b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.dtd index 969dbb18c21..b2cc19f63a1 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.dtd +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.dtd @@ -3,7 +3,7 @@ Joseph Reagle $last changed 20001215$ http://www.w3.org/2000/09/xmldsig# - $Revision: 1.1 $ on $Date: 2002/02/08 20:32:26 $ by $Author: reagle $ + $Revision: 1.6 $ on $Date: 2008/07/24 16:15:03 $ by $Author: mullan $ Copyright 2001 The Internet Society and W3C (Massachusetts Institute of Technology, Institut National de Recherche en Informatique et en diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.xsd b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.xsd index df126b30e68..e8288a526c3 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.xsd +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.xsd @@ -11,7 +11,7 @@ + + + + +This package contains classes that allow the creation +and manipulation of service tags. +This com.sun.servicetag package is intended for +Sun internal use only. +

      +

      +
      Service Tag
      +
      A service tag is an XML-based data structure that contains identifying +information about an instance of a product or component on a system. +
      +
      +
      +
      Service Tag Registry
      +
      A service tag registry is a XML-based registry that contains +the service tags of all the tagged components on a system. The +service tag registry is present on systems that have the +Service Tags software installed. +
      +
      +
      +
      Registration Data
      +
      A registration data is a container of one or more +service tags that identify the +components for product registration and will be used to interface +with the Sun Connection registration services. +
      +
      + +This package contains the methods to create service tags, set up the +registration data for product registration, add service tags to and +remove them from the system service tag registry. +

      +All methods defined in this package will throw {@code NullPointerException} +if {@code null} is passed in any input parameter unless it is stated otherwise. +In addition, they are multi-thread safe. + + + + diff --git a/jdk/src/share/classes/com/sun/servicetag/resources/Putback-Notes.txt b/jdk/src/share/classes/com/sun/servicetag/resources/Putback-Notes.txt new file mode 100644 index 00000000000..70e8cffbd6f --- /dev/null +++ b/jdk/src/share/classes/com/sun/servicetag/resources/Putback-Notes.txt @@ -0,0 +1,25 @@ +README for auto-generating of the offline registration page. + +1. register.html is defined by the xDesign team. + +2. Before putback in the workspace, we need to modify the + register.html to contain the following: + + (a) replace the pathname of the jdk_header.png image to + + + (b) replace the product name from: + Java Development Kit Version 6 Update 5 (e.g.) + to: + Java Development Kit @@JDK_VERSION@@ + + (c) replace the form action for the "Register My JDK" button with: + +

      + + (d) Add this input in the form for posting data after + the line: + + + +3. The jdk_header.png is located under /lib/servicetag directory. diff --git a/jdk/make/tools/auto_multi/Makefile b/jdk/src/share/classes/com/sun/servicetag/resources/javase_5_swordfish.properties similarity index 71% rename from jdk/make/tools/auto_multi/Makefile rename to jdk/src/share/classes/com/sun/servicetag/resources/javase_5_swordfish.properties index f5db35099ad..8b58c32f097 100644 --- a/jdk/make/tools/auto_multi/Makefile +++ b/jdk/src/share/classes/com/sun/servicetag/resources/javase_5_swordfish.properties @@ -1,5 +1,4 @@ -# -# Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -21,23 +20,10 @@ # Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, # CA 95054 USA or visit www.sun.com if you need additional information or # have any questions. -# - -# -# Makefile for building the automulti tool -# - -BUILDDIR = ../.. -PACKAGE = build.tools.automulti -PRODUCT = tools -PROGRAM = automulti -include $(BUILDDIR)/common/Defs.gmk - -BUILDTOOL_SOURCE_ROOT = $(BUILDDIR)/tools/src -BUILDTOOL_MAIN = $(PKGDIR)/AutoMulti.java - -# -# Build tool jar rules. -# -include $(BUILDDIR)/common/BuildToolJar.gmk +servicetag.jdk.urn = urn:uuid:d5bed446-05f2-42ed-ba0a-153105a52413 +servicetag.jdk.name = J2SE 5.0 Development Kit +servicetag.jre.urn = urn:uuid:5c6686aa-fd05-46a6-ba3e-700e2d5f7043 +servicetag.jre.name = J2SE 5.0 Runtime Environment +servicetag.parent.urn = urn:uuid:f3c20172-557a-11d7-93d0-d6a41ea318df +servicetag.parent.name = Java 2 Platform, Standard Edition 5.0 diff --git a/jdk/src/share/classes/com/sun/servicetag/resources/javase_6_swordfish.properties b/jdk/src/share/classes/com/sun/servicetag/resources/javase_6_swordfish.properties new file mode 100644 index 00000000000..982c9666c40 --- /dev/null +++ b/jdk/src/share/classes/com/sun/servicetag/resources/javase_6_swordfish.properties @@ -0,0 +1,29 @@ +# Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Sun designates this +# particular file as subject to the "Classpath" exception as provided +# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. + +servicetag.jdk.urn = urn:uuid:b58ef9a8-5ae8-11db-a023-080020a9ed93 +servicetag.jdk.name = Java SE 6 Development Kit +servicetag.jre.urn = urn:uuid:92d1de8c-1e59-42c6-a280-1c379526bcbc +servicetag.jre.name = Java SE 6 Runtime Environment +servicetag.parent.urn = urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3 +servicetag.parent.name = Java Platform Standard Edition 6 (Java SE 6) diff --git a/jdk/src/share/classes/sun/nio/ch/exceptions b/jdk/src/share/classes/com/sun/servicetag/resources/javase_7_swordfish.properties similarity index 74% rename from jdk/src/share/classes/sun/nio/ch/exceptions rename to jdk/src/share/classes/com/sun/servicetag/resources/javase_7_swordfish.properties index 55d295f871d..45eebd2d319 100644 --- a/jdk/src/share/classes/sun/nio/ch/exceptions +++ b/jdk/src/share/classes/com/sun/servicetag/resources/javase_7_swordfish.properties @@ -1,5 +1,4 @@ -# -# Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -21,19 +20,10 @@ # Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, # CA 95054 USA or visit www.sun.com if you need additional information or # have any questions. -# -# Generated exception classes for sun.nio.ch - -SINCE=1.4 -PACKAGE=sun.nio.ch -# This year should only change if the generated source is modified. -COPYRIGHT_YEARS=2000-2007 - - -SUPER=IllegalStateException - -gen AlreadyBoundException " - * Unchecked exception thrown when an attempt is made to bind a {@link - * SocketChannel} that is already bound." \ - 9002280723481772026L +servicetag.jdk.urn = JSEZ9-007-ZZZZ +servicetag.jdk.name = Java SE 7 Development Kit +servicetag.jre.urn = JSERE-007-ZZZZ +servicetag.jre.name = Java SE 7 Runtime Environment +servicetag.parent.urn = urn:uuid:dc1704fe-264f-11dc-9482-080020a9ed93 +servicetag.parent.name = Java Platform Standard Edition 7 (Java SE 7) diff --git a/jdk/src/share/classes/com/sun/servicetag/resources/jdk_header.png b/jdk/src/share/classes/com/sun/servicetag/resources/jdk_header.png new file mode 100644 index 00000000000..011cfd4cd8a Binary files /dev/null and b/jdk/src/share/classes/com/sun/servicetag/resources/jdk_header.png differ diff --git a/jdk/src/share/classes/com/sun/servicetag/resources/product_registration.xsd b/jdk/src/share/classes/com/sun/servicetag/resources/product_registration.xsd new file mode 100644 index 00000000000..43d27455b46 --- /dev/null +++ b/jdk/src/share/classes/com/sun/servicetag/resources/product_registration.xsd @@ -0,0 +1,301 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jdk/src/share/classes/com/sun/servicetag/resources/register.html b/jdk/src/share/classes/com/sun/servicetag/resources/register.html new file mode 100644 index 00000000000..23e9d717ab7 --- /dev/null +++ b/jdk/src/share/classes/com/sun/servicetag/resources/register.html @@ -0,0 +1,105 @@ + + + + +Register your JDK + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        +
       

      Thank you for installing the + Java Development Kit @@JDK_VERSION@@ + from Sun Microsystems.

      +

      Registering your product will give you the following benefits:

      +
        +
      • Notification of new versions, patches, and updates
      • +
      • Special offers on Sun developer products, services and training
      • +
      • Access to early releases and documentation
      • +
      +

      Product registration is FREE, quick and easy!

      +
      +

      All you need is a Sun Developer Network or other Sun Online account. If you don't already have one, you will be prompted to create one.

      + + + + + +
      + + + + You need to be connected to the Internet to register this Sun product.
      +
      +
        +

      Sun Microsystems, Inc. respects your privacy. + We will use your personal information for communications + and management of your Sun Online Account, the services + and applications you access using your Sun Online Account, + and the products and systems you register with your Sun Online Account.

      +

      For more information on the data that will be collected as + part of the registration process and how it will be managed
      + see http://java.sun.com/javase/registration/JDKRegistrationPrivacy.html.
      +
      + For more information on Sun's Privacy Policy see http://www.sun.com/privacy/ or contact privacy@sun.com.

        
        
      + + diff --git a/jdk/src/share/classes/com/sun/servicetag/resources/register_ja.html b/jdk/src/share/classes/com/sun/servicetag/resources/register_ja.html new file mode 100644 index 00000000000..56ee84f5426 --- /dev/null +++ b/jdk/src/share/classes/com/sun/servicetag/resources/register_ja.html @@ -0,0 +1,91 @@ + + + + +JDK 製å“登録 + + + + + + + + + + + + + + + + + + + + + + + + + + +
       
       

      Sun Microsystems ã® Java Development Kit @@JDK_VERSION@@ をインストールã—ã¦ã„ãŸã ãã€ã‚りãŒã¨ã†ã”ã–ã„ã¾ã™ã€‚

      +

      製å“登録をã™ã‚‹ã¨ã€æ¬¡ã®ã‚ˆã†ãªç‰¹å…¸ã‚’å—ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚

      +
        +
      • 最新ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã€ãƒ‘ッãƒã€ãŠã‚ˆã³æ›´æ–°ã«ã¤ã„ã¦ã®é€šçŸ¥
      • +
      • Sun ã®é–‹ç™ºè€…å‘ã‘製å“ã€ã‚µãƒ¼ãƒ“スã€ãŠã‚ˆã³ãƒˆãƒ¬ãƒ¼ãƒ‹ãƒ³ã‚°ã®ç‰¹åˆ¥è²©å£²
      • +
      • アーリーリリースãŠã‚ˆã³ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã¸ã®ã‚¢ã‚¯ã‚»ã‚¹
      • +
      +

      製å“登録ã¯ç„¡æ–™ã§ã‚りã€è¿…速ã§ç°¡å˜ã§ã™ã€‚

      +
      +

      å¿…è¦ã«ãªã‚‹ã®ã¯ã€Sun 開発者å‘ã‘ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¾ãŸã¯ãã®ä»–ã® Sun オンラインアカウントã ã‘ã§ã™ã€‚ ã¾ã ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒãªã„å ´åˆã¯ã€ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®ä½œæˆãŒæ±‚ã‚られã¾ã™ã€‚

      + + + + + +
      + + +
      ã“ã® Sun 製å“を登録ã™ã‚‹ã«ã¯ã€ã‚¤ãƒ³ã‚¿ãƒ¼ãƒãƒƒãƒˆã«æŽ¥ç¶šã—ã¦ã„ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚
      +
      +
        +

      Sun Microsystems, Inc. ã¯ã€ãŠå®¢æ§˜ã®ãƒ—ライãƒã‚·ãƒ¼ã‚’å°Šé‡ã—ã¾ã™ã€‚ ãŠå®¢æ§˜ã®å€‹äººæƒ…å ±ã¯ã€ãŠå®¢æ§˜ã® Sun オンラインアカウントã€ãŠå®¢æ§˜ãŒ Sun オンラインアカウントを使用ã—ã¦ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã‚µãƒ¼ãƒ“スã¨ã‚¢ãƒ—リケーションã€ãŠã‚ˆã³ãŠå®¢æ§˜ãŒ Sun オンラインアカウントã§ç™»éŒ²ã™ã‚‹è£½å“ã¨ã‚·ã‚¹ãƒ†ãƒ ã®é€šä¿¡ã¨ç®¡ç†ã«ä½¿ç”¨ã—ã¾ã™ã€‚

      +

      登録ã®éš›ã«åŽé›†ã•れるデータやã€ãれらãŒã©ã®ã‚ˆã†ã«ç®¡ç†ã•れるã‹ã«ã¤ã„ã¦ã®è©³ç´°ã¯ã€
      http://java.sun.com/javase/ja/registration/JDKRegistrationPrivacy.html ã‚’å‚ç…§ã—ã¦ãã ã•ã„。

      Sun ã®ãƒ—ライãƒã‚·ãƒ¼ãƒãƒªã‚·ãƒ¼ã«ã¤ã„ã¦ã®è©³ç´°ã¯ã€http://jp.sun.com/privacy/ ã‚’å‚ç…§ã™ã‚‹ã‹ã€ãŠå•ã„åˆã‚ã›ãƒ•ォームã‹ã‚‰ãŠå•ã„åˆã‚ã›ãã ã•ã„。

        
        
      + + diff --git a/jdk/src/share/classes/com/sun/servicetag/resources/register_zh_CN.html b/jdk/src/share/classes/com/sun/servicetag/resources/register_zh_CN.html new file mode 100644 index 00000000000..c47929fb744 --- /dev/null +++ b/jdk/src/share/classes/com/sun/servicetag/resources/register_zh_CN.html @@ -0,0 +1,92 @@ + + + + +注册您的 JDK + + + + + + + + + + + + + + + + + + + + + + + + + + + +
       
       

      感谢您安装 Sun Microsystems 的 Java Development Kit @@JDK_VERSION@@。

      +

      注册产å“åŽæ‚¨å°†èŽ·å¾—å¦‚ä¸‹å¢žå€¼æœåŠ¡ï¼š

      +
        +
      • 获得新版本ã€ä¿®è¡¥ç¨‹åºå’Œæ›´æ–°çš„通知æœåŠ¡
      • +
      • 获得有关 Sun å¼€å‘者产å“ã€æœåŠ¡å’ŒåŸ¹è®­çš„ä¼˜æƒ 
      • +
      • 获得对早期版本和文档的访问æƒé™
      • +
      +

      äº§å“æ³¨å†Œæ˜¯å…费的,å³å¿«é€Ÿåˆè½»æ¾ï¼

      +
      +

      您需è¦å…·æœ‰ Sun å¼€å‘者网络或其他 Sun è”æœºå¸æˆ·ã€‚如果您没有,系统将æç¤ºæ‚¨åˆ›å»ºä¸€ä¸ªã€‚

      + + + + + +
      + + +
      您需è¦è¿žæŽ¥åˆ° Internet æ¥æ³¨å†Œæ­¤ Sun 产å“。
      +
      +
        +

      Sun Microsystems, Inc. å°Šé‡æ‚¨çš„éšç§ã€‚我们会将您的个人信æ¯ç”¨äºŽé€šä¿¡å’Œ Sun è”æœºå¸æˆ·çš„管ç†ã€Sun è”æœºå¸æˆ·è®¿é—®çš„æœåŠ¡å’Œåº”ç”¨ç¨‹åºä»¥åŠç”¨äºŽä½¿ç”¨ Sun è”æœºå¸æˆ·æ³¨å†Œçš„产å“和系统。

      +

      有关注册过程中收集的数æ®ä»¥åŠè¿™äº›æ•°æ®çš„ç®¡ç†æ–¹å¼çš„æ›´å¤šä¿¡æ¯ï¼Œ
      请访问 http://java.sun.com/javase/registration/JDKRegistrationPrivacy.html。

      有关 Sun éšç§æ”¿ç­–的更多信æ¯ï¼Œè¯·è®¿é—® http://www.sun.com/privacy/ 或与 privacy@sun.com è”系。

        
        
      + + diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic.properties index 6087def3607..4dac249bfa0 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic.properties @@ -101,30 +101,41 @@ ColorChooser.resetMnemonic=82 ColorChooser.sampleText=Sample Text Sample Text ColorChooser.swatchesNameText=Swatches ColorChooser.swatchesMnemonic=83 -ColorChooser.swatchesDisplayedMnemonicIndex=0 ColorChooser.swatchesRecentText=Recent: -ColorChooser.hsbNameText=HSB # Each of the ColorChooser types can define a mnemonic, as a KeyEvent.VK_XXX # constant, and an index into the text to render the mnemonic as. The # mnemonic is xxxMnemonic and the index of the character to underline is # xxxDisplayedMnemonicIndex. -ColorChooser.hsbMnemonic=72 -ColorChooser.hsbDisplayedMnemonicIndex=0 -ColorChooser.hsbHueText=H -ColorChooser.hsbSaturationText=S -ColorChooser.hsbBrightnessText=B -ColorChooser.hsbRedText=R -ColorChooser.hsbGreenText=G -ColorChooser.hsbBlueText=B +ColorChooser.hsvNameText=HSV +ColorChooser.hsvMnemonic=72 +ColorChooser.hsvHueText=Hue +ColorChooser.hsvSaturationText=Saturation +ColorChooser.hsvValueText=Value +ColorChooser.hsvTransparencyText=Transparency +ColorChooser.hslNameText=HSL +ColorChooser.hslMnemonic=76 +ColorChooser.hslHueText=Hue +ColorChooser.hslSaturationText=Saturation +ColorChooser.hslLightnessText=Lightness +ColorChooser.hslTransparencyText=Transparency ColorChooser.rgbNameText=RGB ColorChooser.rgbMnemonic=71 -ColorChooser.rgbDisplayedMnemonicIndex=1 ColorChooser.rgbRedText=Red ColorChooser.rgbRedMnemonic=68 ColorChooser.rgbGreenText=Green ColorChooser.rgbGreenMnemonic=78 ColorChooser.rgbBlueText=Blue ColorChooser.rgbBlueMnemonic=66 +ColorChooser.rgbAlphaText=Alpha +ColorChooser.rgbHexCodeText=Color Code +ColorChooser.rgbHexCodeMnemonic=67 +ColorChooser.cmykNameText=CMYK +ColorChooser.cmykMnemonic=77 +ColorChooser.cmykCyanText=Cyan +ColorChooser.cmykMagentaText=Magenta +ColorChooser.cmykYellowText=Yellow +ColorChooser.cmykBlackText=Black +ColorChooser.cmykAlphaText=Alpha ############ OPTION PANE STRINGS ############# # Mnemonic keys correspond to KeyEvent.VK_XXX constant diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_de.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_de.properties index 93660548035..b3455977738 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_de.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_de.properties @@ -101,30 +101,41 @@ ColorChooser.resetMnemonic=90 ColorChooser.sampleText=Beispieltext Beispieltext ColorChooser.swatchesNameText=Muster ColorChooser.swatchesMnemonic=77 -ColorChooser.swatchesDisplayedMnemonicIndex=0 ColorChooser.swatchesRecentText=Aktuell: -ColorChooser.hsbNameText=HSB # Each of the ColorChooser types can define a mnemonic, as a KeyEvent.VK_XXX # constant, and an index into the text to render the mnemonic as. The # mnemonic is xxxMnemonic and the index of the character to underline is # xxxDisplayedMnemonicIndex. -ColorChooser.hsbMnemonic=72 -ColorChooser.hsbDisplayedMnemonicIndex=0 -ColorChooser.hsbHueText=H -ColorChooser.hsbSaturationText=S -ColorChooser.hsbBrightnessText=B -ColorChooser.hsbRedText=R -ColorChooser.hsbGreenText=G -ColorChooser.hsbBlueText=B +ColorChooser.hsvNameText=HSV +ColorChooser.hsvMnemonic=72 +ColorChooser.hsvHueText=Hue +ColorChooser.hsvSaturationText=Saturation +ColorChooser.hsvValueText=Value +ColorChooser.hsvTransparencyText=Transparency +ColorChooser.hslNameText=HSL +ColorChooser.hslMnemonic=76 +ColorChooser.hslHueText=Hue +ColorChooser.hslSaturationText=Saturation +ColorChooser.hslLightnessText=Lightness +ColorChooser.hslTransparencyText=Transparency ColorChooser.rgbNameText=RGB ColorChooser.rgbMnemonic=71 -ColorChooser.rgbDisplayedMnemonicIndex=1 ColorChooser.rgbRedText=Rot ColorChooser.rgbRedMnemonic=82 ColorChooser.rgbGreenText=Gr\u00fcn ColorChooser.rgbGreenMnemonic=78 ColorChooser.rgbBlueText=Blau ColorChooser.rgbBlueMnemonic=66 +ColorChooser.rgbAlphaText=Alpha +ColorChooser.rgbHexCodeText=Color Code +ColorChooser.rgbHexCodeMnemonic=67 +ColorChooser.cmykNameText=CMYK +ColorChooser.cmykMnemonic=77 +ColorChooser.cmykCyanText=Cyan +ColorChooser.cmykMagentaText=Magenta +ColorChooser.cmykYellowText=Yellow +ColorChooser.cmykBlackText=Black +ColorChooser.cmykAlphaText=Alpha ############ OPTION PANE STRINGS ############# # Mnemonic keys correspond to KeyEvent.VK_XXX constant diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_es.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_es.properties index b553b26f065..75877dd6560 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_es.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_es.properties @@ -101,30 +101,41 @@ ColorChooser.resetMnemonic=82 ColorChooser.sampleText=Texto de ejemplo Texto de ejemplo ColorChooser.swatchesNameText=Muestras ColorChooser.swatchesMnemonic=77 -ColorChooser.swatchesDisplayedMnemonicIndex=0 ColorChooser.swatchesRecentText=Reciente: -ColorChooser.hsbNameText=HSB # Each of the ColorChooser types can define a mnemonic, as a KeyEvent.VK_XXX # constant, and an index into the text to render the mnemonic as. The # mnemonic is xxxMnemonic and the index of the character to underline is # xxxDisplayedMnemonicIndex. -ColorChooser.hsbMnemonic=72 -ColorChooser.hsbDisplayedMnemonicIndex=0 -ColorChooser.hsbHueText=H -ColorChooser.hsbSaturationText=S -ColorChooser.hsbBrightnessText=B -ColorChooser.hsbRedText=R -ColorChooser.hsbGreenText=V -ColorChooser.hsbBlueText=A +ColorChooser.hsvNameText=HSV +ColorChooser.hsvMnemonic=72 +ColorChooser.hsvHueText=Hue +ColorChooser.hsvSaturationText=Saturation +ColorChooser.hsvValueText=Value +ColorChooser.hsvTransparencyText=Transparency +ColorChooser.hslNameText=HSL +ColorChooser.hslMnemonic=76 +ColorChooser.hslHueText=Hue +ColorChooser.hslSaturationText=Saturation +ColorChooser.hslLightnessText=Lightness +ColorChooser.hslTransparencyText=Transparency ColorChooser.rgbNameText=RGB ColorChooser.rgbMnemonic=71 -ColorChooser.rgbDisplayedMnemonicIndex=1 ColorChooser.rgbRedText=Rojo ColorChooser.rgbRedMnemonic=74 ColorChooser.rgbGreenText=Verde ColorChooser.rgbGreenMnemonic=86 ColorChooser.rgbBlueText=Azul ColorChooser.rgbBlueMnemonic=76 +ColorChooser.rgbAlphaText=Alpha +ColorChooser.rgbHexCodeText=Color Code +ColorChooser.rgbHexCodeMnemonic=67 +ColorChooser.cmykNameText=CMYK +ColorChooser.cmykMnemonic=77 +ColorChooser.cmykCyanText=Cyan +ColorChooser.cmykMagentaText=Magenta +ColorChooser.cmykYellowText=Yellow +ColorChooser.cmykBlackText=Black +ColorChooser.cmykAlphaText=Alpha ############ OPTION PANE STRINGS ############# # Mnemonic keys correspond to KeyEvent.VK_XXX constant diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_fr.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_fr.properties index b18de0274a8..333a1a82fa1 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_fr.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_fr.properties @@ -101,30 +101,41 @@ ColorChooser.resetMnemonic=82 ColorChooser.sampleText=Echantillon de texte Echantillon de texte ColorChooser.swatchesNameText=Echantillons ColorChooser.swatchesMnemonic=69 -ColorChooser.swatchesDisplayedMnemonicIndex=0 ColorChooser.swatchesRecentText=Dernier : -ColorChooser.hsbNameText=HSB # Each of the ColorChooser types can define a mnemonic, as a KeyEvent.VK_XXX # constant, and an index into the text to render the mnemonic as. The # mnemonic is xxxMnemonic and the index of the character to underline is # xxxDisplayedMnemonicIndex. -ColorChooser.hsbMnemonic=72 -ColorChooser.hsbDisplayedMnemonicIndex=0 -ColorChooser.hsbHueText=H -ColorChooser.hsbSaturationText=S -ColorChooser.hsbBrightnessText=B -ColorChooser.hsbRedText=R -ColorChooser.hsbGreenText=V -ColorChooser.hsbBlueText=B +ColorChooser.hsvNameText=HSV +ColorChooser.hsvMnemonic=72 +ColorChooser.hsvHueText=Hue +ColorChooser.hsvSaturationText=Saturation +ColorChooser.hsvValueText=Value +ColorChooser.hsvTransparencyText=Transparency +ColorChooser.hslNameText=HSL +ColorChooser.hslMnemonic=76 +ColorChooser.hslHueText=Hue +ColorChooser.hslSaturationText=Saturation +ColorChooser.hslLightnessText=Lightness +ColorChooser.hslTransparencyText=Transparency ColorChooser.rgbNameText=RVB ColorChooser.rgbMnemonic=86 -ColorChooser.rgbDisplayedMnemonicIndex=1 ColorChooser.rgbRedText=Rouge ColorChooser.rgbRedMnemonic=71 ColorChooser.rgbGreenText=Vert ColorChooser.rgbGreenMnemonic=84 ColorChooser.rgbBlueText=Bleu ColorChooser.rgbBlueMnemonic=66 +ColorChooser.rgbAlphaText=Alpha +ColorChooser.rgbHexCodeText=Color Code +ColorChooser.rgbHexCodeMnemonic=67 +ColorChooser.cmykNameText=CMYK +ColorChooser.cmykMnemonic=77 +ColorChooser.cmykCyanText=Cyan +ColorChooser.cmykMagentaText=Magenta +ColorChooser.cmykYellowText=Yellow +ColorChooser.cmykBlackText=Black +ColorChooser.cmykAlphaText=Alpha ############ OPTION PANE STRINGS ############# # Mnemonic keys correspond to KeyEvent.VK_XXX constant diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_it.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_it.properties index 1c9f3790e6f..7bc69dbcf5e 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_it.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_it.properties @@ -101,30 +101,41 @@ ColorChooser.resetMnemonic=82 ColorChooser.sampleText=Testo di prova Testo di prova ColorChooser.swatchesNameText=Colori campione ColorChooser.swatchesMnemonic=67 -ColorChooser.swatchesDisplayedMnemonicIndex=0 ColorChooser.swatchesRecentText=Recenti: -ColorChooser.hsbNameText=HSB # Each of the ColorChooser types can define a mnemonic, as a KeyEvent.VK_XXX # constant, and an index into the text to render the mnemonic as. The # mnemonic is xxxMnemonic and the index of the character to underline is # xxxDisplayedMnemonicIndex. -ColorChooser.hsbMnemonic=72 -ColorChooser.hsbDisplayedMnemonicIndex=0 -ColorChooser.hsbHueText=H -ColorChooser.hsbSaturationText=S -ColorChooser.hsbBrightnessText=B -ColorChooser.hsbRedText=R -ColorChooser.hsbGreenText=G -ColorChooser.hsbBlueText=B +ColorChooser.hsvNameText=HSV +ColorChooser.hsvMnemonic=72 +ColorChooser.hsvHueText=Hue +ColorChooser.hsvSaturationText=Saturation +ColorChooser.hsvValueText=Value +ColorChooser.hsvTransparencyText=Transparency +ColorChooser.hslNameText=HSL +ColorChooser.hslMnemonic=76 +ColorChooser.hslHueText=Hue +ColorChooser.hslSaturationText=Saturation +ColorChooser.hslLightnessText=Lightness +ColorChooser.hslTransparencyText=Transparency ColorChooser.rgbNameText=RGB ColorChooser.rgbMnemonic=71 -ColorChooser.rgbDisplayedMnemonicIndex=1 ColorChooser.rgbRedText=Rosso ColorChooser.rgbRedMnemonic=79 ColorChooser.rgbGreenText=Verde ColorChooser.rgbGreenMnemonic=69 ColorChooser.rgbBlueText=Blu ColorChooser.rgbBlueMnemonic=66 +ColorChooser.rgbAlphaText=Alpha +ColorChooser.rgbHexCodeText=Color Code +ColorChooser.rgbHexCodeMnemonic=67 +ColorChooser.cmykNameText=CMYK +ColorChooser.cmykMnemonic=77 +ColorChooser.cmykCyanText=Cyan +ColorChooser.cmykMagentaText=Magenta +ColorChooser.cmykYellowText=Yellow +ColorChooser.cmykBlackText=Black +ColorChooser.cmykAlphaText=Alpha ############ OPTION PANE STRINGS ############# # Mnemonic keys correspond to KeyEvent.VK_XXX constant diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties index 1b5a131cabd..5603e9aa1bc 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties @@ -101,30 +101,41 @@ ColorChooser.resetMnemonic=82 ColorChooser.sampleText=\u30b5\u30f3\u30d7\u30eb\u30c6\u30ad\u30b9\u30c8 \u30b5\u30f3\u30d7\u30eb\u30c6\u30ad\u30b9\u30c8 ColorChooser.swatchesNameText=\u30b5\u30f3\u30d7\u30eb(S) ColorChooser.swatchesMnemonic=83 -ColorChooser.swatchesDisplayedMnemonicIndex=5 ColorChooser.swatchesRecentText=\u6700\u65b0: -ColorChooser.hsbNameText=HSB # Each of the ColorChooser types can define a mnemonic, as a KeyEvent.VK_XXX # constant, and an index into the text to render the mnemonic as. The # mnemonic is xxxMnemonic and the index of the character to underline is # xxxDisplayedMnemonicIndex. -ColorChooser.hsbMnemonic=72 -ColorChooser.hsbDisplayedMnemonicIndex=0 -ColorChooser.hsbHueText=H -ColorChooser.hsbSaturationText=S -ColorChooser.hsbBrightnessText=B -ColorChooser.hsbRedText=R -ColorChooser.hsbGreenText=G -ColorChooser.hsbBlueText=B +ColorChooser.hsvNameText=HSV +ColorChooser.hsvMnemonic=72 +ColorChooser.hsvHueText=Hue +ColorChooser.hsvSaturationText=Saturation +ColorChooser.hsvValueText=Value +ColorChooser.hsvTransparencyText=Transparency +ColorChooser.hslNameText=HSL +ColorChooser.hslMnemonic=76 +ColorChooser.hslHueText=Hue +ColorChooser.hslSaturationText=Saturation +ColorChooser.hslLightnessText=Lightness +ColorChooser.hslTransparencyText=Transparency ColorChooser.rgbNameText=RGB ColorChooser.rgbMnemonic=71 -ColorChooser.rgbDisplayedMnemonicIndex=1 ColorChooser.rgbRedText=\u8d64(D) ColorChooser.rgbRedMnemonic=68 ColorChooser.rgbGreenText=\u7dd1(N) ColorChooser.rgbGreenMnemonic=78 ColorChooser.rgbBlueText=\u9752(B) ColorChooser.rgbBlueMnemonic=66 +ColorChooser.rgbAlphaText=Alpha +ColorChooser.rgbHexCodeText=Color Code +ColorChooser.rgbHexCodeMnemonic=67 +ColorChooser.cmykNameText=CMYK +ColorChooser.cmykMnemonic=77 +ColorChooser.cmykCyanText=Cyan +ColorChooser.cmykMagentaText=Magenta +ColorChooser.cmykYellowText=Yellow +ColorChooser.cmykBlackText=Black +ColorChooser.cmykAlphaText=Alpha ############ OPTION PANE STRINGS ############# # Mnemonic keys correspond to KeyEvent.VK_XXX constant diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties index 9b873a43a61..f3866d01f31 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties @@ -101,30 +101,41 @@ ColorChooser.resetMnemonic=82 ColorChooser.sampleText=\uc0d8\ud50c \ud14d\uc2a4\ud2b8 \uc0d8\ud50c \ud14d\uc2a4\ud2b8 ColorChooser.swatchesNameText=\uacac\ubcf8(S) ColorChooser.swatchesMnemonic=83 -ColorChooser.swatchesDisplayedMnemonicIndex=3 ColorChooser.swatchesRecentText=\ucd5c\uadfc \ubaa9\ub85d: -ColorChooser.hsbNameText=HSB # Each of the ColorChooser types can define a mnemonic, as a KeyEvent.VK_XXX # constant, and an index into the text to render the mnemonic as. The # mnemonic is xxxMnemonic and the index of the character to underline is # xxxDisplayedMnemonicIndex. -ColorChooser.hsbMnemonic=72 -ColorChooser.hsbDisplayedMnemonicIndex=0 -ColorChooser.hsbHueText=H -ColorChooser.hsbSaturationText=S -ColorChooser.hsbBrightnessText=B -ColorChooser.hsbRedText=R -ColorChooser.hsbGreenText=G -ColorChooser.hsbBlueText=B +ColorChooser.hsvNameText=HSV +ColorChooser.hsvMnemonic=72 +ColorChooser.hsvHueText=Hue +ColorChooser.hsvSaturationText=Saturation +ColorChooser.hsvValueText=Value +ColorChooser.hsvTransparencyText=Transparency +ColorChooser.hslNameText=HSL +ColorChooser.hslMnemonic=76 +ColorChooser.hslHueText=Hue +ColorChooser.hslSaturationText=Saturation +ColorChooser.hslLightnessText=Lightness +ColorChooser.hslTransparencyText=Transparency ColorChooser.rgbNameText=RGB ColorChooser.rgbMnemonic=71 -ColorChooser.rgbDisplayedMnemonicIndex=1 ColorChooser.rgbRedText=\ube68\uac04\uc0c9(D) ColorChooser.rgbRedMnemonic=68 ColorChooser.rgbGreenText=\ub179\uc0c9(N) ColorChooser.rgbGreenMnemonic=78 ColorChooser.rgbBlueText=\ud30c\ub780\uc0c9(B) ColorChooser.rgbBlueMnemonic=66 +ColorChooser.rgbAlphaText=Alpha +ColorChooser.rgbHexCodeText=Color Code +ColorChooser.rgbHexCodeMnemonic=67 +ColorChooser.cmykNameText=CMYK +ColorChooser.cmykMnemonic=77 +ColorChooser.cmykCyanText=Cyan +ColorChooser.cmykMagentaText=Magenta +ColorChooser.cmykYellowText=Yellow +ColorChooser.cmykBlackText=Black +ColorChooser.cmykAlphaText=Alpha ############ OPTION PANE STRINGS ############# # Mnemonic keys correspond to KeyEvent.VK_XXX constant diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_sv.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_sv.properties index 2b8561b812e..17ef3b2be26 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_sv.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_sv.properties @@ -101,30 +101,41 @@ ColorChooser.resetMnemonic=84 ColorChooser.sampleText=Exempeltext Exempeltext ColorChooser.swatchesNameText=Prov ColorChooser.swatchesMnemonic=80 -ColorChooser.swatchesDisplayedMnemonicIndex=0 ColorChooser.swatchesRecentText=Tidigare: -ColorChooser.hsbNameText=HSB # Each of the ColorChooser types can define a mnemonic, as a KeyEvent.VK_XXX # constant, and an index into the text to render the mnemonic as. The # mnemonic is xxxMnemonic and the index of the character to underline is # xxxDisplayedMnemonicIndex. -ColorChooser.hsbMnemonic=72 -ColorChooser.hsbDisplayedMnemonicIndex=0 -ColorChooser.hsbHueText=H -ColorChooser.hsbSaturationText=S -ColorChooser.hsbBrightnessText=B -ColorChooser.hsbRedText=R -ColorChooser.hsbGreenText=G -ColorChooser.hsbBlueText=B +ColorChooser.hsvNameText=HSV +ColorChooser.hsvMnemonic=72 +ColorChooser.hsvHueText=Hue +ColorChooser.hsvSaturationText=Saturation +ColorChooser.hsvValueText=Value +ColorChooser.hsvTransparencyText=Transparency +ColorChooser.hslNameText=HSL +ColorChooser.hslMnemonic=76 +ColorChooser.hslHueText=Hue +ColorChooser.hslSaturationText=Saturation +ColorChooser.hslLightnessText=Lightness +ColorChooser.hslTransparencyText=Transparency ColorChooser.rgbNameText=RGB ColorChooser.rgbMnemonic=71 -ColorChooser.rgbDisplayedMnemonicIndex=1 ColorChooser.rgbRedText=R\u00f6d ColorChooser.rgbRedMnemonic=82 ColorChooser.rgbGreenText=Gr\u00f6n ColorChooser.rgbGreenMnemonic=71 ColorChooser.rgbBlueText=Bl\u00e5 ColorChooser.rgbBlueMnemonic=66 +ColorChooser.rgbAlphaText=Alpha +ColorChooser.rgbHexCodeText=Color Code +ColorChooser.rgbHexCodeMnemonic=67 +ColorChooser.cmykNameText=CMYK +ColorChooser.cmykMnemonic=77 +ColorChooser.cmykCyanText=Cyan +ColorChooser.cmykMagentaText=Magenta +ColorChooser.cmykYellowText=Yellow +ColorChooser.cmykBlackText=Black +ColorChooser.cmykAlphaText=Alpha ############ OPTION PANE STRINGS ############# # Mnemonic keys correspond to KeyEvent.VK_XXX constant diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties index 7ef35330d86..b030c20a944 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties @@ -101,30 +101,41 @@ ColorChooser.resetMnemonic=82 ColorChooser.sampleText=\u6837\u54c1\u6587\u672c \u6837\u54c1\u6587\u672c ColorChooser.swatchesNameText=\u6837\u54c1(S) ColorChooser.swatchesMnemonic=83 -ColorChooser.swatchesDisplayedMnemonicIndex=3 ColorChooser.swatchesRecentText=\u6700\u8fd1: -ColorChooser.hsbNameText=HSB # Each of the ColorChooser types can define a mnemonic, as a KeyEvent.VK_XXX # constant, and an index into the text to render the mnemonic as. The # mnemonic is xxxMnemonic and the index of the character to underline is # xxxDisplayedMnemonicIndex. -ColorChooser.hsbMnemonic=72 -ColorChooser.hsbDisplayedMnemonicIndex=0 -ColorChooser.hsbHueText=H -ColorChooser.hsbSaturationText=S -ColorChooser.hsbBrightnessText=B -ColorChooser.hsbRedText=R -ColorChooser.hsbGreenText=G -ColorChooser.hsbBlueText=B +ColorChooser.hsvNameText=HSV +ColorChooser.hsvMnemonic=72 +ColorChooser.hsvHueText=Hue +ColorChooser.hsvSaturationText=Saturation +ColorChooser.hsvValueText=Value +ColorChooser.hsvTransparencyText=Transparency +ColorChooser.hslNameText=HSL +ColorChooser.hslMnemonic=76 +ColorChooser.hslHueText=Hue +ColorChooser.hslSaturationText=Saturation +ColorChooser.hslLightnessText=Lightness +ColorChooser.hslTransparencyText=Transparency ColorChooser.rgbNameText=RGB ColorChooser.rgbMnemonic=71 -ColorChooser.rgbDisplayedMnemonicIndex=1 ColorChooser.rgbRedText=\u7ea2 ColorChooser.rgbRedMnemonic=68 ColorChooser.rgbGreenText=\u7eff ColorChooser.rgbGreenMnemonic=78 ColorChooser.rgbBlueText=\u84dd ColorChooser.rgbBlueMnemonic=66 +ColorChooser.rgbAlphaText=Alpha +ColorChooser.rgbHexCodeText=Color Code +ColorChooser.rgbHexCodeMnemonic=67 +ColorChooser.cmykNameText=CMYK +ColorChooser.cmykMnemonic=77 +ColorChooser.cmykCyanText=Cyan +ColorChooser.cmykMagentaText=Magenta +ColorChooser.cmykYellowText=Yellow +ColorChooser.cmykBlackText=Black +ColorChooser.cmykAlphaText=Alpha ############ OPTION PANE STRINGS ############# # Mnemonic keys correspond to KeyEvent.VK_XXX constant diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties index dba0d76de28..47f99f0dcc9 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties @@ -101,30 +101,41 @@ ColorChooser.resetMnemonic=82 ColorChooser.sampleText=\u7bc4\u4f8b\u6587\u5b57 \u7bc4\u4f8b\u6587\u5b57 ColorChooser.swatchesNameText=\u8abf\u8272\u677f(S) ColorChooser.swatchesMnemonic=83 -ColorChooser.swatchesDisplayedMnemonicIndex=4 ColorChooser.swatchesRecentText=\u6700\u65b0\u9078\u64c7: -ColorChooser.hsbNameText=HSB # Each of the ColorChooser types can define a mnemonic, as a KeyEvent.VK_XXX # constant, and an index into the text to render the mnemonic as. The # mnemonic is xxxMnemonic and the index of the character to underline is # xxxDisplayedMnemonicIndex. -ColorChooser.hsbMnemonic=72 -ColorChooser.hsbDisplayedMnemonicIndex=0 -ColorChooser.hsbHueText=H -ColorChooser.hsbSaturationText=S -ColorChooser.hsbBrightnessText=B -ColorChooser.hsbRedText=R -ColorChooser.hsbGreenText=G -ColorChooser.hsbBlueText=B +ColorChooser.hsvNameText=HSV +ColorChooser.hsvMnemonic=72 +ColorChooser.hsvHueText=Hue +ColorChooser.hsvSaturationText=Saturation +ColorChooser.hsvValueText=Value +ColorChooser.hsvTransparencyText=Transparency +ColorChooser.hslNameText=HSL +ColorChooser.hslMnemonic=76 +ColorChooser.hslHueText=Hue +ColorChooser.hslSaturationText=Saturation +ColorChooser.hslLightnessText=Lightness +ColorChooser.hslTransparencyText=Transparency ColorChooser.rgbNameText=RGB ColorChooser.rgbMnemonic=71 -ColorChooser.rgbDisplayedMnemonicIndex=1 ColorChooser.rgbRedText=\u7d05\u8272(D) ColorChooser.rgbRedMnemonic=68 ColorChooser.rgbGreenText=\u7da0\u8272(N) ColorChooser.rgbGreenMnemonic=78 ColorChooser.rgbBlueText=\u85cd\u8272(B) ColorChooser.rgbBlueMnemonic=66 +ColorChooser.rgbAlphaText=Alpha +ColorChooser.rgbHexCodeText=Color Code +ColorChooser.rgbHexCodeMnemonic=67 +ColorChooser.cmykNameText=CMYK +ColorChooser.cmykMnemonic=77 +ColorChooser.cmykCyanText=Cyan +ColorChooser.cmykMagentaText=Magenta +ColorChooser.cmykYellowText=Yellow +ColorChooser.cmykBlackText=Black +ColorChooser.cmykAlphaText=Alpha ############ OPTION PANE STRINGS ############# # Mnemonic keys correspond to KeyEvent.VK_XXX constant diff --git a/jdk/src/share/classes/com/sun/tools/extcheck/ExtCheck.java b/jdk/src/share/classes/com/sun/tools/extcheck/ExtCheck.java index b83381a6514..b69cf00cd8b 100644 --- a/jdk/src/share/classes/com/sun/tools/extcheck/ExtCheck.java +++ b/jdk/src/share/classes/com/sun/tools/extcheck/ExtCheck.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -256,13 +256,13 @@ public class ExtCheck { private boolean isNotOlderThan(String already,String target) throws NumberFormatException { - if (already == null || already.length() < 1) { + if (already == null || already.length() < 1) { throw new NumberFormatException("Empty version string"); } - // Until it matches scan and compare numbers - StringTokenizer dtok = new StringTokenizer(target, ".", true); - StringTokenizer stok = new StringTokenizer(already, ".", true); + // Until it matches scan and compare numbers + StringTokenizer dtok = new StringTokenizer(target, ".", true); + StringTokenizer stok = new StringTokenizer(already, ".", true); while (dtok.hasMoreTokens() || stok.hasMoreTokens()) { int dver; int sver; @@ -276,19 +276,19 @@ public class ExtCheck { } else sver = 0; - if (sver < dver) - return false; // Known to be incompatible - if (sver > dver) - return true; // Known to be compatible + if (sver < dver) + return false; // Known to be incompatible + if (sver > dver) + return true; // Known to be compatible - // Check for and absorb separators - if (dtok.hasMoreTokens()) - dtok.nextToken(); - if (stok.hasMoreTokens()) - stok.nextToken(); - // Compare next component - } - // All components numerically equal + // Check for and absorb separators + if (dtok.hasMoreTokens()) + dtok.nextToken(); + if (stok.hasMoreTokens()) + stok.nextToken(); + // Compare next component + } + // All components numerically equal return true; } @@ -307,11 +307,10 @@ public class ExtCheck { } /** - * Print out the error message and exit from the program + * Throws a RuntimeException with a message describing the error. */ - static void error(String message){ - System.err.println(message); - System.exit(-1); + static void error(String message) throws RuntimeException { + throw new RuntimeException(message); } @@ -356,19 +355,19 @@ public class ExtCheck { } private JarFile findJarFile(URL url) throws IOException { - // Optimize case where url refers to a local jar file - if ("file".equals(url.getProtocol())) { - String path = url.getFile().replace('/', File.separatorChar); - File file = new File(path); - if (!file.exists()) { - throw new FileNotFoundException(path); - } - return new JarFile(path); - } - URLConnection uc = getBaseURL().openConnection(); - //uc.setRequestProperty(USER_AGENT_JAVA_VERSION, JAVA_VERSION); - return ((JarURLConnection)uc).getJarFile(); - } + // Optimize case where url refers to a local jar file + if ("file".equals(url.getProtocol())) { + String path = url.getFile().replace('/', File.separatorChar); + File file = new File(path); + if (!file.exists()) { + throw new FileNotFoundException(path); + } + return new JarFile(path); + } + URLConnection uc = getBaseURL().openConnection(); + //uc.setRequestProperty(USER_AGENT_JAVA_VERSION, JAVA_VERSION); + return ((JarURLConnection)uc).getJarFile(); + } /* diff --git a/jdk/src/share/classes/com/sun/tools/extcheck/Main.java b/jdk/src/share/classes/com/sun/tools/extcheck/Main.java index 893af063f46..022346efc13 100644 --- a/jdk/src/share/classes/com/sun/tools/extcheck/Main.java +++ b/jdk/src/share/classes/com/sun/tools/extcheck/Main.java @@ -1,5 +1,5 @@ /* - * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,10 @@ import java.io.*; */ public final class Main { - + public static final String INSUFFICIENT = "Insufficient number of arguments"; + public static final String MISSING = "Missing argument"; + public static final String DOES_NOT_EXIST = "Jarfile does not exist: "; + public static final String EXTRA = "Extra command line argument: "; /** * Terminates with one of the following codes @@ -40,26 +43,36 @@ public final class Main { * 0 No newer jar file was found * -1 An internal error occurred */ - public static void main(String args[]){ - - if (args.length < 1){ - System.err.println("Usage: extcheck [-verbose] "); + public static void main(String args[]) { + try { + realMain(args); + } catch (Exception ex) { + System.err.println(ex.getMessage()); System.exit(-1); } + } + + public static void realMain(String[] args) throws Exception { + if (args.length < 1) { + usage(INSUFFICIENT); + } int argIndex = 0; boolean verboseFlag = false; - if (args[argIndex].equals("-verbose")){ + if (args[argIndex].equals("-verbose")) { verboseFlag = true; argIndex++; + if (argIndex >= args.length) { + usage(MISSING); + } } String jarName = args[argIndex]; argIndex++; File jarFile = new File(jarName); if (!jarFile.exists()){ - ExtCheck.error("Jarfile " + jarName + " does not exist"); + usage(DOES_NOT_EXIST + jarName); } if (argIndex < args.length) { - ExtCheck.error("Extra command line argument :"+args[argIndex]); + usage(EXTRA + args[argIndex]); } ExtCheck jt = ExtCheck.create(jarFile,verboseFlag); boolean result = jt.checkInstalledAgainstTarget(); @@ -68,7 +81,10 @@ public final class Main { } else { System.exit(1); } - } + private static void usage(String msg) throws Exception { + throw new Exception(msg + "\nUsage: extcheck [-verbose] "); + } } + diff --git a/jdk/src/share/classes/com/sun/tools/hat/internal/parser/HprofReader.java b/jdk/src/share/classes/com/sun/tools/hat/internal/parser/HprofReader.java index df09dd5c5b6..1bbac940f89 100644 --- a/jdk/src/share/classes/com/sun/tools/hat/internal/parser/HprofReader.java +++ b/jdk/src/share/classes/com/sun/tools/hat/internal/parser/HprofReader.java @@ -120,7 +120,7 @@ public class HprofReader extends Reader /* imports */ implements ArrayTypeCodes private int version; // The version of .hprof being read private int debugLevel; - private int currPos; // Current position in the file + private long currPos; // Current position in the file private int dumpsToSkip; private boolean callStack; // If true, read the call stack of objects @@ -196,7 +196,9 @@ public class HprofReader extends Reader /* imports */ implements ArrayTypeCodes break; } in.readInt(); // Timestamp of this record - int length = in.readInt(); + // Length of record: readInt() will return negative value for record + // length >2GB. so store 32bit value in long to keep it unsigned. + long length = in.readInt() & 0xffffffffL; if (debugLevel > 0) { System.out.println("Read record type " + type + ", length " + length @@ -211,7 +213,7 @@ public class HprofReader extends Reader /* imports */ implements ArrayTypeCodes switch (type) { case HPROF_UTF8: { long id = readID(); - byte[] chars = new byte[length - identifierSize]; + byte[] chars = new byte[(int)length - identifierSize]; in.readFully(chars); names.put(new Long(id), new String(chars)); break; @@ -351,8 +353,8 @@ public class HprofReader extends Reader /* imports */ implements ArrayTypeCodes return snapshot; } - private void skipBytes(int length) throws IOException { - in.skipBytes(length); + private void skipBytes(long length) throws IOException { + in.skipBytes((int)length); } private int readVersionHeader() throws IOException { @@ -381,7 +383,7 @@ public class HprofReader extends Reader /* imports */ implements ArrayTypeCodes throw new IOException("Version string not recognized at byte " + (pos+3)); } - private void readHeapDump(int bytesLeft, int posAtEnd) throws IOException { + private void readHeapDump(long bytesLeft, long posAtEnd) throws IOException { while (bytesLeft > 0) { int type = in.readUnsignedByte(); if (debugLevel > 0) { diff --git a/jdk/src/share/classes/com/sun/tools/jdi/MonitorInfoImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/MonitorInfoImpl.java index ea2f49da5aa..6653199d791 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/MonitorInfoImpl.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/MonitorInfoImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/com/sun/tools/jdi/ThreadReferenceImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/ThreadReferenceImpl.java index 7af01561e9b..eda2dfc747f 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/ThreadReferenceImpl.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/ThreadReferenceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,7 +61,8 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl private ThreadGroupReference threadGroup; // This is cached only while this one thread is suspended. Each time - // the thread is resumed, we clear this and start with a fresh one. + // the thread is resumed, we abandon the current cache object and + // create a new intialized one. private static class LocalCache { JDWP.ThreadReference.Status status = null; List frames = null; @@ -74,6 +75,28 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl boolean triedCurrentContended = false; } + /* + * The localCache instance var is set by resetLocalCache to an initialized + * object as shown above. This occurs when the ThreadReference + * object is created, and when the mirrored thread is resumed. + * The fields are then filled in by the relevant methods as they + * are called. A problem can occur if resetLocalCache is called + * (ie, a resume() is executed) at certain points in the execution + * of some of these methods - see 6751643. To avoid this, each + * method that wants to use this cache must make a local copy of + * this variable and use that. This means that each invocation of + * these methods will use a copy of the cache object that was in + * effect at the point that the copy was made; if a racy resume + * occurs, it won't affect the method's local copy. This means that + * the values returned by these calls may not match the state of + * the debuggee at the time the caller gets the values. EG, + * frameCount() is called and comes up with 5 frames. But before + * it returns this, a resume of the debuggee thread is executed in a + * different debugger thread. The thread is resumed and running at + * the time that the value 5 is returned. Or even worse, the thread + * could be suspended again and have a different number of frames, eg, 24, + * but this call will still return 5. + */ private LocalCache localCache; private void resetLocalCache() { @@ -129,8 +152,9 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl } /** - * Note that we only cache the name string while suspended because - * it can change via Thread.setName arbitrarily + * Note that we only cache the name string while the entire VM is suspended + * because the name can change via Thread.setName arbitrarily while this + * thread is running. */ public String name() { String name = null; @@ -240,19 +264,20 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl } private JDWP.ThreadReference.Status jdwpStatus() { - JDWP.ThreadReference.Status myStatus = localCache.status; + LocalCache snapshot = localCache; + JDWP.ThreadReference.Status myStatus = snapshot.status; try { if (myStatus == null) { myStatus = JDWP.ThreadReference.Status.process(vm, this); if ((myStatus.suspendStatus & SUSPEND_STATUS_SUSPENDED) != 0) { // thread is suspended, we can cache the status. - localCache.status = myStatus; + snapshot.status = myStatus; } } } catch (JDWPException exc) { throw exc.toJDIException(); } - return myStatus; + return myStatus; } public int status() { @@ -304,9 +329,10 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl } public int frameCount() throws IncompatibleThreadStateException { + LocalCache snapshot = localCache; try { - if (localCache.frameCount == -1) { - localCache.frameCount = JDWP.ThreadReference.FrameCount + if (snapshot.frameCount == -1) { + snapshot.frameCount = JDWP.ThreadReference.FrameCount .process(vm, this).frameCount; } } catch (JDWPException exc) { @@ -318,7 +344,7 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl throw exc.toJDIException(); } } - return localCache.frameCount; + return snapshot.frameCount; } public List frames() throws IncompatibleThreadStateException { @@ -335,22 +361,22 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl * local is known to be non-null. Should only be called from * a sync method. */ - private boolean isSubrange(LocalCache localCache, + private boolean isSubrange(LocalCache snapshot, int start, int length) { - if (start < localCache.framesStart) { + if (start < snapshot.framesStart) { return false; } if (length == -1) { - return (localCache.framesLength == -1); + return (snapshot.framesLength == -1); } - if (localCache.framesLength == -1) { - if ((start + length) > (localCache.framesStart + - localCache.frames.size())) { + if (snapshot.framesLength == -1) { + if ((start + length) > (snapshot.framesStart + + snapshot.frames.size())) { throw new IndexOutOfBoundsException(); } return true; } - return ((start + length) <= (localCache.framesStart + localCache.framesLength)); + return ((start + length) <= (snapshot.framesStart + snapshot.framesLength)); } public List frames(int start, int length) @@ -371,14 +397,14 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl // Lock must be held while creating stack frames so if that two threads // do this at the same time, one won't clobber the subset created by the other. - + LocalCache snapshot = localCache; try { - if (localCache.frames == null || !isSubrange(localCache, start, length)) { + if (snapshot.frames == null || !isSubrange(snapshot, start, length)) { JDWP.ThreadReference.Frames.Frame[] jdwpFrames = JDWP.ThreadReference.Frames. process(vm, this, start, length).frames; int count = jdwpFrames.length; - localCache.frames = new ArrayList(count); + snapshot.frames = new ArrayList(count); for (int i = 0; i ownedMonitors() throws IncompatibleThreadStateException { + LocalCache snapshot = localCache; try { - if (localCache.ownedMonitors == null) { - localCache.ownedMonitors = Arrays.asList( + if (snapshot.ownedMonitors == null) { + snapshot.ownedMonitors = Arrays.asList( (ObjectReference[])JDWP.ThreadReference.OwnedMonitors. process(vm, this).owned); if ((vm.traceFlags & vm.TRACE_OBJREFS) != 0) { vm.printTrace(description() + " temporarily caching owned monitors"+ - " (count = " + localCache.ownedMonitors.size() + ")"); + " (count = " + snapshot.ownedMonitors.size() + ")"); } } } catch (JDWPException exc) { @@ -435,54 +462,57 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl throw exc.toJDIException(); } } - return localCache.ownedMonitors; + return snapshot.ownedMonitors; } public ObjectReference currentContendedMonitor() throws IncompatibleThreadStateException { + LocalCache snapshot = localCache; try { - if (localCache.contendedMonitor == null && - !localCache.triedCurrentContended) { - localCache.contendedMonitor = JDWP.ThreadReference.CurrentContendedMonitor. + if (snapshot.contendedMonitor == null && + !snapshot.triedCurrentContended) { + snapshot.contendedMonitor = JDWP.ThreadReference.CurrentContendedMonitor. process(vm, this).monitor; - localCache.triedCurrentContended = true; - if ((localCache.contendedMonitor != null) && + snapshot.triedCurrentContended = true; + if ((snapshot.contendedMonitor != null) && ((vm.traceFlags & vm.TRACE_OBJREFS) != 0)) { vm.printTrace(description() + " temporarily caching contended monitor"+ - " (id = " + localCache.contendedMonitor.uniqueID() + ")"); + " (id = " + snapshot.contendedMonitor.uniqueID() + ")"); } } } catch (JDWPException exc) { switch (exc.errorCode()) { + case JDWP.Error.THREAD_NOT_SUSPENDED: case JDWP.Error.INVALID_THREAD: /* zombie */ throw new IncompatibleThreadStateException(); default: throw exc.toJDIException(); } } - return localCache.contendedMonitor; + return snapshot.contendedMonitor; } public List ownedMonitorsAndFrames() throws IncompatibleThreadStateException { + LocalCache snapshot = localCache; try { - if (localCache.ownedMonitorsInfo == null) { + if (snapshot.ownedMonitorsInfo == null) { JDWP.ThreadReference.OwnedMonitorsStackDepthInfo.monitor[] minfo; minfo = JDWP.ThreadReference.OwnedMonitorsStackDepthInfo.process(vm, this).owned; - localCache.ownedMonitorsInfo = new ArrayList(minfo.length); + snapshot.ownedMonitorsInfo = new ArrayList(minfo.length); for (int i=0; i < minfo.length; i++) { JDWP.ThreadReference.OwnedMonitorsStackDepthInfo.monitor mi = minfo[i]; MonitorInfo mon = new MonitorInfoImpl(vm, minfo[i].monitor, this, minfo[i].stack_depth); - localCache.ownedMonitorsInfo.add(mon); + snapshot.ownedMonitorsInfo.add(mon); } if ((vm.traceFlags & vm.TRACE_OBJREFS) != 0) { vm.printTrace(description() + " temporarily caching owned monitors"+ - " (count = " + localCache.ownedMonitorsInfo.size() + ")"); + " (count = " + snapshot.ownedMonitorsInfo.size() + ")"); } } @@ -495,7 +525,7 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl throw exc.toJDIException(); } } - return localCache.ownedMonitorsInfo; + return snapshot.ownedMonitorsInfo; } public void popFrames(StackFrame frame) throws IncompatibleThreadStateException { diff --git a/jdk/src/share/classes/com/sun/tools/jdi/VMAction.java b/jdk/src/share/classes/com/sun/tools/jdi/VMAction.java index 7a5628e0acd..238824c88b4 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/VMAction.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/VMAction.java @@ -1,5 +1,5 @@ /* - * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/com/sun/tools/jdi/VMState.java b/jdk/src/share/classes/com/sun/tools/jdi/VMState.java index 789e5acdb73..762419797f9 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/VMState.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/VMState.java @@ -1,5 +1,5 @@ /* - * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/java/awt/EventDispatchThread.java b/jdk/src/share/classes/java/awt/EventDispatchThread.java index 35bde43447a..d12a4a67c40 100644 --- a/jdk/src/share/classes/java/awt/EventDispatchThread.java +++ b/jdk/src/share/classes/java/awt/EventDispatchThread.java @@ -39,6 +39,7 @@ import java.util.Vector; import java.util.logging.*; import sun.awt.dnd.SunDragSourceContextPeer; +import sun.awt.EventQueueDelegate; /** * EventDispatchThread is a package-private AWT class which takes @@ -243,10 +244,16 @@ class EventDispatchThread extends Thread { try { AWTEvent event; boolean eventOK; + EventQueueDelegate.Delegate delegate = + EventQueueDelegate.getDelegate(); do { - event = (id == ANY_EVENT) - ? theQueue.getNextEvent() - : theQueue.getNextEvent(id); + if (delegate != null && id == ANY_EVENT) { + event = delegate.getNextEvent(theQueue); + } else { + event = (id == ANY_EVENT) + ? theQueue.getNextEvent() + : theQueue.getNextEvent(id); + } eventOK = true; synchronized (eventFilters) { @@ -272,7 +279,14 @@ class EventDispatchThread extends Thread { eventLog.log(Level.FINEST, "Dispatching: " + event); } + Object handle = null; + if (delegate != null) { + handle = delegate.beforeDispatch(event); + } theQueue.dispatchEvent(event); + if (delegate != null) { + delegate.afterDispatch(event, handle); + } return true; } catch (ThreadDeath death) { diff --git a/jdk/src/share/classes/java/awt/EventQueue.java b/jdk/src/share/classes/java/awt/EventQueue.java index f9c26526210..9697ad5e9f5 100644 --- a/jdk/src/share/classes/java/awt/EventQueue.java +++ b/jdk/src/share/classes/java/awt/EventQueue.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/java/beans/DefaultPersistenceDelegate.java b/jdk/src/share/classes/java/beans/DefaultPersistenceDelegate.java index 6553a517200..5339aba83e4 100644 --- a/jdk/src/share/classes/java/beans/DefaultPersistenceDelegate.java +++ b/jdk/src/share/classes/java/beans/DefaultPersistenceDelegate.java @@ -298,7 +298,7 @@ public class DefaultPersistenceDelegate extends PersistenceDelegate { oldL = (EventListener[])MethodUtil.invoke(m, oldInstance, new Object[]{}); newL = (EventListener[])MethodUtil.invoke(m, newInstance, new Object[]{}); } - catch (Throwable e2) { + catch (Exception e2) { try { Method m = type.getMethod("getListeners", new Class[]{Class.class}); oldL = (EventListener[])MethodUtil.invoke(m, oldInstance, new Object[]{listenerType}); diff --git a/jdk/src/share/classes/java/beans/EventHandler.java b/jdk/src/share/classes/java/beans/EventHandler.java index 5b5be0528a6..2cc005c7927 100644 --- a/jdk/src/share/classes/java/beans/EventHandler.java +++ b/jdk/src/share/classes/java/beans/EventHandler.java @@ -404,7 +404,7 @@ public class EventHandler implements InvocationHandler { Object newTarget = MethodUtil.invoke(getter, target, new Object[]{}); return applyGetters(newTarget, rest); } - catch (Throwable e) { + catch (Exception e) { throw new RuntimeException("Failed to call method: " + first + " on " + target, e); } diff --git a/jdk/src/share/classes/java/beans/MetaData.java b/jdk/src/share/classes/java/beans/MetaData.java index 9bcd505c215..5d8fd697918 100644 --- a/jdk/src/share/classes/java/beans/MetaData.java +++ b/jdk/src/share/classes/java/beans/MetaData.java @@ -650,7 +650,7 @@ class java_util_Map_PersistenceDelegate extends DefaultPersistenceDelegate { // Remove the new elements. // Do this first otherwise we undo the adding work. if (newMap != null) { - for ( Object newKey : newMap.keySet() ) { + for (Object newKey : newMap.keySet().toArray()) { // PENDING: This "key" is not in the right environment. if (!oldMap.containsKey(newKey)) { invokeStatement(oldInstance, "remove", new Object[]{newKey}, out); @@ -986,14 +986,20 @@ class java_awt_Component_PersistenceDelegate extends DefaultPersistenceDelegate // null to defined values after the Windows are made visible - // special case them for now. if (!(oldInstance instanceof java.awt.Window)) { - String[] fieldNames = new String[]{"background", "foreground", "font"}; - for(int i = 0; i < fieldNames.length; i++) { - String name = fieldNames[i]; - Object oldValue = ReflectionUtils.getPrivateField(oldInstance, java.awt.Component.class, name, out.getExceptionListener()); - Object newValue = (newInstance == null) ? null : ReflectionUtils.getPrivateField(newInstance, java.awt.Component.class, name, out.getExceptionListener()); - if (oldValue != null && !oldValue.equals(newValue)) { - invokeStatement(oldInstance, "set" + NameGenerator.capitalize(name), new Object[]{oldValue}, out); - } + Object oldBackground = c.isBackgroundSet() ? c.getBackground() : null; + Object newBackground = c2.isBackgroundSet() ? c2.getBackground() : null; + if (!MetaData.equals(oldBackground, newBackground)) { + invokeStatement(oldInstance, "setBackground", new Object[] { oldBackground }, out); + } + Object oldForeground = c.isForegroundSet() ? c.getForeground() : null; + Object newForeground = c2.isForegroundSet() ? c2.getForeground() : null; + if (!MetaData.equals(oldForeground, newForeground)) { + invokeStatement(oldInstance, "setForeground", new Object[] { oldForeground }, out); + } + Object oldFont = c.isFontSet() ? c.getFont() : null; + Object newFont = c2.isFontSet() ? c2.getFont() : null; + if (!MetaData.equals(oldFont, newFont)) { + invokeStatement(oldInstance, "setFont", new Object[] { oldFont }, out); } } @@ -1104,26 +1110,30 @@ class java_awt_List_PersistenceDelegate extends DefaultPersistenceDelegate { // BorderLayout class java_awt_BorderLayout_PersistenceDelegate extends DefaultPersistenceDelegate { + private static final String[] CONSTRAINTS = { + BorderLayout.NORTH, + BorderLayout.SOUTH, + BorderLayout.EAST, + BorderLayout.WEST, + BorderLayout.CENTER, + BorderLayout.PAGE_START, + BorderLayout.PAGE_END, + BorderLayout.LINE_START, + BorderLayout.LINE_END, + }; + @Override protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { super.initialize(type, oldInstance, newInstance, out); - String[] locations = {"north", "south", "east", "west", "center"}; - String[] names = {java.awt.BorderLayout.NORTH, java.awt.BorderLayout.SOUTH, - java.awt.BorderLayout.EAST, java.awt.BorderLayout.WEST, - java.awt.BorderLayout.CENTER}; - for(int i = 0; i < locations.length; i++) { - Object oldC = ReflectionUtils.getPrivateField(oldInstance, - java.awt.BorderLayout.class, - locations[i], - out.getExceptionListener()); - Object newC = ReflectionUtils.getPrivateField(newInstance, - java.awt.BorderLayout.class, - locations[i], - out.getExceptionListener()); + BorderLayout oldLayout = (BorderLayout) oldInstance; + BorderLayout newLayout = (BorderLayout) newInstance; + for (String constraints : CONSTRAINTS) { + Object oldC = oldLayout.getLayoutComponent(constraints); + Object newC = newLayout.getLayoutComponent(constraints); // Pending, assume any existing elements are OK. if (oldC != null && newC == null) { invokeStatement(oldInstance, "addLayoutComponent", - new Object[]{oldC, names[i]}, out); + new Object[] { oldC, constraints }, out); } } } diff --git a/jdk/src/share/classes/java/beans/PropertyChangeSupport.java b/jdk/src/share/classes/java/beans/PropertyChangeSupport.java index 2d4ed88fdb3..04b510ae2ca 100644 --- a/jdk/src/share/classes/java/beans/PropertyChangeSupport.java +++ b/jdk/src/share/classes/java/beans/PropertyChangeSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,12 +34,49 @@ import java.util.Map.Entry; /** * This is a utility class that can be used by beans that support bound - * properties. You can use an instance of this class as a member field - * of your bean and delegate various work to it. + * properties. It manages a list of listeners and dispatches + * {@link PropertyChangeEvent}s to them. You can use an instance of this class + * as a member field of your bean and delegate these types of work to it. + * The {@link PropertyChangeListener} can be registered for all properties + * or for a property specified by name. + *

      + * Here is an example of {@code PropertyChangeSupport} usage that follows + * the rules and recommendations laid out in the JavaBeans™ specification: + *

      + * public class MyBean {
      + *     private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
        *
      + *     public void addPropertyChangeListener(PropertyChangeListener listener) {
      + *         this.pcs.addPropertyChangeListener(listener);
      + *     }
      + *
      + *     public void removePropertyChangeListener(PropertyChangeListener listener) {
      + *         this.pcs.removePropertyChangeListener(listener);
      + *     }
      + *
      + *     private String value;
      + *
      + *     public String getValue() {
      + *         return this.value;
      + *     }
      + *
      + *     public void setValue(String newValue) {
      + *         String oldValue = this.value;
      + *         this.value = newValue;
      + *         this.pcs.firePropertyChange("value", oldValue, newValue);
      + *     }
      + *
      + *     [...]
      + * }
      + * 
      + *

      + * A {@code PropertyChangeSupport} instance is thread-safe. + *

      * This class is serializable. When it is serialized it will save * (and restore) any listeners that are themselves serializable. Any * non-serializable listeners will be skipped during serialization. + * + * @see VetoableChangeSupport */ public class PropertyChangeSupport implements Serializable { private PropertyChangeListenerMap map = new PropertyChangeListenerMap(); @@ -208,91 +245,91 @@ public class PropertyChangeSupport implements Serializable { } /** - * Report a bound property update to any registered listeners. - * No event is fired if old and new are equal and non-null. - * + * Reports a bound property update to listeners + * that have been registered to track updates of + * all properties or a property with the specified name. + *

      + * No event is fired if old and new values are equal and non-null. *

      * This is merely a convenience wrapper around the more general - * firePropertyChange method that takes {@code - * PropertyChangeEvent} value. + * {@link #firePropertyChange(PropertyChangeEvent)} method. * - * @param propertyName The programmatic name of the property - * that was changed. - * @param oldValue The old value of the property. - * @param newValue The new value of the property. + * @param propertyName the programmatic name of the property that was changed + * @param oldValue the old value of the property + * @param newValue the new value of the property */ - public void firePropertyChange(String propertyName, - Object oldValue, Object newValue) { - if (oldValue != null && newValue != null && oldValue.equals(newValue)) { - return; + public void firePropertyChange(String propertyName, Object oldValue, Object newValue) { + if (oldValue == null || newValue == null || !oldValue.equals(newValue)) { + firePropertyChange(new PropertyChangeEvent(this.source, propertyName, oldValue, newValue)); } - firePropertyChange(new PropertyChangeEvent(source, propertyName, - oldValue, newValue)); } /** - * Report an int bound property update to any registered listeners. - * No event is fired if old and new are equal. + * Reports an integer bound property update to listeners + * that have been registered to track updates of + * all properties or a property with the specified name. + *

      + * No event is fired if old and new values are equal. *

      * This is merely a convenience wrapper around the more general - * firePropertyChange method that takes Object values. + * {@link #firePropertyChange(String, Object, Object)} method. * - * @param propertyName The programmatic name of the property - * that was changed. - * @param oldValue The old value of the property. - * @param newValue The new value of the property. + * @param propertyName the programmatic name of the property that was changed + * @param oldValue the old value of the property + * @param newValue the new value of the property */ - public void firePropertyChange(String propertyName, - int oldValue, int newValue) { - if (oldValue == newValue) { - return; + public void firePropertyChange(String propertyName, int oldValue, int newValue) { + if (oldValue != newValue) { + firePropertyChange(propertyName, Integer.valueOf(oldValue), Integer.valueOf(newValue)); } - firePropertyChange(propertyName, Integer.valueOf(oldValue), Integer.valueOf(newValue)); } /** - * Report a boolean bound property update to any registered listeners. - * No event is fired if old and new are equal. + * Reports a boolean bound property update to listeners + * that have been registered to track updates of + * all properties or a property with the specified name. + *

      + * No event is fired if old and new values are equal. *

      * This is merely a convenience wrapper around the more general - * firePropertyChange method that takes Object values. + * {@link #firePropertyChange(String, Object, Object)} method. * - * @param propertyName The programmatic name of the property - * that was changed. - * @param oldValue The old value of the property. - * @param newValue The new value of the property. + * @param propertyName the programmatic name of the property that was changed + * @param oldValue the old value of the property + * @param newValue the new value of the property */ - public void firePropertyChange(String propertyName, - boolean oldValue, boolean newValue) { - if (oldValue == newValue) { - return; + public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) { + if (oldValue != newValue) { + firePropertyChange(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); } - firePropertyChange(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); } /** - * Fire an existing PropertyChangeEvent to any registered listeners. - * No event is fired if the given event's old and new values are - * equal and non-null. - * @param evt The PropertyChangeEvent object. + * Fires a property change event to listeners + * that have been registered to track updates of + * all properties or a property with the specified name. + *

      + * No event is fired if the given event's old and new values are equal and non-null. + * + * @param event the {@code PropertyChangeEvent} to be fired */ - public void firePropertyChange(PropertyChangeEvent evt) { - Object oldValue = evt.getOldValue(); - Object newValue = evt.getNewValue(); - String propertyName = evt.getPropertyName(); - if (oldValue != null && newValue != null && oldValue.equals(newValue)) { - return; - } - PropertyChangeListener[] common = this.map.get(null); - PropertyChangeListener[] named = (propertyName != null) - ? this.map.get(propertyName) - : null; + public void firePropertyChange(PropertyChangeEvent event) { + Object oldValue = event.getOldValue(); + Object newValue = event.getNewValue(); + if (oldValue == null || newValue == null || !oldValue.equals(newValue)) { + String name = event.getPropertyName(); - fire(common, evt); - fire(named, evt); + PropertyChangeListener[] common = this.map.get(null); + PropertyChangeListener[] named = (name != null) + ? this.map.get(name) + : null; + + fire(common, event); + fire(named, event); + } } - private void fire(PropertyChangeListener[] listeners, PropertyChangeEvent event) { + private static void fire(PropertyChangeListener[] listeners, PropertyChangeEvent event) { if (listeners != null) { for (PropertyChangeListener listener : listeners) { listener.propertyChange(event); @@ -301,78 +338,69 @@ public class PropertyChangeSupport implements Serializable { } /** - * Report a bound indexed property update to any registered - * listeners. + * Reports a bound indexed property update to listeners + * that have been registered to track updates of + * all properties or a property with the specified name. *

      - * No event is fired if old and new values are equal - * and non-null. - * + * No event is fired if old and new values are equal and non-null. *

      * This is merely a convenience wrapper around the more general - * firePropertyChange method that takes {@code PropertyChangeEvent} value. + * {@link #firePropertyChange(PropertyChangeEvent)} method. * - * @param propertyName The programmatic name of the property that - * was changed. - * @param index index of the property element that was changed. - * @param oldValue The old value of the property. - * @param newValue The new value of the property. + * @param propertyName the programmatic name of the property that was changed + * @param index the index of the property element that was changed + * @param oldValue the old value of the property + * @param newValue the new value of the property * @since 1.5 */ - public void fireIndexedPropertyChange(String propertyName, int index, - Object oldValue, Object newValue) { - firePropertyChange(new IndexedPropertyChangeEvent - (source, propertyName, oldValue, newValue, index)); + public void fireIndexedPropertyChange(String propertyName, int index, Object oldValue, Object newValue) { + if (oldValue == null || newValue == null || !oldValue.equals(newValue)) { + firePropertyChange(new IndexedPropertyChangeEvent(source, propertyName, oldValue, newValue, index)); + } } /** - * Report an int bound indexed property update to any registered - * listeners. + * Reports an integer bound indexed property update to listeners + * that have been registered to track updates of + * all properties or a property with the specified name. *

      * No event is fired if old and new values are equal. *

      * This is merely a convenience wrapper around the more general - * fireIndexedPropertyChange method which takes Object values. + * {@link #fireIndexedPropertyChange(String, int, Object, Object)} method. * - * @param propertyName The programmatic name of the property that - * was changed. - * @param index index of the property element that was changed. - * @param oldValue The old value of the property. - * @param newValue The new value of the property. + * @param propertyName the programmatic name of the property that was changed + * @param index the index of the property element that was changed + * @param oldValue the old value of the property + * @param newValue the new value of the property * @since 1.5 */ - public void fireIndexedPropertyChange(String propertyName, int index, - int oldValue, int newValue) { - if (oldValue == newValue) { - return; + public void fireIndexedPropertyChange(String propertyName, int index, int oldValue, int newValue) { + if (oldValue != newValue) { + fireIndexedPropertyChange(propertyName, index, Integer.valueOf(oldValue), Integer.valueOf(newValue)); } - fireIndexedPropertyChange(propertyName, index, - Integer.valueOf(oldValue), - Integer.valueOf(newValue)); } /** - * Report a boolean bound indexed property update to any - * registered listeners. + * Reports a boolean bound indexed property update to listeners + * that have been registered to track updates of + * all properties or a property with the specified name. *

      * No event is fired if old and new values are equal. *

      * This is merely a convenience wrapper around the more general - * fireIndexedPropertyChange method which takes Object values. + * {@link #fireIndexedPropertyChange(String, int, Object, Object)} method. * - * @param propertyName The programmatic name of the property that - * was changed. - * @param index index of the property element that was changed. - * @param oldValue The old value of the property. - * @param newValue The new value of the property. + * @param propertyName the programmatic name of the property that was changed + * @param index the index of the property element that was changed + * @param oldValue the old value of the property + * @param newValue the new value of the property * @since 1.5 */ - public void fireIndexedPropertyChange(String propertyName, int index, - boolean oldValue, boolean newValue) { - if (oldValue == newValue) { - return; + public void fireIndexedPropertyChange(String propertyName, int index, boolean oldValue, boolean newValue) { + if (oldValue != newValue) { + fireIndexedPropertyChange(propertyName, index, Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); } - fireIndexedPropertyChange(propertyName, index, Boolean.valueOf(oldValue), - Boolean.valueOf(newValue)); } /** diff --git a/jdk/src/share/classes/java/beans/PropertyEditor.java b/jdk/src/share/classes/java/beans/PropertyEditor.java index b6ddf415354..965775898a8 100644 --- a/jdk/src/share/classes/java/beans/PropertyEditor.java +++ b/jdk/src/share/classes/java/beans/PropertyEditor.java @@ -204,20 +204,21 @@ public interface PropertyEditor { //---------------------------------------------------------------------- /** - * Register a listener for the PropertyChange event. When a - * PropertyEditor changes its value it should fire a PropertyChange - * event on all registered PropertyChangeListeners, specifying the - * null value for the property name and itself as the source. + * Adds a listener for the value change. + * When the property editor changes its value + * it should fire a {@link PropertyChangeEvent} + * on all registered {@link PropertyChangeListener}s, + * specifying the {@code null} value for the property name + * and itself as the source. * - * @param listener An object to be invoked when a PropertyChange - * event is fired. + * @param listener the {@link PropertyChangeListener} to add */ void addPropertyChangeListener(PropertyChangeListener listener); /** - * Remove a listener for the PropertyChange event. + * Removes a listener for the value change. * - * @param listener The PropertyChange listener to be removed. + * @param listener the {@link PropertyChangeListener} to remove */ void removePropertyChangeListener(PropertyChangeListener listener); diff --git a/jdk/src/share/classes/java/beans/PropertyEditorManager.java b/jdk/src/share/classes/java/beans/PropertyEditorManager.java index 055df1ad98c..a456c2bff54 100644 --- a/jdk/src/share/classes/java/beans/PropertyEditorManager.java +++ b/jdk/src/share/classes/java/beans/PropertyEditorManager.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ package java.beans; +import com.sun.beans.WeakCache; import sun.beans.editors.*; /** @@ -55,32 +56,30 @@ import sun.beans.editors.*; public class PropertyEditorManager { /** - * Register an editor class to be used to edit values of - * a given target class. + * Registers an editor class to edit values of the given target class. + * If the editor class is {@code null}, + * then any existing definition will be removed. + * Thus this method can be used to cancel the registration. + * The registration is canceled automatically + * if either the target or editor class is unloaded. + *

      + * If there is a security manager, its {@code checkPropertiesAccess} + * method is called. This could result in a {@linkplain SecurityException}. * - *

      First, if there is a security manager, its checkPropertiesAccess - * method is called. This could result in a SecurityException. + * @param targetType the class object of the type to be edited + * @param editorClass the class object of the editor class + * @throws SecurityException if a security manager exists and + * its {@code checkPropertiesAccess} method + * doesn't allow setting of system properties * - * @param targetType the Class object of the type to be edited - * @param editorClass the Class object of the editor class. If - * this is null, then any existing definition will be removed. - * @exception SecurityException if a security manager exists and its - * checkPropertiesAccess method doesn't allow setting - * of system properties. * @see SecurityManager#checkPropertiesAccess */ - - public static void registerEditor(Class targetType, Class editorClass) { + public static synchronized void registerEditor(Class targetType, Class editorClass) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPropertiesAccess(); } - initialize(); - if (editorClass == null) { - registry.remove(targetType); - } else { - registry.put(targetType, editorClass); - } + registry.put(targetType, editorClass); } /** @@ -90,10 +89,8 @@ public class PropertyEditorManager { * @return An editor object for the given target class. * The result is null if no suitable editor can be found. */ - public static synchronized PropertyEditor findEditor(Class targetType) { - initialize(); - Class editorClass = (Class)registry.get(targetType); + Class editorClass = registry.get(targetType); if (editorClass != null) { try { Object o = editorClass.newInstance(); @@ -143,10 +140,7 @@ public class PropertyEditorManager { * e.g. Sun implementation initially sets to {"sun.beans.editors"}. */ public static synchronized String[] getEditorSearchPath() { - // Return a copy of the searchPath. - String result[] = new String[searchPath.length]; - System.arraycopy(searchPath, 0, result, 0, searchPath.length); - return result; + return searchPath.clone(); } /** @@ -162,23 +156,22 @@ public class PropertyEditorManager { * of system properties. * @see SecurityManager#checkPropertiesAccess */ - - public static synchronized void setEditorSearchPath(String path[]) { + public static synchronized void setEditorSearchPath(String[] path) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPropertiesAccess(); } - if (path == null) { - path = new String[0]; - } - searchPath = path; + searchPath = (path != null) + ? path.clone() + : EMPTY; } - private static synchronized void initialize() { - if (registry != null) { - return; - } - registry = new java.util.Hashtable(); + private static String[] searchPath = { "sun.beans.editors" }; + private static final String[] EMPTY = {}; + private static final WeakCache, Class> registry; + + static { + registry = new WeakCache, Class>(); registry.put(Byte.TYPE, ByteEditor.class); registry.put(Short.TYPE, ShortEditor.class); registry.put(Integer.TYPE, IntegerEditor.class); @@ -187,7 +180,4 @@ public class PropertyEditorManager { registry.put(Float.TYPE, FloatEditor.class); registry.put(Double.TYPE, DoubleEditor.class); } - - private static String[] searchPath = { "sun.beans.editors" }; - private static java.util.Hashtable registry; } diff --git a/jdk/src/share/classes/java/beans/PropertyEditorSupport.java b/jdk/src/share/classes/java/beans/PropertyEditorSupport.java index 12f07c06bb1..57fddf04365 100644 --- a/jdk/src/share/classes/java/beans/PropertyEditorSupport.java +++ b/jdk/src/share/classes/java/beans/PropertyEditorSupport.java @@ -233,11 +233,20 @@ public class PropertyEditorSupport implements PropertyEditor { //---------------------------------------------------------------------- /** - * Register a listener for the PropertyChange event. The class will - * fire a PropertyChange value whenever the value is updated. + * Adds a listener for the value change. + * When the property editor changes its value + * it should fire a {@link PropertyChangeEvent} + * on all registered {@link PropertyChangeListener}s, + * specifying the {@code null} value for the property name. + * If the source property is set, + * it should be used as the source of the event. + *

      + * The same listener object may be added more than once, + * and will be called as many times as it is added. + * If {@code listener} is {@code null}, + * no exception is thrown and no action is taken. * - * @param listener An object to be invoked when a PropertyChange - * event is fired. + * @param listener the {@link PropertyChangeListener} to add */ public synchronized void addPropertyChangeListener( PropertyChangeListener listener) { @@ -248,9 +257,14 @@ public class PropertyEditorSupport implements PropertyEditor { } /** - * Remove a listener for the PropertyChange event. + * Removes a listener for the value change. + *

      + * If the same listener was added more than once, + * it will be notified one less time after being removed. + * If {@code listener} is {@code null}, or was never added, + * no exception is thrown and no action is taken. * - * @param listener The PropertyChange listener to be removed. + * @param listener the {@link PropertyChangeListener} to remove */ public synchronized void removePropertyChangeListener( PropertyChangeListener listener) { diff --git a/jdk/src/share/classes/java/beans/VetoableChangeSupport.java b/jdk/src/share/classes/java/beans/VetoableChangeSupport.java index 7d1418e17d2..addf68b36cd 100644 --- a/jdk/src/share/classes/java/beans/VetoableChangeSupport.java +++ b/jdk/src/share/classes/java/beans/VetoableChangeSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,12 +34,49 @@ import java.util.Map.Entry; /** * This is a utility class that can be used by beans that support constrained - * properties. You can use an instance of this class as a member field - * of your bean and delegate various work to it. + * properties. It manages a list of listeners and dispatches + * {@link PropertyChangeEvent}s to them. You can use an instance of this class + * as a member field of your bean and delegate these types of work to it. + * The {@link VetoableChangeListener} can be registered for all properties + * or for a property specified by name. + *

      + * Here is an example of {@code VetoableChangeSupport} usage that follows + * the rules and recommendations laid out in the JavaBeans™ specification: + *

      + * public class MyBean {
      + *     private final VetoableChangeSupport vcs = new VetoableChangeSupport(this);
        *
      + *     public void addVetoableChangeListener(VetoableChangeListener listener) {
      + *         this.vcs.addVetoableChangeListener(listener);
      + *     }
      + *
      + *     public void removeVetoableChangeListener(VetoableChangeListener listener) {
      + *         this.vcs.removeVetoableChangeListener(listener);
      + *     }
      + *
      + *     private String value;
      + *
      + *     public String getValue() {
      + *         return this.value;
      + *     }
      + *
      + *     public void setValue(String newValue) throws PropertyVetoException {
      + *         String oldValue = this.value;
      + *         this.vcs.fireVetoableChange("value", oldValue, newValue);
      + *         this.value = newValue;
      + *     }
      + *
      + *     [...]
      + * }
      + * 
      + *

      + * A {@code VetoableChangeSupport} instance is thread-safe. + *

      * This class is serializable. When it is serialized it will save * (and restore) any listeners that are themselves serializable. Any * non-serializable listeners will be skipped during serialization. + * + * @see PropertyChangeSupport */ public class VetoableChangeSupport implements Serializable { private VetoableChangeListenerMap map = new VetoableChangeListenerMap(); @@ -208,126 +245,149 @@ public class VetoableChangeSupport implements Serializable { } /** - * Report a vetoable property update to any registered listeners. If - * anyone vetos the change, then fire a new event reverting everyone to - * the old value and then rethrow the PropertyVetoException. + * Reports a constrained property update to listeners + * that have been registered to track updates of + * all properties or a property with the specified name. *

      - * No event is fired if old and new are equal and non-null. - * - * @param propertyName The programmatic name of the property - * that is about to change.. - * @param oldValue The old value of the property. - * @param newValue The new value of the property. - * @exception PropertyVetoException if the recipient wishes the property - * change to be rolled back. - */ - public void fireVetoableChange(String propertyName, - Object oldValue, Object newValue) - throws PropertyVetoException { - if (oldValue != null && newValue != null && oldValue.equals(newValue)) { - return; - } - PropertyChangeEvent evt = new PropertyChangeEvent(source, propertyName, - oldValue, newValue); - fireVetoableChange(evt); - } - - /** - * Report a int vetoable property update to any registered listeners. - * No event is fired if old and new are equal. + * Any listener can throw a {@code PropertyVetoException} to veto the update. + * If one of the listeners vetoes the update, this method passes + * a new "undo" {@code PropertyChangeEvent} that reverts to the old value + * to all listeners that already confirmed this update + * and throws the {@code PropertyVetoException} again. + *

      + * No event is fired if old and new values are equal and non-null. *

      * This is merely a convenience wrapper around the more general - * fireVetoableChange method that takes Object values. + * {@link #fireVetoableChange(PropertyChangeEvent)} method. * - * @param propertyName The programmatic name of the property - * that is about to change. - * @param oldValue The old value of the property. - * @param newValue The new value of the property. + * @param propertyName the programmatic name of the property that is about to change + * @param oldValue the old value of the property + * @param newValue the new value of the property + * @throws PropertyVetoException if one of listeners vetoes the property update */ - public void fireVetoableChange(String propertyName, - int oldValue, int newValue) - throws PropertyVetoException { - if (oldValue == newValue) { - return; + public void fireVetoableChange(String propertyName, Object oldValue, Object newValue) + throws PropertyVetoException { + if (oldValue == null || newValue == null || !oldValue.equals(newValue)) { + fireVetoableChange(new PropertyChangeEvent(this.source, propertyName, oldValue, newValue)); } - fireVetoableChange(propertyName, Integer.valueOf(oldValue), Integer.valueOf(newValue)); } /** - * Report a boolean vetoable property update to any registered listeners. - * No event is fired if old and new are equal. + * Reports an integer constrained property update to listeners + * that have been registered to track updates of + * all properties or a property with the specified name. + *

      + * Any listener can throw a {@code PropertyVetoException} to veto the update. + * If one of the listeners vetoes the update, this method passes + * a new "undo" {@code PropertyChangeEvent} that reverts to the old value + * to all listeners that already confirmed this update + * and throws the {@code PropertyVetoException} again. + *

      + * No event is fired if old and new values are equal. *

      * This is merely a convenience wrapper around the more general - * fireVetoableChange method that takes Object values. + * {@link #fireVetoableChange(String, Object, Object)} method. * - * @param propertyName The programmatic name of the property - * that is about to change. - * @param oldValue The old value of the property. - * @param newValue The new value of the property. + * @param propertyName the programmatic name of the property that is about to change + * @param oldValue the old value of the property + * @param newValue the new value of the property + * @throws PropertyVetoException if one of listeners vetoes the property update */ - public void fireVetoableChange(String propertyName, - boolean oldValue, boolean newValue) - throws PropertyVetoException { - if (oldValue == newValue) { - return; + public void fireVetoableChange(String propertyName, int oldValue, int newValue) + throws PropertyVetoException { + if (oldValue != newValue) { + fireVetoableChange(propertyName, Integer.valueOf(oldValue), Integer.valueOf(newValue)); } - fireVetoableChange(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); } /** - * Fire a vetoable property update to any registered listeners. If - * anyone vetos the change, then fire a new event reverting everyone to - * the old value and then rethrow the PropertyVetoException. + * Reports a boolean constrained property update to listeners + * that have been registered to track updates of + * all properties or a property with the specified name. *

      - * No event is fired if old and new are equal and non-null. + * Any listener can throw a {@code PropertyVetoException} to veto the update. + * If one of the listeners vetoes the update, this method passes + * a new "undo" {@code PropertyChangeEvent} that reverts to the old value + * to all listeners that already confirmed this update + * and throws the {@code PropertyVetoException} again. + *

      + * No event is fired if old and new values are equal. + *

      + * This is merely a convenience wrapper around the more general + * {@link #fireVetoableChange(String, Object, Object)} method. * - * @param evt The PropertyChangeEvent to be fired. - * @exception PropertyVetoException if the recipient wishes the property - * change to be rolled back. + * @param propertyName the programmatic name of the property that is about to change + * @param oldValue the old value of the property + * @param newValue the new value of the property + * @throws PropertyVetoException if one of listeners vetoes the property update */ - public void fireVetoableChange(PropertyChangeEvent evt) - throws PropertyVetoException { - - Object oldValue = evt.getOldValue(); - Object newValue = evt.getNewValue(); - String propertyName = evt.getPropertyName(); - if (oldValue != null && newValue != null && oldValue.equals(newValue)) { - return; + public void fireVetoableChange(String propertyName, boolean oldValue, boolean newValue) + throws PropertyVetoException { + if (oldValue != newValue) { + fireVetoableChange(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); } - VetoableChangeListener[] common = this.map.get(null); - VetoableChangeListener[] named = (propertyName != null) - ? this.map.get(propertyName) - : null; - fire(common, evt); - fire(named, evt); } - private void fire(VetoableChangeListener[] listeners, PropertyChangeEvent event) throws PropertyVetoException { - if (listeners != null) { - VetoableChangeListener current = null; - try { - for (VetoableChangeListener listener : listeners) { - current = listener; - listener.vetoableChange(event); - } - } catch (PropertyVetoException veto) { - // Create an event to revert everyone to the old value. - event = new PropertyChangeEvent( this.source, - event.getPropertyName(), - event.getNewValue(), - event.getOldValue() ); - for (VetoableChangeListener listener : listeners) { - if (current == listener) { - break; - } - try { - listener.vetoableChange(event); - } catch (PropertyVetoException ex) { - // We just ignore exceptions that occur during reversions. + /** + * Fires a property change event to listeners + * that have been registered to track updates of + * all properties or a property with the specified name. + *

      + * Any listener can throw a {@code PropertyVetoException} to veto the update. + * If one of the listeners vetoes the update, this method passes + * a new "undo" {@code PropertyChangeEvent} that reverts to the old value + * to all listeners that already confirmed this update + * and throws the {@code PropertyVetoException} again. + *

      + * No event is fired if the given event's old and new values are equal and non-null. + * + * @param event the {@code PropertyChangeEvent} to be fired + * @throws PropertyVetoException if one of listeners vetoes the property update + */ + public void fireVetoableChange(PropertyChangeEvent event) + throws PropertyVetoException { + Object oldValue = event.getOldValue(); + Object newValue = event.getNewValue(); + if (oldValue == null || newValue == null || !oldValue.equals(newValue)) { + String name = event.getPropertyName(); + + VetoableChangeListener[] common = this.map.get(null); + VetoableChangeListener[] named = (name != null) + ? this.map.get(name) + : null; + + VetoableChangeListener[] listeners; + if (common == null) { + listeners = named; + } + else if (named == null) { + listeners = common; + } + else { + listeners = new VetoableChangeListener[common.length + named.length]; + System.arraycopy(common, 0, listeners, 0, common.length); + System.arraycopy(named, 0, listeners, common.length, named.length); + } + if (listeners != null) { + int current = 0; + try { + while (current < listeners.length) { + listeners[current].vetoableChange(event); + current++; } } - // And now rethrow the PropertyVetoException. - throw veto; + catch (PropertyVetoException veto) { + event = new PropertyChangeEvent(this.source, name, newValue, oldValue); + for (int i = 0; i < current; i++) { + try { + listeners[i].vetoableChange(event); + } + catch (PropertyVetoException exception) { + // ignore exceptions that occur during rolling back + } + } + throw veto; // rethrow the veto exception + } } } } diff --git a/jdk/src/share/classes/java/io/CharConversionException.java b/jdk/src/share/classes/java/io/CharConversionException.java index 9e4b0ad0a33..d3a79e80ff2 100644 --- a/jdk/src/share/classes/java/io/CharConversionException.java +++ b/jdk/src/share/classes/java/io/CharConversionException.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-1999 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,8 @@ package java.io; public class CharConversionException extends java.io.IOException { + private static final long serialVersionUID = -8680016352018427031L; + /** * This provides no detailed message. */ diff --git a/jdk/src/share/classes/java/io/EOFException.java b/jdk/src/share/classes/java/io/EOFException.java index d91ecf627c3..6094837f599 100644 --- a/jdk/src/share/classes/java/io/EOFException.java +++ b/jdk/src/share/classes/java/io/EOFException.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-2000 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,8 @@ package java.io; */ public class EOFException extends IOException { + private static final long serialVersionUID = 6433858223774886977L; + /** * Constructs an EOFException with null * as its error detail message. diff --git a/jdk/src/share/classes/java/io/FileNotFoundException.java b/jdk/src/share/classes/java/io/FileNotFoundException.java index 18ed3f18cb2..198bbba8166 100644 --- a/jdk/src/share/classes/java/io/FileNotFoundException.java +++ b/jdk/src/share/classes/java/io/FileNotFoundException.java @@ -1,5 +1,5 @@ /* - * Copyright 1994-1999 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,7 @@ package java.io; */ public class FileNotFoundException extends IOException { + private static final long serialVersionUID = -897856973823710492L; /** * Constructs a FileNotFoundException with diff --git a/jdk/src/share/classes/java/io/InterruptedIOException.java b/jdk/src/share/classes/java/io/InterruptedIOException.java index 41cedf6b87a..054fe2bb133 100644 --- a/jdk/src/share/classes/java/io/InterruptedIOException.java +++ b/jdk/src/share/classes/java/io/InterruptedIOException.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-2000 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,8 @@ package java.io; */ public class InterruptedIOException extends IOException { + private static final long serialVersionUID = 4020568460727500567L; + /** * Constructs an InterruptedIOException with * null as its error detail message. diff --git a/jdk/src/share/classes/java/io/SyncFailedException.java b/jdk/src/share/classes/java/io/SyncFailedException.java index b2583ad2bdc..b08c8d97dbf 100644 --- a/jdk/src/share/classes/java/io/SyncFailedException.java +++ b/jdk/src/share/classes/java/io/SyncFailedException.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-1999 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,8 @@ package java.io; * @since JDK1.1 */ public class SyncFailedException extends IOException { + private static final long serialVersionUID = -2353342684412443330L; + /** * Constructs an SyncFailedException with a detail message. * A detail message is a String that describes this particular exception. diff --git a/jdk/src/share/classes/java/io/UTFDataFormatException.java b/jdk/src/share/classes/java/io/UTFDataFormatException.java index bb89c164521..2f789a0192f 100644 --- a/jdk/src/share/classes/java/io/UTFDataFormatException.java +++ b/jdk/src/share/classes/java/io/UTFDataFormatException.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,6 +44,8 @@ package java.io; */ public class UTFDataFormatException extends IOException { + private static final long serialVersionUID = 420743449228280612L; + /** * Constructs a UTFDataFormatException with * null as its error detail message. diff --git a/jdk/src/share/classes/java/io/UnsupportedEncodingException.java b/jdk/src/share/classes/java/io/UnsupportedEncodingException.java index 2ee9cb647be..9ccdd2ee603 100644 --- a/jdk/src/share/classes/java/io/UnsupportedEncodingException.java +++ b/jdk/src/share/classes/java/io/UnsupportedEncodingException.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-1999 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,8 @@ package java.io; public class UnsupportedEncodingException extends IOException { + private static final long serialVersionUID = -4274276298326136670L; + /** * Constructs an UnsupportedEncodingException without a detail message. */ diff --git a/jdk/src/share/classes/java/lang/AbstractMethodError.java b/jdk/src/share/classes/java/lang/AbstractMethodError.java index 15dcb96a78f..a8f11e7abc9 100644 --- a/jdk/src/share/classes/java/lang/AbstractMethodError.java +++ b/jdk/src/share/classes/java/lang/AbstractMethodError.java @@ -1,5 +1,5 @@ /* - * Copyright 1994-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,8 @@ package java.lang; */ public class AbstractMethodError extends IncompatibleClassChangeError { + private static final long serialVersionUID = -1654391082989018462L; + /** * Constructs an AbstractMethodError with no detail message. */ diff --git a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java index 4ba130b4989..973e0854d61 100644 --- a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java +++ b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { /** * The value is used for character storage. */ - char value[]; + char[] value; /** * The count is the number of characters used. @@ -333,8 +333,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { * dst.length *

    */ - public void getChars(int srcBegin, int srcEnd, char dst[], - int dstBegin) + public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { if (srcBegin < 0) throw new StringIndexOutOfBoundsException(srcBegin); @@ -366,14 +365,14 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Appends the string representation of the Object - * argument. + * Appends the string representation of the {@code Object} argument. *

    - * The argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then appended to this sequence. + * The overall effect is exactly as if the argument were converted + * to a string by the method {@link String#valueOf(Object)}, + * and the characters of that string were then + * {@link #append(String) appended} to this character sequence. * - * @param obj an Object. + * @param obj an {@code Object}. * @return a reference to this object. */ public AbstractStringBuilder append(Object obj) { @@ -383,17 +382,17 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { /** * Appends the specified string to this character sequence. *

    - * The characters of the String argument are appended, in + * The characters of the {@code String} argument are appended, in * order, increasing the length of this sequence by the length of the - * argument. If str is null, then the four - * characters "null" are appended. + * argument. If {@code str} is {@code null}, then the four + * characters {@code "null"} are appended. *

    * Let n be the length of this character sequence just prior to - * execution of the append method. Then the character at + * execution of the {@code append} method. Then the character at * index k in the new character sequence is equal to the character * at index k in the old character sequence, if k is less * than n; otherwise, it is equal to the character at index - * k-n in the argument str. + * k-n in the argument {@code str}. * * @param str a string. * @return a reference to this object. @@ -435,33 +434,33 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Appends a subsequence of the specified CharSequence to this + * Appends a subsequence of the specified {@code CharSequence} to this * sequence. *

    - * Characters of the argument s, starting at - * index start, are appended, in order, to the contents of - * this sequence up to the (exclusive) index end. The length - * of this sequence is increased by the value of end - start. + * Characters of the argument {@code s}, starting at + * index {@code start}, are appended, in order, to the contents of + * this sequence up to the (exclusive) index {@code end}. The length + * of this sequence is increased by the value of {@code end - start}. *

    * Let n be the length of this character sequence just prior to - * execution of the append method. Then the character at + * execution of the {@code append} method. Then the character at * index k in this character sequence becomes equal to the * character at index k in this sequence, if k is less than * n; otherwise, it is equal to the character at index - * k+start-n in the argument s. + * k+start-n in the argument {@code s}. *

    - * If s is null, then this method appends + * If {@code s} is {@code null}, then this method appends * characters as if the s parameter was a sequence containing the four - * characters "null". + * characters {@code "null"}. * * @param s the sequence to append. * @param start the starting index of the subsequence to be appended. * @param end the end index of the subsequence to be appended. * @return a reference to this object. * @throws IndexOutOfBoundsException if - * start or end are negative, or - * start is greater than end or - * end is greater than s.length() + * {@code start} is negative, or + * {@code start} is greater than {@code end} or + * {@code end} is greater than {@code s.length()} */ public AbstractStringBuilder append(CharSequence s, int start, int end) { if (s == null) @@ -483,22 +482,22 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Appends the string representation of the char array + * Appends the string representation of the {@code char} array * argument to this sequence. *

    * The characters of the array argument are appended, in order, to * the contents of this sequence. The length of this sequence * increases by the length of the argument. *

    - * The overall effect is exactly as if the argument were converted to - * a string by the method {@link String#valueOf(char[])} and the - * characters of that string were then {@link #append(String) appended} - * to this character sequence. + * The overall effect is exactly as if the argument were converted + * to a string by the method {@link String#valueOf(char[])}, + * and the characters of that string were then + * {@link #append(String) appended} to this character sequence. * * @param str the characters to be appended. * @return a reference to this object. */ - public AbstractStringBuilder append(char str[]) { + public AbstractStringBuilder append(char[] str) { int newCount = count + str.length; if (newCount > value.length) expandCapacity(newCount); @@ -509,22 +508,25 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { /** * Appends the string representation of a subarray of the - * char array argument to this sequence. + * {@code char} array argument to this sequence. *

    - * Characters of the char array str, starting at - * index offset, are appended, in order, to the contents + * Characters of the {@code char} array {@code str}, starting at + * index {@code offset}, are appended, in order, to the contents * of this sequence. The length of this sequence increases - * by the value of len. + * by the value of {@code len}. *

    - * The overall effect is exactly as if the arguments were converted to - * a string by the method {@link String#valueOf(char[],int,int)} and the - * characters of that string were then {@link #append(String) appended} - * to this character sequence. + * The overall effect is exactly as if the arguments were converted + * to a string by the method {@link String#valueOf(char[],int,int)}, + * and the characters of that string were then + * {@link #append(String) appended} to this character sequence. * * @param str the characters to be appended. - * @param offset the index of the first char to append. - * @param len the number of chars to append. + * @param offset the index of the first {@code char} to append. + * @param len the number of {@code char}s to append. * @return a reference to this object. + * @throws IndexOutOfBoundsException + * if {@code offset < 0} or {@code len < 0} + * or {@code offset+len > str.length} */ public AbstractStringBuilder append(char str[], int offset, int len) { int newCount = count + len; @@ -536,14 +538,15 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Appends the string representation of the boolean + * Appends the string representation of the {@code boolean} * argument to the sequence. *

    - * The argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then appended to this sequence. + * The overall effect is exactly as if the argument were converted + * to a string by the method {@link String#valueOf(boolean)}, + * and the characters of that string were then + * {@link #append(String) appended} to this character sequence. * - * @param b a boolean. + * @param b a {@code boolean}. * @return a reference to this object. */ public AbstractStringBuilder append(boolean b) { @@ -569,18 +572,18 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Appends the string representation of the char + * Appends the string representation of the {@code char} * argument to this sequence. *

    * The argument is appended to the contents of this sequence. - * The length of this sequence increases by 1. + * The length of this sequence increases by {@code 1}. *

    - * The overall effect is exactly as if the argument were converted to - * a string by the method {@link String#valueOf(char)} and the character - * in that string were then {@link #append(String) appended} to this - * character sequence. + * The overall effect is exactly as if the argument were converted + * to a string by the method {@link String#valueOf(char)}, + * and the character in that string were then + * {@link #append(String) appended} to this character sequence. * - * @param c a char. + * @param c a {@code char}. * @return a reference to this object. */ public AbstractStringBuilder append(char c) { @@ -592,14 +595,15 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Appends the string representation of the int + * Appends the string representation of the {@code int} * argument to this sequence. *

    - * The argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then appended to this sequence. + * The overall effect is exactly as if the argument were converted + * to a string by the method {@link String#valueOf(int)}, + * and the characters of that string were then + * {@link #append(String) appended} to this character sequence. * - * @param i an int. + * @param i an {@code int}. * @return a reference to this object. */ public AbstractStringBuilder append(int i) { @@ -618,14 +622,15 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Appends the string representation of the long + * Appends the string representation of the {@code long} * argument to this sequence. *

    - * The argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then appended to this sequence. + * The overall effect is exactly as if the argument were converted + * to a string by the method {@link String#valueOf(long)}, + * and the characters of that string were then + * {@link #append(String) appended} to this character sequence. * - * @param l a long. + * @param l a {@code long}. * @return a reference to this object. */ public AbstractStringBuilder append(long l) { @@ -644,14 +649,15 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Appends the string representation of the float + * Appends the string representation of the {@code float} * argument to this sequence. *

    - * The argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then appended to this string sequence. + * The overall effect is exactly as if the argument were converted + * to a string by the method {@link String#valueOf(float)}, + * and the characters of that string were then + * {@link #append(String) appended} to this character sequence. * - * @param f a float. + * @param f a {@code float}. * @return a reference to this object. */ public AbstractStringBuilder append(float f) { @@ -660,14 +666,15 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Appends the string representation of the double + * Appends the string representation of the {@code double} * argument to this sequence. *

    - * The argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then appended to this sequence. + * The overall effect is exactly as if the argument were converted + * to a string by the method {@link String#valueOf(double)}, + * and the characters of that string were then + * {@link #append(String) appended} to this character sequence. * - * @param d a double. + * @param d a {@code double}. * @return a reference to this object. */ public AbstractStringBuilder append(double d) { @@ -677,17 +684,17 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { /** * Removes the characters in a substring of this sequence. - * The substring begins at the specified start and extends to - * the character at index end - 1 or to the end of the + * The substring begins at the specified {@code start} and extends to + * the character at index {@code end - 1} or to the end of the * sequence if no such character exists. If - * start is equal to end, no changes are made. + * {@code start} is equal to {@code end}, no changes are made. * * @param start The beginning index, inclusive. * @param end The ending index, exclusive. * @return This object. - * @throws StringIndexOutOfBoundsException if start - * is negative, greater than length(), or - * greater than end. + * @throws StringIndexOutOfBoundsException if {@code start} + * is negative, greater than {@code length()}, or + * greater than {@code end}. */ public AbstractStringBuilder delete(int start, int end) { if (start < 0) @@ -705,7 +712,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Appends the string representation of the codePoint + * Appends the string representation of the {@code codePoint} * argument to this sequence. * *

    The argument is appended to the contents of this sequence. @@ -713,15 +720,15 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { * {@link Character#charCount(int) Character.charCount(codePoint)}. * *

    The overall effect is exactly as if the argument were - * converted to a char array by the method {@link - * Character#toChars(int)} and the character in that array were - * then {@link #append(char[]) appended} to this character + * converted to a {@code char} array by the method + * {@link Character#toChars(int)} and the character in that array + * were then {@link #append(char[]) appended} to this character * sequence. * * @param codePoint a Unicode code point * @return a reference to this object. * @exception IllegalArgumentException if the specified - * codePoint isn't a valid Unicode code point + * {@code codePoint} isn't a valid Unicode code point */ public AbstractStringBuilder appendCodePoint(int codePoint) { if (!Character.isValidCodePoint(codePoint)) { @@ -879,27 +886,27 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Inserts the string representation of a subarray of the str + * Inserts the string representation of a subarray of the {@code str} * array argument into this sequence. The subarray begins at the - * specified offset and extends len chars. + * specified {@code offset} and extends {@code len} {@code char}s. * The characters of the subarray are inserted into this sequence at - * the position indicated by index. The length of this - * sequence increases by len chars. + * the position indicated by {@code index}. The length of this + * sequence increases by {@code len} {@code char}s. * * @param index position at which to insert subarray. - * @param str A char array. - * @param offset the index of the first char in subarray to + * @param str A {@code char} array. + * @param offset the index of the first {@code char} in subarray to * be inserted. - * @param len the number of chars in the subarray to + * @param len the number of {@code char}s in the subarray to * be inserted. * @return This object - * @throws StringIndexOutOfBoundsException if index - * is negative or greater than length(), or - * offset or len are negative, or - * (offset+len) is greater than - * str.length. + * @throws StringIndexOutOfBoundsException if {@code index} + * is negative or greater than {@code length()}, or + * {@code offset} or {@code len} are negative, or + * {@code (offset+len)} is greater than + * {@code str.length}. */ - public AbstractStringBuilder insert(int index, char str[], int offset, + public AbstractStringBuilder insert(int index, char[] str, int offset, int len) { if ((index < 0) || (index > length())) @@ -918,20 +925,21 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Inserts the string representation of the Object + * Inserts the string representation of the {@code Object} * argument into this character sequence. *

    - * The second argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then inserted into this sequence at the indicated - * offset. + * The overall effect is exactly as if the second argument were + * converted to a string by the method {@link String#valueOf(Object)}, + * and the characters of that string were then + * {@link #insert(int,String) inserted} into this character + * sequence at the indicated offset. *

    - * The offset argument must be greater than or equal to - * 0, and less than or equal to the length of this - * sequence. + * The {@code offset} argument must be greater than or equal to + * {@code 0}, and less than or equal to the {@linkplain #length() length} + * of this sequence. * * @param offset the offset. - * @param obj an Object. + * @param obj an {@code Object}. * @return a reference to this object. * @throws StringIndexOutOfBoundsException if the offset is invalid. */ @@ -942,28 +950,28 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { /** * Inserts the string into this character sequence. *

    - * The characters of the String argument are inserted, in + * The characters of the {@code String} argument are inserted, in * order, into this sequence at the indicated offset, moving up any * characters originally above that position and increasing the length * of this sequence by the length of the argument. If - * str is null, then the four characters - * "null" are inserted into this sequence. + * {@code str} is {@code null}, then the four characters + * {@code "null"} are inserted into this sequence. *

    * The character at index k in the new character sequence is * equal to: *

      *
    • the character at index k in the old character sequence, if - * k is less than offset - *
    • the character at index k-offset in the - * argument str, if k is not less than - * offset but is less than offset+str.length() - *
    • the character at index k-str.length() in the + * k is less than {@code offset} + *
    • the character at index k{@code -offset} in the + * argument {@code str}, if k is not less than + * {@code offset} but is less than {@code offset+str.length()} + *
    • the character at index k{@code -str.length()} in the * old character sequence, if k is not less than - * offset+str.length() + * {@code offset+str.length()} *

    - * The offset argument must be greater than or equal to - * 0, and less than or equal to the length of this - * sequence. + * The {@code offset} argument must be greater than or equal to + * {@code 0}, and less than or equal to the {@linkplain #length() length} + * of this sequence. * * @param offset the offset. * @param str a string. @@ -986,27 +994,30 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Inserts the string representation of the char array + * Inserts the string representation of the {@code char} array * argument into this sequence. *

    * The characters of the array argument are inserted into the * contents of this sequence at the position indicated by - * offset. The length of this sequence increases by + * {@code offset}. The length of this sequence increases by * the length of the argument. *

    - * The overall effect is exactly as if the argument were converted to - * a string by the method {@link String#valueOf(char[])} and the - * characters of that string were then - * {@link #insert(int,String) inserted} into this - * character sequence at the position indicated by - * offset. + * The overall effect is exactly as if the second argument were + * converted to a string by the method {@link String#valueOf(char[])}, + * and the characters of that string were then + * {@link #insert(int,String) inserted} into this character + * sequence at the indicated offset. + *

    + * The {@code offset} argument must be greater than or equal to + * {@code 0}, and less than or equal to the {@linkplain #length() length} + * of this sequence. * * @param offset the offset. * @param str a character array. * @return a reference to this object. * @throws StringIndexOutOfBoundsException if the offset is invalid. */ - public AbstractStringBuilder insert(int offset, char str[]) { + public AbstractStringBuilder insert(int offset, char[] str) { if ((offset < 0) || (offset > length())) throw new StringIndexOutOfBoundsException(offset); int len = str.length; @@ -1020,18 +1031,20 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Inserts the specified CharSequence into this sequence. + * Inserts the specified {@code CharSequence} into this sequence. *

    - * The characters of the CharSequence argument are inserted, + * The characters of the {@code CharSequence} argument are inserted, * in order, into this sequence at the indicated offset, moving up * any characters originally above that position and increasing the length * of this sequence by the length of the argument s. *

    * The result of this method is exactly the same as if it were an - * invocation of this object's insert(dstOffset, s, 0, s.length()) method. + * invocation of this object's + * {@link #insert(int,CharSequence,int,int) insert}(dstOffset, s, 0, s.length()) + * method. * - *

    If s is null, then the four characters - * "null" are inserted into this sequence. + *

    If {@code s} is {@code null}, then the four characters + * {@code "null"} are inserted into this sequence. * * @param dstOffset the offset. * @param s the sequence to be inserted @@ -1047,51 +1060,51 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Inserts a subsequence of the specified CharSequence into + * Inserts a subsequence of the specified {@code CharSequence} into * this sequence. *

    - * The subsequence of the argument s specified by - * start and end are inserted, + * The subsequence of the argument {@code s} specified by + * {@code start} and {@code end} are inserted, * in order, into this sequence at the specified destination offset, moving * up any characters originally above that position. The length of this - * sequence is increased by end - start. + * sequence is increased by {@code end - start}. *

    * The character at index k in this sequence becomes equal to: *

      *
    • the character at index k in this sequence, if - * k is less than dstOffset - *
    • the character at index k+start-dstOffset in - * the argument s, if k is greater than or equal to - * dstOffset but is less than dstOffset+end-start - *
    • the character at index k-(end-start) in this + * k is less than {@code dstOffset} + *
    • the character at index k{@code +start-dstOffset} in + * the argument {@code s}, if k is greater than or equal to + * {@code dstOffset} but is less than {@code dstOffset+end-start} + *
    • the character at index k{@code -(end-start)} in this * sequence, if k is greater than or equal to - * dstOffset+end-start + * {@code dstOffset+end-start} *

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

    The start argument must be nonnegative, and not greater than - * end. + * {@code end}. *

    The end argument must be greater than or equal to - * start, and less than or equal to the length of s. + * {@code start}, and less than or equal to the length of s. * - *

    If s is null, then this method inserts + *

    If {@code s} is {@code null}, then this method inserts * characters as if the s parameter was a sequence containing the four - * characters "null". + * characters {@code "null"}. * * @param dstOffset the offset in this sequence. * @param s the sequence to be inserted. * @param start the starting index of the subsequence to be inserted. * @param end the end index of the subsequence to be inserted. * @return a reference to this object. - * @throws IndexOutOfBoundsException if dstOffset - * is negative or greater than this.length(), or - * start or end are negative, or - * start is greater than end or - * end is greater than s.length() + * @throws IndexOutOfBoundsException if {@code dstOffset} + * is negative or greater than {@code this.length()}, or + * {@code start} or {@code end} are negative, or + * {@code start} is greater than {@code end} or + * {@code end} is greater than {@code s.length()} */ public AbstractStringBuilder insert(int dstOffset, CharSequence s, - int start, int end) { + int start, int end) { if (s == null) s = "null"; if ((dstOffset < 0) || (dstOffset > this.length())) @@ -1115,20 +1128,21 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Inserts the string representation of the boolean + * Inserts the string representation of the {@code boolean} * argument into this sequence. *

    - * The second argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then inserted into this sequence at the indicated - * offset. + * The overall effect is exactly as if the second argument were + * converted to a string by the method {@link String#valueOf(boolean)}, + * and the characters of that string were then + * {@link #insert(int,String) inserted} into this character + * sequence at the indicated offset. *

    - * The offset argument must be greater than or equal to - * 0, and less than or equal to the length of this - * sequence. + * The {@code offset} argument must be greater than or equal to + * {@code 0}, and less than or equal to the {@linkplain #length() length} + * of this sequence. * * @param offset the offset. - * @param b a boolean. + * @param b a {@code boolean}. * @return a reference to this object. * @throws StringIndexOutOfBoundsException if the offset is invalid. */ @@ -1137,25 +1151,21 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Inserts the string representation of the char + * Inserts the string representation of the {@code char} * argument into this sequence. *

    - * The second argument is inserted into the contents of this sequence - * at the position indicated by offset. The length - * of this sequence increases by one. + * The overall effect is exactly as if the second argument were + * converted to a string by the method {@link String#valueOf(char)}, + * and the character in that string were then + * {@link #insert(int,String) inserted} into this character + * sequence at the indicated offset. *

    - * The overall effect is exactly as if the argument were converted to - * a string by the method {@link String#valueOf(char)} and the character - * in that string were then {@link #insert(int, String) inserted} into - * this character sequence at the position indicated by - * offset. - *

    - * The offset argument must be greater than or equal to - * 0, and less than or equal to the length of this - * sequence. + * The {@code offset} argument must be greater than or equal to + * {@code 0}, and less than or equal to the {@linkplain #length() length} + * of this sequence. * * @param offset the offset. - * @param c a char. + * @param c a {@code char}. * @return a reference to this object. * @throws IndexOutOfBoundsException if the offset is invalid. */ @@ -1170,20 +1180,21 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Inserts the string representation of the second int + * Inserts the string representation of the second {@code int} * argument into this sequence. *

    - * The second argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then inserted into this sequence at the indicated - * offset. + * The overall effect is exactly as if the second argument were + * converted to a string by the method {@link String#valueOf(int)}, + * and the characters of that string were then + * {@link #insert(int,String) inserted} into this character + * sequence at the indicated offset. *

    - * The offset argument must be greater than or equal to - * 0, and less than or equal to the length of this - * sequence. + * The {@code offset} argument must be greater than or equal to + * {@code 0}, and less than or equal to the {@linkplain #length() length} + * of this sequence. * * @param offset the offset. - * @param i an int. + * @param i an {@code int}. * @return a reference to this object. * @throws StringIndexOutOfBoundsException if the offset is invalid. */ @@ -1192,20 +1203,21 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Inserts the string representation of the long + * Inserts the string representation of the {@code long} * argument into this sequence. *

    - * The second argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then inserted into this sequence at the position - * indicated by offset. + * The overall effect is exactly as if the second argument were + * converted to a string by the method {@link String#valueOf(long)}, + * and the characters of that string were then + * {@link #insert(int,String) inserted} into this character + * sequence at the indicated offset. *

    - * The offset argument must be greater than or equal to - * 0, and less than or equal to the length of this - * sequence. + * The {@code offset} argument must be greater than or equal to + * {@code 0}, and less than or equal to the {@linkplain #length() length} + * of this sequence. * * @param offset the offset. - * @param l a long. + * @param l a {@code long}. * @return a reference to this object. * @throws StringIndexOutOfBoundsException if the offset is invalid. */ @@ -1214,20 +1226,21 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Inserts the string representation of the float + * Inserts the string representation of the {@code float} * argument into this sequence. *

    - * The second argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then inserted into this sequence at the indicated - * offset. + * The overall effect is exactly as if the second argument were + * converted to a string by the method {@link String#valueOf(float)}, + * and the characters of that string were then + * {@link #insert(int,String) inserted} into this character + * sequence at the indicated offset. *

    - * The offset argument must be greater than or equal to - * 0, and less than or equal to the length of this - * sequence. + * The {@code offset} argument must be greater than or equal to + * {@code 0}, and less than or equal to the {@linkplain #length() length} + * of this sequence. * * @param offset the offset. - * @param f a float. + * @param f a {@code float}. * @return a reference to this object. * @throws StringIndexOutOfBoundsException if the offset is invalid. */ @@ -1236,20 +1249,21 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * Inserts the string representation of the double + * Inserts the string representation of the {@code double} * argument into this sequence. *

    - * The second argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then inserted into this sequence at the indicated - * offset. + * The overall effect is exactly as if the second argument were + * converted to a string by the method {@link String#valueOf(double)}, + * and the characters of that string were then + * {@link #insert(int,String) inserted} into this character + * sequence at the indicated offset. *

    - * The offset argument must be greater than or equal to - * 0, and less than or equal to the length of this - * sequence. + * The {@code offset} argument must be greater than or equal to + * {@code 0}, and less than or equal to the {@linkplain #length() length} + * of this sequence. * * @param offset the offset. - * @param d a double. + * @param d a {@code double}. * @return a reference to this object. * @throws StringIndexOutOfBoundsException if the offset is invalid. */ diff --git a/jdk/src/share/classes/java/lang/ArithmeticException.java b/jdk/src/share/classes/java/lang/ArithmeticException.java index a90cda11c9e..a51d95db821 100644 --- a/jdk/src/share/classes/java/lang/ArithmeticException.java +++ b/jdk/src/share/classes/java/lang/ArithmeticException.java @@ -1,5 +1,5 @@ /* - * Copyright 1994-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ package java.lang; */ public class ArithmeticException extends RuntimeException { + private static final long serialVersionUID = 2256477558314496007L; + /** * Constructs an ArithmeticException with no detail * message. diff --git a/jdk/src/share/classes/java/lang/ArrayIndexOutOfBoundsException.java b/jdk/src/share/classes/java/lang/ArrayIndexOutOfBoundsException.java index 5c96020bf44..cc51bdd043b 100644 --- a/jdk/src/share/classes/java/lang/ArrayIndexOutOfBoundsException.java +++ b/jdk/src/share/classes/java/lang/ArrayIndexOutOfBoundsException.java @@ -1,5 +1,5 @@ /* - * Copyright 1994-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ package java.lang; */ public class ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException { + private static final long serialVersionUID = -5116101128118950844L; + /** * Constructs an ArrayIndexOutOfBoundsException with no * detail message. diff --git a/jdk/src/share/classes/java/lang/ArrayStoreException.java b/jdk/src/share/classes/java/lang/ArrayStoreException.java index 9aa4f7a9874..af24f1ac2f6 100644 --- a/jdk/src/share/classes/java/lang/ArrayStoreException.java +++ b/jdk/src/share/classes/java/lang/ArrayStoreException.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,8 @@ package java.lang; */ public class ArrayStoreException extends RuntimeException { + private static final long serialVersionUID = -4522193890499838241L; + /** * Constructs an ArrayStoreException with no detail message. */ diff --git a/jdk/src/share/classes/java/lang/AssertionError.java b/jdk/src/share/classes/java/lang/AssertionError.java index 0e6e45c210b..b64b7cbae3d 100644 --- a/jdk/src/share/classes/java/lang/AssertionError.java +++ b/jdk/src/share/classes/java/lang/AssertionError.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,8 @@ package java.lang; * @since 1.4 */ public class AssertionError extends Error { + private static final long serialVersionUID = -5013299493970297370L; + /** * Constructs an AssertionError with no detail message. */ diff --git a/jdk/src/share/classes/java/lang/ClassCastException.java b/jdk/src/share/classes/java/lang/ClassCastException.java index 057b55bb5e3..310c87f94d9 100644 --- a/jdk/src/share/classes/java/lang/ClassCastException.java +++ b/jdk/src/share/classes/java/lang/ClassCastException.java @@ -1,5 +1,5 @@ /* - * Copyright 1994-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,8 @@ package java.lang; */ public class ClassCastException extends RuntimeException { + private static final long serialVersionUID = -9223365651070458532L; + /** * Constructs a ClassCastException with no detail message. */ diff --git a/jdk/src/share/classes/java/lang/ClassCircularityError.java b/jdk/src/share/classes/java/lang/ClassCircularityError.java index 5d522626d30..27d5dfbf08c 100644 --- a/jdk/src/share/classes/java/lang/ClassCircularityError.java +++ b/jdk/src/share/classes/java/lang/ClassCircularityError.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,8 @@ package java.lang; * @since JDK1.0 */ public class ClassCircularityError extends LinkageError { + private static final long serialVersionUID = 1054362542914539689L; + /** * Constructs a {@code ClassCircularityError} with no detail message. */ diff --git a/jdk/src/share/classes/java/lang/ClassFormatError.java b/jdk/src/share/classes/java/lang/ClassFormatError.java index d2e61a4e290..75a042118be 100644 --- a/jdk/src/share/classes/java/lang/ClassFormatError.java +++ b/jdk/src/share/classes/java/lang/ClassFormatError.java @@ -1,5 +1,5 @@ /* - * Copyright 1994-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ package java.lang; */ public class ClassFormatError extends LinkageError { + private static final long serialVersionUID = -8420114879011949195L; + /** * Constructs a ClassFormatError with no detail message. */ diff --git a/jdk/src/share/classes/java/lang/CloneNotSupportedException.java b/jdk/src/share/classes/java/lang/CloneNotSupportedException.java index d3b7b3373dc..cfa643fc475 100644 --- a/jdk/src/share/classes/java/lang/CloneNotSupportedException.java +++ b/jdk/src/share/classes/java/lang/CloneNotSupportedException.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,8 @@ package java.lang; public class CloneNotSupportedException extends Exception { + private static final long serialVersionUID = 5195511250079656443L; + /** * Constructs a CloneNotSupportedException with no * detail message. diff --git a/jdk/src/share/classes/java/lang/EnumConstantNotPresentException.java b/jdk/src/share/classes/java/lang/EnumConstantNotPresentException.java index c09a9129656..4807691b210 100644 --- a/jdk/src/share/classes/java/lang/EnumConstantNotPresentException.java +++ b/jdk/src/share/classes/java/lang/EnumConstantNotPresentException.java @@ -1,5 +1,5 @@ /* - * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,8 @@ package java.lang; * @since 1.5 */ public class EnumConstantNotPresentException extends RuntimeException { + private static final long serialVersionUID = -6046998521960521108L; + /** * The type of the missing enum constant. */ diff --git a/jdk/src/share/classes/java/lang/IllegalAccessError.java b/jdk/src/share/classes/java/lang/IllegalAccessError.java index 58812dbffec..959c9421913 100644 --- a/jdk/src/share/classes/java/lang/IllegalAccessError.java +++ b/jdk/src/share/classes/java/lang/IllegalAccessError.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,8 @@ package java.lang; * @since JDK1.0 */ public class IllegalAccessError extends IncompatibleClassChangeError { + private static final long serialVersionUID = -8988904074992417891L; + /** * Constructs an IllegalAccessError with no detail message. */ diff --git a/jdk/src/share/classes/java/lang/IllegalAccessException.java b/jdk/src/share/classes/java/lang/IllegalAccessException.java index 8f3ca867725..19b51b90fef 100644 --- a/jdk/src/share/classes/java/lang/IllegalAccessException.java +++ b/jdk/src/share/classes/java/lang/IllegalAccessException.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-2000 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,6 +57,8 @@ package java.lang; * @since JDK1.0 */ public class IllegalAccessException extends Exception { + private static final long serialVersionUID = 6616958222490762034L; + /** * Constructs an IllegalAccessException without a * detail message. diff --git a/jdk/src/share/classes/java/lang/IllegalMonitorStateException.java b/jdk/src/share/classes/java/lang/IllegalMonitorStateException.java index b719afa0fce..6375a10b2c6 100644 --- a/jdk/src/share/classes/java/lang/IllegalMonitorStateException.java +++ b/jdk/src/share/classes/java/lang/IllegalMonitorStateException.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,8 @@ package java.lang; */ public class IllegalMonitorStateException extends RuntimeException { + private static final long serialVersionUID = 3713306369498869069L; + /** * Constructs an IllegalMonitorStateException with no * detail message. diff --git a/jdk/src/share/classes/java/lang/IllegalThreadStateException.java b/jdk/src/share/classes/java/lang/IllegalThreadStateException.java index 7f76da0dd0b..56ced227adb 100644 --- a/jdk/src/share/classes/java/lang/IllegalThreadStateException.java +++ b/jdk/src/share/classes/java/lang/IllegalThreadStateException.java @@ -1,5 +1,5 @@ /* - * Copyright 1994-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,8 @@ package java.lang; * @since JDK1.0 */ public class IllegalThreadStateException extends IllegalArgumentException { + private static final long serialVersionUID = -7626246362397460174L; + /** * Constructs an IllegalThreadStateException with no * detail message. diff --git a/jdk/src/share/classes/java/lang/IncompatibleClassChangeError.java b/jdk/src/share/classes/java/lang/IncompatibleClassChangeError.java index a2688c0c101..a92a18b7a79 100644 --- a/jdk/src/share/classes/java/lang/IncompatibleClassChangeError.java +++ b/jdk/src/share/classes/java/lang/IncompatibleClassChangeError.java @@ -1,5 +1,5 @@ /* - * Copyright 1994-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ package java.lang; */ public class IncompatibleClassChangeError extends LinkageError { + private static final long serialVersionUID = -4914975503642802119L; + /** * Constructs an IncompatibleClassChangeError with no * detail message. diff --git a/jdk/src/share/classes/java/lang/IndexOutOfBoundsException.java b/jdk/src/share/classes/java/lang/IndexOutOfBoundsException.java index 72a8b67f0e0..1375204df70 100644 --- a/jdk/src/share/classes/java/lang/IndexOutOfBoundsException.java +++ b/jdk/src/share/classes/java/lang/IndexOutOfBoundsException.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,8 @@ package java.lang; */ public class IndexOutOfBoundsException extends RuntimeException { + private static final long serialVersionUID = 234122996006267687L; + /** * Constructs an IndexOutOfBoundsException with no * detail message. diff --git a/jdk/src/share/classes/java/lang/InstantiationError.java b/jdk/src/share/classes/java/lang/InstantiationError.java index 4824b3d4347..9724fc48722 100644 --- a/jdk/src/share/classes/java/lang/InstantiationError.java +++ b/jdk/src/share/classes/java/lang/InstantiationError.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,8 @@ package java.lang; public class InstantiationError extends IncompatibleClassChangeError { + private static final long serialVersionUID = -4885810657349421204L; + /** * Constructs an InstantiationError with no detail message. */ diff --git a/jdk/src/share/classes/java/lang/InstantiationException.java b/jdk/src/share/classes/java/lang/InstantiationException.java index ab008ab6b9e..ace382ae437 100644 --- a/jdk/src/share/classes/java/lang/InstantiationException.java +++ b/jdk/src/share/classes/java/lang/InstantiationException.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,6 +44,8 @@ package java.lang; */ public class InstantiationException extends Exception { + private static final long serialVersionUID = -8441929162975509110L; + /** * Constructs an {@code InstantiationException} with no detail message. */ diff --git a/jdk/src/share/classes/java/lang/InternalError.java b/jdk/src/share/classes/java/lang/InternalError.java index d712af5e2bf..b49f7d755f4 100644 --- a/jdk/src/share/classes/java/lang/InternalError.java +++ b/jdk/src/share/classes/java/lang/InternalError.java @@ -1,5 +1,5 @@ /* - * Copyright 1994-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,8 @@ package java.lang; */ public class InternalError extends VirtualMachineError { + private static final long serialVersionUID = -9062593416125562365L; + /** * Constructs an InternalError with no detail message. */ diff --git a/jdk/src/share/classes/java/lang/InterruptedException.java b/jdk/src/share/classes/java/lang/InterruptedException.java index d57bb62d523..d8ddd36547e 100644 --- a/jdk/src/share/classes/java/lang/InterruptedException.java +++ b/jdk/src/share/classes/java/lang/InterruptedException.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,6 +48,8 @@ package java.lang; */ public class InterruptedException extends Exception { + private static final long serialVersionUID = 6700697376100628473L; + /** * Constructs an InterruptedException with no detail message. */ diff --git a/jdk/src/share/classes/java/lang/LinkageError.java b/jdk/src/share/classes/java/lang/LinkageError.java index 237188f3662..39d09467814 100644 --- a/jdk/src/share/classes/java/lang/LinkageError.java +++ b/jdk/src/share/classes/java/lang/LinkageError.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,8 @@ package java.lang; */ public class LinkageError extends Error { + private static final long serialVersionUID = 3579600108157160122L; + /** * Constructs a LinkageError with no detail message. */ diff --git a/jdk/src/share/classes/java/lang/NegativeArraySizeException.java b/jdk/src/share/classes/java/lang/NegativeArraySizeException.java index 64b76354615..903409b8248 100644 --- a/jdk/src/share/classes/java/lang/NegativeArraySizeException.java +++ b/jdk/src/share/classes/java/lang/NegativeArraySizeException.java @@ -1,5 +1,5 @@ /* - * Copyright 1994-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,8 @@ package java.lang; */ public class NegativeArraySizeException extends RuntimeException { + private static final long serialVersionUID = -8960118058596991861L; + /** * Constructs a NegativeArraySizeException with no * detail message. diff --git a/jdk/src/share/classes/java/lang/NoClassDefFoundError.java b/jdk/src/share/classes/java/lang/NoClassDefFoundError.java index a8a1273e1be..c9cf976717e 100644 --- a/jdk/src/share/classes/java/lang/NoClassDefFoundError.java +++ b/jdk/src/share/classes/java/lang/NoClassDefFoundError.java @@ -1,5 +1,5 @@ /* - * Copyright 1994-2000 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,8 @@ package java.lang; */ public class NoClassDefFoundError extends LinkageError { + private static final long serialVersionUID = 9095859863287012458L; + /** * Constructs a NoClassDefFoundError with no detail message. */ diff --git a/jdk/src/share/classes/java/lang/NoSuchFieldError.java b/jdk/src/share/classes/java/lang/NoSuchFieldError.java index 5dc7f9c1bc6..8b77c71b18c 100644 --- a/jdk/src/share/classes/java/lang/NoSuchFieldError.java +++ b/jdk/src/share/classes/java/lang/NoSuchFieldError.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,6 +38,8 @@ package java.lang; */ public class NoSuchFieldError extends IncompatibleClassChangeError { + private static final long serialVersionUID = -3456430195886129035L; + /** * Constructs a NoSuchFieldException with no detail message. */ diff --git a/jdk/src/share/classes/java/lang/NoSuchFieldException.java b/jdk/src/share/classes/java/lang/NoSuchFieldException.java index c75113a8c09..b44fb173ebb 100644 --- a/jdk/src/share/classes/java/lang/NoSuchFieldException.java +++ b/jdk/src/share/classes/java/lang/NoSuchFieldException.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-1999 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,8 @@ package java.lang; * @since JDK1.1 */ public class NoSuchFieldException extends Exception { + private static final long serialVersionUID = -6143714805279938260L; + /** * Constructor. */ diff --git a/jdk/src/share/classes/java/lang/NoSuchMethodError.java b/jdk/src/share/classes/java/lang/NoSuchMethodError.java index 5f3a798144b..74de82f3c16 100644 --- a/jdk/src/share/classes/java/lang/NoSuchMethodError.java +++ b/jdk/src/share/classes/java/lang/NoSuchMethodError.java @@ -1,5 +1,5 @@ /* - * Copyright 1994-1998 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,8 @@ package java.lang; */ public class NoSuchMethodError extends IncompatibleClassChangeError { + private static final long serialVersionUID = -3765521442372831335L; + /** * Constructs a NoSuchMethodError with no detail message. */ diff --git a/jdk/src/share/classes/java/lang/NoSuchMethodException.java b/jdk/src/share/classes/java/lang/NoSuchMethodException.java index 0fc7113ad1c..720fbfcbbc6 100644 --- a/jdk/src/share/classes/java/lang/NoSuchMethodException.java +++ b/jdk/src/share/classes/java/lang/NoSuchMethodException.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,8 @@ package java.lang; */ public class NoSuchMethodException extends Exception { + private static final long serialVersionUID = 5034388446362600923L; + /** * Constructs a NoSuchMethodException without a detail message. */ diff --git a/jdk/src/share/classes/java/lang/NullPointerException.java b/jdk/src/share/classes/java/lang/NullPointerException.java index 68fef23ac28..15e899cf0c9 100644 --- a/jdk/src/share/classes/java/lang/NullPointerException.java +++ b/jdk/src/share/classes/java/lang/NullPointerException.java @@ -1,5 +1,5 @@ /* - * Copyright 1994-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,6 +46,8 @@ package java.lang; */ public class NullPointerException extends RuntimeException { + private static final long serialVersionUID = 5162710183389028792L; + /** * Constructs a NullPointerException with no detail message. */ diff --git a/jdk/src/share/classes/java/lang/OutOfMemoryError.java b/jdk/src/share/classes/java/lang/OutOfMemoryError.java index 3ab19d24048..842b5c60d3f 100644 --- a/jdk/src/share/classes/java/lang/OutOfMemoryError.java +++ b/jdk/src/share/classes/java/lang/OutOfMemoryError.java @@ -1,5 +1,5 @@ /* - * Copyright 1994-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ package java.lang; */ public class OutOfMemoryError extends VirtualMachineError { + private static final long serialVersionUID = 8228564086184010517L; + /** * Constructs an OutOfMemoryError with no detail message. */ diff --git a/jdk/src/share/classes/java/lang/StackOverflowError.java b/jdk/src/share/classes/java/lang/StackOverflowError.java index 00cd783b440..992a395f2d7 100644 --- a/jdk/src/share/classes/java/lang/StackOverflowError.java +++ b/jdk/src/share/classes/java/lang/StackOverflowError.java @@ -1,5 +1,5 @@ /* - * Copyright 1994-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,8 @@ package java.lang; */ public class StackOverflowError extends VirtualMachineError { + private static final long serialVersionUID = 8609175038441759607L; + /** * Constructs a StackOverflowError with no detail message. */ diff --git a/jdk/src/share/classes/java/lang/StringBuffer.java b/jdk/src/share/classes/java/lang/StringBuffer.java index e0ecbef0ebe..c8cb51da81a 100644 --- a/jdk/src/share/classes/java/lang/StringBuffer.java +++ b/jdk/src/share/classes/java/lang/StringBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright 1994-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -212,7 +212,7 @@ package java.lang; * @throws NullPointerException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ - public synchronized void getChars(int srcBegin, int srcEnd, char dst[], + public synchronized void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { super.getChars(srcBegin, srcEnd, dst, dstBegin); @@ -228,10 +228,6 @@ package java.lang; value[index] = ch; } - /** - * @see java.lang.String#valueOf(java.lang.Object) - * @see #append(java.lang.String) - */ public synchronized StringBuffer append(Object obj) { super.append(String.valueOf(obj)); return this; @@ -314,20 +310,19 @@ package java.lang; return this; } - public synchronized StringBuffer append(char str[]) { + public synchronized StringBuffer append(char[] str) { super.append(str); return this; } - public synchronized StringBuffer append(char str[], int offset, int len) { + /** + * @throws IndexOutOfBoundsException {@inheritDoc} + */ + public synchronized StringBuffer append(char[] str, int offset, int len) { super.append(str, offset, len); return this; } - /** - * @see java.lang.String#valueOf(boolean) - * @see #append(java.lang.String) - */ public synchronized StringBuffer append(boolean b) { super.append(b); return this; @@ -338,10 +333,6 @@ package java.lang; return this; } - /** - * @see java.lang.String#valueOf(int) - * @see #append(java.lang.String) - */ public synchronized StringBuffer append(int i) { super.append(i); return this; @@ -355,28 +346,16 @@ package java.lang; return this; } - /** - * @see java.lang.String#valueOf(long) - * @see #append(java.lang.String) - */ public synchronized StringBuffer append(long lng) { super.append(lng); return this; } - /** - * @see java.lang.String#valueOf(float) - * @see #append(java.lang.String) - */ public synchronized StringBuffer append(float f) { super.append(f); return this; } - /** - * @see java.lang.String#valueOf(double) - * @see #append(java.lang.String) - */ public synchronized StringBuffer append(double d) { super.append(d); return this; @@ -437,7 +416,7 @@ package java.lang; * @throws StringIndexOutOfBoundsException {@inheritDoc} * @since 1.2 */ - public synchronized StringBuffer insert(int index, char str[], int offset, + public synchronized StringBuffer insert(int index, char[] str, int offset, int len) { super.insert(index, str, offset, len); @@ -446,9 +425,6 @@ package java.lang; /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(java.lang.Object) - * @see #insert(int, java.lang.String) - * @see #length() */ public synchronized StringBuffer insert(int offset, Object obj) { super.insert(offset, String.valueOf(obj)); @@ -457,7 +433,6 @@ package java.lang; /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see #length() */ public synchronized StringBuffer insert(int offset, String str) { super.insert(offset, str); @@ -467,7 +442,7 @@ package java.lang; /** * @throws StringIndexOutOfBoundsException {@inheritDoc} */ - public synchronized StringBuffer insert(int offset, char str[]) { + public synchronized StringBuffer insert(int offset, char[] str) { super.insert(offset, str); return this; } @@ -498,9 +473,6 @@ package java.lang; /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(boolean) - * @see #insert(int, java.lang.String) - * @see #length() */ public StringBuffer insert(int offset, boolean b) { return insert(offset, String.valueOf(b)); @@ -508,7 +480,6 @@ package java.lang; /** * @throws IndexOutOfBoundsException {@inheritDoc} - * @see #length() */ public synchronized StringBuffer insert(int offset, char c) { super.insert(offset, c); @@ -517,9 +488,6 @@ package java.lang; /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(int) - * @see #insert(int, java.lang.String) - * @see #length() */ public StringBuffer insert(int offset, int i) { return insert(offset, String.valueOf(i)); @@ -527,9 +495,6 @@ package java.lang; /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(long) - * @see #insert(int, java.lang.String) - * @see #length() */ public StringBuffer insert(int offset, long l) { return insert(offset, String.valueOf(l)); @@ -537,9 +502,6 @@ package java.lang; /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(float) - * @see #insert(int, java.lang.String) - * @see #length() */ public StringBuffer insert(int offset, float f) { return insert(offset, String.valueOf(f)); @@ -547,9 +509,6 @@ package java.lang; /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(double) - * @see #insert(int, java.lang.String) - * @see #length() */ public StringBuffer insert(int offset, double d) { return insert(offset, String.valueOf(d)); diff --git a/jdk/src/share/classes/java/lang/StringBuilder.java b/jdk/src/share/classes/java/lang/StringBuilder.java index 99f19768d62..803d70e39e8 100644 --- a/jdk/src/share/classes/java/lang/StringBuilder.java +++ b/jdk/src/share/classes/java/lang/StringBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -124,10 +124,6 @@ public final class StringBuilder append(seq); } - /** - * @see java.lang.String#valueOf(java.lang.Object) - * @see #append(java.lang.String) - */ public StringBuilder append(Object obj) { return append(String.valueOf(obj)); } @@ -175,7 +171,6 @@ public final class StringBuilder } /** - * @throws IndexOutOfBoundsException {@inheritDoc} */ public StringBuilder append(CharSequence s) { if (s == null) @@ -197,20 +192,19 @@ public final class StringBuilder return this; } - public StringBuilder append(char str[]) { + public StringBuilder append(char[] str) { super.append(str); return this; } - public StringBuilder append(char str[], int offset, int len) { + /** + * @throws IndexOutOfBoundsException {@inheritDoc} + */ + public StringBuilder append(char[] str, int offset, int len) { super.append(str, offset, len); return this; } - /** - * @see java.lang.String#valueOf(boolean) - * @see #append(java.lang.String) - */ public StringBuilder append(boolean b) { super.append(b); return this; @@ -221,37 +215,21 @@ public final class StringBuilder return this; } - /** - * @see java.lang.String#valueOf(int) - * @see #append(java.lang.String) - */ public StringBuilder append(int i) { super.append(i); return this; } - /** - * @see java.lang.String#valueOf(long) - * @see #append(java.lang.String) - */ public StringBuilder append(long lng) { super.append(lng); return this; } - /** - * @see java.lang.String#valueOf(float) - * @see #append(java.lang.String) - */ public StringBuilder append(float f) { super.append(f); return this; } - /** - * @see java.lang.String#valueOf(double) - * @see #append(java.lang.String) - */ public StringBuilder append(double d) { super.append(d); return this; @@ -292,7 +270,7 @@ public final class StringBuilder /** * @throws StringIndexOutOfBoundsException {@inheritDoc} */ - public StringBuilder insert(int index, char str[], int offset, + public StringBuilder insert(int index, char[] str, int offset, int len) { super.insert(index, str, offset, len); @@ -301,9 +279,6 @@ public final class StringBuilder /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(java.lang.Object) - * @see #insert(int, java.lang.String) - * @see #length() */ public StringBuilder insert(int offset, Object obj) { return insert(offset, String.valueOf(obj)); @@ -311,7 +286,6 @@ public final class StringBuilder /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see #length() */ public StringBuilder insert(int offset, String str) { super.insert(offset, str); @@ -321,7 +295,7 @@ public final class StringBuilder /** * @throws StringIndexOutOfBoundsException {@inheritDoc} */ - public StringBuilder insert(int offset, char str[]) { + public StringBuilder insert(int offset, char[] str) { super.insert(offset, str); return this; } @@ -349,9 +323,6 @@ public final class StringBuilder /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(boolean) - * @see #insert(int, java.lang.String) - * @see #length() */ public StringBuilder insert(int offset, boolean b) { super.insert(offset, b); @@ -360,7 +331,6 @@ public final class StringBuilder /** * @throws IndexOutOfBoundsException {@inheritDoc} - * @see #length() */ public StringBuilder insert(int offset, char c) { super.insert(offset, c); @@ -369,9 +339,6 @@ public final class StringBuilder /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(int) - * @see #insert(int, java.lang.String) - * @see #length() */ public StringBuilder insert(int offset, int i) { return insert(offset, String.valueOf(i)); @@ -379,9 +346,6 @@ public final class StringBuilder /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(long) - * @see #insert(int, java.lang.String) - * @see #length() */ public StringBuilder insert(int offset, long l) { return insert(offset, String.valueOf(l)); @@ -389,9 +353,6 @@ public final class StringBuilder /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(float) - * @see #insert(int, java.lang.String) - * @see #length() */ public StringBuilder insert(int offset, float f) { return insert(offset, String.valueOf(f)); @@ -399,9 +360,6 @@ public final class StringBuilder /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see java.lang.String#valueOf(double) - * @see #insert(int, java.lang.String) - * @see #length() */ public StringBuilder insert(int offset, double d) { return insert(offset, String.valueOf(d)); diff --git a/jdk/src/share/classes/java/lang/StringIndexOutOfBoundsException.java b/jdk/src/share/classes/java/lang/StringIndexOutOfBoundsException.java index 35bf7b4c64b..a2386205686 100644 --- a/jdk/src/share/classes/java/lang/StringIndexOutOfBoundsException.java +++ b/jdk/src/share/classes/java/lang/StringIndexOutOfBoundsException.java @@ -1,5 +1,5 @@ /* - * Copyright 1994-2000 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,8 @@ package java.lang; */ public class StringIndexOutOfBoundsException extends IndexOutOfBoundsException { + private static final long serialVersionUID = -6762910422159637258L; + /** * Constructs a StringIndexOutOfBoundsException with no * detail message. diff --git a/jdk/src/share/classes/java/lang/Thread.java b/jdk/src/share/classes/java/lang/Thread.java index e6dd655b366..60300ebc911 100644 --- a/jdk/src/share/classes/java/lang/Thread.java +++ b/jdk/src/share/classes/java/lang/Thread.java @@ -1,5 +1,5 @@ /* - * Copyright 1994-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,6 @@ import java.security.AccessControlContext; import java.security.PrivilegedAction; import java.util.Map; import java.util.HashMap; -import java.util.Collections; import java.util.concurrent.locks.LockSupport; import sun.misc.SoftCache; import sun.nio.ch.Interruptible; @@ -120,6 +119,10 @@ import sun.security.util.SecurityConstants; * Every thread has a name for identification purposes. More than * one thread may have the same name. If a name is not specified when * a thread is created, a new name is generated for it. + *

    + * Unless otherwise noted, passing a {@code null} argument to a constructor + * or method in this class will cause a {@link NullPointerException} to be + * thrown. * * @author unascribed * @see Runnable @@ -348,6 +351,10 @@ class Thread implements Runnable { */ private void init(ThreadGroup g, Runnable target, String name, long stackSize) { + if (name == null) { + throw new NullPointerException("name cannot be null"); + } + Thread parent = currentThread(); SecurityManager security = System.getSecurityManager(); if (g == null) { @@ -379,7 +386,6 @@ class Thread implements Runnable { } } - g.addUnstarted(); this.group = g; @@ -403,160 +409,175 @@ class Thread implements Runnable { tid = nextThreadID(); } - /** - * Allocates a new Thread object. This constructor has - * the same effect as Thread(null, null, - * gname), where gname is - * a newly generated name. Automatically generated names are of the - * form "Thread-"+n, where n is an integer. - * - * @see #Thread(ThreadGroup, Runnable, String) + /** + * Allocates a new {@code Thread} object. This constructor has the same + * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread} + * {@code (null, null, gname)}, where {@code gname} is a newly generated + * name. Automatically generated names are of the form + * {@code "Thread-"+}n, where n is an integer. */ public Thread() { init(null, null, "Thread-" + nextThreadNum(), 0); } /** - * Allocates a new Thread object. This constructor has - * the same effect as Thread(null, target, - * gname), where gname is - * a newly generated name. Automatically generated names are of the - * form "Thread-"+n, where n is an integer. + * Allocates a new {@code Thread} object. This constructor has the same + * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread} + * {@code (null, target, gname)}, where {@code gname} is a newly generated + * name. Automatically generated names are of the form + * {@code "Thread-"+}n, where n is an integer. * - * @param target the object whose run method is called. - * @see #Thread(ThreadGroup, Runnable, String) + * @param target + * the object whose {@code run} method is invoked when this thread + * is started. If {@code null}, this classes {@code run} method does + * nothing. */ public Thread(Runnable target) { init(null, target, "Thread-" + nextThreadNum(), 0); } /** - * Allocates a new Thread object. This constructor has - * the same effect as Thread(group, target, - * gname), where gname is - * a newly generated name. Automatically generated names are of the - * form "Thread-"+n, where n is an integer. + * Allocates a new {@code Thread} object. This constructor has the same + * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread} + * {@code (group, target, gname)} ,where {@code gname} is a newly generated + * name. Automatically generated names are of the form + * {@code "Thread-"+}n, where n is an integer. * - * @param group the thread group. - * @param target the object whose run method is called. - * @exception SecurityException if the current thread cannot create a - * thread in the specified thread group. - * @see #Thread(ThreadGroup, Runnable, String) + * @param group + * the thread group. If {@code null} and there is a security + * manager, the group is determined by {@linkplain + * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}. + * If there is not a security manager or {@code + * SecurityManager.getThreadGroup()} returns {@code null}, the group + * is set to the current thread's thread group. + * + * @param target + * the object whose {@code run} method is invoked when this thread + * is started. If {@code null}, this thread's run method is invoked. + * + * @throws SecurityException + * if the current thread cannot create a thread in the specified + * thread group */ public Thread(ThreadGroup group, Runnable target) { init(group, target, "Thread-" + nextThreadNum(), 0); } /** - * Allocates a new Thread object. This constructor has - * the same effect as Thread(null, null, name). + * Allocates a new {@code Thread} object. This constructor has the same + * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread} + * {@code (null, null, name)}. * - * @param name the name of the new thread. - * @see #Thread(ThreadGroup, Runnable, String) + * @param name + * the name of the new thread */ public Thread(String name) { init(null, null, name, 0); } /** - * Allocates a new Thread object. This constructor has - * the same effect as Thread(group, null, name) + * Allocates a new {@code Thread} object. This constructor has the same + * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread} + * {@code (group, null, name)}. * - * @param group the thread group. - * @param name the name of the new thread. - * @exception SecurityException if the current thread cannot create a - * thread in the specified thread group. - * @see #Thread(ThreadGroup, Runnable, String) + * @param group + * the thread group. If {@code null} and there is a security + * manager, the group is determined by {@linkplain + * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}. + * If there is not a security manager or {@code + * SecurityManager.getThreadGroup()} returns {@code null}, the group + * is set to the current thread's thread group. + * + * @param name + * the name of the new thread + * + * @throws SecurityException + * if the current thread cannot create a thread in the specified + * thread group */ public Thread(ThreadGroup group, String name) { init(group, null, name, 0); } /** - * Allocates a new Thread object. This constructor has - * the same effect as Thread(null, target, name). + * Allocates a new {@code Thread} object. This constructor has the same + * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread} + * {@code (null, target, name)}. * - * @param target the object whose run method is called. - * @param name the name of the new thread. - * @see #Thread(ThreadGroup, Runnable, String) + * @param target + * the object whose {@code run} method is invoked when this thread + * is started. If {@code null}, this thread's run method is invoked. + * + * @param name + * the name of the new thread */ public Thread(Runnable target, String name) { init(null, target, name, 0); } /** - * Allocates a new Thread object so that it has - * target as its run object, has the specified - * name as its name, and belongs to the thread group - * referred to by group. - *

    - * If group is null and there is a - * security manager, the group is determined by the security manager's - * getThreadGroup method. If group is - * null and there is not a security manager, or the - * security manager's getThreadGroup method returns - * null, the group is set to be the same ThreadGroup - * as the thread that is creating the new thread. + * Allocates a new {@code Thread} object so that it has {@code target} + * as its run object, has the specified {@code name} as its name, + * and belongs to the thread group referred to by {@code group}. * - *

    If there is a security manager, its checkAccess - * method is called with the ThreadGroup as its argument. - *

    In addition, its checkPermission - * method is called with the - * RuntimePermission("enableContextClassLoaderOverride") + *

    If there is a security manager, its + * {@link SecurityManager#checkAccess(ThreadGroup) checkAccess} + * method is invoked with the ThreadGroup as its argument. + * + *

    In addition, its {@code checkPermission} method is invoked with + * the {@code RuntimePermission("enableContextClassLoaderOverride")} * permission when invoked directly or indirectly by the constructor - * of a subclass which overrides the getContextClassLoader - * or setContextClassLoader methods. - * This may result in a SecurityException. - - *

    - * If the target argument is not null, the - * run method of the target is called when - * this thread is started. If the target argument is - * null, this thread's run method is called - * when this thread is started. - *

    - * The priority of the newly created thread is set equal to the - * priority of the thread creating it, that is, the currently running - * thread. The method setPriority may be used to - * change the priority to a new value. - *

    - * The newly created thread is initially marked as being a daemon - * thread if and only if the thread creating it is currently marked - * as a daemon thread. The method setDaemon may be used - * to change whether or not a thread is a daemon. + * of a subclass which overrides the {@code getContextClassLoader} + * or {@code setContextClassLoader} methods. * - * @param group the thread group. - * @param target the object whose run method is called. - * @param name the name of the new thread. - * @exception SecurityException if the current thread cannot create a - * thread in the specified thread group or cannot - * override the context class loader methods. - * @see Runnable#run() - * @see #run() - * @see #setDaemon(boolean) - * @see #setPriority(int) - * @see ThreadGroup#checkAccess() - * @see SecurityManager#checkAccess + *

    The priority of the newly created thread is set equal to the + * priority of the thread creating it, that is, the currently running + * thread. The method {@linkplain #setPriority setPriority} may be + * used to change the priority to a new value. + * + *

    The newly created thread is initially marked as being a daemon + * thread if and only if the thread creating it is currently marked + * as a daemon thread. The method {@linkplain #setDaemon setDaemon} + * may be used to change whether or not a thread is a daemon. + * + * @param group + * the thread group. If {@code null} and there is a security + * manager, the group is determined by {@linkplain + * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}. + * If there is not a security manager or {@code + * SecurityManager.getThreadGroup()} returns {@code null}, the group + * is set to the current thread's thread group. + * + * @param target + * the object whose {@code run} method is invoked when this thread + * is started. If {@code null}, this thread's run method is invoked. + * + * @param name + * the name of the new thread + * + * @throws SecurityException + * if the current thread cannot create a thread in the specified + * thread group or cannot override the context class loader methods. */ public Thread(ThreadGroup group, Runnable target, String name) { init(group, target, name, 0); } /** - * Allocates a new Thread object so that it has - * target as its run object, has the specified - * name as its name, belongs to the thread group referred to - * by group, and has the specified stack size. + * Allocates a new {@code Thread} object so that it has {@code target} + * as its run object, has the specified {@code name} as its name, + * and belongs to the thread group referred to by {@code group}, and has + * the specified stack size. * *

    This constructor is identical to {@link * #Thread(ThreadGroup,Runnable,String)} with the exception of the fact * that it allows the thread stack size to be specified. The stack size * is the approximate number of bytes of address space that the virtual * machine is to allocate for this thread's stack. The effect of the - * stackSize parameter, if any, is highly platform dependent. + * {@code stackSize} parameter, if any, is highly platform dependent. * *

    On some platforms, specifying a higher value for the - * stackSize parameter may allow a thread to achieve greater + * {@code stackSize} parameter may allow a thread to achieve greater * recursion depth before throwing a {@link StackOverflowError}. * Similarly, specifying a lower value may allow a greater number of * threads to exist concurrently without throwing an {@link @@ -564,9 +585,9 @@ class Thread implements Runnable { * the relationship between the value of the stackSize parameter * and the maximum recursion depth and concurrency level are * platform-dependent. On some platforms, the value of the - * stackSize parameter may have no effect whatsoever. + * {@code stackSize} parameter may have no effect whatsoever. * - *

    The virtual machine is free to treat the stackSize + *

    The virtual machine is free to treat the {@code stackSize} * parameter as a suggestion. If the specified value is unreasonably low * for the platform, the virtual machine may instead use some * platform-specific minimum value; if the specified value is unreasonably @@ -574,9 +595,9 @@ class Thread implements Runnable { * maximum. Likewise, the virtual machine is free to round the specified * value up or down as it sees fit (or to ignore it completely). * - *

    Specifying a value of zero for the stackSize parameter will + *

    Specifying a value of zero for the {@code stackSize} parameter will * cause this constructor to behave exactly like the - * Thread(ThreadGroup, Runnable, String) constructor. + * {@code Thread(ThreadGroup, Runnable, String)} constructor. * *

    Due to the platform-dependent nature of the behavior of this * constructor, extreme care should be exercised in its use. @@ -588,15 +609,32 @@ class Thread implements Runnable { * *

    Implementation note: Java platform implementers are encouraged to * document their implementation's behavior with respect to the - * stackSize parameter. + * {@code stackSize} parameter. + * + * + * @param group + * the thread group. If {@code null} and there is a security + * manager, the group is determined by {@linkplain + * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}. + * If there is not a security manager or {@code + * SecurityManager.getThreadGroup()} returns {@code null}, the group + * is set to the current thread's thread group. + * + * @param target + * the object whose {@code run} method is invoked when this thread + * is started. If {@code null}, this thread's run method is invoked. + * + * @param name + * the name of the new thread + * + * @param stackSize + * the desired stack size for the new thread, or zero to indicate + * that this parameter is to be ignored. + * + * @throws SecurityException + * if the current thread cannot create a thread in the specified + * thread group * - * @param group the thread group. - * @param target the object whose run method is called. - * @param name the name of the new thread. - * @param stackSize the desired stack size for the new thread, or - * zero to indicate that this parameter is to be ignored. - * @exception SecurityException if the current thread cannot create a - * thread in the specified thread group. * @since 1.4 */ public Thread(ThreadGroup group, Runnable target, String name, @@ -669,6 +707,7 @@ class Thread implements Runnable { * @see #stop() * @see #Thread(ThreadGroup, Runnable, String) */ + @Override public void run() { if (target != null) { target.run(); @@ -1386,28 +1425,25 @@ class Thread implements Runnable { * Returns the context ClassLoader for this Thread. The context * ClassLoader is provided by the creator of the thread for use * by code running in this thread when loading classes and resources. - * If not set, the default is the ClassLoader context of the parent - * Thread. The context ClassLoader of the primordial thread is - * typically set to the class loader used to load the application. + * If not {@linkplain #setContextClassLoader set}, the default is the + * ClassLoader context of the parent Thread. The context ClassLoader of the + * primordial thread is typically set to the class loader used to load the + * application. * - *

    First, if there is a security manager, and the caller's class - * loader is not null and the caller's class loader is not the same as or - * an ancestor of the context class loader for the thread whose - * context class loader is being requested, then the security manager's - * checkPermission - * method is called with a - * RuntimePermission("getClassLoader") permission - * to see if it's ok to get the context ClassLoader.. + *

    If a security manager is present, and the invoker's class loader is not + * {@code null} and is not the same as or an ancestor of the context class + * loader, then this method invokes the security manager's {@link + * SecurityManager#checkPermission(java.security.Permission) checkPermission} + * method with a {@link RuntimePermission RuntimePermission}{@code + * ("getClassLoader")} permission to verify that retrieval of the context + * class loader is permitted. * - * @return the context ClassLoader for this Thread + * @return the context ClassLoader for this Thread, or {@code null} + * indicating the system class loader (or, failing that, the + * bootstrap class loader) * - * @throws SecurityException - * if a security manager exists and its - * checkPermission method doesn't allow - * getting the context ClassLoader. - * @see #setContextClassLoader - * @see SecurityManager#checkPermission - * @see RuntimePermission + * @throws SecurityException + * if the current thread cannot get the context ClassLoader * * @since 1.2 */ @@ -1428,21 +1464,22 @@ class Thread implements Runnable { /** * Sets the context ClassLoader for this Thread. The context * ClassLoader can be set when a thread is created, and allows - * the creator of the thread to provide the appropriate class loader - * to code running in the thread when loading classes and resources. + * the creator of the thread to provide the appropriate class loader, + * through {@code getContextClassLoader}, to code running in the thread + * when loading classes and resources. * - *

    First, if there is a security manager, its checkPermission - * method is called with a - * RuntimePermission("setContextClassLoader") permission - * to see if it's ok to set the context ClassLoader.. + *

    If a security manager is present, its {@link + * SecurityManager#checkPermission(java.security.Permission) checkPermission} + * method is invoked with a {@link RuntimePermission RuntimePermission}{@code + * ("setContextClassLoader")} permission to see if setting the context + * ClassLoader is permitted. * - * @param cl the context ClassLoader for this Thread + * @param cl + * the context ClassLoader for this Thread, or null indicating the + * system class loader (or, failing that, the bootstrap class loader) * - * @exception SecurityException if the current thread cannot set the - * context ClassLoader. - * @see #getContextClassLoader - * @see SecurityManager#checkPermission - * @see RuntimePermission + * @throws SecurityException + * if the current thread cannot set the context ClassLoader * * @since 1.2 */ diff --git a/jdk/src/share/classes/java/lang/ThreadDeath.java b/jdk/src/share/classes/java/lang/ThreadDeath.java index 1cab266993f..6a346023674 100644 --- a/jdk/src/share/classes/java/lang/ThreadDeath.java +++ b/jdk/src/share/classes/java/lang/ThreadDeath.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,4 +46,6 @@ package java.lang; * @since JDK1.0 */ -public class ThreadDeath extends Error {} +public class ThreadDeath extends Error { + private static final long serialVersionUID = -4417128565033088268L; +} diff --git a/jdk/src/share/classes/java/lang/TypeNotPresentException.java b/jdk/src/share/classes/java/lang/TypeNotPresentException.java index 44570349082..d7fa0d6bdeb 100644 --- a/jdk/src/share/classes/java/lang/TypeNotPresentException.java +++ b/jdk/src/share/classes/java/lang/TypeNotPresentException.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,8 @@ package java.lang; * @since 1.5 */ public class TypeNotPresentException extends RuntimeException { + private static final long serialVersionUID = -5101214195716534496L; + private String typeName; /** diff --git a/jdk/src/share/classes/java/lang/UnknownError.java b/jdk/src/share/classes/java/lang/UnknownError.java index 966b3344569..437441d46e0 100644 --- a/jdk/src/share/classes/java/lang/UnknownError.java +++ b/jdk/src/share/classes/java/lang/UnknownError.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,8 @@ package java.lang; */ public class UnknownError extends VirtualMachineError { + private static final long serialVersionUID = 2524784860676771849L; + /** * Constructs an UnknownError with no detail message. */ diff --git a/jdk/src/share/classes/java/lang/UnsatisfiedLinkError.java b/jdk/src/share/classes/java/lang/UnsatisfiedLinkError.java index 70426b4eb08..8ffe6cc7345 100644 --- a/jdk/src/share/classes/java/lang/UnsatisfiedLinkError.java +++ b/jdk/src/share/classes/java/lang/UnsatisfiedLinkError.java @@ -1,5 +1,5 @@ /* - * Copyright 1994-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ package java.lang; */ public class UnsatisfiedLinkError extends LinkageError { + private static final long serialVersionUID = -4019343241616879428L; + /** * Constructs an UnsatisfiedLinkError with no detail message. */ diff --git a/jdk/src/share/classes/java/lang/UnsupportedClassVersionError.java b/jdk/src/share/classes/java/lang/UnsupportedClassVersionError.java index a36bdb79bfc..ec846508f49 100644 --- a/jdk/src/share/classes/java/lang/UnsupportedClassVersionError.java +++ b/jdk/src/share/classes/java/lang/UnsupportedClassVersionError.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-1999 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,8 @@ package java.lang; */ public class UnsupportedClassVersionError extends ClassFormatError { + private static final long serialVersionUID = -7123279212883497373L; + /** * Constructs a UnsupportedClassVersionError * with no detail message. diff --git a/jdk/src/share/classes/java/lang/VerifyError.java b/jdk/src/share/classes/java/lang/VerifyError.java index 46f2b10dcc4..a24d34bfcbc 100644 --- a/jdk/src/share/classes/java/lang/VerifyError.java +++ b/jdk/src/share/classes/java/lang/VerifyError.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ package java.lang; */ public class VerifyError extends LinkageError { + private static final long serialVersionUID = 7001962396098498785L; + /** * Constructs an VerifyError with no detail message. */ diff --git a/jdk/src/share/classes/java/lang/annotation/AnnotationFormatError.java b/jdk/src/share/classes/java/lang/annotation/AnnotationFormatError.java index 1ec3d457a72..0bc2fd15169 100644 --- a/jdk/src/share/classes/java/lang/annotation/AnnotationFormatError.java +++ b/jdk/src/share/classes/java/lang/annotation/AnnotationFormatError.java @@ -1,5 +1,5 @@ /* - * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,8 @@ package java.lang.annotation; * @since 1.5 */ public class AnnotationFormatError extends Error { + private static final long serialVersionUID = -4256701562333669892L; + /** * Constructs a new AnnotationFormatError with the specified * detail message. diff --git a/jdk/src/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java b/jdk/src/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java index 3af297dca93..c4cb7534c31 100644 --- a/jdk/src/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java +++ b/jdk/src/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ import java.lang.reflect.Method; * @since 1.5 */ public class AnnotationTypeMismatchException extends RuntimeException { + private static final long serialVersionUID = 8125925355765570191L; + /** * The Method object for the annotation element. */ diff --git a/jdk/src/share/classes/java/lang/annotation/IncompleteAnnotationException.java b/jdk/src/share/classes/java/lang/annotation/IncompleteAnnotationException.java index abea0ac331b..04070a1bbd4 100644 --- a/jdk/src/share/classes/java/lang/annotation/IncompleteAnnotationException.java +++ b/jdk/src/share/classes/java/lang/annotation/IncompleteAnnotationException.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ package java.lang.annotation; * @since 1.5 */ public class IncompleteAnnotationException extends RuntimeException { + private static final long serialVersionUID = 8445097402741811912L; + private Class annotationType; private String elementName; diff --git a/jdk/src/share/classes/java/lang/instrument/IllegalClassFormatException.java b/jdk/src/share/classes/java/lang/instrument/IllegalClassFormatException.java index 94c4933e4c0..5594165fb3e 100644 --- a/jdk/src/share/classes/java/lang/instrument/IllegalClassFormatException.java +++ b/jdk/src/share/classes/java/lang/instrument/IllegalClassFormatException.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,8 @@ package java.lang.instrument; * @since 1.5 */ public class IllegalClassFormatException extends Exception { + private static final long serialVersionUID = -3841736710924794009L; + /** * Constructs an IllegalClassFormatException with no * detail message. diff --git a/jdk/src/share/classes/java/lang/instrument/UnmodifiableClassException.java b/jdk/src/share/classes/java/lang/instrument/UnmodifiableClassException.java index 418ad7b3af8..d754fb2bbf0 100644 --- a/jdk/src/share/classes/java/lang/instrument/UnmodifiableClassException.java +++ b/jdk/src/share/classes/java/lang/instrument/UnmodifiableClassException.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,8 @@ package java.lang.instrument; * @since 1.5 */ public class UnmodifiableClassException extends Exception { + private static final long serialVersionUID = 1716652643585309178L; + /** * Constructs an UnmodifiableClassException with no * detail message. diff --git a/jdk/src/share/classes/java/lang/management/ManagementPermission.java b/jdk/src/share/classes/java/lang/management/ManagementPermission.java index 5330e75399b..7eeadd5c5ec 100644 --- a/jdk/src/share/classes/java/lang/management/ManagementPermission.java +++ b/jdk/src/share/classes/java/lang/management/ManagementPermission.java @@ -1,5 +1,5 @@ /* - * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -83,6 +83,7 @@ at the permission allows, and associated risks"> */ public final class ManagementPermission extends java.security.BasicPermission { + private static final long serialVersionUID = 1897496590799378737L; /** * Constructs a ManagementPermission with the specified name. diff --git a/jdk/src/share/classes/java/lang/management/PlatformComponent.java b/jdk/src/share/classes/java/lang/management/PlatformComponent.java index 3cd5d369da4..77c01161c91 100644 --- a/jdk/src/share/classes/java/lang/management/PlatformComponent.java +++ b/jdk/src/share/classes/java/lang/management/PlatformComponent.java @@ -32,6 +32,7 @@ import java.util.HashSet; import java.util.Set; import java.util.logging.LoggingMXBean; import java.util.logging.LogManager; +import java.nio.BufferPoolMXBean; import javax.management.MBeanServerConnection; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; @@ -188,6 +189,23 @@ enum PlatformComponent { } }), + + /** + * Buffer pools. + */ + BUFFER_POOL( + "java.nio.BufferPoolMXBean", + "java.nio", "BufferPool", keyProperties("name"), + new MXBeanFetcher() { + public List getMXBeans() { + List pools = new ArrayList(2); + pools.add( sun.misc.SharedSecrets.getJavaNioAccess().getDirectBufferPoolMXBean() ); + pools.add( sun.nio.ch.FileChannelImpl.getMappedBufferPoolMXBean() ); + return pools; + } + }), + + // Sun Platform Extension /** @@ -370,7 +388,7 @@ enum PlatformComponent { // if there are more than 1 key properties (i.e. other than "type") domainAndType += ",*"; } - ObjectName on = com.sun.jmx.mbeanserver.Util.newObjectName(domainAndType); + ObjectName on = ObjectName.valueOf(domainAndType); Set set = mbs.queryNames(on, null); for (PlatformComponent pc : subComponents) { set.addAll(pc.getObjectNames(mbs)); diff --git a/jdk/src/share/classes/java/lang/reflect/GenericSignatureFormatError.java b/jdk/src/share/classes/java/lang/reflect/GenericSignatureFormatError.java index 6ecdd3b24fd..717bc8bdeb0 100644 --- a/jdk/src/share/classes/java/lang/reflect/GenericSignatureFormatError.java +++ b/jdk/src/share/classes/java/lang/reflect/GenericSignatureFormatError.java @@ -1,5 +1,5 @@ /* - * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,4 +33,6 @@ package java.lang.reflect; * * @since 1.5 */ -public class GenericSignatureFormatError extends ClassFormatError{} +public class GenericSignatureFormatError extends ClassFormatError { + private static final long serialVersionUID = 6709919147137911034L; +} diff --git a/jdk/src/share/classes/java/lang/reflect/MalformedParameterizedTypeException.java b/jdk/src/share/classes/java/lang/reflect/MalformedParameterizedTypeException.java index 6089687ec24..0ed0b399fba 100644 --- a/jdk/src/share/classes/java/lang/reflect/MalformedParameterizedTypeException.java +++ b/jdk/src/share/classes/java/lang/reflect/MalformedParameterizedTypeException.java @@ -1,5 +1,5 @@ /* - * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,4 +34,6 @@ package java.lang.reflect; * * @since 1.5 */ -public class MalformedParameterizedTypeException extends RuntimeException{} +public class MalformedParameterizedTypeException extends RuntimeException { + private static final long serialVersionUID = -5696557788586220964L; +} diff --git a/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java b/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java index 2e5ea31cbd5..597783bf730 100644 --- a/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java +++ b/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java @@ -308,6 +308,12 @@ abstract class AbstractPlainSocketImpl extends SocketImpl FileDescriptor fd = acquireFD(); try { socketConnect(address, port, timeout); + /* socket may have been closed during poll/select */ + synchronized (fdLock) { + if (closePending) { + throw new SocketException ("Socket closed"); + } + } // If we have a ref. to the Socket, then sets the flags // created, bound & connected to true. // This is normally done in Socket.connect() but some diff --git a/jdk/src/share/classes/java/net/BindException.java b/jdk/src/share/classes/java/net/BindException.java index 9ea95d6f72b..b2975e52d48 100644 --- a/jdk/src/share/classes/java/net/BindException.java +++ b/jdk/src/share/classes/java/net/BindException.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,7 @@ package java.net; */ public class BindException extends SocketException { + private static final long serialVersionUID = -5945005768251722951L; /** * Constructs a new BindException with the specified detail diff --git a/jdk/src/share/classes/java/net/ConnectException.java b/jdk/src/share/classes/java/net/ConnectException.java index 29b46ab6642..ed97e6b91bb 100644 --- a/jdk/src/share/classes/java/net/ConnectException.java +++ b/jdk/src/share/classes/java/net/ConnectException.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,8 @@ package java.net; * @since JDK1.1 */ public class ConnectException extends SocketException { + private static final long serialVersionUID = 3831404271622369215L; + /** * Constructs a new ConnectException with the specified detail * message as to why the connect error occurred. diff --git a/jdk/src/share/classes/java/net/HttpCookie.java b/jdk/src/share/classes/java/net/HttpCookie.java index 6e495e060bb..1fcdd6c51da 100644 --- a/jdk/src/share/classes/java/net/HttpCookie.java +++ b/jdk/src/share/classes/java/net/HttpCookie.java @@ -75,6 +75,7 @@ public final class HttpCookie implements Cloneable { private String path; // Path=VALUE ... URLs that see the cookie private String portlist; // Port[="portlist"] ... the port cookie may be returned to private boolean secure; // Secure ... e.g. use SSL + private boolean httpOnly; // HttpOnly ... i.e. not accessible to scripts private int version = 1; // Version=1 ... RFC 2965 style // @@ -656,6 +657,32 @@ public final class HttpCookie implements Cloneable { version = v; } + /** + * Returns {@code true} if this cookie contains the HttpOnly + * attribute. This means that the cookie should not be accessible to + * scripting engines, like javascript. + * + * @return {@code true} if this cookie should be considered http only. + * @see #setHttpOnly(boolean) + */ + public boolean isHttpOnly() + { + return httpOnly; + } + + /** + * Indicates whether the cookie should be considered HTTP Only. If set to + * {@code true} it means the cookie should not be accessible to scripting + * engines like javascript. + * + * @param httpOnly if {@code true} make the cookie HTTP only, i.e. + * only visible as part of an HTTP request. + * @see #isHttpOnly() + */ + public void setHttpOnly(boolean httpOnly) + { + this.httpOnly = httpOnly; + } /** * The utility method to check whether a host name is in a domain @@ -877,6 +904,7 @@ public final class HttpCookie implements Cloneable { || name.equalsIgnoreCase("Port") // rfc2965 only || name.equalsIgnoreCase("Secure") || name.equalsIgnoreCase("Version") + || name.equalsIgnoreCase("HttpOnly") || name.charAt(0) == '$') { return true; @@ -996,6 +1024,11 @@ public final class HttpCookie implements Cloneable { cookie.setSecure(true); } }); + assignors.put("httponly", new CookieAttributeAssignor(){ + public void assign(HttpCookie cookie, String attrName, String attrValue) { + cookie.setHttpOnly(true); + } + }); assignors.put("version", new CookieAttributeAssignor(){ public void assign(HttpCookie cookie, String attrName, String attrValue) { try { diff --git a/jdk/src/share/classes/java/net/HttpRetryException.java b/jdk/src/share/classes/java/net/HttpRetryException.java index d6f336e3e7c..5e75dc94ab7 100644 --- a/jdk/src/share/classes/java/net/HttpRetryException.java +++ b/jdk/src/share/classes/java/net/HttpRetryException.java @@ -1,5 +1,5 @@ /* - * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,7 @@ import java.io.IOException; */ public class HttpRetryException extends IOException { + private static final long serialVersionUID = -9186022286469111381L; private int responseCode; private String location; diff --git a/jdk/src/share/classes/java/net/Inet6Address.java b/jdk/src/share/classes/java/net/Inet6Address.java index 0778f5a02fe..9441fed9405 100644 --- a/jdk/src/share/classes/java/net/Inet6Address.java +++ b/jdk/src/share/classes/java/net/Inet6Address.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/java/net/MalformedURLException.java b/jdk/src/share/classes/java/net/MalformedURLException.java index c38cd542cb2..b8f3b6fb5ec 100644 --- a/jdk/src/share/classes/java/net/MalformedURLException.java +++ b/jdk/src/share/classes/java/net/MalformedURLException.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,8 @@ import java.io.IOException; * @since JDK1.0 */ public class MalformedURLException extends IOException { + private static final long serialVersionUID = -182787522200415866L; + /** * Constructs a MalformedURLException with no detail message. */ diff --git a/jdk/src/share/classes/java/net/NetworkInterface.java b/jdk/src/share/classes/java/net/NetworkInterface.java index 7852fa363cb..da9503d573b 100644 --- a/jdk/src/share/classes/java/net/NetworkInterface.java +++ b/jdk/src/share/classes/java/net/NetworkInterface.java @@ -25,7 +25,6 @@ package java.net; -import java.net.SocketException; import java.util.Enumeration; import java.util.NoSuchElementException; import sun.security.action.*; @@ -203,11 +202,17 @@ public final class NetworkInterface { } /** - * Get the index of this network interface. + * Returns the index of this network interface. The index is an integer greater + * or equal to zero, or {@code -1} for unknown. This is a system specific value + * and interfaces with the same name can have different indexes on different + * machines. * - * @return the index of this network interface + * @return the index of this network interface or {@code -1} if the index is + * unknown + * @see #getByIndex(int) + * @since 1.7 */ - int getIndex() { + public int getIndex() { return index; } @@ -249,11 +254,18 @@ public final class NetworkInterface { * Get a network interface given its index. * * @param index an integer, the index of the interface - * @return the NetworkInterface obtained from its index - * @exception SocketException if an I/O error occurs. + * @return the NetworkInterface obtained from its index, or {@code null} if + * there is no interface with such an index on the system + * @throws SocketException if an I/O error occurs. + * @throws IllegalArgumentException if index has a negative value + * @see #getIndex() + * @since 1.7 */ - native static NetworkInterface getByIndex(int index) - throws SocketException; + public static NetworkInterface getByIndex(int index) throws SocketException { + if (index < 0) + throw new IllegalArgumentException("Interface index can't be negative"); + return getByIndex0(index); + } /** * Convenience method to search for a network interface that @@ -325,6 +337,9 @@ public final class NetworkInterface { private native static NetworkInterface getByName0(String name) throws SocketException; + private native static NetworkInterface getByIndex0(int index) + throws SocketException; + private native static NetworkInterface getByInetAddress0(InetAddress addr) throws SocketException; diff --git a/jdk/src/share/classes/java/net/NoRouteToHostException.java b/jdk/src/share/classes/java/net/NoRouteToHostException.java index 8bfc3de72ad..e6db581a222 100644 --- a/jdk/src/share/classes/java/net/NoRouteToHostException.java +++ b/jdk/src/share/classes/java/net/NoRouteToHostException.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,8 @@ package java.net; * @since JDK1.1 */ public class NoRouteToHostException extends SocketException { + private static final long serialVersionUID = -1897550894873493790L; + /** * Constructs a new NoRouteToHostException with the specified detail * message as to why the remote host cannot be reached. diff --git a/jdk/src/share/classes/java/net/PortUnreachableException.java b/jdk/src/share/classes/java/net/PortUnreachableException.java index cf8f24d23a9..e4491d89132 100644 --- a/jdk/src/share/classes/java/net/PortUnreachableException.java +++ b/jdk/src/share/classes/java/net/PortUnreachableException.java @@ -1,5 +1,5 @@ /* - * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,7 @@ package java.net; */ public class PortUnreachableException extends SocketException { + private static final long serialVersionUID = 8462541992376507323L; /** * Constructs a new PortUnreachableException with a diff --git a/jdk/src/share/classes/java/net/ProtocolException.java b/jdk/src/share/classes/java/net/ProtocolException.java index 3eef7d5382b..b0567f2e573 100644 --- a/jdk/src/share/classes/java/net/ProtocolException.java +++ b/jdk/src/share/classes/java/net/ProtocolException.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,8 @@ import java.io.IOException; */ public class ProtocolException extends IOException { + private static final long serialVersionUID = -6098449442062388080L; + /** * Constructs a new ProtocolException with the * specified detail message. diff --git a/jdk/src/share/classes/java/net/ProtocolFamily.java b/jdk/src/share/classes/java/net/ProtocolFamily.java new file mode 100644 index 00000000000..b997c7bb0a6 --- /dev/null +++ b/jdk/src/share/classes/java/net/ProtocolFamily.java @@ -0,0 +1,39 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.net; + +/** + * Represents a family of communication protocols. + * + * @since 1.7 + */ + +public interface ProtocolFamily { + /** + * Returns the name of the protocol family. + */ + String name(); +} diff --git a/jdk/src/share/classes/java/net/ServerSocket.java b/jdk/src/share/classes/java/net/ServerSocket.java index d28d874b2c0..983c737c3b7 100644 --- a/jdk/src/share/classes/java/net/ServerSocket.java +++ b/jdk/src/share/classes/java/net/ServerSocket.java @@ -142,14 +142,18 @@ class ServerSocket implements java.io.Closeable { * as its argument to ensure the operation is allowed. * This could result in a SecurityException. * - *

    The backlog argument must be a positive - * value greater than 0. If the value passed is equal or less - * than 0, then the default value will be assumed. + * The backlog argument is the requested maximum number of + * pending connections on the socket. Its exact semantics are implementation + * specific. In particular, an implementation may impose a maximum length + * or may choose to ignore the parameter altogther. The value provided + * should be greater than 0. If it is less than or equal to + * 0, then an implementation specific default will be used. *

    * * @param port the port number, or 0 to use a port * number that is automatically allocated. - * @param backlog the maximum length of the queue. + * @param backlog requested maximum length of the queue of incoming + * connections. * * @exception IOException if an I/O error occurs when opening the socket. * @exception SecurityException @@ -187,13 +191,17 @@ class ServerSocket implements java.io.Closeable { * as its argument to ensure the operation is allowed. * This could result in a SecurityException. * - *

    The backlog argument must be a positive - * value greater than 0. If the value passed is equal or less - * than 0, then the default value will be assumed. + * The backlog argument is the requested maximum number of + * pending connections on the socket. Its exact semantics are implementation + * specific. In particular, an implementation may impose a maximum length + * or may choose to ignore the parameter altogther. The value provided + * should be greater than 0. If it is less than or equal to + * 0, then an implementation specific default will be used. *

    * @param port the port number, or 0 to use a port * number that is automatically allocated. - * @param backlog the listen backlog + * @param backlog requested maximum length of the queue of incoming + * connections. * @param bindAddr the local InetAddress the server will bind to * * @throws SecurityException if a security manager exists and @@ -321,11 +329,15 @@ class ServerSocket implements java.io.Closeable { * If the address is null, then the system will pick up * an ephemeral port and a valid local address to bind the socket. *

    - * The backlog argument must be a positive - * value greater than 0. If the value passed is equal or less - * than 0, then the default value will be assumed. + * The backlog argument is the requested maximum number of + * pending connections on the socket. Its exact semantics are implementation + * specific. In particular, an implementation may impose a maximum length + * or may choose to ignore the parameter altogther. The value provided + * should be greater than 0. If it is less than or equal to + * 0, then an implementation specific default will be used. * @param endpoint The IP address & port number to bind to. - * @param backlog The listen backlog length. + * @param backlog requested maximum length of the queue of + * incoming connections. * @throws IOException if the bind operation fails, or if the socket * is already bound. * @throws SecurityException if a SecurityManager is present and diff --git a/jdk/src/share/classes/java/net/SocketException.java b/jdk/src/share/classes/java/net/SocketException.java index 6b40c3c832d..6e6f60d340e 100644 --- a/jdk/src/share/classes/java/net/SocketException.java +++ b/jdk/src/share/classes/java/net/SocketException.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ import java.io.IOException; */ public class SocketException extends IOException { + private static final long serialVersionUID = -5935874303556886934L; + /** * Constructs a new SocketException with the * specified detail message. diff --git a/jdk/src/share/classes/java/net/SocketOption.java b/jdk/src/share/classes/java/net/SocketOption.java new file mode 100644 index 00000000000..afc9714b5ab --- /dev/null +++ b/jdk/src/share/classes/java/net/SocketOption.java @@ -0,0 +1,55 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.net; + +/** + * A socket option associated with a socket. + * + *

    In the {@link java.nio.channels channels} package, the {@link + * java.nio.channels.NetworkChannel} interface defines the {@link + * java.nio.channels.NetworkChannel#setOption(SocketOption,Object) setOption} + * and {@link java.nio.channels.NetworkChannel#getOption(SocketOption) getOption} + * methods to set and query the channel's socket options. + * + * @param The type of the socket option value. + * + * @since 1.7 + * + * @see StandardSocketOption + */ + +public interface SocketOption { + + /** + * Returns the name of the socket option. + */ + String name(); + + /** + * Returns the type of the socket option value. + */ + Class type(); +} diff --git a/jdk/src/share/classes/java/net/SocketTimeoutException.java b/jdk/src/share/classes/java/net/SocketTimeoutException.java index b4499595956..fab3a5810a5 100644 --- a/jdk/src/share/classes/java/net/SocketTimeoutException.java +++ b/jdk/src/share/classes/java/net/SocketTimeoutException.java @@ -1,5 +1,5 @@ /* - * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ package java.net; */ public class SocketTimeoutException extends java.io.InterruptedIOException { + private static final long serialVersionUID = -8846654841826352300L; /** * Constructs a new SocketTimeoutException with a detail diff --git a/jdk/src/share/classes/java/net/StandardProtocolFamily.java b/jdk/src/share/classes/java/net/StandardProtocolFamily.java new file mode 100644 index 00000000000..7c11b32f59f --- /dev/null +++ b/jdk/src/share/classes/java/net/StandardProtocolFamily.java @@ -0,0 +1,45 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.net; + +/** + * Defines the standard family of communication protocols. + * + * @since 1.7 + */ + +public enum StandardProtocolFamily implements ProtocolFamily { + + /** + * Internet Protocol Version 4 (IPv4) + */ + INET, + + /** + * Internet Protocol Version 6 (IPv6) + */ + INET6 +} diff --git a/jdk/src/share/classes/java/net/StandardSocketOption.java b/jdk/src/share/classes/java/net/StandardSocketOption.java new file mode 100644 index 00000000000..405038cc1c2 --- /dev/null +++ b/jdk/src/share/classes/java/net/StandardSocketOption.java @@ -0,0 +1,352 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.net; + +/** + * Defines the standard socket options. + * + *

    The {@link SocketOption#name name} of each socket option defined by this + * class is its field name. + * + *

    In this release, the socket options defined here are used by {@link + * java.nio.channels.NetworkChannel network} channels in the {@link + * java.nio.channels channels} package. + * + * @since 1.7 + */ + +public final class StandardSocketOption { + private StandardSocketOption() { } + + // -- SOL_SOCKET -- + + /** + * Allow transmission of broadcast datagrams. + * + *

    The value of this socket option is a {@code Boolean} that represents + * whether the option is enabled or disabled. The option is specific to + * datagram-oriented sockets sending to {@link java.net.Inet4Address IPv4} + * broadcast addresses. When the socket option is enabled then the socket + * can be used to send broadcast datagrams. + * + *

    The initial value of this socket option is {@code FALSE}. The socket + * option may be enabled or disabled at any time. Some operating systems may + * require that the Java virtual machine be started with implementation + * specific privileges to enable this option or send broadcast datagrams. + * + * @see RFC 929: + * Broadcasting Internet Datagrams + */ + public static final SocketOption SO_BROADCAST = + new StdSocketOption("SO_BROADCAST", Boolean.class); + + /** + * Keep connection alive. + * + *

    The value of this socket option is a {@code Boolean} that represents + * whether the option is enabled or disabled. When the {@code SO_KEEPALIVE} + * option is enabled the operating system may use a keep-alive + * mechanism to periodically probe the other end of a connection when the + * connection is otherwise idle. The exact semantics of the keep alive + * mechanism is system dependent and therefore unspecified. + * + *

    The initial value of this socket option is {@code FALSE}. The socket + * option may be enabled or disabled at any time. + * + * @see RFC 1122 + * Requirements for Internet Hosts -- Communication Layers + */ + public static final SocketOption SO_KEEPALIVE = + new StdSocketOption("SO_KEEPALIVE", Boolean.class); + + /** + * The size of the socket send buffer. + * + *

    The value of this socket option is an {@code Integer} that is the + * size of the socket send buffer in bytes. The socket send buffer is an + * output buffer used by the networking implementation. It may need to be + * increased for high-volume connections. The value of the socket option is + * a hint to the implementation to size the buffer and the actual + * size may differ. The socket option can be queried to retrieve the actual + * size. + * + *

    For datagram-oriented sockets, the size of the send buffer may limit + * the size of the datagrams that may be sent by the socket. Whether + * datagrams larger than the buffer size are sent or discarded is system + * dependent. + * + *

    The initial/default size of the socket send buffer and the range of + * allowable values is system dependent although a negative size is not + * allowed. An attempt to set the socket send buffer to larger than its + * maximum size causes it to be set to its maximum size. + * + *

    An implementation allows this socket option to be set before the + * socket is bound or connected. Whether an implementation allows the + * socket send buffer to be changed after the socket is bound is system + * dependent. + */ + public static final SocketOption SO_SNDBUF = + new StdSocketOption("SO_SNDBUF", Integer.class); + + + /** + * The size of the socket receive buffer. + * + *

    The value of this socket option is an {@code Integer} that is the + * size of the socket receive buffer in bytes. The socket receive buffer is + * an input buffer used by the networking implementation. It may need to be + * increased for high-volume connections or decreased to limit the possible + * backlog of incoming data. The value of the socket option is a + * hint to the implementation to size the buffer and the actual + * size may differ. + * + *

    For datagram-oriented sockets, the size of the receive buffer may + * limit the size of the datagrams that can be received. Whether datagrams + * larger than the buffer size can be received is system dependent. + * Increasing the socket receive buffer may be important for cases where + * datagrams arrive in bursts faster than they can be processed. + * + *

    In the case of stream-oriented sockets and the TCP/IP protocol, the + * size of the socket receive buffer may be used when advertising the size + * of the TCP receive window to the remote peer. + * + *

    The initial/default size of the socket receive buffer and the range + * of allowable values is system dependent although a negative size is not + * allowed. An attempt to set the socket receive buffer to larger than its + * maximum size causes it to be set to its maximum size. + * + *

    An implementation allows this socket option to be set before the + * socket is bound or connected. Whether an implementation allows the + * socket receive buffer to be changed after the socket is bound is system + * dependent. + * + * @see RFC 1323: TCP + * Extensions for High Performance + */ + public static final SocketOption SO_RCVBUF = + new StdSocketOption("SO_RCVBUF", Integer.class); + + /** + * Re-use address. + * + *

    The value of this socket option is a {@code Boolean} that represents + * whether the option is enabled or disabled. The exact semantics of this + * socket option are socket type and system dependent. + * + *

    In the case of stream-oriented sockets, this socket option will + * usually determine whether the socket can be bound to a socket address + * when a previous connection involving that socket address is in the + * TIME_WAIT state. On implementations where the semantics differ, + * and the socket option is not required to be enabled in order to bind the + * socket when a previous connection is in this state, then the + * implementation may choose to ignore this option. + * + *

    For datagram-oriented sockets the socket option is used to allow + * multiple programs bind to the same address. This option should be enabled + * when the socket is to be used for Internet Protocol (IP) multicasting. + * + *

    An implementation allows this socket option to be set before the + * socket is bound or connected. Changing the value of this socket option + * after the socket is bound has no effect. The default value of this + * socket option is system dependent. + * + * @see RFC 793: Transmission + * Control Protocol + */ + public static final SocketOption SO_REUSEADDR = + new StdSocketOption("SO_REUSEADDR", Boolean.class); + + /** + * Linger on close if data is present. + * + *

    The value of this socket option is an {@code Integer} that controls + * the action taken when unsent data is queued on the socket and a method + * to close the socket is invoked. If the value of the socket option is zero + * or greater, then it represents a timeout value, in seconds, known as the + * linger interval. The linger interval is the timeout for the + * {@code close} method to block while the operating system attempts to + * transmit the unsent data or it decides that it is unable to transmit the + * data. If the value of the socket option is less than zero then the option + * is disabled. In that case the {@code close} method does not wait until + * unsent data is transmitted; if possible the operating system will transmit + * any unsent data before the connection is closed. + * + *

    This socket option is intended for use with sockets that are configured + * in {@link java.nio.channels.SelectableChannel#isBlocking() blocking} mode + * only. The behavior of the {@code close} method when this option is + * enabled on a non-blocking socket is not defined. + * + *

    The initial value of this socket option is a negative value, meaning + * that the option is disabled. The option may be enabled, or the linger + * interval changed, at any time. The maximum value of the linger interval + * is system dependent. Setting the linger interval to a value that is + * greater than its maximum value causes the linger interval to be set to + * its maximum value. + */ + public static final SocketOption SO_LINGER = + new StdSocketOption("SO_LINGER", Integer.class); + + + // -- IPPROTO_IP -- + + /** + * The Type of Service (ToS) octet in the Internet Protocol (IP) header. + * + *

    The value of this socket option is an {@code Integer}, the least + * significant 8 bits of which represents the value of the ToS octet in IP + * packets sent by sockets to an {@link StandardProtocolFamily#INET IPv4} + * socket. The interpretation of the ToS octet is network specific and + * is not defined by this class. Further information on the ToS octet can be + * found in RFC 1349 + * and RFC 2474. The + * value of the socket option is a hint. An implementation may + * ignore the value, or ignore specific values. + * + *

    The initial/default value of the TOS field in the ToS octet is + * implementation specific but will typically be {@code 0}. For + * datagram-oriented sockets the option may be configured at any time after + * the socket has been bound. The new value of the octet is used when sending + * subsequent datagrams. It is system dependent whether this option can be + * queried or changed prior to binding the socket. + * + *

    The behavior of this socket option on a stream-oriented socket, or an + * {@link StandardProtocolFamily#INET6 IPv6} socket, is not defined in this + * release. + */ + public static final SocketOption IP_TOS = + new StdSocketOption("IP_TOS", Integer.class); + + /** + * The network interface for Internet Protocol (IP) multicast datagrams. + * + *

    The value of this socket option is a {@link NetworkInterface} that + * represents the outgoing interface for multicast datagrams sent by the + * datagram-oriented socket. For {@link StandardProtocolFamily#INET6 IPv6} + * sockets then it is system dependent whether setting this option also + * sets the outgoing interface for multlicast datagrams sent to IPv4 + * addresses. + * + *

    The initial/default value of this socket option may be {@code null} + * to indicate that outgoing interface will be selected by the operating + * system, typically based on the network routing tables. An implementation + * allows this socket option to be set after the socket is bound. Whether + * the socket option can be queried or changed prior to binding the socket + * is system dependent. + * + * @see java.nio.channels.MulticastChannel + */ + public static final SocketOption IP_MULTICAST_IF = + new StdSocketOption("IP_MULTICAST_IF", NetworkInterface.class); + + /** + * The time-to-live for Internet Protocol (IP) multicast datagrams. + * + *

    The value of this socket option is an {@code Integer} in the range + * 0 <= value <= 255. It is used to control + * the scope of multicast datagrams sent by the datagram-oriented socket. + * In the case of an {@link StandardProtocolFamily#INET IPv4} socket + * the option is the time-to-live (TTL) on multicast datagrams sent by the + * socket. Datagrams with a TTL of zero are not transmitted on the network + * but may be delivered locally. In the case of an {@link + * StandardProtocolFamily#INET6 IPv6} socket the option is the + * hop limit which is number of hops that the datagram can + * pass through before expiring on the network. For IPv6 sockets it is + * system dependent whether the option also sets the time-to-live + * on multicast datagrams sent to IPv4 addresses. + * + *

    The initial/default value of the time-to-live setting is typically + * {@code 1}. An implementation allows this socket option to be set after + * the socket is bound. Whether the socket option can be queried or changed + * prior to binding the socket is system dependent. + * + * @see java.nio.channels.MulticastChannel + */ + public static final SocketOption IP_MULTICAST_TTL = + new StdSocketOption("IP_MULTICAST_TTL", Integer.class); + + /** + * Loopback for Internet Protocol (IP) multicast datagrams. + * + *

    The value of this socket option is a {@code Boolean} that controls + * the loopback of multicast datagrams. The value of the socket + * option represents if the option is enabled or disabled. + * + *

    The exact semantics of this socket options are system dependent. + * In particular, it is system dependent whether the loopback applies to + * multicast datagrams sent from the socket or received by the socket. + * For {@link StandardProtocolFamily#INET6 IPv6} sockets then it is + * system dependent whether the option also applies to multicast datagrams + * sent to IPv4 addresses. + * + *

    The initial/default value of this socket option is {@code TRUE}. An + * implementation allows this socket option to be set after the socket is + * bound. Whether the socket option can be queried or changed prior to + * binding the socket is system dependent. + * + * @see java.nio.channels.MulticastChannel + */ + public static final SocketOption IP_MULTICAST_LOOP = + new StdSocketOption("IP_MULTICAST_LOOP", Boolean.class); + + + // -- IPPROTO_TCP -- + + /** + * Disable the Nagle algorithm. + * + *

    The value of this socket option is a {@code Boolean} that represents + * whether the option is enabled or disabled. The socket option is specific to + * stream-oriented sockets using the TCP/IP protocol. TCP/IP uses an algorithm + * known as The Nagle Algorithm to coalesce short segments and + * improve network efficiency. + * + *

    The default value of this socket option is {@code FALSE}. The + * socket option should only be enabled in cases where it is known that the + * coalescing impacts performance. The socket option may be enabled at any + * time. In other words, the Nagle Algorithm can be disabled. Once the option + * is enabled, it is system dependent whether it can be subsequently + * disabled. In that case, invoking the {@code setOption} method to disable + * the option has no effect. + * + * @see RFC 1122: + * Requirements for Internet Hosts -- Communication Layers + */ + public static final SocketOption TCP_NODELAY = + new StdSocketOption("TCP_NODELAY", Boolean.class); + + + private static class StdSocketOption implements SocketOption { + private final String name; + private final Class type; + StdSocketOption(String name, Class type) { + this.name = name; + this.type = type; + } + @Override public String name() { return name; } + @Override public Class type() { return type; } + @Override public String toString() { return name; } + } +} diff --git a/jdk/src/share/classes/java/net/URISyntaxException.java b/jdk/src/share/classes/java/net/URISyntaxException.java index e1882be40fe..17a6bbb72d0 100644 --- a/jdk/src/share/classes/java/net/URISyntaxException.java +++ b/jdk/src/share/classes/java/net/URISyntaxException.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,6 +38,8 @@ package java.net; public class URISyntaxException extends Exception { + private static final long serialVersionUID = 2137979680897488891L; + private String input; private int index; diff --git a/jdk/src/share/classes/java/net/UnknownHostException.java b/jdk/src/share/classes/java/net/UnknownHostException.java index b6df3be5d8d..860b847d6aa 100644 --- a/jdk/src/share/classes/java/net/UnknownHostException.java +++ b/jdk/src/share/classes/java/net/UnknownHostException.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ import java.io.IOException; */ public class UnknownHostException extends IOException { + private static final long serialVersionUID = -4639126076052875403L; + /** * Constructs a new UnknownHostException with the * specified detail message. diff --git a/jdk/src/share/classes/java/net/UnknownServiceException.java b/jdk/src/share/classes/java/net/UnknownServiceException.java index 9e3e7fd3520..d006e3af23c 100644 --- a/jdk/src/share/classes/java/net/UnknownServiceException.java +++ b/jdk/src/share/classes/java/net/UnknownServiceException.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-1997 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,8 @@ import java.io.IOException; * @since JDK1.0 */ public class UnknownServiceException extends IOException { + private static final long serialVersionUID = -4169033248853639508L; + /** * Constructs a new UnknownServiceException with no * detail message. diff --git a/jdk/src/share/classes/java/nio/Bits.java b/jdk/src/share/classes/java/nio/Bits.java index 603ee11bb2a..8627103a531 100644 --- a/jdk/src/share/classes/java/nio/Bits.java +++ b/jdk/src/share/classes/java/nio/Bits.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,8 @@ import java.security.AccessController; import java.security.PrivilegedAction; import sun.misc.Unsafe; import sun.misc.VM; +import javax.management.ObjectName; +import javax.management.MalformedObjectNameException; /** * Access to bits, native and otherwise. @@ -625,13 +627,15 @@ class Bits { // package-private // direct buffer memory. This value may be changed during VM // initialization if it is launched with "-XX:MaxDirectMemorySize=". private static volatile long maxMemory = VM.maxDirectMemory(); - private static volatile long reservedMemory = 0; + private static volatile long reservedMemory; + private static volatile long usedMemory; + private static volatile long count; private static boolean memoryLimitSet = false; // These methods should be called whenever direct memory is allocated or // freed. They allow the user to control the amount of direct memory // which a process may access. All sizes are specified in bytes. - static void reserveMemory(long size) { + static void reserveMemory(long size, int cap) { synchronized (Bits.class) { if (!memoryLimitSet && VM.isBooted()) { @@ -640,6 +644,8 @@ class Bits { // package-private } if (size <= maxMemory - reservedMemory) { reservedMemory += size; + usedMemory += cap; + count++; return; } } @@ -655,17 +661,71 @@ class Bits { // package-private if (reservedMemory + size > maxMemory) throw new OutOfMemoryError("Direct buffer memory"); reservedMemory += size; + usedMemory += cap; + count++; } } - static synchronized void unreserveMemory(long size) { + static synchronized void unreserveMemory(long size, int cap) { if (reservedMemory > 0) { reservedMemory -= size; + usedMemory -= cap; + count--; assert (reservedMemory > -1); } } + // -- Management interface for monitoring of direct buffer usage -- + + static { + // setup access to this package in SharedSecrets + sun.misc.SharedSecrets.setJavaNioAccess( + new sun.misc.JavaNioAccess() { + @Override + public BufferPoolMXBean getDirectBufferPoolMXBean() { + return LazyInitialization.directBufferPoolMXBean; + } + } + ); + } + + // Lazy initialization of management interface + private static class LazyInitialization { + static final BufferPoolMXBean directBufferPoolMXBean = directBufferPoolMXBean(); + + private static BufferPoolMXBean directBufferPoolMXBean() { + final String pool = "direct"; + final ObjectName obj; + try { + obj = new ObjectName("java.nio:type=BufferPool,name=" + pool); + } catch (MalformedObjectNameException x) { + throw new AssertionError(x); + } + return new BufferPoolMXBean() { + @Override + public ObjectName getObjectName() { + return obj; + } + @Override + public String getName() { + return pool; + } + @Override + public long getCount() { + return Bits.count; + } + @Override + public long getTotalCapacity() { + return Bits.usedMemory; + } + @Override + public long getMemoryUsed() { + return Bits.reservedMemory; + } + }; + } + } // -- Bulk get/put acceleration -- @@ -675,14 +735,68 @@ class Bits { // package-private static final int JNI_COPY_TO_ARRAY_THRESHOLD = 6; static final int JNI_COPY_FROM_ARRAY_THRESHOLD = 6; + // This number limits the number of bytes to copy per call to Unsafe's + // copyMemory method. A limit is imposed to allow for safepoint polling + // during a large copy + static final long UNSAFE_COPY_THRESHOLD = 1024L * 1024L; + // These methods do no bounds checking. Verification that the copy will not // result in memory corruption should be done prior to invocation. // All positions and lengths are specified in bytes. - static native void copyFromByteArray(Object src, long srcPos, long dstAddr, - long length); - static native void copyToByteArray(long srcAddr, Object dst, long dstPos, - long length); + /** + * Copy from given source array to destination address. + * + * @param src + * source array + * @param srcBaseOffset + * offset of first element of storage in source array + * @param srcPos + * offset within source array of the first element to read + * @param dstAddr + * destination address + * @param length + * number of bytes to copy + */ + static void copyFromArray(Object src, long srcBaseOffset, long srcPos, + long dstAddr, long length) + { + long offset = srcBaseOffset + srcPos; + while (length > 0) { + long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length; + unsafe.copyMemory(src, offset, null, dstAddr, size); + length -= size; + offset += size; + dstAddr += size; + } + } + + /** + * Copy from source address into given destination array. + * + * @param srcAddr + * source address + * @param dst + * destination array + * @param dstBaseOffset + * offset of first element of storage in destination array + * @param dstPos + * offset within destination array of the first element to write + * @param length + * number of bytes to copy + */ + static void copyToArray(long srcAddr, Object dst, long dstBaseOffset, long dstPos, + long length) + { + long offset = dstBaseOffset + dstPos; + while (length > 0) { + long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length; + unsafe.copyMemory(null, srcAddr, dst, offset, size); + length -= size; + srcAddr += size; + offset += size; + } + } static void copyFromCharArray(Object src, long srcPos, long dstAddr, long length) diff --git a/jdk/src/share/classes/java/nio/BufferPoolMXBean.java b/jdk/src/share/classes/java/nio/BufferPoolMXBean.java new file mode 100644 index 00000000000..0a7fe303f24 --- /dev/null +++ b/jdk/src/share/classes/java/nio/BufferPoolMXBean.java @@ -0,0 +1,94 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.nio; + +import java.lang.management.PlatformManagedObject; + +/** + * The management interface for a buffer pool. + * + *

    A class implementing this interface is an MXBean. A Java + * virtual machine has one or more implementations of this interface. The {@link + * java.lang.management.ManagementFactory#getPlatformMXBeans getPlatformMXBeans} + * method can be used to obtain the list of {@code BufferPoolMXBean} objects + * representing the management interfaces for pools of buffers as follows: + *

    + *     List<BufferPoolMXBean> pools = ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class);
    + * 
    + * + *

    The management interfaces are also registered with the platform {@link + * javax.management.MBeanServer MBeanServer}. The {@link + * javax.management.ObjectName ObjectName} that uniquely identifies the + * management interface within the {@code MBeanServer} takes the form: + *

    + * java.nio:type=BufferPool,name=pool name + *
    + * where pool name is the {@link #getName name} of the buffer pool. + * + * @since 1.7 + */ + +public interface BufferPoolMXBean extends PlatformManagedObject { + + /** + * Returns the name representing this buffer pool. + * + * @return The name of this buffer pool. + */ + String getName(); + + /** + * Returns an estimate of the number of buffers in the pool. + * + * @return An estimate of the number of buffers in this pool + */ + long getCount(); + + /** + * Returns an estimate of the total capacity of the buffers in this pool. + * A buffer's capacity is the number of elements it contains and the value + * returned by this method is an estimate of the total capacity of buffers + * in the pool in bytes. + * + * @return An estimate of the total capacity of the buffers in this pool + * in bytes + */ + long getTotalCapacity(); + + /** + * Returns an estimate of the memory that the Java virtual machine is using + * for this buffer pool. The value returned by this method may differ + * from the estimate of the total {@link #getTotalCapacity capacity} of + * the buffers in this pool. This difference is explained by alignment, + * memory allocator, and other implementation specific reasons. + * + * @return An estimate of the memory that the Java virtual machine is using + * for this buffer pool in bytes, or {@code -1L} if an estimate of + * the memory usage is not available + */ + long getMemoryUsed(); +} diff --git a/jdk/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java b/jdk/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java index 5761fd867a4..54deb4c8f3e 100644 --- a/jdk/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java +++ b/jdk/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -186,7 +186,7 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private // --- Methods to support CharSequence --- - public CharSequence subSequence(int start, int end) { + public CharBuffer subSequence(int start, int end) { int pos = position(); int lim = limit(); assert (pos <= lim); diff --git a/jdk/src/share/classes/java/nio/Direct-X-Buffer.java b/jdk/src/share/classes/java/nio/Direct-X-Buffer.java index 092ac0e83ed..26b31956a31 100644 --- a/jdk/src/share/classes/java/nio/Direct-X-Buffer.java +++ b/jdk/src/share/classes/java/nio/Direct-X-Buffer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,9 @@ class Direct$Type$Buffer$RW$$BO$ // Cached unsafe-access object protected static final Unsafe unsafe = Bits.unsafe(); + // Cached array base offset + private static final long arrayBaseOffset = (long)unsafe.arrayBaseOffset($type$[].class); + // Cached unaligned-access capability protected static final boolean unaligned = Bits.unaligned(); @@ -71,11 +74,13 @@ class Direct$Type$Buffer$RW$$BO$ private static Unsafe unsafe = Unsafe.getUnsafe(); private long address; + private long size; private int capacity; - private Deallocator(long address, int capacity) { + private Deallocator(long address, long size, int capacity) { assert (address != 0); this.address = address; + this.size = size; this.capacity = capacity; } @@ -86,7 +91,7 @@ class Direct$Type$Buffer$RW$$BO$ } unsafe.freeMemory(address); address = 0; - Bits.unreserveMemory(capacity); + Bits.unreserveMemory(size, capacity); } } @@ -110,23 +115,25 @@ class Direct$Type$Buffer$RW$$BO$ Direct$Type$Buffer$RW$(int cap) { // package-private #if[rw] super(-1, 0, cap, cap, false); - Bits.reserveMemory(cap); int ps = Bits.pageSize(); + int size = cap + ps; + Bits.reserveMemory(size, cap); + long base = 0; try { - base = unsafe.allocateMemory(cap + ps); + base = unsafe.allocateMemory(size); } catch (OutOfMemoryError x) { - Bits.unreserveMemory(cap); + Bits.unreserveMemory(size, cap); throw x; } - unsafe.setMemory(base, cap + ps, (byte) 0); + unsafe.setMemory(base, size, (byte) 0); if (base % ps != 0) { // Round up to page boundary address = base + ps - (base & (ps - 1)); } else { address = base; } - cleaner = Cleaner.create(this, new Deallocator(base, cap)); + cleaner = Cleaner.create(this, new Deallocator(base, size, cap)); #else[rw] super(cap); #end[rw] @@ -238,14 +245,16 @@ class Direct$Type$Buffer$RW$$BO$ if (length > rem) throw new BufferUnderflowException(); +#if[!byte] if (order() != ByteOrder.nativeOrder()) Bits.copyTo$Memtype$Array(ix(pos), dst, offset << $LG_BYTES_PER_VALUE$, length << $LG_BYTES_PER_VALUE$); else - Bits.copyToByteArray(ix(pos), dst, - offset << $LG_BYTES_PER_VALUE$, - length << $LG_BYTES_PER_VALUE$); +#end[!byte] + Bits.copyToArray(ix(pos), dst, arrayBaseOffset, + offset << $LG_BYTES_PER_VALUE$, + length << $LG_BYTES_PER_VALUE$); position(pos + length); } else { super.get(dst, offset, length); @@ -328,12 +337,14 @@ class Direct$Type$Buffer$RW$$BO$ if (length > rem) throw new BufferOverflowException(); +#if[!byte] if (order() != ByteOrder.nativeOrder()) Bits.copyFrom$Memtype$Array(src, offset << $LG_BYTES_PER_VALUE$, ix(pos), length << $LG_BYTES_PER_VALUE$); else - Bits.copyFromByteArray(src, offset << $LG_BYTES_PER_VALUE$, - ix(pos), length << $LG_BYTES_PER_VALUE$); +#end[!byte] + Bits.copyFromArray(src, arrayBaseOffset, offset << $LG_BYTES_PER_VALUE$, + ix(pos), length << $LG_BYTES_PER_VALUE$); position(pos + length); } else { super.put(src, offset, length); @@ -391,7 +402,7 @@ class Direct$Type$Buffer$RW$$BO$ // --- Methods to support CharSequence --- - public CharSequence subSequence(int start, int end) { + public CharBuffer subSequence(int start, int end) { int pos = position(); int lim = limit(); assert (pos <= lim); diff --git a/jdk/src/share/classes/java/nio/Heap-X-Buffer.java b/jdk/src/share/classes/java/nio/Heap-X-Buffer.java index 0c19ca5549e..28f1ca8abe1 100644 --- a/jdk/src/share/classes/java/nio/Heap-X-Buffer.java +++ b/jdk/src/share/classes/java/nio/Heap-X-Buffer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2002 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -566,7 +566,7 @@ class Heap$Type$Buffer$RW$ // --- Methods to support CharSequence --- - public CharSequence subSequence(int start, int end) { + public CharBuffer subSequence(int start, int end) { if ((start < 0) || (end > length()) || (start > end)) diff --git a/jdk/src/share/classes/java/nio/StringCharBuffer.java b/jdk/src/share/classes/java/nio/StringCharBuffer.java index 3f49ae1eb12..648b1986fca 100644 --- a/jdk/src/share/classes/java/nio/StringCharBuffer.java +++ b/jdk/src/share/classes/java/nio/StringCharBuffer.java @@ -99,7 +99,7 @@ class StringCharBuffer // package-private return str.toString().substring(start + offset, end + offset); } - public final CharSequence subSequence(int start, int end) { + public final CharBuffer subSequence(int start, int end) { try { int pos = position(); return new StringCharBuffer(str, -1, diff --git a/jdk/src/share/classes/java/nio/X-Buffer.java b/jdk/src/share/classes/java/nio/X-Buffer.java index 99a7468fff8..9fc8185b646 100644 --- a/jdk/src/share/classes/java/nio/X-Buffer.java +++ b/jdk/src/share/classes/java/nio/X-Buffer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1239,13 +1239,13 @@ public abstract class $Type$Buffer * smaller than start and no larger than * remaining() * - * @return The new character sequence + * @return The new character buffer * * @throws IndexOutOfBoundsException * If the preconditions on start and end * do not hold */ - public abstract CharSequence subSequence(int start, int end); + public abstract CharBuffer subSequence(int start, int end); // --- Methods to support Appendable --- diff --git a/jdk/src/share/classes/java/nio/channels/DatagramChannel.java b/jdk/src/share/classes/java/nio/channels/DatagramChannel.java index 744495c5589..b8697fa1dc6 100644 --- a/jdk/src/share/classes/java/nio/channels/DatagramChannel.java +++ b/jdk/src/share/classes/java/nio/channels/DatagramChannel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2001 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,28 +26,21 @@ package java.nio.channels; import java.io.IOException; +import java.net.ProtocolFamily; import java.net.DatagramSocket; +import java.net.SocketOption; import java.net.SocketAddress; import java.nio.ByteBuffer; import java.nio.channels.spi.*; - /** * A selectable channel for datagram-oriented sockets. * - * - *

    Datagram channels are not a complete abstraction of network datagram - * sockets. Binding and the manipulation of socket options must be done - * through an associated {@link java.net.DatagramSocket} object obtained by - * invoking the {@link #socket() socket} method. It is not possible to create - * a channel for an arbitrary, pre-existing datagram socket, nor is it possible - * to specify the {@link java.net.DatagramSocketImpl} object to be used by a - * datagram socket associated with a datagram channel. - * - *

    A datagram channel is created by invoking the {@link #open open} method - * of this class. A newly-created datagram channel is open but not connected. - * A datagram channel need not be connected in order for the {@link #send send} - * and {@link #receive receive} methods to be used. A datagram channel may be + *

    A datagram channel is created by invoking one of the {@link #open open} methods + * of this class. It is not possible to create a channel for an arbitrary, + * pre-existing datagram socket. A newly-created datagram channel is open but not + * connected. A datagram channel need not be connected in order for the {@link #send + * send} and {@link #receive receive} methods to be used. A datagram channel may be * connected, by invoking its {@link #connect connect} method, in order to * avoid the overhead of the security checks are otherwise performed as part of * every send and receive operation. A datagram channel must be connected in @@ -59,11 +52,57 @@ import java.nio.channels.spi.*; * disconnected or closed. Whether or not a datagram channel is connected may * be determined by invoking its {@link #isConnected isConnected} method. * + *

    Socket options are configured using the {@link #setOption(SocketOption,Object) + * setOption} method. Datagram channels support the following options: + *

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    Option NameDescription
    {@link java.net.StandardSocketOption#SO_SNDBUF SO_SNDBUF} The size of the socket send buffer
    {@link java.net.StandardSocketOption#SO_RCVBUF SO_RCVBUF} The size of the socket receive buffer
    {@link java.net.StandardSocketOption#SO_REUSEADDR SO_REUSEADDR} Re-use address
    {@link java.net.StandardSocketOption#SO_BROADCAST SO_BROADCAST} Allow transmission of broadcast datagrams
    {@link java.net.StandardSocketOption#IP_TOS IP_TOS} The Type of Service (ToS) octet in the Internet Protocol (IP) header
    {@link java.net.StandardSocketOption#IP_MULTICAST_IF IP_MULTICAST_IF} The network interface for Internet Protocol (IP) multicast datagrams
    {@link java.net.StandardSocketOption#IP_MULTICAST_TTL + * IP_MULTICAST_TTL} The time-to-live for Internet Protocol (IP) multicast + * datagrams
    {@link java.net.StandardSocketOption#IP_MULTICAST_LOOP + * IP_MULTICAST_LOOP} Loopback for Internet Protocol (IP) multicast datagrams
    + *
    + * Additional (implementation specific) options may also be supported. + * *

    Datagram channels are safe for use by multiple concurrent threads. They * support concurrent reading and writing, though at most one thread may be * reading and at most one thread may be writing at any given time.

    * - * * @author Mark Reinhold * @author JSR-51 Expert Group * @since 1.4 @@ -71,7 +110,7 @@ import java.nio.channels.spi.*; public abstract class DatagramChannel extends AbstractSelectableChannel - implements ByteChannel, ScatteringByteChannel, GatheringByteChannel + implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, MulticastChannel { /** @@ -88,7 +127,13 @@ public abstract class DatagramChannel * java.nio.channels.spi.SelectorProvider#openDatagramChannel() * openDatagramChannel} method of the system-wide default {@link * java.nio.channels.spi.SelectorProvider} object. The channel will not be - * connected.

    + * connected. + * + *

    The {@link ProtocolFamily ProtocolFamily} of the channel's socket + * is platform (and possibly configuration) dependent and therefore unspecified. + * The {@link #open(ProtocolFamily) open} allows the protocol family to be + * selected when opening a datagram channel, and should be used to open + * datagram channels that are intended for Internet Protocol multicasting. * * @return A new datagram channel * @@ -99,6 +144,39 @@ public abstract class DatagramChannel return SelectorProvider.provider().openDatagramChannel(); } + /** + * Opens a datagram channel. + * + *

    The {@code family} parameter is used to specify the {@link + * ProtocolFamily}. If the datagram channel is to be used for IP multicasing + * then this should correspond to the address type of the multicast groups + * that this channel will join. + * + *

    The new channel is created by invoking the {@link + * java.nio.channels.spi.SelectorProvider#openDatagramChannel(ProtocolFamily) + * openDatagramChannel} method of the system-wide default {@link + * java.nio.channels.spi.SelectorProvider} object. The channel will not be + * connected. + * + * @param family + * The protocol family + * + * @return A new datagram channel + * + * @throws UnsupportedOperationException + * If the specified protocol family is not supported. For example, + * suppose the parameter is specified as {@link + * java.net.StandardProtocolFamily#INET6 StandardProtocolFamily.INET6} + * but IPv6 is not enabled on the platform. + * @throws IOException + * If an I/O error occurs + * + * @since 1.7 + */ + public static DatagramChannel open(ProtocolFamily family) throws IOException { + return SelectorProvider.provider().openDatagramChannel(family); + } + /** * Returns an operation set identifying this channel's supported * operations. @@ -117,6 +195,32 @@ public abstract class DatagramChannel // -- Socket-specific operations -- + /** + * @throws AlreadyBoundException {@inheritDoc} + * @throws UnsupportedAddressTypeException {@inheritDoc} + * @throws ClosedChannelException {@inheritDoc} + * @throws IOException {@inheritDoc} + * @throws SecurityException + * If a security manager has been installed and its {@link + * SecurityManager#checkListen checkListen} method denies the + * operation + * + * @since 1.7 + */ + public abstract DatagramChannel bind(SocketAddress local) + throws IOException; + + /** + * @throws IllegalArgumentException {@inheritDoc} + * @throws ClosedChannelException {@inheritDoc} + * @throws IOException {@inheritDoc} + * + * @since 1.7 + */ + public abstract DatagramChannel setOption(SocketOption name, T value) + throws IOException; + + /** * Retrieves a datagram socket associated with this channel. * @@ -128,10 +232,10 @@ public abstract class DatagramChannel public abstract DatagramSocket socket(); /** - * Tells whether or not this channel's socket is connected.

    + * Tells whether or not this channel's socket is connected. * - * @return true if, and only if, this channel's socket - * is connected + * @return {@code true} if, and only if, this channel's socket + * is {@link #isOpen open} and connected */ public abstract boolean isConnected(); @@ -206,6 +310,19 @@ public abstract class DatagramChannel */ public abstract DatagramChannel disconnect() throws IOException; + /** + * Returns the remote address to which this channel's socket is connected. + * + * @return The remote address; {@code null} if the channel is not {@link + * #isOpen open} or the channel's socket is not connected + * + * @throws IOException + * If an I/O error occurs + * + * @since 1.7 + */ + public abstract SocketAddress getConnectedAddress() throws IOException; + /** * Receives a datagram via this channel. * diff --git a/jdk/src/share/classes/java/nio/channels/MembershipKey.java b/jdk/src/share/classes/java/nio/channels/MembershipKey.java new file mode 100644 index 00000000000..0d2fc52bc4d --- /dev/null +++ b/jdk/src/share/classes/java/nio/channels/MembershipKey.java @@ -0,0 +1,183 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.nio.channels; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.io.IOException; +import java.util.List; + +/** + * A token representing the membership of an Internet Protocol (IP) multicast + * group. + * + *

    A membership key may represent a membership to receive all datagrams sent + * to the group, or it may be source-specific, meaning that it + * represents a membership that receives only datagrams from a specific source + * address. Whether or not a membership key is source-specific may be determined + * by invoking its {@link #getSourceAddress() getSourceAddress} method. + * + *

    A membership key is valid upon creation and remains valid until the + * membership is dropped by invoking the {@link #drop() drop} method, or + * the channel is closed. The validity of the membership key may be tested + * by invoking its {@link #isValid() isValid} method. + * + *

    Where a membership key is not source-specific and the underlying operation + * system supports source filtering, then the {@link #block block} and {@link + * #unblock unblock} methods can be used to block or unblock multicast datagrams + * from particular source addresses. + * + * @see MulticastChannel + * + * @since 1.7 + */ +public abstract class MembershipKey { + + /** + * Initializes a new instance of this class. + */ + protected MembershipKey() { + } + + /** + * Tells whether or not this membership is valid. + * + *

    A multicast group membership is valid upon creation and remains + * valid until the membership is dropped by invoking the {@link #drop() drop} + * method, or the channel is closed. + * + * @return {@code true} if this membership key is valid, {@code false} + * otherwise + */ + public abstract boolean isValid(); + + /** + * Drop membership. + * + *

    If the membership key represents a membership to receive all datagrams + * then the membership is dropped and the channel will no longer receive any + * datagrams sent to the group. If the membership key is source-specific + * then the channel will no longer receive datagrams sent to the group from + * that source address. + * + *

    After membership is dropped it may still be possible to receive + * datagrams sent to the group. This can arise when datagrams are waiting to + * be received in the socket's receive buffer. After membership is dropped + * then the channel may {@link MulticastChannel#join join} the group again + * in which case a new membership key is returned. + * + *

    Upon return, this membership object will be {@link #isValid() invalid}. + * If the multicast group membership is already invalid then invoking this + * method has no effect. Once a multicast group membership is invalid, + * it remains invalid forever. + * + * @throws IOException + * If an I/O error occurs + */ + public abstract void drop() throws IOException; + + /** + * Block multicast datagrams from the given source address. + * + *

    If this membership key is not source-specific, and the underlying + * operating system supports source filtering, then this method blocks + * multicast datagrams from the given source address. If the given source + * address is already blocked then this method has no effect. + * After a source address is blocked it may still be possible to receive + * datagams from that source. This can arise when datagrams are waiting to + * be received in the socket's receive buffer. + * + * @param source + * The source address to block + * + * @return This membership key + * + * @throws IllegalArgumentException + * If the {@code source} parameter is not a unicast address or + * is not the same address type as the multicast group + * @throws IllegalStateException + * If this membership key is source-specific or is no longer valid + * @throws UnsupportedOperationException + * If the underlying operating system does not support source + * filtering + * @throws IOException + * If an I/O error occurs + */ + public abstract MembershipKey block(InetAddress source) throws IOException; + + /** + * Unblock multicast datagrams from the given source address that was + * previously blocked using the {@link #block(InetAddress) block} method. + * + * @param source + * The source address to unblock + * + * @return This membership key + * + * @throws IllegalStateException + * If the given source address is not currently blocked or the + * membership key is no longer valid + * @throws IOException + * If an I/O error occurs + */ + public abstract MembershipKey unblock(InetAddress source) throws IOException; + + /** + * Returns the channel for which this membership key was created. This + * method will continue to return the channel even after the membership + * becomes {@link #isValid invalid}. + * + * @return the channel + */ + public abstract MulticastChannel getChannel(); + + /** + * Returns the multicast group for which this membership key was created. + * This method will continue to return the group even after the membership + * becomes {@link #isValid invalid}. + * + * @return the multicast group + */ + public abstract InetAddress getGroup(); + + /** + * Returns the network interface for which this membership key was created. + * This method will continue to return the network interface even after the + * membership becomes {@link #isValid invalid}. + * + * @return the network interface + */ + public abstract NetworkInterface getNetworkInterface(); + + /** + * Returns the source address if this membership key is source-specific, + * or {@code null} if this membership is not source-specific. + * + * @return The source address if this membership key is source-specific, + * otherwise {@code null} + */ + public abstract InetAddress getSourceAddress(); +} diff --git a/jdk/src/share/classes/java/nio/channels/MulticastChannel.java b/jdk/src/share/classes/java/nio/channels/MulticastChannel.java new file mode 100644 index 00000000000..440dd2a8b85 --- /dev/null +++ b/jdk/src/share/classes/java/nio/channels/MulticastChannel.java @@ -0,0 +1,211 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.nio.channels; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.io.IOException; +import java.net.ProtocolFamily; // javadoc +import java.net.StandardProtocolFamily; // javadoc +import java.net.StandardSocketOption; // javadoc + +/** + * A network channel that supports Internet Protocol (IP) multicasting. + * + *

    IP multicasting is the transmission of IP datagrams to members of + * a group that is zero or more hosts identified by a single destination + * address. + * + *

    In the case of a channel to an {@link StandardProtocolFamily#INET IPv4} socket, + * the underlying operating system supports + * RFC 2236: Internet Group Management Protocol, Version 2 (IGMPv2). + * It may optionally support source filtering as specified by RFC 3376: Internet Group + * Management Protocol, Version 3 (IGMPv3). + * For channels to an {@link StandardProtocolFamily#INET6 IPv6} socket, the equivalent + * standards are RFC 2710: + * Multicast Listener Discovery (MLD) for IPv6 and RFC 3810: Multicast Listener + * Discovery Version 2 (MLDv2) for IPv6. + * + *

    The {@link #join(InetAddress,NetworkInterface)} method is used to + * join a group and receive all multicast datagrams sent to the group. A channel + * may join several multicast groups and may join the same group on several + * {@link NetworkInterface interfaces}. Membership is dropped by invoking the {@link + * MembershipKey#drop drop} method on the returned {@link MembershipKey}. If the + * underlying platform supports source filtering then the {@link MembershipKey#block + * block} and {@link MembershipKey#unblock unblock} methods can be used to block or + * unblock multicast datagrams from particular source addresses. + * + *

    The {@link #join(InetAddress,NetworkInterface,InetAddress)} method + * is used to begin receiving datagrams sent to a group whose source address matches + * a given source address. This method throws {@link UnsupportedOperationException} + * if the underlying platform does not support source filtering. Membership is + * cumulative and this method may be invoked again with the same group + * and interface to allow receiving datagrams from other source addresses. The + * method returns a {@link MembershipKey} that represents membership to receive + * datagrams from the given source address. Invoking the key's {@link + * MembershipKey#drop drop} method drops membership so that datagrams from the + * source address can no longer be received. + * + *

    Platform dependencies

    + * + * The multicast implementation is intended to map directly to the native + * multicasting facility. Consequently, the following items should be considered + * when developing an application that receives IP multicast datagrams: + * + *
      + * + *
    1. The creation of the channel should specify the {@link ProtocolFamily} + * that corresponds to the address type of the multicast groups that the channel + * will join. There is no guarantee that a channel to a socket in one protocol + * family can join and receive multicast datagrams when the address of the + * multicast group corresponds to another protocol family. For example, it is + * implementation specific if a channel to an {@link StandardProtocolFamily#INET6 IPv6} + * socket can join an {@link StandardProtocolFamily#INET IPv4} multicast group and receive + * multicast datagrams sent to the group.

    2. + * + *
    3. The channel's socket should be bound to the {@link + * InetAddress#isAnyLocalAddress wildcard} address. If the socket is bound to + * a specific address, rather than the wildcard address then it is implementation + * specific if multicast datagrams are received by the socket.

    4. + * + *
    5. The {@link StandardSocketOption#SO_REUSEADDR SO_REUSEADDR} option should be + * enabled prior to {@link NetworkChannel#bind binding} the socket. This is + * required to allow multiple members of the group to bind to the same + * address.

    6. + * + *
    + * + *

    Usage Example: + *

    + *     // join multicast group on this interface, and also use this
    + *     // interface for outgoing multicast datagrams
    + *     NetworkInterface ni = NetworkInterface.getByName("hme0");
    + *
    + *     DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET)
    + *         .setOption(StandardSocketOption.SO_REUSEADDR, true)
    + *         .bind(new InetSocketAddress(5000))
    + *         .setOption(StandardSocketOption.IP_MULTICAST_IF, ni);
    + *
    + *     InetAddress group = InetAddress.getByName("225.4.5.6");
    + *
    + *     MembershipKey key = dc.join(group, ni);
    + * 
    + * + * @since 1.7 + */ + +public interface MulticastChannel + extends NetworkChannel +{ + /** + * Joins a multicast group to begin receiving all datagrams sent to the group, + * returning a membership key. + * + *

    If this channel is currently a member of the group on the given + * interface to receive all datagrams then the membership key, representing + * that membership, is returned. Otherwise this channel joins the group and + * the resulting new membership key is returned. The resulting membership key + * is not {@link MembershipKey#getSourceAddress source-specific}. + * + *

    A multicast channel may join several multicast groups, including + * the same group on more than one interface. An implementation may impose a + * limit on the number of groups that may be joined at the same time. + * + * @param group + * The multicast address to join + * @param interf + * The network interface on which to join the group + * + * @return The membership key + * + * @throws IllegalArgumentException + * If the group parameter is not a {@link InetAddress#isMulticastAddress + * multicast} address, or the group parameter is an address type + * that is not supported by this channel + * @throws IllegalStateException + * If the channel already has source-specific membership of the + * group on the interface + * @throws ClosedChannelException + * If this channel is closed + * @throws IOException + * If an I/O error occurs + * @throws SecurityException + * If a security manager is set, and its + * {@link SecurityManager#checkMulticast(InetAddress) checkMulticast} + * method denies access to the multiast group + */ + MembershipKey join(InetAddress group, NetworkInterface interf) + throws IOException; + + /** + * Joins a multicast group to begin receiving datagrams sent to the group + * from a given source address. + * + *

    If this channel is currently a member of the group on the given + * interface to receive datagrams from the given source address then the + * membership key, representing that membership, is returned. Otherwise this + * channel joins the group and the resulting new membership key is returned. + * The resulting membership key is {@link MembershipKey#getSourceAddress + * source-specific}. + * + *

    Membership is cumulative and this method may be invoked + * again with the same group and interface to allow receiving datagrams sent + * by other source addresses to the group. + * + * @param group + * The multicast address to join + * @param interf + * The network interface on which to join the group + * @param source + * The source address + * + * @return The membership key + * + * @throws IllegalArgumentException + * If the group parameter is not a {@link + * InetAddress#isMulticastAddress multicast} address, the + * source parameter is not a unicast address, the group + * parameter is an address type that is not supported by this channel, + * or the source parameter is not the same address type as the group + * @throws IllegalStateException + * If the channel is currently a member of the group on the given + * interface to receive all datagrams + * @throws UnsupportedOperationException + * If the underlying operation system does not support source filtering + * @throws ClosedChannelException + * If this channel is closed + * @throws IOException + * If an I/O error occurs + * @throws SecurityException + * If a security manager is set, and its + * {@link SecurityManager#checkMulticast(InetAddress) checkMulticast} + * method denies access to the multiast group + */ + MembershipKey join(InetAddress group, NetworkInterface interf, InetAddress source) + throws IOException; +} diff --git a/jdk/src/share/classes/java/nio/channels/NetworkChannel.java b/jdk/src/share/classes/java/nio/channels/NetworkChannel.java new file mode 100644 index 00000000000..fae642fcbdb --- /dev/null +++ b/jdk/src/share/classes/java/nio/channels/NetworkChannel.java @@ -0,0 +1,158 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.nio.channels; + +import java.net.SocketOption; +import java.net.SocketAddress; +import java.util.Set; +import java.io.IOException; + +/** + * A channel to a network socket. + * + *

    A channel that implements this interface is a channel to a network + * socket. The {@link #bind(SocketAddress) bind} method is used to bind the + * socket to a local {@link SocketAddress address}, the {@link #getLocalAddress() + * getLocalAddress} method returns the address that the socket is bound to, and + * the {@link #setOption(SocketOption,Object) setOption} and {@link + * #getOption(SocketOption) getOption} methods are used to set and query socket + * options. An implementation of this interface should specify the socket options + * that it supports. + * + *

    The {@link #bind bind} and {@link #setOption setOption} methods that do + * not otherwise have a value to return are specified to return the network + * channel upon which they are invoked. This allows method invocations to be + * chained. Implementations of this interface should specialize the return type + * so that method invocations on the implementation class can be chained. + * + * @since 1.7 + */ + +public interface NetworkChannel + extends Channel +{ + /** + * Binds the channel's socket to a local address. + * + *

    This method is used to establish an association between the socket and + * a local address. Once an association is established then the socket remains + * bound until the channel is closed. If the {@code local} parameter has the + * value {@code null} then the socket will be bound to an address that is + * assigned automatically. + * + * @param local + * The address to bind the socket, or {@code null} to bind the socket + * to an automatically assigned socket address + * + * @return This channel + * + * @throws AlreadyBoundException + * If the socket is already bound + * @throws UnsupportedAddressTypeException + * If the type of the given address is not supported + * @throws ClosedChannelException + * If the channel is closed + * @throws IOException + * If some other I/O error occurs + * @throws SecurityException + * If a security manager is installed and it denies an unspecified + * permission. An implementation of this interface should specify + * any required permissions. + * + * @see #getLocalAddress + */ + NetworkChannel bind(SocketAddress local) throws IOException; + + /** + * Returns the socket address that this channel's socket is bound to, or + * {@code null} if the socket is not bound. + * + *

    Where the channel is {@link #bind bound} to an Internet Protocol + * socket address then the return value from this method is of type {@link + * java.net.InetSocketAddress}. + * + * @return The socket address that the socket is bound to, or {@code null} + * if the channel is not {@link #isOpen open} or the channel's socket + * is not bound + * + * @throws IOException + * If an I/O error occurs + */ + SocketAddress getLocalAddress() throws IOException; + + /** + * Sets the value of a socket option. + * + * @param name + * The socket option + * @param value + * The value of the socket option. A value of {@code null} may be + * a valid value for some socket options. + * + * @return This channel + * + * @throws IllegalArgumentException + * If the socket option is not supported by this channel, or + * the value is not a valid value for this socket option + * @throws ClosedChannelException + * If this channel is closed + * @throws IOException + * If an I/O error occurs + * + * @see java.net.StandardSocketOption + */ + NetworkChannel setOption(SocketOption name, T value) throws IOException; + + /** + * Returns the value of a socket option. + * + * @param name + * The socket option + * + * @return The value of the socket option. A value of {@code null} may be + * a valid value for some socket options. + * + * @throws IllegalArgumentException + * If the socket option is not supported by this channel + * @throws ClosedChannelException + * If this channel is closed + * @throws IOException + * If an I/O error occurs + * + * @see java.net.StandardSocketOption + */ + T getOption(SocketOption name) throws IOException; + + /** + * Returns a set of the socket options supported by this channel. + * + *

    This method will continue to return the set of options even after the + * channel has been closed. + * + * @return A set of the socket options supported by this channel + */ + Set> options(); +} diff --git a/jdk/src/share/classes/java/nio/channels/SelectionKey.java b/jdk/src/share/classes/java/nio/channels/SelectionKey.java index 00fd36f463a..032f240b912 100644 --- a/jdk/src/share/classes/java/nio/channels/SelectionKey.java +++ b/jdk/src/share/classes/java/nio/channels/SelectionKey.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/java/nio/channels/ServerSocketChannel.java b/jdk/src/share/classes/java/nio/channels/ServerSocketChannel.java index 0ffed003a6c..84ea062c9f0 100644 --- a/jdk/src/share/classes/java/nio/channels/ServerSocketChannel.java +++ b/jdk/src/share/classes/java/nio/channels/ServerSocketChannel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2001 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,33 +27,44 @@ package java.nio.channels; import java.io.IOException; import java.net.ServerSocket; +import java.net.SocketOption; import java.net.SocketAddress; import java.nio.channels.spi.*; - /** * A selectable channel for stream-oriented listening sockets. * - *

    Server-socket channels are not a complete abstraction of listening - * network sockets. Binding and the manipulation of socket options must be - * done through an associated {@link java.net.ServerSocket} object obtained by - * invoking the {@link #socket() socket} method. It is not possible to create - * a channel for an arbitrary, pre-existing server socket, nor is it possible - * to specify the {@link java.net.SocketImpl} object to be used by a server - * socket associated with a server-socket channel. - * *

    A server-socket channel is created by invoking the {@link #open() open} - * method of this class. A newly-created server-socket channel is open but not - * yet bound. An attempt to invoke the {@link #accept() accept} method of an - * unbound server-socket channel will cause a {@link NotYetBoundException} to - * be thrown. A server-socket channel can be bound by invoking one of the - * {@link java.net.ServerSocket#bind(java.net.SocketAddress,int) bind} methods - * of an associated server socket. + * method of this class. It is not possible to create a channel for an arbitrary, + * pre-existing {@link ServerSocket}. A newly-created server-socket channel is + * open but not yet bound. An attempt to invoke the {@link #accept() accept} + * method of an unbound server-socket channel will cause a {@link NotYetBoundException} + * to be thrown. A server-socket channel can be bound by invoking one of the + * {@link #bind(java.net.SocketAddress,int) bind} methods defined by this class. + * + *

    Socket options are configured using the {@link #setOption(SocketOption,Object) + * setOption} method. Server-socket channels support the following options: + *

    + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    Option NameDescription
    {@link java.net.StandardSocketOption#SO_RCVBUF SO_RCVBUF} The size of the socket receive buffer
    {@link java.net.StandardSocketOption#SO_REUSEADDR SO_REUSEADDR} Re-use address
    + *
    + * Additional (implementation specific) options may also be supported. * *

    Server-socket channels are safe for use by multiple concurrent threads. *

    * - * * @author Mark Reinhold * @author JSR-51 Expert Group * @since 1.4 @@ -61,6 +72,7 @@ import java.nio.channels.spi.*; public abstract class ServerSocketChannel extends AbstractSelectableChannel + implements NetworkChannel { /** @@ -109,6 +121,89 @@ public abstract class ServerSocketChannel // -- ServerSocket-specific operations -- + /** + * Binds the channel's socket to a local address and configures the socket + * to listen for connections. + * + *

    An invocation of this method is equivalent to the following: + *

    +     * bind(local, 0);
    +     * 
    + * + * @param local + * The local address to bind the socket, or {@code null} to bind + * to an automatically assigned socket address + * + * @return This channel + * + * @throws AlreadyBoundException {@inheritDoc} + * @throws UnsupportedAddressTypeException {@inheritDoc} + * @throws ClosedChannelException {@inheritDoc} + * @throws IOException {@inheritDoc} + * @throws SecurityException + * If a security manager has been installed and its {@link + * SecurityManager#checkListen checkListen} method denies the + * operation + * + * @since 1.7 + */ + public final ServerSocketChannel bind(SocketAddress local) + throws IOException + { + return bind(local, 0); + } + + /** + * Binds the channel's socket to a local address and configures the socket to + * listen for connections. + * + *

    This method is used to establish an association between the socket and + * a local address. Once an association is established then the socket remains + * bound until the channel is closed. + * + *

    The {@code backlog} parameter is the maximum number of pending + * connections on the socket. Its exact semantics are implementation specific. + * In particular, an implementation may impose a maximum length or may choose + * to ignore the parameter altogther. If the {@code backlog} parameter has + * the value {@code 0}, or a negative value, then an implementation specific + * default is used. + * + * @param local + * The address to bind the socket, or {@code null} to bind to an + * automatically assigned socket address + * @param backlog + * The maximum number of pending connections + * + * @return This channel + * + * @throws AlreadyBoundException + * If the socket is already bound + * @throws UnsupportedAddressTypeException + * If the type of the given address is not supported + * @throws ClosedChannelException + * If this channel is closed + * @throws IOException + * If some other I/O error occurs + * @throws SecurityException + * If a security manager has been installed and its {@link + * SecurityManager#checkListen checkListen} method denies the + * operation + * + * @since 1.7 + */ + public abstract ServerSocketChannel bind(SocketAddress local, int backlog) + throws IOException; + + /** + * @throws IllegalArgumentException {@inheritDoc} + * @throws ClosedChannelException {@inheritDoc} + * @throws IOException {@inheritDoc} + * + * @since 1.7 + */ + public abstract ServerSocketChannel setOption(SocketOption name, T value) + throws IOException; + /** * Retrieves a server socket associated with this channel. * diff --git a/jdk/src/share/classes/java/nio/channels/SocketChannel.java b/jdk/src/share/classes/java/nio/channels/SocketChannel.java index 8266994227b..2e96bd2e4ce 100644 --- a/jdk/src/share/classes/java/nio/channels/SocketChannel.java +++ b/jdk/src/share/classes/java/nio/channels/SocketChannel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2001 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,24 +27,17 @@ package java.nio.channels; import java.io.IOException; import java.net.Socket; +import java.net.SocketOption; import java.net.SocketAddress; import java.nio.ByteBuffer; import java.nio.channels.spi.*; - /** * A selectable channel for stream-oriented connecting sockets. * - *

    Socket channels are not a complete abstraction of connecting network - * sockets. Binding, shutdown, and the manipulation of socket options must be - * done through an associated {@link java.net.Socket} object obtained by - * invoking the {@link #socket() socket} method. It is not possible to create - * a channel for an arbitrary, pre-existing socket, nor is it possible to - * specify the {@link java.net.SocketImpl} object to be used by a socket - * associated with a socket channel. - * *

    A socket channel is created by invoking one of the {@link #open open} - * methods of this class. A newly-created socket channel is open but not yet + * methods of this class. It is not possible to create a channel for an arbitrary, + * pre-existing socket. A newly-created socket channel is open but not yet * connected. An attempt to invoke an I/O operation upon an unconnected * channel will cause a {@link NotYetConnectedException} to be thrown. A * socket channel can be connected by invoking its {@link #connect connect} @@ -59,16 +52,6 @@ import java.nio.channels.spi.*; * Whether or not a connection operation is in progress may be determined by * invoking the {@link #isConnectionPending isConnectionPending} method. * - *

    The input and output sides of a socket channel may independently be - * shut down without actually closing the channel. Shutting down the - * input side of a channel by invoking the {@link java.net.Socket#shutdownInput - * shutdownInput} method of an associated socket object will cause further - * reads on the channel to return -1, the end-of-stream indication. - * Shutting down the output side of the channel by invoking the {@link - * java.net.Socket#shutdownOutput shutdownOutput} method of an associated - * socket object will cause further writes on the channel to throw a {@link - * ClosedChannelException}. - * *

    Socket channels support asynchronous shutdown, which is similar * to the asynchronous close operation specified in the {@link Channel} class. * If the input side of a socket is shut down by one thread while another @@ -79,6 +62,43 @@ import java.nio.channels.spi.*; * channel, then the blocked thread will receive an {@link * AsynchronousCloseException}. * + *

    Socket options are configured using the {@link #setOption(SocketOption,Object) + * setOption} method. Socket channels support the following options: + *

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    Option NameDescription
    {@link java.net.StandardSocketOption#SO_SNDBUF SO_SNDBUF} The size of the socket send buffer
    {@link java.net.StandardSocketOption#SO_RCVBUF SO_RCVBUF} The size of the socket receive buffer
    {@link java.net.StandardSocketOption#SO_KEEPALIVE SO_KEEPALIVE} Keep connection alive
    {@link java.net.StandardSocketOption#SO_REUSEADDR SO_REUSEADDR} Re-use address
    {@link java.net.StandardSocketOption#SO_LINGER SO_LINGER} Linger on close if data is present (when configured in blocking mode + * only)
    {@link java.net.StandardSocketOption#TCP_NODELAY TCP_NODELAY} Disable the Nagle algorithm
    + *
    + * Additional (implementation specific) options may also be supported. + * *

    Socket channels are safe for use by multiple concurrent threads. They * support concurrent reading and writing, though at most one thread may be * reading and at most one thread may be writing at any given time. The {@link @@ -87,7 +107,6 @@ import java.nio.channels.spi.*; * or write operation while an invocation of one of these methods is in * progress will block until that invocation is complete.

    * - * * @author Mark Reinhold * @author JSR-51 Expert Group * @since 1.4 @@ -95,7 +114,7 @@ import java.nio.channels.spi.*; public abstract class SocketChannel extends AbstractSelectableChannel - implements ByteChannel, ScatteringByteChannel, GatheringByteChannel + implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, NetworkChannel { /** @@ -191,6 +210,73 @@ public abstract class SocketChannel // -- Socket-specific operations -- + /** + * @throws ConnectionPendingException + * If a non-blocking connection operation is already in progress on + * this channel + * @throws AlreadyBoundException {@inheritDoc} + * @throws UnsupportedAddressTypeException {@inheritDoc} + * @throws ClosedChannelException {@inheritDoc} + * @throws IOException {@inheritDoc} + * + * @since 1.7 + */ + @Override + public abstract SocketChannel bind(SocketAddress local) + throws IOException; + + /** + * @throws IllegalArgumentException {@inheritDoc} + * @throws ClosedChannelException {@inheritDoc} + * @throws IOException {@inheritDoc} + * + * @since 1.7 + */ + @Override + public abstract SocketChannel setOption(SocketOption name, T value) + throws IOException; + + /** + * Shutdown the connection for reading without closing the channel. + * + *

    Once shutdown for reading then further reads on the channel will + * return {@code -1}, the end-of-stream indication. If the input side of the + * connection is already shutdown then invoking this method has no effect. + * + * @return The channel + * + * @throws NotYetConnectedException + * If this channel is not yet connected + * @throws ClosedChannelException + * If this channel is closed + * @throws IOException + * If some other I/O error occurs + * + * @since 1.7 + */ + public abstract SocketChannel shutdownInput() throws IOException; + + /** + * Shutdown the connection for writing without closing the channel. + * + *

    Once shutdown for writing then further attempts to write to the + * channel will throw {@link ClosedChannelException}. If the output side of + * the connection is already shutdown then invoking this method has no + * effect. + * + * @return The channel + * + * @throws NotYetConnectedException + * If this channel is not yet connected + * @throws ClosedChannelException + * If this channel is closed + * @throws IOException + * If some other I/O error occurs + * + * @since 1.7 + */ + public abstract SocketChannel shutdownOutput() throws IOException; + /** * Retrieves a socket associated with this channel. * @@ -202,10 +288,10 @@ public abstract class SocketChannel public abstract Socket socket(); /** - * Tells whether or not this channel's network socket is connected.

    + * Tells whether or not this channel's network socket is connected. * * @return true if, and only if, this channel's network socket - * is connected + * is {@link #isOpen open} and connected */ public abstract boolean isConnected(); @@ -339,6 +425,22 @@ public abstract class SocketChannel */ public abstract boolean finishConnect() throws IOException; + /** + * Returns the remote address to which this channel's socket is connected. + * + *

    Where the channel is bound and connected to an Internet Protocol + * socket address then the return value from this method is of type {@link + * java.net.InetSocketAddress}. + * + * @return The remote address; {@code null} if the channel is not {@link + * #isOpen open} or the channel's socket is not connected + * + * @throws IOException + * If an I/O error occurs + * + * @since 1.7 + */ + public abstract SocketAddress getConnectedAddress() throws IOException; // -- ByteChannel operations -- diff --git a/jdk/src/share/classes/java/nio/channels/exceptions b/jdk/src/share/classes/java/nio/channels/exceptions index ae4d4c0d960..04cfbe03e29 100644 --- a/jdk/src/share/classes/java/nio/channels/exceptions +++ b/jdk/src/share/classes/java/nio/channels/exceptions @@ -1,5 +1,5 @@ # -# Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -146,3 +146,14 @@ gen OverlappingFileLockException " * virtual machine, or when another thread is already waiting to lock an * overlapping region of the same file." \ 2047812138163068433L + + +SINCE=1.7 + +SUPER=IllegalStateException + +gen AlreadyBoundException " + * Unchecked exception thrown when an attempt is made to bind the socket a + * network oriented channel that is already bound." \ + 6796072983322737592L + diff --git a/jdk/src/share/classes/java/nio/channels/package-info.java b/jdk/src/share/classes/java/nio/channels/package-info.java new file mode 100644 index 00000000000..e8c2a929d4b --- /dev/null +++ b/jdk/src/share/classes/java/nio/channels/package-info.java @@ -0,0 +1,231 @@ +/* + * Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * Defines channels, which represent connections to entities that are capable of + * performing I/O operations, such as files and sockets; defines selectors, for + * multiplexed, non-blocking I/O operations. + * + * + * + *

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *

    Channels

    Description

    {@link java.nio.channels.Channel}A nexus for I/O operations
      {@link java.nio.channels.ReadableByteChannel}Can read into a buffer
        {@link java.nio.channels.ScatteringByteChannel}  Can read into a sequence of buffers
      {@link java.nio.channels.WritableByteChannel}Can write from a buffer
        {@link java.nio.channels.GatheringByteChannel}Can write from a sequence of buffers
      {@link java.nio.channels.ByteChannel}Can read/write to/from a buffer
        {@link java.nio.channels.SeekableByteChannel}A {@code ByteChannel} connected to an entity that contains a variable-length sequence of bytes
      {@link java.nio.channels.NetworkChannel}A channel to a network socket
        {@link java.nio.channels.MulticastChannel}Can join Internet Protocol (IP) multicast groups
    {@link java.nio.channels.Channels}Utility methods for channel/stream interoperation
    + * + *

    A channel represents an open connection to an entity such as a + * hardware device, a file, a network socket, or a program component that is + * capable of performing one or more distinct I/O operations, for example reading + * or writing. As specified in the {@link java.nio.channels.Channel} interface, + * channels are either open or closed, and they are both asynchronously + * closeable and interruptible. + * + *

    The {@link java.nio.channels.Channel} interface is extended by several + * other interfaces. + * + *

    The {@link java.nio.channels.ReadableByteChannel} interface specifies a + * {@link java.nio.channels.ReadableByteChannel#read read} method that reads bytes + * from the channel into a buffer; similarly, the {@link + * java.nio.channels.WritableByteChannel} interface specifies a {@link + * java.nio.channels.WritableByteChannel#write write} method that writes bytes + * from a buffer to the channel. The {@link java.nio.channels.ByteChannel} + * interface unifies these two interfaces for the common case of channels that can + * both read and write bytes. The {@link java.nio.channels.SeekableByteChannel} + * interface extends the {@code ByteChannel} interface with methods to {@link + * java.nio.channels.SeekableByteChannel#position() query} and {@link + * java.nio.channels.SeekableByteChannel#position(long) modify} the channel's + * current position, and its {@link java.nio.channels.SeekableByteChannel#size + * size}. + * + *

    The {@link java.nio.channels.ScatteringByteChannel} and {@link + * java.nio.channels.GatheringByteChannel} interfaces extend the {@link + * java.nio.channels.ReadableByteChannel} and {@link + * java.nio.channels.WritableByteChannel} interfaces, respectively, adding {@link + * java.nio.channels.ScatteringByteChannel#read read} and {@link + * java.nio.channels.GatheringByteChannel#write write} methods that take a + * sequence of buffers rather than a single buffer. + * + *

    The {@link java.nio.channels.NetworkChannel} interface specifies methods + * to {@link java.nio.channels.NetworkChannel#bind bind} the channel's socket, + * obtain the address to which the socket is bound, and methods to {@link + * java.nio.channels.NetworkChannel#getOption get} and {@link + * java.nio.channels.NetworkChannel#setOption set} socket options. The {@link + * java.nio.channels.MulticastChannel} interface specifies methods to join + * Internet Protocol (IP) multicast groups. + * + *

    The {@link java.nio.channels.Channels} utility class defines static methods + * that support the interoperation of the stream classes of the {@link + * java.io} package with the channel classes of this package. An appropriate + * channel can be constructed from an {@link java.io.InputStream} or an {@link + * java.io.OutputStream}, and conversely an {@link java.io.InputStream} or an + * {@link java.io.OutputStream} can be constructed from a channel. A {@link + * java.io.Reader} can be constructed that uses a given charset to decode bytes + * from a given readable byte channel, and conversely a {@link java.io.Writer} can + * be constructed that uses a given charset to encode characters into bytes and + * write them to a given writable byte channel. + * + *

    + * + * + * + * + * + * + * + *

    File channels

    Description

    {@link java.nio.channels.FileChannel}Reads, writes, maps, and manipulates files
    {@link java.nio.channels.FileLock}A lock on a (region of a) file
    {@link java.nio.MappedByteBuffer}/{@link java.nio.MappedBigByteBuffer}  A direct byte buffer or big byte buffer mapped to a region of a file
    + * + *

    The {@link java.nio.channels.FileChannel} class supports the usual + * operations of reading bytes from, and writing bytes to, a channel connected to + * a file, as well as those of querying and modifying the current file position + * and truncating the file to a specific size. It defines methods for acquiring + * locks on the whole file or on a specific region of a file; these methods return + * instances of the {@link java.nio.channels.FileLock} class. Finally, it defines + * methods for forcing updates to the file to be written to the storage device that + * contains it, for efficiently transferring bytes between the file and other + * channels, and for mapping a region of the file directly into memory. + * + *

    A {@code FileChannel} is created by invoking one of its static {@link + * java.nio.channels.FileChannel#open open} methods, or by invoking the {@code + * getChannel} method of a {@link java.io.FileInputStream}, {@link + * java.io.FileOutputStream}, or {@link java.io.RandomAccessFile} to return a + * file channel connected to the same underlying file as the {@link java.io} + * class. + * + * + *

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *

    Multiplexed, non-blocking I/O

    Description

    {@link java.nio.channels.SelectableChannel}A channel that can be multiplexed
      {@link java.nio.channels.DatagramChannel}A channel to a datagram-oriented socket
      {@link java.nio.channels.Pipe.SinkChannel}The write end of a pipe
      {@link java.nio.channels.Pipe.SourceChannel}The read end of a pipe
      {@link java.nio.channels.ServerSocketChannel}  A channel to a stream-oriented listening socket
      {@link java.nio.channels.SocketChannel}A channel for a stream-oriented connecting socket
    {@link java.nio.channels.Selector}A multiplexor of selectable channels
    {@link java.nio.channels.SelectionKey}A token representing the registration
    of a channel + * with a selector
    {@link java.nio.channels.Pipe}Two channels that form a unidirectional pipe
    + * + *

    Multiplexed, non-blocking I/O, which is much more scalable than + * thread-oriented, blocking I/O, is provided by selectors, selectable + * channels, and selection keys. + * + *

    A selector is a multiplexor of selectable channels, which in turn are + * a special type of channel that can be put into non-blocking mode. To perform + * multiplexed I/O operations, one or more selectable channels are first created, + * put into non-blocking mode, and {@link + * java.nio.channels.SelectableChannel#register registered} + * with a selector. Registering a channel specifies the set of I/O operations + * that will be tested for readiness by the selector, and returns a selection key that represents the + * registration. + * + *

    Once some channels have been registered with a selector, a selection operation can be performed in + * order to discover which channels, if any, have become ready to perform one or + * more of the operations in which interest was previously declared. If a channel + * is ready then the key returned when it was registered will be added to the + * selector's selected-key set. The key set, and the keys within it, can + * be examined in order to determine the operations for which each channel is + * ready. From each key one can retrieve the corresponding channel in order to + * perform whatever I/O operations are required. + * + *

    That a selection key indicates that its channel is ready for some operation + * is a hint, but not a guarantee, that such an operation can be performed by a + * thread without causing the thread to block. It is imperative that code that + * performs multiplexed I/O be written so as to ignore these hints when they prove + * to be incorrect. + * + *

    This package defines selectable-channel classes corresponding to the {@link + * java.net.DatagramSocket}, {@link java.net.ServerSocket}, and {@link + * java.net.Socket} classes defined in the {@link java.net} package. + * Minor changes to these classes have been made in order to support sockets that + * are associated with channels. This package also defines a simple class that + * implements unidirectional pipes. In all cases, a new selectable channel is + * created by invoking the static open method of the corresponding class. + * If a channel needs an associated socket then a socket will be created as a side + * effect of this operation. + * + *

    The implementation of selectors, selectable channels, and selection keys + * can be replaced by "plugging in" an alternative definition or instance of the + * {@link java.nio.channels.spi.SelectorProvider} class defined in the {@link + * java.nio.channels.spi} package. It is not expected that many developers + * will actually make use of this facility; it is provided primarily so that + * sophisticated users can take advantage of operating-system-specific + * I/O-multiplexing mechanisms when very high performance is required. + * + *

    Much of the bookkeeping and synchronization required to implement the + * multiplexed-I/O abstractions is performed by the {@link + * java.nio.channels.spi.AbstractInterruptibleChannel}, {@link + * java.nio.channels.spi.AbstractSelectableChannel}, {@link + * java.nio.channels.spi.AbstractSelectionKey}, and {@link + * java.nio.channels.spi.AbstractSelector} classes in the {@link + * java.nio.channels.spi} package. When defining a custom selector provider, + * only the {@link java.nio.channels.spi.AbstractSelector} and {@link + * java.nio.channels.spi.AbstractSelectionKey} classes should be subclassed + * directly; custom channel classes should extend the appropriate {@link + * java.nio.channels.SelectableChannel} subclasses defined in this package. + * + *


    + *

    Unless otherwise noted, passing a null argument to a constructor + * or method in any class or interface in this package will cause a {@link + * java.lang.NullPointerException NullPointerException} to be thrown. + * + * @since 1.4 + * @author Mark Reinhold + * @author JSR-51 Expert Group + */ + +package java.nio.channels; diff --git a/jdk/src/share/classes/java/nio/channels/package.html b/jdk/src/share/classes/java/nio/channels/package.html deleted file mode 100644 index 151378f78fd..00000000000 --- a/jdk/src/share/classes/java/nio/channels/package.html +++ /dev/null @@ -1,222 +0,0 @@ - - - - - - -Defines channels, which represent connections to entities that are capable of -performing I/O operations, such as files and sockets; defines selectors, for -multiplexed, non-blocking I/O operations. - - - - -

    - - - - - - - - - - - - - - - -

    Channels

    Description

    {@link java.nio.channels.Channel}A nexus for I/O operations
      {@link java.nio.channels.ReadableByteChannel}Can read into a buffer
        {@link java.nio.channels.ScatteringByteChannel}  Can read into a sequence of buffers
      {@link java.nio.channels.WritableByteChannel}Can write from a buffer
        {@link java.nio.channels.GatheringByteChannel}Can write from a sequence of buffers
      {@link java.nio.channels.ByteChannel}Can read/write to/from a buffer
    {@link java.nio.channels.Channels}Utility methods for channel/stream interoperation
    - -

    A channel represents an open connection to an entity such as a -hardware device, a file, a network socket, or a program component that is -capable of performing one or more distinct I/O operations, for example reading -or writing. As specified in the {@link java.nio.channels.Channel} interface, -channels are either open or closed, and they are both asynchronously -closeable and interruptible. - -

    The {@link java.nio.channels.Channel} interface is extended by several -other interfaces, each of which specifies a new I/O operation. - -

    The {@link java.nio.channels.ReadableByteChannel} interface specifies a -{@link java.nio.channels.ReadableByteChannel#read read} method that reads bytes -from the channel into a buffer; similarly, the {@link -java.nio.channels.WritableByteChannel} interface specifies a {@link -java.nio.channels.WritableByteChannel#write write} method that writes bytes -from a buffer to the channel. The {@link java.nio.channels.ByteChannel} -interface unifies these two interfaces for the common case of channels that can -both read and write bytes. - -

    The {@link java.nio.channels.ScatteringByteChannel} and {@link -java.nio.channels.GatheringByteChannel} interfaces extend the {@link -java.nio.channels.ReadableByteChannel} and {@link -java.nio.channels.WritableByteChannel} interfaces, respectively, adding {@link -java.nio.channels.ScatteringByteChannel#read read} and {@link -java.nio.channels.GatheringByteChannel#write write} methods that take a -sequence of buffers rather than a single buffer. - -

    The {@link java.nio.channels.Channels} utility class defines static methods -that support the interoperation of the stream classes of the {@link -java.io} package with the channel classes of this package. An appropriate -channel can be constructed from an {@link java.io.InputStream} or an {@link -java.io.OutputStream}, and conversely an {@link java.io.InputStream} or an -{@link java.io.OutputStream} can be constructed from a channel. A {@link -java.io.Reader} can be constructed that uses a given charset to decode bytes -from a given readable byte channel, and conversely a {@link java.io.Writer} can -be constructed that uses a given charset to encode characters into bytes and -write them to a given writable byte channel. - - -

    - - - - - - - -

    File channels

    Description

    {@link java.nio.channels.FileChannel}Reads, writes, maps, and manipulates files
    {@link java.nio.channels.FileLock}A lock on a (region of a) file
    {@link java.nio.MappedByteBuffer}  A direct byte buffer mapped to a region of a file
    - -

    The {@link java.nio.channels.FileChannel} class supports the usual -operations of reading bytes from, and writing bytes to, a channel connected to -a file, as well as those of querying and modifying the current file position -and truncating the file to a specific size. It defines methods for acquiring -locks on the whole file or on a specific region of a file; these methods return -instances of the {@link java.nio.channels.FileLock} class. Finally, it defines -methods for forcing updates to the file to be written to the storage device that -contains it, for efficiently transferring bytes between the file and other -channels, and for mapping a region of the file directly into memory. This last -operation creates an instance of the {@link java.nio.MappedByteBuffer} -class, which extends the {@link java.nio.ByteBuffer} class with several -file-related operations. - -

    A getChannel method has been added to each of the {@link -java.io.FileInputStream#getChannel FileInputStream}, {@link -java.io.FileOutputStream#getChannel FileOutputStream}, and {@link -java.io.RandomAccessFile#getChannel RandomAccessFile} classes of the {@link -java.io java.io} package. Invoking this method upon an instance of one of -these classes will return a file channel connected to the underlying file. - - - - -

    - - - - - - - - - - - - - - - - - - - -

    Multiplexed, non-blocking I/O

    Description

    {@link java.nio.channels.SelectableChannel}A channel that can be multiplexed
      {@link java.nio.channels.DatagramChannel}A channel for a {@link java.net.DatagramSocket java.net.DatagramSocket}
      {@link java.nio.channels.Pipe.SinkChannel}The write end of a pipe
      {@link java.nio.channels.Pipe.SourceChannel}The read end of a pipe
      {@link java.nio.channels.ServerSocketChannel}  A channel for a {@link java.net.ServerSocket java.net.ServerSocket}
      {@link java.nio.channels.SocketChannel}A channel for a {@link java.net.Socket java.net.Socket}
    {@link java.nio.channels.Selector}A multiplexor of selectable channels
    {@link java.nio.channels.SelectionKey}A token representing the registration
    of a channel - with a selector
    {@link java.nio.channels.Pipe}Two channels that form a unidirectional pipe
    - -

    Multiplexed, non-blocking I/O, which is much more scalable than -thread-oriented, blocking I/O, is provided by selectors, selectable -channels, and selection keys. - -

    A selector is a multiplexor of selectable channels, which in turn are -a special type of channel that can be put into non-blocking mode. To perform -multiplexed I/O operations, one or more selectable channels are first created, -put into non-blocking mode, and {@link -java.nio.channels.SelectableChannel#register registered} -with a selector. Registering a channel specifies the set of I/O operations -that will be tested for readiness by the selector, and returns a selection key that represents the -registration. - -

    Once some channels have been registered with a selector, a selection operation can be performed in -order to discover which channels, if any, have become ready to perform one or -more of the operations in which interest was previously declared. If a channel -is ready then the key returned when it was registered will be added to the -selector's selected-key set. The key set, and the keys within it, can -be examined in order to determine the operations for which each channel is -ready. From each key one can retrieve the corresponding channel in order to -perform whatever I/O operations are required. - -

    That a selection key indicates that its channel is ready for some operation -is a hint, but not a guarantee, that such an operation can be performed by a -thread without causing the thread to block. It is imperative that code that -performs multiplexed I/O be written so as to ignore these hints when they prove -to be incorrect. - -

    This package defines selectable-channel classes corresponding to the {@link -java.net.DatagramSocket}, {@link java.net.ServerSocket}, and {@link -java.net.Socket} classes defined in the {@link java.net} package. -Minor changes to these classes have been made in order to support sockets that -are associated with channels. This package also defines a simple class that -implements unidirectional pipes. In all cases, a new selectable channel is -created by invoking the static open method of the corresponding class. -If a channel needs an associated socket then a socket will be created as a side -effect of this operation. - -

    The implementation of selectors, selectable channels, and selection keys -can be replaced by "plugging in" an alternative definition or instance of the -{@link java.nio.channels.spi.SelectorProvider} class defined in the {@link -java.nio.channels.spi} package. It is not expected that many developers -will actually make use of this facility; it is provided primarily so that -sophisticated users can take advantage of operating-system-specific -I/O-multiplexing mechanisms when very high performance is required. - -

    Much of the bookkeeping and synchronization required to implement the -multiplexed-I/O abstractions is performed by the {@link -java.nio.channels.spi.AbstractInterruptibleChannel}, {@link -java.nio.channels.spi.AbstractSelectableChannel}, {@link -java.nio.channels.spi.AbstractSelectionKey}, and {@link -java.nio.channels.spi.AbstractSelector} classes in the {@link -java.nio.channels.spi} package. When defining a custom selector provider, -only the {@link java.nio.channels.spi.AbstractSelector} and {@link -java.nio.channels.spi.AbstractSelectionKey} classes should be subclassed -directly; custom channel classes should extend the appropriate {@link -java.nio.channels.SelectableChannel} subclasses defined in this package. - -

    Unless otherwise noted, passing a null argument to a constructor -or method in any class or interface in this package will cause a {@link -java.lang.NullPointerException NullPointerException} to be thrown. - - -@since 1.4 -@author Mark Reinhold -@author JSR-51 Expert Group - - - diff --git a/jdk/src/share/classes/java/nio/channels/spi/AbstractSelector.java b/jdk/src/share/classes/java/nio/channels/spi/AbstractSelector.java index 019dd6ef49d..060d2d3c50e 100644 --- a/jdk/src/share/classes/java/nio/channels/spi/AbstractSelector.java +++ b/jdk/src/share/classes/java/nio/channels/spi/AbstractSelector.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/java/nio/channels/spi/SelectorProvider.java b/jdk/src/share/classes/java/nio/channels/spi/SelectorProvider.java index 9a8a3cc707c..dc61c9c270a 100644 --- a/jdk/src/share/classes/java/nio/channels/spi/SelectorProvider.java +++ b/jdk/src/share/classes/java/nio/channels/spi/SelectorProvider.java @@ -25,10 +25,8 @@ package java.nio.channels.spi; -import java.io.FileDescriptor; import java.io.IOException; -import java.net.ServerSocket; -import java.net.Socket; +import java.net.ProtocolFamily; import java.nio.channels.*; import java.security.AccessController; import java.security.PrivilegedAction; @@ -190,7 +188,25 @@ public abstract class SelectorProvider { throws IOException; /** - * Opens a pipe.

    + * Opens a datagram channel. + * + * @param family + * The protocol family + * + * @return A new datagram channel + * + * @throws UnsupportedOperationException + * If the specified protocol family is not supported + * @throws IOException + * If an I/O error occurs + * + * @since 1.7 + */ + public abstract DatagramChannel openDatagramChannel(ProtocolFamily family) + throws IOException; + + /** + * Opens a pipe.

    * * @return The new pipe */ diff --git a/jdk/src/share/classes/java/nio/charset/Charset-X-Coder.java b/jdk/src/share/classes/java/nio/charset/Charset-X-Coder.java index 1593be1da3d..6b4967ca082 100644 --- a/jdk/src/share/classes/java/nio/charset/Charset-X-Coder.java +++ b/jdk/src/share/classes/java/nio/charset/Charset-X-Coder.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/java/nio/charset/Charset.java b/jdk/src/share/classes/java/nio/charset/Charset.java index 4908c77d1db..804d0091c48 100644 --- a/jdk/src/share/classes/java/nio/charset/Charset.java +++ b/jdk/src/share/classes/java/nio/charset/Charset.java @@ -85,6 +85,9 @@ import sun.security.action.GetPropertyAction; *
  • The dash character '-' * ('\u002d'HYPHEN-MINUS), * + *
  • The plus character '+' + * ('\u002b'PLUS SIGN), + * *
  • The period character '.' * ('\u002e'FULL STOP), * @@ -307,6 +310,7 @@ public abstract class Charset if (c >= 'a' && c <= 'z') continue; if (c >= '0' && c <= '9') continue; if (c == '-' && i != 0) continue; + if (c == '+' && i != 0) continue; if (c == ':' && i != 0) continue; if (c == '_' && i != 0) continue; if (c == '.' && i != 0) continue; diff --git a/jdk/src/share/classes/java/nio/charset/CoderResult.java b/jdk/src/share/classes/java/nio/charset/CoderResult.java index 8f3c0befacc..123214941ce 100644 --- a/jdk/src/share/classes/java/nio/charset/CoderResult.java +++ b/jdk/src/share/classes/java/nio/charset/CoderResult.java @@ -1,5 +1,5 @@ /* - * Copyright 2001-2002 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/java/security/cert/CertPathValidatorException.java b/jdk/src/share/classes/java/security/cert/CertPathValidatorException.java index 5fd70c24a87..8a04aeff5f3 100644 --- a/jdk/src/share/classes/java/security/cert/CertPathValidatorException.java +++ b/jdk/src/share/classes/java/security/cert/CertPathValidatorException.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,9 @@ package java.security.cert; +import java.io.InvalidObjectException; +import java.io.IOException; +import java.io.ObjectInputStream; import java.security.GeneralSecurityException; /** @@ -36,10 +39,11 @@ import java.security.GeneralSecurityException; * if any, that caused this exception to be thrown. *

    * A CertPathValidatorException may also include the - * certification path that was being validated when the exception was thrown - * and the index of the certificate in the certification path that caused the - * exception to be thrown. Use the {@link #getCertPath getCertPath} and - * {@link #getIndex getIndex} methods to retrieve this information. + * certification path that was being validated when the exception was thrown, + * the index of the certificate in the certification path that caused the + * exception to be thrown, and the reason that caused the failure. Use the + * {@link #getCertPath getCertPath}, {@link #getIndex getIndex}, and + * {@link #getReason getReason} methods to retrieve this information. * *

    * Concurrent Access @@ -71,12 +75,17 @@ public class CertPathValidatorException extends GeneralSecurityException { */ private CertPath certPath; + /** + * @serial the reason the validation failed + */ + private Reason reason = BasicReason.UNSPECIFIED; + /** * Creates a CertPathValidatorException with * no detail message. */ public CertPathValidatorException() { - super(); + this(null, null); } /** @@ -87,7 +96,7 @@ public class CertPathValidatorException extends GeneralSecurityException { * @param msg the detail message */ public CertPathValidatorException(String msg) { - super(msg); + this(msg, null); } /** @@ -104,7 +113,7 @@ public class CertPathValidatorException extends GeneralSecurityException { * permitted, and indicates that the cause is nonexistent or unknown.) */ public CertPathValidatorException(Throwable cause) { - super(cause); + this(null, cause); } /** @@ -117,7 +126,7 @@ public class CertPathValidatorException extends GeneralSecurityException { * permitted, and indicates that the cause is nonexistent or unknown.) */ public CertPathValidatorException(String msg, Throwable cause) { - super(msg, cause); + this(msg, cause, null, -1); } /** @@ -139,6 +148,32 @@ public class CertPathValidatorException extends GeneralSecurityException { */ public CertPathValidatorException(String msg, Throwable cause, CertPath certPath, int index) { + this(msg, cause, certPath, index, BasicReason.UNSPECIFIED); + } + + /** + * Creates a CertPathValidatorException with the specified + * detail message, cause, certification path, index, and reason. + * + * @param msg the detail message (or null if none) + * @param cause the cause (or null if none) + * @param certPath the certification path that was in the process of + * being validated when the error was encountered + * @param index the index of the certificate in the certification path + * that caused the error (or -1 if not applicable). Note that + * the list of certificates in a CertPath is zero based. + * @param reason the reason the validation failed + * @throws IndexOutOfBoundsException if the index is out of range + * (index < -1 || (certPath != null && index >= + * certPath.getCertificates().size()) + * @throws IllegalArgumentException if certPath is + * null and index is not -1 + * @throws NullPointerException if reason is null + * + * @since 1.7 + */ + public CertPathValidatorException(String msg, Throwable cause, + CertPath certPath, int index, Reason reason) { super(msg, cause); if (certPath == null && index != -1) { throw new IllegalArgumentException(); @@ -147,8 +182,12 @@ public class CertPathValidatorException extends GeneralSecurityException { (certPath != null && index >= certPath.getCertificates().size())) { throw new IndexOutOfBoundsException(); } + if (reason == null) { + throw new NullPointerException("reason can't be null"); + } this.certPath = certPath; this.index = index; + this.reason = reason; } /** @@ -174,4 +213,79 @@ public class CertPathValidatorException extends GeneralSecurityException { return this.index; } + /** + * Returns the reason that the validation failed. The reason is + * associated with the index of the certificate returned by + * {@link getIndex}. + * + * @return the reason that the validation failed, or + * BasicReason.UNSPECIFIED if a reason has not been + * specified + * + * @since 1.7 + */ + public Reason getReason() { + return this.reason; + } + + private void readObject(ObjectInputStream stream) + throws ClassNotFoundException, IOException { + stream.defaultReadObject(); + if (reason == null) { + reason = BasicReason.UNSPECIFIED; + } + if (certPath == null && index != -1) { + throw new InvalidObjectException("certpath is null and index != -1"); + } + if (index < -1 || + (certPath != null && index >= certPath.getCertificates().size())) { + throw new InvalidObjectException("index out of range"); + } + } + + /** + * The reason the validation algorithm failed. + * + * @since 1.7 + */ + public static interface Reason extends java.io.Serializable { } + + + /** + * The BasicReason enumerates the potential reasons that a certification + * path of any type may be invalid. + * + * @since 1.7 + */ + public static enum BasicReason implements Reason { + /** + * Unspecified reason. + */ + UNSPECIFIED, + + /** + * The certificate is expired. + */ + EXPIRED, + + /** + * The certificate is not yet valid. + */ + NOT_YET_VALID, + + /** + * The certificate is revoked. + */ + REVOKED, + + /** + * The revocation status of the certificate could not be determined. + */ + UNDETERMINED_REVOCATION_STATUS, + + /** + * The signature is invalid. + */ + INVALID_SIGNATURE + } } diff --git a/jdk/src/share/classes/java/security/cert/PKIXReason.java b/jdk/src/share/classes/java/security/cert/PKIXReason.java new file mode 100644 index 00000000000..ed798d334f2 --- /dev/null +++ b/jdk/src/share/classes/java/security/cert/PKIXReason.java @@ -0,0 +1,77 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.security.cert; + +/** + * The PKIXReason enumerates the potential PKIX-specific reasons + * that an X.509 certification path may be invalid according to the PKIX + * (RFC 3280) standard. These reasons are in addition to those of the + * CertPathValidatorException.BasicReason enumeration. + * + * @since 1.7 + */ +public enum PKIXReason implements CertPathValidatorException.Reason { + /** + * The certificate does not chain correctly. + */ + NAME_CHAINING, + + /** + * The certificate's key usage is invalid. + */ + INVALID_KEY_USAGE, + + /** + * The policy constraints have been violated. + */ + INVALID_POLICY, + + /** + * No acceptable trust anchor found. + */ + NO_TRUST_ANCHOR, + + /** + * The certificate contains one or more unrecognized critical + * extensions. + */ + UNRECOGNIZED_CRIT_EXT, + + /** + * The certificate is not a CA certificate. + */ + NOT_CA_CERT, + + /** + * The path length constraint has been violated. + */ + PATH_TOO_LONG, + + /** + * The name constraints have been violated. + */ + INVALID_NAME +} diff --git a/jdk/src/share/classes/java/text/SimpleDateFormat.java b/jdk/src/share/classes/java/text/SimpleDateFormat.java index 548ffb730f3..e543899fe95 100644 --- a/jdk/src/share/classes/java/text/SimpleDateFormat.java +++ b/jdk/src/share/classes/java/text/SimpleDateFormat.java @@ -373,6 +373,24 @@ public class SimpleDateFormat extends DateFormat { */ private String pattern; + /** + * Saved numberFormat and pattern. + * @see SimpleDateFormat#checkNegativeNumberExpression + */ + transient private NumberFormat originalNumberFormat; + transient private String originalNumberPattern; + + /** + * The minus sign to be used with format and parse. + */ + transient private char minusSign = '-'; + + /** + * True when a negative sign follows a number. + * (True as default in Arabic.) + */ + transient private boolean hasFollowingMinusSign = false; + /** * The compiled pattern. */ @@ -1226,6 +1244,8 @@ public class SimpleDateFormat extends DateFormat { */ public Date parse(String text, ParsePosition pos) { + checkNegativeNumberExpression(); + int start = pos.index; int oldStart = start; int textLength = text.length(); @@ -1271,14 +1291,42 @@ public class SimpleDateFormat extends DateFormat { // digit text (e.g., "20010704") with a pattern which // has no delimiters between fields, like "yyyyMMdd". boolean obeyCount = false; + + // In Arabic, a minus sign for a negative number is put after + // the number. Even in another locale, a minus sign can be + // put after a number using DateFormat.setNumberFormat(). + // If both the minus sign and the field-delimiter are '-', + // subParse() needs to determine whether a '-' after a number + // in the given text is a delimiter or is a minus sign for the + // preceding number. We give subParse() a clue based on the + // information in compiledPattern. + boolean useFollowingMinusSignAsDelimiter = false; + if (i < compiledPattern.length) { int nextTag = compiledPattern[i] >>> 8; - if (!(nextTag == TAG_QUOTE_ASCII_CHAR || nextTag == TAG_QUOTE_CHARS)) { + if (!(nextTag == TAG_QUOTE_ASCII_CHAR || + nextTag == TAG_QUOTE_CHARS)) { obeyCount = true; } + + if (hasFollowingMinusSign && + (nextTag == TAG_QUOTE_ASCII_CHAR || + nextTag == TAG_QUOTE_CHARS)) { + int c; + if (nextTag == TAG_QUOTE_ASCII_CHAR) { + c = compiledPattern[i] & 0xff; + } else { + c = compiledPattern[i+1]; + } + + if (c == minusSign) { + useFollowingMinusSignAsDelimiter = true; + } + } } start = subParse(text, start, tag, count, obeyCount, - ambiguousYear, pos); + ambiguousYear, pos, + useFollowingMinusSignAsDelimiter); if (start < 0) { pos.index = oldStart; return null; @@ -1482,10 +1530,13 @@ public class SimpleDateFormat extends DateFormat { // If the time zone matched uses the same name // (abbreviation) for both standard and daylight time, // let the time zone in the Calendar decide which one. - if (!useSameName) { + // + // Also if tz.getDSTSaving() returns 0 for DST, use tz to + // determine the local time. (6645292) + int dstAmount = (nameIndex >= 3) ? tz.getDSTSavings() : 0; + if (!(useSameName || (nameIndex >= 3 && dstAmount == 0))) { calendar.set(Calendar.ZONE_OFFSET, tz.getRawOffset()); - calendar.set(Calendar.DST_OFFSET, - nameIndex >= 3 ? tz.getDSTSavings() : 0); + calendar.set(Calendar.DST_OFFSET, dstAmount); } return (start + zoneNames[nameIndex].length()); } @@ -1511,8 +1562,8 @@ public class SimpleDateFormat extends DateFormat { */ private int subParse(String text, int start, int patternCharIndex, int count, boolean obeyCount, boolean[] ambiguousYear, - ParsePosition origPos) - { + ParsePosition origPos, + boolean useFollowingMinusSignAsDelimiter) { Number number = null; int value = 0; ParsePosition pos = new ParsePosition(0); @@ -1537,10 +1588,10 @@ public class SimpleDateFormat extends DateFormat { // a number value. We handle further, more generic cases below. We need // to handle some of them here because some fields require extra processing on // the parsed value. - if (patternCharIndex == 4 /*HOUR_OF_DAY1_FIELD*/ || - patternCharIndex == 15 /*HOUR1_FIELD*/ || - (patternCharIndex == 2 /*MONTH_FIELD*/ && count <= 2) || - patternCharIndex == 1) { + if (patternCharIndex == 4 /* HOUR_OF_DAY1_FIELD */ || + patternCharIndex == 15 /* HOUR1_FIELD */ || + (patternCharIndex == 2 /* MONTH_FIELD */ && count <= 2) || + patternCharIndex == 1 /* YEAR_FIELD */) { // It would be good to unify this with the obeyCount logic below, // but that's going to be difficult. if (obeyCount) { @@ -1557,6 +1608,15 @@ public class SimpleDateFormat extends DateFormat { } } else { value = number.intValue(); + + if (useFollowingMinusSignAsDelimiter && (value < 0) && + (((pos.index < text.length()) && + (text.charAt(pos.index) != minusSign)) || + ((pos.index == text.length()) && + (text.charAt(pos.index-1) == minusSign)))) { + value = -value; + pos.index--; + } } } @@ -1888,7 +1948,18 @@ public class SimpleDateFormat extends DateFormat { number = numberFormat.parse(text, pos); } if (number != null) { - calendar.set(field, number.intValue()); + value = number.intValue(); + + if (useFollowingMinusSignAsDelimiter && (value < 0) && + (((pos.index < text.length()) && + (text.charAt(pos.index) != minusSign)) || + ((pos.index == text.length()) && + (text.charAt(pos.index-1) == minusSign)))) { + value = -value; + pos.index--; + } + + calendar.set(field, value); return pos.index; } break parsing; @@ -2099,4 +2170,33 @@ public class SimpleDateFormat extends DateFormat { } } } + + /** + * Analyze the negative subpattern of DecimalFormat and set/update values + * as necessary. + */ + private void checkNegativeNumberExpression() { + if ((numberFormat instanceof DecimalFormat) && + !numberFormat.equals(originalNumberFormat)) { + String numberPattern = ((DecimalFormat)numberFormat).toPattern(); + if (!numberPattern.equals(originalNumberPattern)) { + hasFollowingMinusSign = false; + + int separatorIndex = numberPattern.indexOf(';'); + // If the negative subpattern is not absent, we have to analayze + // it in order to check if it has a following minus sign. + if (separatorIndex > -1) { + int minusIndex = numberPattern.indexOf('-', separatorIndex); + if ((minusIndex > numberPattern.lastIndexOf('0')) && + (minusIndex > numberPattern.lastIndexOf('#'))) { + hasFollowingMinusSign = true; + minusSign = ((DecimalFormat)numberFormat).getDecimalFormatSymbols().getMinusSign(); + } + } + originalNumberPattern = numberPattern; + } + originalNumberFormat = numberFormat; + } + } + } diff --git a/jdk/src/share/classes/java/util/ConcurrentModificationException.java b/jdk/src/share/classes/java/util/ConcurrentModificationException.java index 19a30286538..fbe9282dc59 100644 --- a/jdk/src/share/classes/java/util/ConcurrentModificationException.java +++ b/jdk/src/share/classes/java/util/ConcurrentModificationException.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,6 +67,8 @@ package java.util; * @since 1.2 */ public class ConcurrentModificationException extends RuntimeException { + private static final long serialVersionUID = -3666751008965953603L; + /** * Constructs a ConcurrentModificationException with no * detail message. diff --git a/jdk/src/share/classes/java/util/CurrencyData.properties b/jdk/src/share/classes/java/util/CurrencyData.properties index 7b2bd36ba19..15c45302e96 100644 --- a/jdk/src/share/classes/java/util/CurrencyData.properties +++ b/jdk/src/share/classes/java/util/CurrencyData.properties @@ -1,5 +1,5 @@ # -# Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/java/util/EmptyStackException.java b/jdk/src/share/classes/java/util/EmptyStackException.java index 0bdaa2ee2e5..09ba39b0ec5 100644 --- a/jdk/src/share/classes/java/util/EmptyStackException.java +++ b/jdk/src/share/classes/java/util/EmptyStackException.java @@ -1,5 +1,5 @@ /* - * Copyright 1994-1998 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ package java.util; */ public class EmptyStackException extends RuntimeException { + private static final long serialVersionUID = 5084686378493302095L; + /** * Constructs a new EmptyStackException with null * as its error message string. diff --git a/jdk/src/share/classes/java/util/EnumSet.java b/jdk/src/share/classes/java/util/EnumSet.java index d5c8d23dfa3..c6c013d5202 100644 --- a/jdk/src/share/classes/java/util/EnumSet.java +++ b/jdk/src/share/classes/java/util/EnumSet.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -432,4 +432,11 @@ public abstract class EnumSet> extends AbstractSet Object writeReplace() { return new SerializationProxy(this); } + + // readObject method for the serialization proxy pattern + // See Effective Java, Second Ed., Item 78. + private void readObject(java.io.ObjectInputStream stream) + throws java.io.InvalidObjectException { + throw new java.io.InvalidObjectException("Proxy required"); + } } diff --git a/jdk/src/share/classes/java/util/InputMismatchException.java b/jdk/src/share/classes/java/util/InputMismatchException.java index 87b0c60bfe1..ff1729c2133 100644 --- a/jdk/src/share/classes/java/util/InputMismatchException.java +++ b/jdk/src/share/classes/java/util/InputMismatchException.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,8 @@ package java.util; */ public class InputMismatchException extends NoSuchElementException { + private static final long serialVersionUID = 8811230760997066428L; + /** * Constructs an InputMismatchException with null * as its error message string. diff --git a/jdk/src/share/classes/java/util/NoSuchElementException.java b/jdk/src/share/classes/java/util/NoSuchElementException.java index 9750122cb4a..e4cbe8eef80 100644 --- a/jdk/src/share/classes/java/util/NoSuchElementException.java +++ b/jdk/src/share/classes/java/util/NoSuchElementException.java @@ -1,5 +1,5 @@ /* - * Copyright 1994-1998 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,8 @@ package java.util; */ public class NoSuchElementException extends RuntimeException { + private static final long serialVersionUID = 6769829250639411880L; + /** * Constructs a NoSuchElementException with null * as its error message string. diff --git a/jdk/src/share/classes/java/util/Timer.java b/jdk/src/share/classes/java/util/Timer.java index 22442097271..2387c478e50 100644 --- a/jdk/src/share/classes/java/util/Timer.java +++ b/jdk/src/share/classes/java/util/Timer.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ package java.util; import java.util.Date; +import java.util.concurrent.atomic.AtomicInteger; /** * A facility for threads to schedule tasks for future execution in a @@ -92,12 +93,12 @@ public class Timer { * and the timer thread consumes, executing timer tasks as appropriate, * and removing them from the queue when they're obsolete. */ - private TaskQueue queue = new TaskQueue(); + private final TaskQueue queue = new TaskQueue(); /** * The timer thread. */ - private TimerThread thread = new TimerThread(queue); + private final TimerThread thread = new TimerThread(queue); /** * This object causes the timer's task execution thread to exit @@ -106,7 +107,7 @@ public class Timer { * Timer as such a finalizer would be susceptible to a subclass's * finalizer forgetting to call it. */ - private Object threadReaper = new Object() { + private final Object threadReaper = new Object() { protected void finalize() throws Throwable { synchronized(queue) { thread.newTasksMayBeScheduled = false; @@ -116,12 +117,11 @@ public class Timer { }; /** - * This ID is used to generate thread names. (It could be replaced - * by an AtomicInteger as soon as they become available.) + * This ID is used to generate thread names. */ - private static int nextSerialNumber = 0; - private static synchronized int serialNumber() { - return nextSerialNumber++; + private final static AtomicInteger nextSerialNumber = new AtomicInteger(0); + private static int serialNumber() { + return nextSerialNumber.getAndIncrement(); } /** @@ -387,6 +387,11 @@ public class Timer { if (time < 0) throw new IllegalArgumentException("Illegal execution time."); + // Constrain value of period sufficiently to prevent numeric + // overflow while still being effectively infinitely large. + if (Math.abs(period) > (Long.MAX_VALUE >> 1)) + period >>= 1; + synchronized(queue) { if (!thread.newTasksMayBeScheduled) throw new IllegalStateException("Timer already cancelled."); diff --git a/jdk/src/share/classes/java/util/TooManyListenersException.java b/jdk/src/share/classes/java/util/TooManyListenersException.java index f7778a5edd1..c9feb957180 100644 --- a/jdk/src/share/classes/java/util/TooManyListenersException.java +++ b/jdk/src/share/classes/java/util/TooManyListenersException.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-1999 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,6 +48,7 @@ package java.util; */ public class TooManyListenersException extends Exception { + private static final long serialVersionUID = 5074640544770687831L; /** * Constructs a TooManyListenersException with no detail message. diff --git a/jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java b/jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java index dc7fe113f2a..67a8b32205e 100644 --- a/jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java +++ b/jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java @@ -223,8 +223,7 @@ public class ScheduledThreadPoolExecutor } public long getDelay(TimeUnit unit) { - long d = unit.convert(time - now(), TimeUnit.NANOSECONDS); - return d; + return unit.convert(time - now(), TimeUnit.NANOSECONDS); } public int compareTo(Delayed other) { @@ -264,7 +263,7 @@ public class ScheduledThreadPoolExecutor if (p > 0) time += p; else - time = now() - p; + time = triggerTime(-p); } public boolean cancel(boolean mayInterruptIfRunning) { @@ -472,6 +471,38 @@ public class ScheduledThreadPoolExecutor new DelayedWorkQueue(), threadFactory, handler); } + /** + * Returns the trigger time of a delayed action. + */ + private long triggerTime(long delay, TimeUnit unit) { + return triggerTime(unit.toNanos((delay < 0) ? 0 : delay)); + } + + /** + * Returns the trigger time of a delayed action. + */ + long triggerTime(long delay) { + return now() + + ((delay < (Long.MAX_VALUE >> 1)) ? delay : overflowFree(delay)); + } + + /** + * Constrains the values of all delays in the queue to be within + * Long.MAX_VALUE of each other, to avoid overflow in compareTo. + * This may occur if a task is eligible to be dequeued, but has + * not yet been, while some other task is added with a delay of + * Long.MAX_VALUE. + */ + private long overflowFree(long delay) { + Delayed head = (Delayed) super.getQueue().peek(); + if (head != null) { + long headDelay = head.getDelay(TimeUnit.NANOSECONDS); + if (headDelay < 0 && (delay - headDelay < 0)) + delay = Long.MAX_VALUE + headDelay; + } + return delay; + } + /** * @throws RejectedExecutionException {@inheritDoc} * @throws NullPointerException {@inheritDoc} @@ -481,10 +512,9 @@ public class ScheduledThreadPoolExecutor TimeUnit unit) { if (command == null || unit == null) throw new NullPointerException(); - if (delay < 0) delay = 0; - long triggerTime = now() + unit.toNanos(delay); RunnableScheduledFuture t = decorateTask(command, - new ScheduledFutureTask(command, null, triggerTime)); + new ScheduledFutureTask(command, null, + triggerTime(delay, unit))); delayedExecute(t); return t; } @@ -498,10 +528,9 @@ public class ScheduledThreadPoolExecutor TimeUnit unit) { if (callable == null || unit == null) throw new NullPointerException(); - if (delay < 0) delay = 0; - long triggerTime = now() + unit.toNanos(delay); RunnableScheduledFuture t = decorateTask(callable, - new ScheduledFutureTask(callable, triggerTime)); + new ScheduledFutureTask(callable, + triggerTime(delay, unit))); delayedExecute(t); return t; } @@ -519,12 +548,10 @@ public class ScheduledThreadPoolExecutor throw new NullPointerException(); if (period <= 0) throw new IllegalArgumentException(); - if (initialDelay < 0) initialDelay = 0; - long triggerTime = now() + unit.toNanos(initialDelay); ScheduledFutureTask sft = new ScheduledFutureTask(command, null, - triggerTime, + triggerTime(initialDelay, unit), unit.toNanos(period)); RunnableScheduledFuture t = decorateTask(command, sft); sft.outerTask = t; @@ -545,12 +572,10 @@ public class ScheduledThreadPoolExecutor throw new NullPointerException(); if (delay <= 0) throw new IllegalArgumentException(); - if (initialDelay < 0) initialDelay = 0; - long triggerTime = now() + unit.toNanos(initialDelay); ScheduledFutureTask sft = new ScheduledFutureTask(command, null, - triggerTime, + triggerTime(initialDelay, unit), unit.toNanos(-delay)); RunnableScheduledFuture t = decorateTask(command, sft); sft.outerTask = t; diff --git a/jdk/src/share/classes/java/util/jar/JarException.java b/jdk/src/share/classes/java/util/jar/JarException.java index a8c66b692f1..a28bbcc5b74 100644 --- a/jdk/src/share/classes/java/util/jar/JarException.java +++ b/jdk/src/share/classes/java/util/jar/JarException.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-1999 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,8 @@ package java.util.jar; */ public class JarException extends java.util.zip.ZipException { + private static final long serialVersionUID = 7159778400963954473L; + /** * Constructs a JarException with no detail message. */ diff --git a/jdk/src/share/classes/java/util/logging/Logging.java b/jdk/src/share/classes/java/util/logging/Logging.java index 72468699ead..d99782407a5 100644 --- a/jdk/src/share/classes/java/util/logging/Logging.java +++ b/jdk/src/share/classes/java/util/logging/Logging.java @@ -118,6 +118,6 @@ class Logging implements LoggingMXBean { } public ObjectName getObjectName() { - return com.sun.jmx.mbeanserver.Util.newObjectName(LogManager.LOGGING_MXBEAN_NAME); + return ObjectName.valueOf(LogManager.LOGGING_MXBEAN_NAME); } } diff --git a/jdk/src/share/classes/java/util/regex/PatternSyntaxException.java b/jdk/src/share/classes/java/util/regex/PatternSyntaxException.java index 093b6a39816..404756ed6d5 100644 --- a/jdk/src/share/classes/java/util/regex/PatternSyntaxException.java +++ b/jdk/src/share/classes/java/util/regex/PatternSyntaxException.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,7 @@ import sun.security.action.GetPropertyAction; public class PatternSyntaxException extends IllegalArgumentException { + private static final long serialVersionUID = -3864639126226059218L; private final String desc; private final String pattern; diff --git a/jdk/src/share/classes/java/util/zip/DataFormatException.java b/jdk/src/share/classes/java/util/zip/DataFormatException.java index db884f21e00..08730b87581 100644 --- a/jdk/src/share/classes/java/util/zip/DataFormatException.java +++ b/jdk/src/share/classes/java/util/zip/DataFormatException.java @@ -1,5 +1,5 @@ /* - * Copyright 1996 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,8 @@ package java.util.zip; */ public class DataFormatException extends Exception { + private static final long serialVersionUID = 2219632870893641452L; + /** * Constructs a DataFormatException with no detail message. */ diff --git a/jdk/src/share/classes/java/util/zip/Inflater.java b/jdk/src/share/classes/java/util/zip/Inflater.java index bc0bdf55f3e..68c8d623397 100644 --- a/jdk/src/share/classes/java/util/zip/Inflater.java +++ b/jdk/src/share/classes/java/util/zip/Inflater.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -73,11 +73,13 @@ package java.util.zip; public class Inflater { private long strm; - private byte[] buf = new byte[0]; + private byte[] buf = defaultBuf; private int off, len; private boolean finished; private boolean needDict; + private static final byte[] defaultBuf = new byte[0]; + static { /* Zip library is loaded from System.initializeSystemClass */ initIDs(); @@ -318,6 +320,7 @@ class Inflater { public synchronized void reset() { ensureOpen(); reset(strm); + buf = defaultBuf; finished = false; needDict = false; off = len = 0; diff --git a/jdk/src/share/classes/java/util/zip/ZipException.java b/jdk/src/share/classes/java/util/zip/ZipException.java index 467a51c9baf..a5dbc12a153 100644 --- a/jdk/src/share/classes/java/util/zip/ZipException.java +++ b/jdk/src/share/classes/java/util/zip/ZipException.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-2001 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,8 @@ import java.io.IOException; public class ZipException extends IOException { + private static final long serialVersionUID = 8000196834066748623L; + /** * Constructs an ZipException with null * as its error detail message. diff --git a/jdk/src/share/classes/java/util/zip/ZipFile.java b/jdk/src/share/classes/java/util/zip/ZipFile.java index 8ad177fdc92..37e92ddecb7 100644 --- a/jdk/src/share/classes/java/util/zip/ZipFile.java +++ b/jdk/src/share/classes/java/util/zip/ZipFile.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -278,7 +278,6 @@ class ZipFile implements ZipConstants { int size = inflaters.size(); if (size > 0) { Inflater inf = (Inflater)inflaters.remove(size - 1); - inf.reset(); return inf; } else { return new Inflater(true); @@ -291,6 +290,7 @@ class ZipFile implements ZipConstants { */ private void releaseInflater(Inflater inf) { synchronized (inflaters) { + inf.reset(); inflaters.add(inf); } } diff --git a/jdk/src/share/classes/java/util/zip/ZipOutputStream.java b/jdk/src/share/classes/java/util/zip/ZipOutputStream.java index 65394268297..797a37392fe 100644 --- a/jdk/src/share/classes/java/util/zip/ZipOutputStream.java +++ b/jdk/src/share/classes/java/util/zip/ZipOutputStream.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -317,9 +317,6 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants { if (current != null) { closeEntry(); } - if (xentries.size() < 1) { - throw new ZipException("ZIP file must have at least one entry"); - } // write central directory long off = written; for (XEntry xentry : xentries) diff --git a/jdk/src/share/classes/javax/management/Description.java b/jdk/src/share/classes/javax/management/Description.java index a0bf96d9b1d..3232054a8c9 100644 --- a/jdk/src/share/classes/javax/management/Description.java +++ b/jdk/src/share/classes/javax/management/Description.java @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/javax/management/Descriptor.java b/jdk/src/share/classes/javax/management/Descriptor.java index 9aa992486a0..70c17f2eedb 100644 --- a/jdk/src/share/classes/javax/management/Descriptor.java +++ b/jdk/src/share/classes/javax/management/Descriptor.java @@ -1,5 +1,5 @@ /* - * Portions Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Portions Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/javax/management/DescriptorFields.java b/jdk/src/share/classes/javax/management/DescriptorFields.java index 95a4b3a6df1..12642532600 100644 --- a/jdk/src/share/classes/javax/management/DescriptorFields.java +++ b/jdk/src/share/classes/javax/management/DescriptorFields.java @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/javax/management/DescriptorKey.java b/jdk/src/share/classes/javax/management/DescriptorKey.java index 9f919490512..7646862ce6a 100644 --- a/jdk/src/share/classes/javax/management/DescriptorKey.java +++ b/jdk/src/share/classes/javax/management/DescriptorKey.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/javax/management/DynamicWrapperMBean.java b/jdk/src/share/classes/javax/management/DynamicWrapperMBean.java index 4a67a96795a..45d2f17cf96 100644 --- a/jdk/src/share/classes/javax/management/DynamicWrapperMBean.java +++ b/jdk/src/share/classes/javax/management/DynamicWrapperMBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/javax/management/ImmutableDescriptor.java b/jdk/src/share/classes/javax/management/ImmutableDescriptor.java index cdfe459d0e7..6a3bdc576b9 100644 --- a/jdk/src/share/classes/javax/management/ImmutableDescriptor.java +++ b/jdk/src/share/classes/javax/management/ImmutableDescriptor.java @@ -128,13 +128,13 @@ public class ImmutableDescriptor implements Descriptor { * @throws InvalidObjectException if the read object has invalid fields. */ private Object readResolve() throws InvalidObjectException { - if (names.length == 0 && getClass() == ImmutableDescriptor.class) - return EMPTY_DESCRIPTOR; boolean bad = false; if (names == null || values == null || names.length != values.length) bad = true; if (!bad) { + if (names.length == 0 && getClass() == ImmutableDescriptor.class) + return EMPTY_DESCRIPTOR; final Comparator compare = String.CASE_INSENSITIVE_ORDER; String lastName = ""; // also catches illegal null name for (int i = 0; i < names.length; i++) { diff --git a/jdk/src/share/classes/javax/management/Impact.java b/jdk/src/share/classes/javax/management/Impact.java index 9416df6fac8..a922e20ae37 100644 --- a/jdk/src/share/classes/javax/management/Impact.java +++ b/jdk/src/share/classes/javax/management/Impact.java @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/javax/management/InstanceNotFoundException.java b/jdk/src/share/classes/javax/management/InstanceNotFoundException.java index f572d614d00..0b992d344f8 100644 --- a/jdk/src/share/classes/javax/management/InstanceNotFoundException.java +++ b/jdk/src/share/classes/javax/management/InstanceNotFoundException.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,4 +51,16 @@ public class InstanceNotFoundException extends OperationsException { public InstanceNotFoundException(String message) { super(message); } + + /** + * Constructor for the frequent case where the message is the ObjectName + * of the missing MBean. + * + * @param name the ObjectName of the missing MBean. + * + * @since 1.7 + */ + public InstanceNotFoundException(ObjectName name) { + this(String.valueOf(name)); + } } diff --git a/jdk/src/share/classes/javax/management/MBean.java b/jdk/src/share/classes/javax/management/MBean.java index 6837740334c..4b609c3da70 100644 --- a/jdk/src/share/classes/javax/management/MBean.java +++ b/jdk/src/share/classes/javax/management/MBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/javax/management/MBeanOperationInfo.java b/jdk/src/share/classes/javax/management/MBeanOperationInfo.java index 5863e96ef39..e3c26df5265 100644 --- a/jdk/src/share/classes/javax/management/MBeanOperationInfo.java +++ b/jdk/src/share/classes/javax/management/MBeanOperationInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/javax/management/MBeanPermission.java b/jdk/src/share/classes/javax/management/MBeanPermission.java index 762f5defc7c..fe328c2dae8 100644 --- a/jdk/src/share/classes/javax/management/MBeanPermission.java +++ b/jdk/src/share/classes/javax/management/MBeanPermission.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ package javax.management; +import com.sun.jmx.mbeanserver.Util; import java.io.IOException; import java.io.ObjectInputStream; import java.security.Permission; @@ -42,10 +43,10 @@ import java.security.Permission; * permission that you need. When a sensitive operation is * being checked for permission, an MBeanPermission is constructed * representing the permission you need. The operation is only - * allowed if the permissions you have {@link #implies imply} the + * allowed if the permissions you have {@linkplain #implies imply} the * permission you need.

    * - *

    An MBeanPermission contains four items of information:

    + *

    An MBeanPermission contains five items of information:

    * *
      * @@ -57,6 +58,23 @@ import java.security.Permission; * *

      The action is returned by {@link #getActions()}.

      * + *
    • The MBean Server name.

      + * + *

      For a permission you need, this is the {@linkplain + * javax.management.MBeanServerFactory#getMBeanServerName + * name of the MBeanServer} + * containing the MBean for which the MBean + * permission is checked.

      + * + *

      For a permission you have, this is either the {@linkplain + * javax.management.MBeanServerFactory#getMBeanServerName + * name of the MBeanServer} in which the MBean + * you have this permission for must be registered, + * or a pattern against which that MBean Server name will be matched.
      + * An {@code mbeanServerName} pattern can also be empty or the single + * character {@code "*"}, both of which will match any {@code MBeanServer} name. + *

      + * *
    • The class name.

      * *

      For a permission you need, this is the class name of an MBean @@ -88,7 +106,7 @@ import java.security.Permission; * or operation you can access, or it is empty or the single character * "*", both of which grant access to any member.

      * - *
    • The object name.

      + *
    • The object name.

      * *

      For a permission you need, this is the {@link ObjectName} of the * MBean you are accessing. For operations that do not reference a @@ -103,15 +121,15 @@ import java.security.Permission; *

    * *

    If you have an MBeanPermission, it allows operations only if all - * four of the items match.

    + * five of the items match.

    * - *

    The class name, member, and object name can be written together - * as a single string, which is the name of this permission. + *

    The MBean Server name, class name, member, and object name can be written + * together as a single string, which is the name of this permission. * The name of the permission is the string returned by {@link * Permission#getName() getName()}. The format of the string is:

    * *
    - * className#member[objectName] + * mbeanServerName::className#member[objectName] *
    * *

    The object name is written using the usual syntax for {@link @@ -119,15 +137,18 @@ import java.security.Permission; * ]. It is terminated by a ] character * that is the last character in the string.

    * - *

    One or more of the className, member, - * or objectName may be omitted. If the - * member is omitted, the # may be too (but + *

    One or more of the mbeanServerName, className, + * member, or objectName may be omitted. If the + * mbeanServerName is omitted, the :: may be too (but + * does not have to be). + * If the member is omitted, the # may be too (but * does not have to be). If the objectName is omitted, * the [] may be too (but does not have to be). It is - * not legal to omit all three items, that is to have a name + * not legal to omit all four items, that is to have a name * that is the empty string.

    * - *

    One or more of the className, member, + *

    One or more of the mbeanServerName, className, + * member, * or objectName may be the character "-", * which is equivalent to a null value. A null value is implied by * any value (including another null value) but does not imply any @@ -246,6 +267,13 @@ public class MBeanPermission extends Permission { */ private transient ObjectName objectName; + /** + * The name of the MBeanServer in which this permission is checked, or + * granted. If null, is implied by any MBean Server name + * but does not imply any non-null MBean Server name. + */ + private transient String mbeanServerName; + /** * Parse actions parameter. */ @@ -283,6 +311,13 @@ public class MBeanPermission extends Permission { throw new IllegalArgumentException("MBeanPermission name " + "cannot be empty"); + final int sepIndex = name.indexOf("::"); + if (sepIndex < 0) { + setMBeanServerName("*"); + } else { + setMBeanServerName(name.substring(0,sepIndex)); + } + /* The name looks like "class#member[objectname]". We subtract elements from the right as we parse, so after parsing the objectname we have "class#member" and after parsing the @@ -290,11 +325,14 @@ public class MBeanPermission extends Permission { // Parse ObjectName - int openingBracket = name.indexOf("["); + + final int start = (sepIndex<0)?0:sepIndex+2; + int openingBracket = name.indexOf("[",start); if (openingBracket == -1) { // If "[on]" missing then ObjectName("*:*") // objectName = ObjectName.WILDCARD; + name = name.substring(start); } else { if (!name.endsWith("]")) { throw new IllegalArgumentException("MBeanPermission: " + @@ -305,11 +343,11 @@ public class MBeanPermission extends Permission { } else { // Create ObjectName // + String on = name.substring(openingBracket + 1, + name.length() - 1); try { // If "[]" then ObjectName("*:*") // - String on = name.substring(openingBracket + 1, - name.length() - 1); if (on.equals("")) objectName = ObjectName.WILDCARD; else if (on.equals("-")) @@ -320,11 +358,11 @@ public class MBeanPermission extends Permission { throw new IllegalArgumentException("MBeanPermission: " + "The target name does " + "not specify a valid " + - "ObjectName"); + "ObjectName", e); } } - name = name.substring(0, openingBracket); + name = name.substring(start, openingBracket); } // Parse member @@ -348,8 +386,9 @@ public class MBeanPermission extends Permission { * Assign fields based on className, member, and objectName * parameters. */ - private void initName(String className, String member, - ObjectName objectName) { + private void initName(String mbeanServerName, String className, + String member, ObjectName objectName) { + setMBeanServerName(mbeanServerName); setClassName(className); setMember(member); this.objectName = objectName; @@ -381,19 +420,30 @@ public class MBeanPermission extends Permission { this.member = member; } + private void setMBeanServerName(String mbeanServerName) { + if (mbeanServerName == null || mbeanServerName.equals("-")) { + this.mbeanServerName = null; + } else if (mbeanServerName.equals("")) { + this.mbeanServerName = "*"; + } else { + this.mbeanServerName = mbeanServerName; + } + } + + /** *

    Create a new MBeanPermission object with the specified target name * and actions.

    * *

    The target name is of the form - * "className#member[objectName]" where each part is - * optional. It must not be empty or null.

    + * "mbeanServerName::className#member[objectName]" where + * each part is optional. It must not be empty or null.

    * *

    The actions parameter contains a comma-separated list of the * desired actions granted on the target name. It must not be * empty or null.

    * - * @param name the triplet "className#member[objectName]". + * @param name the quadruplet "mbeanServerName::className#member[objectName]". * @param actions the action string. * * @exception IllegalArgumentException if the name or @@ -418,6 +468,12 @@ public class MBeanPermission extends Permission { * optional. This will be the result of {@link #getName()} on the * resultant MBeanPermission.

    * + *

    This corresponds to a permission granted for all + * MBean servers present in the JVM and is equivalent to + * {@link #MBeanPermission(String,String,String,ObjectName,String) + * MBeanPermission("*",className,member,objectName,actions)}. + *

    + * *

    The actions parameter contains a comma-separated list of the * desired actions granted on the target name. It must not be * empty or null.

    @@ -439,17 +495,67 @@ public class MBeanPermission extends Permission { String member, ObjectName objectName, String actions) { + this("*",className,member,objectName,actions); + } - super(makeName(className, member, objectName)); - initName(className, member, objectName); + /** + *

    Create a new MBeanPermission object with the specified target name + * (MBean Server name, class name, member, object name) and actions.

    + * + *

    The MBean Server name, class name, member and object name + * parameters define a target name of the form + * "mbeanServerName::className#member[objectName]" where each + * part is optional. This will be the result of {@link #getName()} on the + * resultant MBeanPermission. + * If the mbeanServerName is empty or exactly {@code "*"}, then + * "{@code mbeanServerName::}" is omitted in that result. + *

    + * + *

    The actions parameter contains a comma-separated list of the + * desired actions granted on the target name. It must not be + * empty or null.

    + * + * @param mbeanServerName the name of the {@code MBeanServer} to which this + * permission applies. + * May be null or "-", which represents an MBeanServer name + * that is implied by any MBeanServer name but does not imply any other + * MBeanServer name. + * @param className the class name to which this permission applies. + * May be null or "-", which represents a class name + * that is implied by any class name but does not imply any other + * class name. + * @param member the member to which this permission applies. May + * be null or "-", which represents a member that is + * implied by any member but does not imply any other member. + * @param objectName the object name to which this permission + * applies. May be null, which represents an object name that is + * implied by any object name but does not imply any other object + * name. + * @param actions the action string. + * + * @since 1.7 + */ + public MBeanPermission(String mbeanServerName, + String className, + String member, + ObjectName objectName, + String actions) { + + super(makeName(mbeanServerName,className, member, objectName)); + initName(mbeanServerName,className, member, objectName); this.actions = actions; parseActions(); } - private static String makeName(String className, String member, + private static String makeName(String mbeanServerName, String className, + String member, ObjectName objectName) { final StringBuilder name = new StringBuilder(); + if (mbeanServerName == null) + mbeanServerName = "-"; + if (!mbeanServerName.equals("") && !mbeanServerName.equals("*")) + name.append(mbeanServerName).append("::"); if (className == null) className = "-"; name.append(className); @@ -991,6 +1097,9 @@ public class MBeanPermission extends Permission { * *
  • p is an instance of MBeanPermission; and
  • * + *
  • p has a null mbeanServerName or p's mbeanServerName + * matches this object's mbeanServerName; and
  • + * *
  • p has a null className or p's className * matches this object's className; and
  • * @@ -1004,6 +1113,13 @@ public class MBeanPermission extends Permission { * * * + *

    If this object's mbeanServerName is a pattern, then p's + * mbeanServerName is matched against that pattern. An empty + * mbeanServerName is equivalent to "{@code *}". A null + * mbeanServerName is equivalent to "{@code -}".

    + *

    If this object's mbeanServerName is "*" or is + * empty, p's mbeanServerName always matches it.

    + * *

    If this object's className is "*", p's * className always matches it. If it is "a.*", p's * className matches it if it begins with "a.".

    @@ -1050,6 +1166,12 @@ public class MBeanPermission extends Permission { // Target name // + // The 'mbeanServerName' check is true iff: + // 1) the mbeanServerName in 'this' permission is omitted or "*", or + // 2) the mbeanServerName in 'that' permission is omitted or "*", or + // 3) the mbeanServerName in 'this' permission does pattern + // matching with the mbeanServerName in 'that' permission. + // // The 'className' check is true iff: // 1) the className in 'this' permission is omitted or "*", or // 2) the className in 'that' permission is omitted or "*", or @@ -1076,6 +1198,17 @@ public class MBeanPermission extends Permission { expect that "that" contains a wildcard, since it is a needed permission. So we assume that.classNameExactMatch. */ + if (that.mbeanServerName == null) { + // bottom is implied + } else if (this.mbeanServerName == null) { + // bottom implies nothing but itself + return false; + } else if (that.mbeanServerName.equals(this.mbeanServerName)) { + // exact match + } else if (!Util.wildmatch(that.mbeanServerName,this.mbeanServerName)) { + return false; // no match + } + if (that.classNamePrefix == null) { // bottom is implied } else if (this.classNamePrefix == null) { diff --git a/jdk/src/share/classes/javax/management/MBeanRegistration.java b/jdk/src/share/classes/javax/management/MBeanRegistration.java index 1ba1c0d827f..723045acc93 100644 --- a/jdk/src/share/classes/javax/management/MBeanRegistration.java +++ b/jdk/src/share/classes/javax/management/MBeanRegistration.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -158,7 +158,19 @@ public interface MBeanRegistration { /** * Allows the MBean to perform any operations needed after having been * registered in the MBean server or after the registration has failed. - * + *

    If the implementation of this method throws a {@link RuntimeException} + * or an {@link Error}, the MBean Server will rethrow those inside + * a {@link RuntimeMBeanException} or {@link RuntimeErrorException}, + * respectively. However, throwing an exception in {@code postRegister} + * will not change the state of the MBean: + * if the MBean was already registered ({@code registrationDone} is + * {@code true}), the MBean will remain registered.

    + *

    This might be confusing for the code calling {@code createMBean()} + * or {@code registerMBean()}, as such code might assume that MBean + * registration has failed when such an exception is raised. + * Therefore it is recommended that implementations of + * {@code postRegister} do not throw Runtime Exceptions or Errors if it + * can be avoided.

    * @param registrationDone Indicates whether or not the MBean has * been successfully registered in the MBean server. The value * false means that the registration phase has failed. @@ -178,6 +190,17 @@ public interface MBeanRegistration { /** * Allows the MBean to perform any operations needed after having been * unregistered in the MBean server. + *

    If the implementation of this method throws a {@link RuntimeException} + * or an {@link Error}, the MBean Server will rethrow those inside + * a {@link RuntimeMBeanException} or {@link RuntimeErrorException}, + * respectively. However, throwing an excepption in {@code postDeregister} + * will not change the state of the MBean: + * the MBean was already successfully deregistered and will remain so.

    + *

    This might be confusing for the code calling + * {@code unregisterMBean()}, as it might assume that MBean deregistration + * has failed. Therefore it is recommended that implementations of + * {@code postDeregister} do not throw Runtime Exceptions or Errors if it + * can be avoided.

    */ public void postDeregister(); diff --git a/jdk/src/share/classes/javax/management/MBeanServer.java b/jdk/src/share/classes/javax/management/MBeanServer.java index f0d4d16c46f..90d42d2df6c 100644 --- a/jdk/src/share/classes/javax/management/MBeanServer.java +++ b/jdk/src/share/classes/javax/management/MBeanServer.java @@ -42,7 +42,7 @@ import javax.management.loading.ClassLoaderRepository; * *

    User code does not usually implement this interface. Instead, * an object that implements this interface is obtained with one of - * the methods in the {@link MBeanServerFactory} class.

    + * the methods in the {@link javax.management.MBeanServerFactory} class.

    * *

    Every MBean which is added to the MBean server becomes * manageable: its attributes and operations become remotely @@ -50,8 +50,8 @@ import javax.management.loading.ClassLoaderRepository; * server. A Java object cannot be registered in the MBean server * unless it is a JMX compliant MBean.

    * - *

    When an MBean is registered or unregistered in the MBean server - * a {@link javax.management.MBeanServerNotification + *

    When an MBean is registered or unregistered in the + * MBean server a {@link javax.management.MBeanServerNotification * MBeanServerNotification} Notification is emitted. To register an * object as listener to MBeanServerNotifications you should call the * MBean server method {@link #addNotificationListener @@ -62,8 +62,12 @@ import javax.management.loading.ClassLoaderRepository; * JMImplementation:type=MBeanServerDelegate.

    * *

    An object obtained from the {@link - * MBeanServerFactory#createMBeanServer(String) createMBeanServer} or - * {@link MBeanServerFactory#newMBeanServer(String) newMBeanServer} + * MBeanServerFactory#createMBeanServer(String) createMBeanServer}, {@link + * MBeanServerFactory#createNamedMBeanServer(String,String) createNamedMBeanServer}, + * {@link + * MBeanServerFactory#newMBeanServer(String) newMBeanServer}, or + * {@link + * MBeanServerFactory#newNamedMBeanServer(String,String) newNamedMBeanServer} * methods of the {@link MBeanServerFactory} class applies security * checks to its methods, as follows.

    * @@ -73,9 +77,26 @@ import javax.management.loading.ClassLoaderRepository; * *

    Assuming that there is a security manager, or that the * implementation chooses to make checks anyway, the checks are made - * as detailed below. In what follows, className is the + * as detailed below. + * In what follows, and unless otherwise specified: + *

    + *
    • className is the * string returned by {@link MBeanInfo#getClassName()} for the target - * MBean.

      + * MBean,
    • + *
    • {@code mbeanServerName} is the + * {@linkplain MBeanServerFactory#getMBeanServerName name of the + * MBean Server} in which the target MBean is registered. This is the + * value returned by {@link MBeanServerFactory#getMBeanServerName + * MBeanServerFactory.getMBeanServerName(MBeanServer)}, and + * is usually the {@code mbeanServerName} parameter that was supplied + * to the {@link + * MBeanServerFactory#createNamedMBeanServer(String,String) + * createNamedMBeanServer} or {@link + * MBeanServerFactory#newNamedMBeanServer(String,String) newNamedMBeanServer} + * methods of the {@link MBeanServerFactory} when the MBeanServer was created, + * or {@value javax.management.MBeanServerFactory#DEFAULT_MBEANSERVER_NAME} if + * no name was supplied. + *
    * *

    If a security check fails, the method throws {@link * SecurityException}.

    @@ -89,78 +110,86 @@ import javax.management.loading.ClassLoaderRepository; * *
  • For the {@link #invoke invoke} method, the caller's * permissions must imply {@link - * MBeanPermission#MBeanPermission(String,String,ObjectName,String) - * MBeanPermission(className, operationName, name, "invoke")}.

    + * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String) + * MBeanPermission(mbeanServerName, className, operationName, name, "invoke")}. + *

    * *
  • For the {@link #getAttribute getAttribute} method, the * caller's permissions must imply {@link - * MBeanPermission#MBeanPermission(String,String,ObjectName,String) - * MBeanPermission(className, attribute, name, "getAttribute")}.

    + * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String) + * MBeanPermission(mbeanServerName, className, attribute, name, + * "getAttribute")}.

    * *
  • For the {@link #getAttributes getAttributes} method, the * caller's permissions must imply {@link - * MBeanPermission#MBeanPermission(String,String,ObjectName,String) - * MBeanPermission(className, null, name, "getAttribute")}. + * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String) + * MBeanPermission(mbeanServerName,className, null, name, "getAttribute")}. * Additionally, for each attribute a in the {@link * AttributeList}, if the caller's permissions do not imply {@link - * MBeanPermission#MBeanPermission(String,String,ObjectName,String) - * MBeanPermission(className, a, name, "getAttribute")}, the + * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String) + * MBeanPermission(mbeanServerName, className, a, name, + * "getAttribute")}, the * MBean server will behave as if that attribute had not been in the * supplied list.

    * *
  • For the {@link #setAttribute setAttribute} method, the * caller's permissions must imply {@link - * MBeanPermission#MBeanPermission(String,String,ObjectName,String) - * MBeanPermission(className, attrName, name, "setAttribute")}, where + * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String) + * MBeanPermission(mbeanServerName, className, attrName, name, + * "setAttribute")}, where * attrName is {@link Attribute#getName() * attribute.getName()}.

    * *
  • For the {@link #setAttributes setAttributes} method, the * caller's permissions must imply {@link - * MBeanPermission#MBeanPermission(String,String,ObjectName,String) - * MBeanPermission(className, null, name, "setAttribute")}. + * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String) + * MBeanPermission(mbeanServerName, className, null, name, "setAttribute")}. * Additionally, for each attribute a in the {@link * AttributeList}, if the caller's permissions do not imply {@link - * MBeanPermission#MBeanPermission(String,String,ObjectName,String) - * MBeanPermission(className, a, name, "setAttribute")}, the + * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String) + * MBeanPermission(mbeanServerName, className, a, name, + * "setAttribute")}, the * MBean server will behave as if that attribute had not been in the * supplied list.

    * *
  • For the addNotificationListener methods, * the caller's permissions must imply {@link - * MBeanPermission#MBeanPermission(String,String,ObjectName,String) - * MBeanPermission(className, null, name, + * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String) + * MBeanPermission(mbeanServerName, className, null, name, * "addNotificationListener")}.

    * *
  • For the removeNotificationListener methods, * the caller's permissions must imply {@link - * MBeanPermission#MBeanPermission(String,String,ObjectName,String) - * MBeanPermission(className, null, name, + * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String) + * MBeanPermission(mbeanServerName, className, null, name, * "removeNotificationListener")}.

    * *
  • For the {@link #getMBeanInfo getMBeanInfo} method, the * caller's permissions must imply {@link - * MBeanPermission#MBeanPermission(String,String,ObjectName,String) - * MBeanPermission(className, null, name, "getMBeanInfo")}.

    + * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String) + * MBeanPermission(mbeanServerName, className, null, name, "getMBeanInfo")}. + *

    * *
  • For the {@link #getObjectInstance getObjectInstance} method, * the caller's permissions must imply {@link - * MBeanPermission#MBeanPermission(String,String,ObjectName,String) - * MBeanPermission(className, null, name, "getObjectInstance")}.

    + * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String) + * MBeanPermission(mbeanServerName, className, null, name, + * "getObjectInstance")}.

    * *
  • For the {@link #isInstanceOf isInstanceOf} method, the * caller's permissions must imply {@link - * MBeanPermission#MBeanPermission(String,String,ObjectName,String) - * MBeanPermission(className, null, name, "isInstanceOf")}.

    + * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String) + * MBeanPermission(mbeanServerName, className, null, name, "isInstanceOf")}. + *

    * *
  • For the {@link #queryMBeans queryMBeans} method, the * caller's permissions must imply {@link - * MBeanPermission#MBeanPermission(String,String,ObjectName,String) - * MBeanPermission(null, null, name, "queryMBeans")}. + * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String) + * MBeanPermission(mbeanServerName, null, null, null, "queryMBeans")}. * Additionally, for each MBean that matches name, * if the caller's permissions do not imply {@link - * MBeanPermission#MBeanPermission(String,String,ObjectName,String) - * MBeanPermission(className, null, name, "queryMBeans")}, the + * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String) + * MBeanPermission(mbeanServerName, className, null, name, "queryMBeans")}, the * MBean server will behave as if that MBean did not exist.

    * *

    Certain query elements perform operations on the MBean server. @@ -179,10 +208,10 @@ import javax.management.loading.ClassLoaderRepository; * *

  • For the {@link #getDomains getDomains} method, the caller's * permissions must imply {@link - * MBeanPermission#MBeanPermission(String,String,ObjectName,String) - * MBeanPermission(null, null, name, "getDomains")}. Additionally, - * for each domain d in the returned array, if the caller's - * permissions do not imply {@link + * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String) + * MBeanPermission(mbeanServerName, null, null, null, "getDomains")}. + * Additionally, for each domain d in the returned array, if the + * caller's permissions do not imply {@link * MBeanPermission#MBeanPermission(String,String,ObjectName,String) * MBeanPermission(null, null, new ObjectName("d:x=x"), * "getDomains")}, the domain is eliminated from the array. Here, @@ -191,21 +220,22 @@ import javax.management.loading.ClassLoaderRepository; * *

  • For the {@link #getClassLoader getClassLoader} method, the * caller's permissions must imply {@link - * MBeanPermission#MBeanPermission(String,String,ObjectName,String) - * MBeanPermission(className, null, loaderName, + * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String) + * MBeanPermission(mbeanServerName, className, null, loaderName, * "getClassLoader")}.

    * *
  • For the {@link #getClassLoaderFor getClassLoaderFor} method, * the caller's permissions must imply {@link - * MBeanPermission#MBeanPermission(String,String,ObjectName,String) - * MBeanPermission(className, null, mbeanName, + * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String) + * MBeanPermission(mbeanServerName, className, null, mbeanName, * "getClassLoaderFor")}.

    * *
  • For the {@link #getClassLoaderRepository * getClassLoaderRepository} method, the caller's permissions must * imply {@link - * MBeanPermission#MBeanPermission(String,String,ObjectName,String) - * MBeanPermission(null, null, null, "getClassLoaderRepository")}.

    + * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String) + * MBeanPermission(mbeanServerName, null, null, null, + * "getClassLoaderRepository")}.

    * *
  • For the deprecated deserialize methods, the * required permissions are the same as for the methods that replace @@ -213,15 +243,15 @@ import javax.management.loading.ClassLoaderRepository; * *

  • For the instantiate methods, the caller's * permissions must imply {@link - * MBeanPermission#MBeanPermission(String,String,ObjectName,String) - * MBeanPermission(className, null, null, "instantiate")}.

    + * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String) + * MBeanPermission(mbeanServerName, className, null, null, "instantiate")}, + * where {@code className} is the name of the class which is to + * be instantiated.

    * *
  • For the {@link #registerMBean registerMBean} method, the * caller's permissions must imply {@link - * MBeanPermission#MBeanPermission(String,String,ObjectName,String) - * MBeanPermission(className, null, name, "registerMBean")}. Here - * className is the string returned by {@link - * MBeanInfo#getClassName()} for an object of this class. + * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String) + * MBeanPermission(mbeanServerName, className, null, name, "registerMBean")}. * *

    If the MBeanPermission check succeeds, the MBean's * class is validated by checking that its {@link @@ -241,8 +271,9 @@ import javax.management.loading.ClassLoaderRepository; * *

  • For the {@link #unregisterMBean unregisterMBean} method, * the caller's permissions must imply {@link - * MBeanPermission#MBeanPermission(String,String,ObjectName,String) - * MBeanPermission(className, null, name, "unregisterMBean")}.

    + * MBeanPermission#MBeanPermission(String,String,String,ObjectName,String) + * MBeanPermission(mbeanServerName, className, null, name, "unregisterMBean")}. + *

    * * * @@ -262,6 +293,10 @@ public interface MBeanServer extends MBeanServerConnection { * {@inheritDoc} *

    If this method successfully creates an MBean, a notification * is sent as described above.

    + * + * @throws RuntimeOperationsException {@inheritDoc} + * @throws RuntimeMBeanException {@inheritDoc} + * @throws RuntimeErrorException {@inheritDoc} */ public ObjectInstance createMBean(String className, ObjectName name) throws ReflectionException, InstanceAlreadyExistsException, @@ -272,6 +307,10 @@ public interface MBeanServer extends MBeanServerConnection { * {@inheritDoc} *

    If this method successfully creates an MBean, a notification * is sent as described above.

    + * + * @throws RuntimeOperationsException {@inheritDoc} + * @throws RuntimeMBeanException {@inheritDoc} + * @throws RuntimeErrorException {@inheritDoc} */ public ObjectInstance createMBean(String className, ObjectName name, ObjectName loaderName) @@ -283,6 +322,10 @@ public interface MBeanServer extends MBeanServerConnection { * {@inheritDoc} *

    If this method successfully creates an MBean, a notification * is sent as described above.

    + * + * @throws RuntimeOperationsException {@inheritDoc} + * @throws RuntimeMBeanException {@inheritDoc} + * @throws RuntimeErrorException {@inheritDoc} */ public ObjectInstance createMBean(String className, ObjectName name, Object params[], String signature[]) @@ -294,6 +337,10 @@ public interface MBeanServer extends MBeanServerConnection { * {@inheritDoc} *

    If this method successfully creates an MBean, a notification * is sent as described above.

    + * + * @throws RuntimeOperationsException {@inheritDoc} + * @throws RuntimeMBeanException {@inheritDoc} + * @throws RuntimeErrorException {@inheritDoc} */ public ObjectInstance createMBean(String className, ObjectName name, ObjectName loaderName, Object params[], @@ -328,11 +375,30 @@ public interface MBeanServer extends MBeanServerConnection { * preRegister (MBeanRegistration * interface) method of the MBean has thrown an exception. The * MBean will not be registered. + * @exception RuntimeMBeanException If the postRegister + * (MBeanRegistration interface) method of the MBean throws a + * RuntimeException, the registerMBean method will + * throw a RuntimeMBeanException, although the MBean + * registration succeeded. In such a case, the MBean will be actually + * registered even though the registerMBean method + * threw an exception. Note that RuntimeMBeanException can + * also be thrown by preRegister, in which case the MBean + * will not be registered. + * @exception RuntimeErrorException If the postRegister + * (MBeanRegistration interface) method of the MBean throws an + * Error, the registerMBean method will + * throw a RuntimeErrorException, although the MBean + * registration succeeded. In such a case, the MBean will be actually + * registered even though the registerMBean method + * threw an exception. Note that RuntimeErrorException can + * also be thrown by preRegister, in which case the MBean + * will not be registered. * @exception NotCompliantMBeanException This object is not a JMX * compliant MBean * @exception RuntimeOperationsException Wraps a * java.lang.IllegalArgumentException: The object * passed in parameter is null or no object name is specified. + * @see javax.management.MBeanRegistration */ public ObjectInstance registerMBean(Object object, ObjectName name) throws InstanceAlreadyExistsException, MBeanRegistrationException, @@ -343,6 +409,8 @@ public interface MBeanServer extends MBeanServerConnection { * *

    If this method successfully unregisters an MBean, a notification * is sent as described above.

    + * + * @throws RuntimeOperationsException {@inheritDoc} */ public void unregisterMBean(ObjectName name) throws InstanceNotFoundException, MBeanRegistrationException; @@ -358,6 +426,9 @@ public interface MBeanServer extends MBeanServerConnection { public Set queryNames(ObjectName name, QueryExp query); // doc comment inherited from MBeanServerConnection + /** + * @throws RuntimeOperationsException {@inheritDoc} + */ public boolean isRegistered(ObjectName name); /** @@ -370,21 +441,33 @@ public interface MBeanServer extends MBeanServerConnection { public Integer getMBeanCount(); // doc comment inherited from MBeanServerConnection + /** + * @throws RuntimeOperationsException {@inheritDoc} + */ public Object getAttribute(ObjectName name, String attribute) throws MBeanException, AttributeNotFoundException, InstanceNotFoundException, ReflectionException; // doc comment inherited from MBeanServerConnection + /** + * @throws RuntimeOperationsException {@inheritDoc} + */ public AttributeList getAttributes(ObjectName name, String[] attributes) throws InstanceNotFoundException, ReflectionException; // doc comment inherited from MBeanServerConnection + /** + * @throws RuntimeOperationsException {@inheritDoc} + */ public void setAttribute(ObjectName name, Attribute attribute) throws InstanceNotFoundException, AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException; // doc comment inherited from MBeanServerConnection + /** + * @throws RuntimeOperationsException {@inheritDoc} + */ public AttributeList setAttributes(ObjectName name, AttributeList attributes) throws InstanceNotFoundException, ReflectionException; @@ -401,14 +484,23 @@ public interface MBeanServer extends MBeanServerConnection { // doc comment inherited from MBeanServerConnection public String[] getDomains(); - // doc comment inherited from MBeanServerConnection + // doc comment inherited from MBeanServerConnection, plus: + /** + * {@inheritDoc} + * If the source of the notification + * is a reference to an MBean object, the MBean server will replace it + * by that MBean's ObjectName. Otherwise the source is unchanged. + */ public void addNotificationListener(ObjectName name, NotificationListener listener, NotificationFilter filter, Object handback) throws InstanceNotFoundException; - // doc comment inherited from MBeanServerConnection + /** + * {@inheritDoc} + * @throws RuntimeOperationsException {@inheritDoc} + */ public void addNotificationListener(ObjectName name, ObjectName listener, NotificationFilter filter, diff --git a/jdk/src/share/classes/javax/management/MBeanServerConnection.java b/jdk/src/share/classes/javax/management/MBeanServerConnection.java index 4047373c261..0897684a0b5 100644 --- a/jdk/src/share/classes/javax/management/MBeanServerConnection.java +++ b/jdk/src/share/classes/javax/management/MBeanServerConnection.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ package javax.management; // java import import java.io.IOException; import java.util.Set; +import javax.management.event.NotificationManager; /** @@ -39,7 +40,7 @@ import java.util.Set; * * @since 1.5 */ -public interface MBeanServerConnection { +public interface MBeanServerConnection extends NotificationManager { /** *

    Instantiates and registers an MBean in the MBean server. The * MBean server will use its {@link @@ -75,6 +76,24 @@ public interface MBeanServerConnection { * preRegister (MBeanRegistration * interface) method of the MBean has thrown an exception. The * MBean will not be registered. + * @exception RuntimeMBeanException If the postRegister + * (MBeanRegistration interface) method of the MBean throws a + * RuntimeException, the createMBean method will + * throw a RuntimeMBeanException, although the MBean creation + * and registration succeeded. In such a case, the MBean will be actually + * registered even though the createMBean method + * threw an exception. Note that RuntimeMBeanException can + * also be thrown by preRegister, in which case the MBean + * will not be registered. + * @exception RuntimeErrorException If the postRegister + * (MBeanRegistration interface) method of the MBean throws an + * Error, the createMBean method will + * throw a RuntimeErrorException, although the MBean creation + * and registration succeeded. In such a case, the MBean will be actually + * registered even though the createMBean method + * threw an exception. Note that RuntimeErrorException can + * also be thrown by preRegister, in which case the MBean + * will not be registered. * @exception MBeanException The constructor of the MBean has * thrown an exception * @exception NotCompliantMBeanException This class is not a JMX @@ -86,7 +105,7 @@ public interface MBeanServerConnection { * is specified for the MBean. * @exception IOException A communication problem occurred when * talking to the MBean server. - * + * @see javax.management.MBeanRegistration */ public ObjectInstance createMBean(String className, ObjectName name) throws ReflectionException, InstanceAlreadyExistsException, @@ -129,6 +148,24 @@ public interface MBeanServerConnection { * preRegister (MBeanRegistration * interface) method of the MBean has thrown an exception. The * MBean will not be registered. + * @exception RuntimeMBeanException If the postRegister + * (MBeanRegistration interface) method of the MBean throws a + * RuntimeException, the createMBean method will + * throw a RuntimeMBeanException, although the MBean creation + * and registration succeeded. In such a case, the MBean will be actually + * registered even though the createMBean method + * threw an exception. Note that RuntimeMBeanException can + * also be thrown by preRegister, in which case the MBean + * will not be registered. + * @exception RuntimeErrorException If the postRegister + * (MBeanRegistration interface) method of the MBean throws an + * Error, the createMBean method will + * throw a RuntimeErrorException, although the MBean creation + * and registration succeeded. In such a case, the MBean will be actually + * registered even though the createMBean method + * threw an exception. Note that RuntimeErrorException can + * also be thrown by preRegister, in which case the MBean + * will not be registered. * @exception MBeanException The constructor of the MBean has * thrown an exception * @exception NotCompliantMBeanException This class is not a JMX @@ -142,6 +179,7 @@ public interface MBeanServerConnection { * is specified for the MBean. * @exception IOException A communication problem occurred when * talking to the MBean server. + * @see javax.management.MBeanRegistration */ public ObjectInstance createMBean(String className, ObjectName name, ObjectName loaderName) @@ -185,6 +223,24 @@ public interface MBeanServerConnection { * preRegister (MBeanRegistration * interface) method of the MBean has thrown an exception. The * MBean will not be registered. + * @exception RuntimeMBeanException If the postRegister + * (MBeanRegistration interface) method of the MBean throws a + * RuntimeException, the createMBean method will + * throw a RuntimeMBeanException, although the MBean creation + * and registration succeeded. In such a case, the MBean will be actually + * registered even though the createMBean method + * threw an exception. Note that RuntimeMBeanException can + * also be thrown by preRegister, in which case the MBean + * will not be registered. + * @exception RuntimeErrorException If the postRegister + * (MBeanRegistration interface) method of the MBean throws an + * Error, the createMBean method will + * throw a RuntimeErrorException, although the MBean creation + * and registration succeeded. In such a case, the MBean will be actually + * registered even though the createMBean method + * threw an exception. Note that RuntimeErrorException can + * also be thrown by preRegister, in which case the MBean + * will not be registered. * @exception MBeanException The constructor of the MBean has * thrown an exception * @exception NotCompliantMBeanException This class is not a JMX @@ -196,7 +252,7 @@ public interface MBeanServerConnection { * is specified for the MBean. * @exception IOException A communication problem occurred when * talking to the MBean server. - * + * @see javax.management.MBeanRegistration */ public ObjectInstance createMBean(String className, ObjectName name, Object params[], String signature[]) @@ -239,6 +295,24 @@ public interface MBeanServerConnection { * preRegister (MBeanRegistration * interface) method of the MBean has thrown an exception. The * MBean will not be registered. + * @exception RuntimeMBeanException If the postRegister + * (MBeanRegistration interface) method of the MBean throws a + * RuntimeException, the createMBean method will + * throw a RuntimeMBeanException, although the MBean creation + * and registration succeeded. In such a case, the MBean will be actually + * registered even though the createMBean method + * threw an exception. Note that RuntimeMBeanException can + * also be thrown by preRegister, in which case the MBean + * will not be registered. + * @exception RuntimeErrorException If the postRegister method + * (MBeanRegistration interface) method of the MBean throws an + * Error, the createMBean method will + * throw a RuntimeErrorException, although the MBean creation + * and registration succeeded. In such a case, the MBean will be actually + * registered even though the createMBean method + * threw an exception. Note that RuntimeErrorException can + * also be thrown by preRegister, in which case the MBean + * will not be registered. * @exception MBeanException The constructor of the MBean has * thrown an exception * @exception NotCompliantMBeanException This class is not a JMX @@ -252,7 +326,7 @@ public interface MBeanServerConnection { * is specified for the MBean. * @exception IOException A communication problem occurred when * talking to the MBean server. - * + * @see javax.management.MBeanRegistration */ public ObjectInstance createMBean(String className, ObjectName name, ObjectName loaderName, Object params[], @@ -275,6 +349,24 @@ public interface MBeanServerConnection { * @exception MBeanRegistrationException The preDeregister * ((MBeanRegistration interface) method of the MBean * has thrown an exception. + * @exception RuntimeMBeanException If the postDeregister + * (MBeanRegistration interface) method of the MBean throws a + * RuntimeException, the unregisterMBean method + * will throw a RuntimeMBeanException, although the MBean + * unregistration succeeded. In such a case, the MBean will be actually + * unregistered even though the unregisterMBean method + * threw an exception. Note that RuntimeMBeanException can + * also be thrown by preDeregister, in which case the MBean + * will remain registered. + * @exception RuntimeErrorException If the postDeregister + * (MBeanRegistration interface) method of the MBean throws an + * Error, the unregisterMBean method will + * throw a RuntimeErrorException, although the MBean + * unregistration succeeded. In such a case, the MBean will be actually + * unregistered even though the unregisterMBean method + * threw an exception. Note that RuntimeMBeanException can + * also be thrown by preDeregister, in which case the MBean + * will remain registered. * @exception RuntimeOperationsException Wraps a * java.lang.IllegalArgumentException: The object * name in parameter is null or the MBean you are when trying to @@ -282,7 +374,7 @@ public interface MBeanServerConnection { * MBeanServerDelegate} MBean. * @exception IOException A communication problem occurred when * talking to the MBean server. - * + * @see javax.management.MBeanRegistration */ public void unregisterMBean(ObjectName name) throws InstanceNotFoundException, MBeanRegistrationException, @@ -585,32 +677,7 @@ public interface MBeanServerConnection { public String[] getDomains() throws IOException; - /** - *

    Adds a listener to a registered MBean.

    - * - *

    A notification emitted by an MBean will be forwarded by the - * MBeanServer to the listener. If the source of the notification - * is a reference to an MBean object, the MBean server will replace it - * by that MBean's ObjectName. Otherwise the source is unchanged. - * - * @param name The name of the MBean on which the listener should - * be added. - * @param listener The listener object which will handle the - * notifications emitted by the registered MBean. - * @param filter The filter object. If filter is null, no - * filtering will be performed before handling notifications. - * @param handback The context to be sent to the listener when a - * notification is emitted. - * - * @exception InstanceNotFoundException The MBean name provided - * does not match any of the registered MBeans. - * @exception IOException A communication problem occurred when - * talking to the MBean server. - * - * @see #removeNotificationListener(ObjectName, NotificationListener) - * @see #removeNotificationListener(ObjectName, NotificationListener, - * NotificationFilter, Object) - */ + // doc inherited from NotificationManager public void addNotificationListener(ObjectName name, NotificationListener listener, NotificationFilter filter, @@ -727,65 +794,13 @@ public interface MBeanServerConnection { throws InstanceNotFoundException, ListenerNotFoundException, IOException; - - /** - *

    Removes a listener from a registered MBean.

    - * - *

    If the listener is registered more than once, perhaps with - * different filters or callbacks, this method will remove all - * those registrations. - * - * @param name The name of the MBean on which the listener should - * be removed. - * @param listener The listener to be removed. - * - * @exception InstanceNotFoundException The MBean name provided - * does not match any of the registered MBeans. - * @exception ListenerNotFoundException The listener is not - * registered in the MBean. - * @exception IOException A communication problem occurred when - * talking to the MBean server. - * - * @see #addNotificationListener(ObjectName, NotificationListener, - * NotificationFilter, Object) - */ + // doc inherited from NotificationManager public void removeNotificationListener(ObjectName name, NotificationListener listener) throws InstanceNotFoundException, ListenerNotFoundException, IOException; - /** - *

    Removes a listener from a registered MBean.

    - * - *

    The MBean must have a listener that exactly matches the - * given listener, filter, and - * handback parameters. If there is more than one - * such listener, only one is removed.

    - * - *

    The filter and handback parameters - * may be null if and only if they are null in a listener to be - * removed.

    - * - * @param name The name of the MBean on which the listener should - * be removed. - * @param listener The listener to be removed. - * @param filter The filter that was specified when the listener - * was added. - * @param handback The handback that was specified when the - * listener was added. - * - * @exception InstanceNotFoundException The MBean name provided - * does not match any of the registered MBeans. - * @exception ListenerNotFoundException The listener is not - * registered in the MBean, or it is not registered with the given - * filter and handback. - * @exception IOException A communication problem occurred when - * talking to the MBean server. - * - * @see #addNotificationListener(ObjectName, NotificationListener, - * NotificationFilter, Object) - * - */ + // doc inherited from NotificationManager public void removeNotificationListener(ObjectName name, NotificationListener listener, NotificationFilter filter, diff --git a/jdk/src/share/classes/javax/management/MBeanServerDelegate.java b/jdk/src/share/classes/javax/management/MBeanServerDelegate.java index 4ee9766306b..aa706da12c2 100644 --- a/jdk/src/share/classes/javax/management/MBeanServerDelegate.java +++ b/jdk/src/share/classes/javax/management/MBeanServerDelegate.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,9 @@ package javax.management; +import com.sun.jmx.defaults.JmxProperties; import com.sun.jmx.defaults.ServiceName; +import com.sun.jmx.mbeanserver.Util; /** * Represents the MBean server from the management point of view. @@ -39,6 +41,7 @@ public class MBeanServerDelegate implements MBeanServerDelegateMBean, /** The MBean server agent identification.*/ private String mbeanServerId ; + private String mbeanServerName; /** The NotificationBroadcasterSupport object that sends the notifications */ @@ -68,6 +71,7 @@ public class MBeanServerDelegate implements MBeanServerDelegateMBean, public MBeanServerDelegate () { stamp = getStamp(); broadcaster = new NotificationBroadcasterSupport() ; + mbeanServerName=null; } @@ -82,13 +86,102 @@ public class MBeanServerDelegate implements MBeanServerDelegateMBean, try { localHost = java.net.InetAddress.getLocalHost().getHostName(); } catch (java.net.UnknownHostException e) { + JmxProperties.MISC_LOGGER.finest("Can't get local host name, " + + "using \"localhost\" instead. Cause is: "+e); localHost = "localhost"; } - mbeanServerId = localHost + "_" + stamp; + mbeanServerId = + Util.insertMBeanServerName(localHost + "_" + stamp, + mbeanServerName); } return mbeanServerId; } + /** + * The name of the MBeanServer. + * @return The name of the MBeanServer, or {@value + * javax.management.MBeanServerFactory#DEFAULT_MBEANSERVER_NAME} if no + * name was specified. + * + * @since 1.7 + * @see #setMBeanServerName + */ + public synchronized String getMBeanServerName() { + if (Util.isMBeanServerNameUndefined(mbeanServerName)) + return MBeanServerFactory.DEFAULT_MBEANSERVER_NAME; + return mbeanServerName; + } + + /** + * Sets the name of the MBeanServer. The name will be embedded into the + * {@link #getMBeanServerId MBeanServerId} using the following format:
    + * {@code mbeanServerId: ;mbeanServerName=} + *

    The characters {@code ':'} (colon), {@code ';'} (semicolon ), + * {@code '*'} (star) and {@code '?'} (question mark) are not legal in an + * MBean Server name.

    + *

    For instance, if the {@code mbeanServerName} provided is + * {@code "com.mycompany.myapp.server1"}, and the original + * {@code MBeanServerId} was {@code "myhost_1213353064145"}, + * then {@code mbeanServerName} will be + * embedded in the {@code MBeanServerId} - and the new value of the + * {@code MBeanServerId} will be: + *

    + *
    +     *       "myhost_1213353064145;mbeanServerName=com.mycompany.myapp.server1"
    +     * 
    + *

    Note: The {@code mbeanServerName} is usually set by the + * {@code MBeanServerFactory}. It is set only once, before the + * MBean Server is returned by the factory. Once the MBean Server name is + * set, it is not possible to change it. + *

    + * @param mbeanServerName The MBeanServer name. + * @throws IllegalArgumentException if the MBeanServerName is already set + * to a different value, or if the provided name contains + * illegal characters, or if the provided name is {@code ""} + * (the empty string) or "-" (dash). + * @throws UnsupportedOperationException if this object is of a legacy + * subclass of MBeanServerDelegate which overrides {@link + * #getMBeanServerId()} + * in a way that doesn't support setting an MBeanServer name. + * @see MBeanServerFactory#getMBeanServerName + * @since 1.7 + */ + public synchronized void setMBeanServerName(String mbeanServerName) { + // Sets the name on the delegate. For complex backward + // compatibility reasons it is not possible to give the + // name to the MBeanServerDelegate constructor. + // + // The method setMBeanServerName() will call getMBeanServerId() + // to check that the name is accurately set in the MBeanServerId. + // If not (which could happen if a custom MBeanServerDelegate + // implementation overrides getMBeanServerId() and was not updated + // with respect to JMX 2.0 spec), this method will throw an + // IllegalStateException... + + // will fail if mbeanServerName is illegal + final String name = Util.checkServerName(mbeanServerName); + + // can only set mbeanServerDelegate once. + if (this.mbeanServerName != null && !this.mbeanServerName.equals(name)) + throw new IllegalArgumentException( + "MBeanServerName already set to a different value"); + + this.mbeanServerName = name; + + // will fail if mbeanServerId already has a different mbeanServerName + mbeanServerId = + Util.insertMBeanServerName(getMBeanServerId(),name); + + // check that we don't have a subclass which overrides + // getMBeanServerId() without setting mbeanServerName + if (!name.equals( + Util.extractMBeanServerName(getMBeanServerId()))) + throw new UnsupportedOperationException( + "Can't set MBeanServerName in MBeanServerId - " + + "unsupported by "+this.getClass().getName()+"?"); + // OK: at this point we know that we have correctly set mbeanServerName. + } + /** * Returns the full name of the JMX specification implemented * by this product. @@ -210,15 +303,8 @@ public class MBeanServerDelegate implements MBeanServerDelegateMBean, * * @since 1.6 */ - public static final ObjectName DELEGATE_NAME; - static { - try { - DELEGATE_NAME = - new ObjectName("JMImplementation:type=MBeanServerDelegate"); - } catch (MalformedObjectNameException e) { - throw new Error("Can't initialize delegate name", e); - } - } + public static final ObjectName DELEGATE_NAME = + ObjectName.valueOf("JMImplementation:type=MBeanServerDelegate"); /* Return a timestamp that is monotonically increasing even if System.currentTimeMillis() isn't (for example, if you call this diff --git a/jdk/src/share/classes/javax/management/MBeanServerFactory.java b/jdk/src/share/classes/javax/management/MBeanServerFactory.java index 743ca3a1827..365f2a7d9b5 100644 --- a/jdk/src/share/classes/javax/management/MBeanServerFactory.java +++ b/jdk/src/share/classes/javax/management/MBeanServerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,16 +25,19 @@ package javax.management; +import com.sun.jmx.defaults.JmxProperties; import static com.sun.jmx.defaults.JmxProperties.JMX_INITIAL_BUILDER; import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER; -import com.sun.jmx.interceptor.DefaultMBeanServerInterceptor; import com.sun.jmx.mbeanserver.GetPropertyAction; +import com.sun.jmx.mbeanserver.Util; import java.security.AccessController; import java.security.Permission; import java.util.ArrayList; +import java.util.List; import java.util.logging.Level; import javax.management.loading.ClassLoaderRepository; + /** *

    Provides MBean server references. There are no instances of * this class.

    @@ -80,10 +83,53 @@ import javax.management.loading.ClassLoaderRepository; * returned by the default MBeanServerBuilder implementation, for the purpose * of e.g. adding an additional security layer.

    * + *

    Since version 2.0 of the JMX API, when creating + * an MBeanServer, + * it is possible to specify an {@linkplain #getMBeanServerName + * MBean Server name}. + * To create an MBean Server with a name, the MBeanServerFactory provides two + * new methods:

    + *
    • {@link #createNamedMBeanServer + * createNamedMBeanServer(mbeanServerName, defaultDomain)}: creates a named + * MBeanServer and keeps an internal reference to the created object. The + * MBeanServer can be later retrieved using {@link #findMBeanServer + * findMBeanServer(mbeanServerId)} or + * {@link #findMBeanServerByName findMBeanServerByName(mbeanServerName)}, and + * can be released through {@link + * #releaseMBeanServer releaseMBeanServer(mbeanServer)}.
    • + *
    • {@link #newNamedMBeanServer + * newNamedMBeanServer(mbeanServerName, defaultDomain)}: + * creates a named MBeanServer without keeping any internal reference to the + * named server.
    • + *
    + *

    The name of the MBeanServer is stored in the + * {@linkplain MBeanServerDelegate MBean Server delegate MBean} + * and is embedded in its {@link MBeanServerDelegate#getMBeanServerId + * MBeanServerId} attribute.

    + *

    The name of the MBeanServer is particularly useful when + * MBean permissions are checked: + * it makes it + * possible to distinguish between an MBean named "X" in MBeanServer named + * "M1", and another MBean of the same name "X" in another MBeanServer named + * "M2".

    + *

    When naming MBean servers it is recommended to use a name that starts + * with a Java package name. It is also recommended that the default domain and + * the MBeanServer name be the same.

    + * * @since 1.5 */ public class MBeanServerFactory { + /** + * The MBean Server name that will be + * checked by a permission you need + * when checking access to an MBean registered in an MBeanServer for + * which no MBeanServer name was specified. + * + * @since 1.7 + */ + public final static String DEFAULT_MBEANSERVER_NAME = "default"; + /* * There are no instances of this class so don't generate the * default public constructor. @@ -222,13 +268,78 @@ public class MBeanServerFactory { * javax.management.builder.initial exists and can be * instantiated but is not assignment compatible with {@link * MBeanServerBuilder}. + * + * @see #createNamedMBeanServer */ public static MBeanServer createMBeanServer(String domain) { - checkPermission("createMBeanServer"); + return createMBeanServer(null,domain); + } - final MBeanServer mBeanServer = newMBeanServer(domain); - addMBeanServer(mBeanServer); - return mBeanServer; + /** + *

    Return a new object implementing the {@link MBeanServer} + * interface with the specified + * MBean Server name + * and default domain name. The given MBean server name + * is used in security checks, and + * can also be used to {@linkplain #findMBeanServerByName(java.lang.String) + * find an MBeanServer by name}. The given + * domain name is used as the domain part in the ObjectName of + * MBeans when the domain is specified by the user is null.

    + * + *

    The MBeanServer reference is internally kept. This will + * allow findMBeanServer to return a reference to + * this MBeanServer object.

    + * + * @param mbeanServerName the name for the created + * MBeanServer. This is the name that will be included in the + * {@linkplain MBeanPermission permission you need} when checking + * MBean Permissions for accessing + * an MBean registered in the returned MBeanServer. The characters + * {@code ':'} (colon), {@code ';'} (semicolon), {@code '*'} (star) + * and {@code '?'} are not legal. + * It is recommended that the {@code mbeanServerName} + * be unique in the context of a JVM, and in the form of a java package + * identifier. If {@code mbeanServerName} is {@code null} then the created + * MBean Server has no name - and {@value #DEFAULT_MBEANSERVER_NAME} is used. + * Calling {@code createNamedMBeanServer(null,domain)} is equivalent + * to calling {@link #createMBeanServer(String) createMBeanServer(domain)}. + * + * @param domain the default domain name for the created + * MBeanServer. This is the value that will be returned by {@link + * MBeanServer#getDefaultDomain}. If a non null mbeanServerName is given, + * it is recommended to pass the same value as default domain. + * + * @return the newly created MBeanServer. + * + * @exception SecurityException if there is a SecurityManager and + * the caller's permissions do not include or imply {@link + * MBeanServerPermission}("createMBeanServer"). + * + * @exception JMRuntimeException if the property + * javax.management.builder.initial exists but the + * class it names cannot be instantiated through a public + * no-argument constructor; or if the instantiated builder returns + * null from its {@link MBeanServerBuilder#newMBeanServerDelegate + * newMBeanServerDelegate} or {@link + * MBeanServerBuilder#newMBeanServer newMBeanServer} methods. + * + * @exception ClassCastException if the property + * javax.management.builder.initial exists and can be + * instantiated but is not assignment compatible with {@link + * MBeanServerBuilder}. + * + * @exception IllegalArgumentException if the specified + * {@code mbeanServerName} is empty, or is {@code "-"}, or contains a + * character which is not legal. + * + * @exception UnsupportedOperationException if the specified + * {@code mbeanServerName} cannot be set. + * + * @since 1.7 + */ + public static MBeanServer createNamedMBeanServer(String mbeanServerName, + String domain) { + return createMBeanServer(mbeanServerName, domain); } /** @@ -307,6 +418,88 @@ public class MBeanServerFactory { * MBeanServerBuilder}. */ public static MBeanServer newMBeanServer(String domain) { + return newMBeanServer(null,domain); + } + + /** + *

    Return a new object implementing the MBeanServer interface + * with the specified MBean server name + * and default domain name, without keeping an + * internal reference to this new object. The given MBean server name + * is used in security checks. + * The given domain name + * is used as the domain part in the ObjectName of MBeans when the + * domain is specified by the user is null.

    + * + *

    No reference is kept. findMBeanServer and + * findMBeanServerByName will not + * be able to return a reference to this MBeanServer object, but + * the garbage collector will be able to remove the MBeanServer + * object when it is no longer referenced.

    + * + * @param mbeanServerName the name for the created + * MBeanServer. This is the name that will be included in the + * {@linkplain MBeanPermission permission you need} when checking + * MBean Permissions for accessing + * an MBean registered in the returned MBeanServer. The characters + * {@code ':'} (colon), {@code ';'} (semicolon), {@code '*'} (star) + * and {@code '?'} are not legal. + * It is recommended that the mbeanServerName + * be unique in the context of a JVM, and in the form of a java package + * identifier. If {@code mbeanServerName} is {@code null} then the created + * MBean Server has no name - and {@value #DEFAULT_MBEANSERVER_NAME} is used. + * Calling {@code newNamedMBeanServer(null,domain)} is equivalent + * to calling {@link #newMBeanServer(String) newMBeanServer(domain)}. + * + * @param domain the default domain name for the created + * MBeanServer. This is the value that will be returned by {@link + * MBeanServer#getDefaultDomain}. + * + * @return the newly created MBeanServer. + * + * @exception SecurityException if there is a SecurityManager and the + * caller's permissions do not include or imply {@link + * MBeanServerPermission}("newMBeanServer"). + * + * @exception JMRuntimeException if the property + * javax.management.builder.initial exists but the + * class it names cannot be instantiated through a public + * no-argument constructor; or if the instantiated builder returns + * null from its {@link MBeanServerBuilder#newMBeanServerDelegate + * newMBeanServerDelegate} or {@link + * MBeanServerBuilder#newMBeanServer newMBeanServer} methods. + * + * @exception ClassCastException if the property + * javax.management.builder.initial exists and can be + * instantiated but is not assignment compatible with {@link + * MBeanServerBuilder}. + * + * @exception IllegalArgumentException if the specified + * {@code mbeanServerName} is empty, or is {@code "-"}, + * or contains a character which is not legal. + * + * @exception UnsupportedOperationException if the specified + * {@code mbeanServerName} cannot be set. + * + * @since 1.7 + */ + public static MBeanServer newNamedMBeanServer(String mbeanServerName, + String domain) { + return newMBeanServer(mbeanServerName, domain); + } + + private static MBeanServer createMBeanServer(String mbeanServerName, + String domain) { + checkPermission("createMBeanServer"); + + final MBeanServer mBeanServer = + newMBeanServer(mbeanServerName,domain); + addMBeanServer(mBeanServer); + return mBeanServer; + } + + private static MBeanServer newMBeanServer(String mbeanServerName, + String domain) { checkPermission("newMBeanServer"); // Get the builder. Creates a new one if necessary. @@ -316,20 +509,50 @@ public class MBeanServerFactory { synchronized(mbsBuilder) { final MBeanServerDelegate delegate = - mbsBuilder.newMBeanServerDelegate(); + mbsBuilder.newMBeanServerDelegate(); if (delegate == null) { final String msg = - "MBeanServerBuilder.newMBeanServerDelegate() " + - "returned null"; + "MBeanServerBuilder.newMBeanServerDelegate() " + + "returned null"; throw new JMRuntimeException(msg); } + + // Sets the name on the delegate. For complex backward + // compatibility reasons it is not possible to give the + // name to the MBeanServerDelegate constructor. + // + // The method setMBeanServerName() will call getMBeanServerId() + // to check that the name is accurately set in the MBeanServerId. + // If not (which could happen if a custom MBeanServerDelegate + // implementation overrides getMBeanServerId() and was not updated + // with respect to JMX 2.0 spec, this method will throw an + // IllegalStateException... + // + if (!Util.isMBeanServerNameUndefined(mbeanServerName)) { + delegate.setMBeanServerName(mbeanServerName); + } + final MBeanServer mbeanServer = - mbsBuilder.newMBeanServer(domain,null,delegate); + mbsBuilder.newMBeanServer(domain,null,delegate); if (mbeanServer == null) { final String msg = - "MBeanServerBuilder.newMBeanServer() returned null"; + "MBeanServerBuilder.newMBeanServer() returned null"; throw new JMRuntimeException(msg); } + + // double check that the MBeanServer name is correctly set. + // "*" might mean that the caller doesn't have the permission + // to see the MBeanServer name. + // + final String mbsName = Util.getMBeanServerSecurityName(mbeanServer); + if (!mbsName.equals(Util.checkServerName(mbeanServerName)) + && !mbsName.equals("*")) { + throw new UnsupportedOperationException( + "can't create MBeanServer with name \""+ + mbeanServerName+"\" using "+ + builder.getClass().getName()); + } + return mbeanServer; } } @@ -363,16 +586,107 @@ public class MBeanServerFactory { ArrayList result = new ArrayList(); for (MBeanServer mbs : mBeanServerList) { - String name = mBeanServerName(mbs); + String name = mBeanServerId(mbs); if (agentId.equals(name)) result.add(mbs); } return result; } + /** + *

    Returns a list of registered MBeanServer objects with the given name. A + * registered MBeanServer object is one that was created by one of + * the createMBeanServer or createNamedMBeanServer + * methods and not subsequently released with releaseMBeanServer.

    + *

    See the section about MBean Server names + * above.

    + * + * @param mbeanServerName The name of the MBeanServer to + * retrieve. If this parameter is null, all registered MBeanServers + * in this JVM are returned. + * Otherwise, only those MBeanServers that have a name + * matching mbeanServerName are returned: this + * parameter can be a pattern, where {@code '*'} matches any + * sequence of characters and {@code '?'} matches any character.
    + * The name of an MBeanServer, if specified, is embedded in the + * MBeanServerId attribute of its delegate MBean: + * this method will parse the MBeanServerId to get the + * MBeanServer name. If this parameter is equal to {@code "*"} then + * all registered MBeanServers in this JVM are returned, whether they have + * a name or not: {@code findMBeanServerByName(null)}, + * {@code findMBeanServerByName("*")} and {@code findMBeanServer(null)}, + * are equivalent. It is also possible to get all MBeanServers for which + * no name was specified by calling findMBeanServerByName({@value + * #DEFAULT_MBEANSERVER_NAME}). + * + * @return A list of MBeanServer objects. + * + * @exception SecurityException if there is a SecurityManager and the + * caller's permissions do not include or imply {@link + * MBeanServerPermission}("findMBeanServer"). + * + * @see #getMBeanServerName(MBeanServer) + * @since 1.7 + */ + public synchronized static + List findMBeanServerByName(String mbeanServerName) { + + checkPermission("findMBeanServer"); + + if (mbeanServerName==null || "*".equals(mbeanServerName)) + return new ArrayList(mBeanServerList); + + // noname=true iff we are looking for MBeanServers for which no name + // were specified. + ArrayList result = new ArrayList(); + for (MBeanServer mbs : mBeanServerList) { + final String name = Util.getMBeanServerSecurityName(mbs); + if (Util.wildmatch(name, mbeanServerName)) result.add(mbs); + } + return result; + } + + /** + * Returns the name of the MBeanServer embedded in the MBeanServerId of + * the given {@code server}. If the given MBeanServerId doesn't contain + * any name, {@value #DEFAULT_MBEANSERVER_NAME} is returned. + * The MBeanServerId is expected to be of the form: + * {@code *[;mbeanServerName=[;*]]} + *
    where {@code *} denotes any sequence of characters, and {@code [ ]} + * indicate optional parts. + *

    + *

    For instance, if an MBeanServer is created using {@link + * #createNamedMBeanServer(java.lang.String, java.lang.String) + * server = + * MBeanServerFactory.createNamedMBeanServer("com.mycompany.myapp.server1", + * null)} then {@code MBeanServerFactory.getMBeanServerName(server)} + * will return {@code "com.mycompany.myapp.server1"} and + * server.getAttribute({@link + * javax.management.MBeanServerDelegate#DELEGATE_NAME + * MBeanServerDelegate.DELEGATE_NAME}, "MBeanServerId") will return + * something like + * {@code "myhost_1213353064145;mbeanServerName=com.mycompany.myapp.server1"}. + *

    + *

    See the section about MBean Server names + * above.

    + * @param server A named (or unnamed) MBeanServer. + * @return the name of the MBeanServer if found, or + * {@value #DEFAULT_MBEANSERVER_NAME} if no name is + * present in its MBeanServerId, or "*" if its + * MBeanServerId couldn't be obtained. Returning "*" means that + * only {@link MBeanPermission}s that allow all MBean Server names + * will apply to this MBean Server. + * @see MBeanServerDelegate + * @since 1.7 + */ + public static String getMBeanServerName(MBeanServer server) { + return Util.getMBeanServerSecurityName(server); + } + /** * Return the ClassLoaderRepository used by the given MBeanServer. - * This method is equivalent to {@link MBeanServer#getClassLoaderRepository() server.getClassLoaderRepository()}. + * This method is equivalent to {@link + * MBeanServer#getClassLoaderRepository() server.getClassLoaderRepository()}. * @param server The MBeanServer under examination. Since JMX 1.2, * if server is null, the result is a * {@link NullPointerException}. This behavior differs from what @@ -387,21 +701,23 @@ public class MBeanServerFactory { * **/ public static ClassLoaderRepository getClassLoaderRepository( - MBeanServer server) { + MBeanServer server) { return server.getClassLoaderRepository(); } - private static String mBeanServerName(MBeanServer mbs) { + private static String mBeanServerId(MBeanServer mbs) { try { return (String) mbs.getAttribute(MBeanServerDelegate.DELEGATE_NAME, - "MBeanServerId"); + "MBeanServerId"); } catch (JMException e) { + JmxProperties.MISC_LOGGER.finest( + "Ignoring exception while getting MBeanServerId: "+e); return null; } } private static void checkPermission(String action) - throws SecurityException { + throws SecurityException { SecurityManager sm = System.getSecurityManager(); if (sm != null) { Permission perm = new MBeanServerPermission(action); @@ -425,16 +741,16 @@ public class MBeanServerFactory { } private static final ArrayList mBeanServerList = - new ArrayList(); + new ArrayList(); /** * Load the builder class through the context class loader. * @param builderClassName The name of the builder class. **/ private static Class loadBuilderClass(String builderClassName) - throws ClassNotFoundException { + throws ClassNotFoundException { final ClassLoader loader = - Thread.currentThread().getContextClassLoader(); + Thread.currentThread().getContextClassLoader(); if (loader != null) { // Try with context class loader @@ -453,14 +769,14 @@ public class MBeanServerFactory { **/ private static MBeanServerBuilder newBuilder(Class builderClass) { try { - final Object builder = builderClass.newInstance(); - return (MBeanServerBuilder)builder; + final Object abuilder = builderClass.newInstance(); + return (MBeanServerBuilder)abuilder; } catch (RuntimeException x) { throw x; } catch (Exception x) { final String msg = - "Failed to instantiate a MBeanServerBuilder from " + - builderClass + ": " + x; + "Failed to instantiate a MBeanServerBuilder from " + + builderClass + ": " + x; throw new JMRuntimeException(msg, x); } } @@ -472,7 +788,7 @@ public class MBeanServerFactory { private static synchronized void checkMBeanServerBuilder() { try { GetPropertyAction act = - new GetPropertyAction(JMX_INITIAL_BUILDER); + new GetPropertyAction(JMX_INITIAL_BUILDER); String builderClassName = AccessController.doPrivileged(act); try { @@ -493,8 +809,8 @@ public class MBeanServerFactory { builder = newBuilder(newBuilderClass); } catch (ClassNotFoundException x) { final String msg = - "Failed to load MBeanServerBuilder class " + - builderClassName + ": " + x; + "Failed to load MBeanServerBuilder class " + + builderClassName + ": " + x; throw new JMRuntimeException(msg, x); } } catch (RuntimeException x) { diff --git a/jdk/src/share/classes/javax/management/MBeanServerNotification.java b/jdk/src/share/classes/javax/management/MBeanServerNotification.java index 25f125df0f7..723d2d4c1e6 100644 --- a/jdk/src/share/classes/javax/management/MBeanServerNotification.java +++ b/jdk/src/share/classes/javax/management/MBeanServerNotification.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,56 +38,64 @@ package javax.management; * * @since 1.5 */ - public class MBeanServerNotification extends Notification { +public class MBeanServerNotification extends Notification { - /* Serial version */ - private static final long serialVersionUID = 2876477500475969677L; + /* Serial version */ + private static final long serialVersionUID = 2876477500475969677L; + /** + * Notification type denoting that an MBean has been registered. + * Value is "JMX.mbean.registered". + */ + public static final String REGISTRATION_NOTIFICATION = + "JMX.mbean.registered"; + /** + * Notification type denoting that an MBean has been unregistered. + * Value is "JMX.mbean.unregistered". + */ + public static final String UNREGISTRATION_NOTIFICATION = + "JMX.mbean.unregistered"; + /** + * @serial The object names of the MBeans concerned by this notification + */ + private final ObjectName objectName; - /** - * Notification type denoting that an MBean has been registered. Value is "JMX.mbean.registered". - */ - public static final String REGISTRATION_NOTIFICATION = "JMX.mbean.registered" ; + /** + * Creates an MBeanServerNotification object specifying object names of + * the MBeans that caused the notification and the specified notification + * type. + * + * @param type A string denoting the type of the + * notification. Set it to one these values: {@link + * #REGISTRATION_NOTIFICATION}, {@link + * #UNREGISTRATION_NOTIFICATION}. + * @param source The MBeanServerNotification object responsible + * for forwarding MBean server notification. + * @param sequenceNumber A sequence number that can be used to order + * received notifications. + * @param objectName The object name of the MBean that caused the + * notification. + * + */ + public MBeanServerNotification(String type, Object source, + long sequenceNumber, ObjectName objectName) { + super(type, source, sequenceNumber); + this.objectName = objectName; + } - /** - * Notification type denoting that an MBean has been unregistered. Value is "JMX.mbean.unregistered". - */ - public static final String UNREGISTRATION_NOTIFICATION = "JMX.mbean.unregistered" ; + /** + * Returns the object name of the MBean that caused the notification. + * + * @return the object name of the MBean that caused the notification. + */ + public ObjectName getMBeanName() { + return objectName; + } + @Override + public String toString() { + return super.toString() + "[mbeanName=" + objectName + "]"; - /** - * @serial The object names of the MBeans concerned by this notification - */ - private final ObjectName objectName; - - - /** - * Creates an MBeanServerNotification object specifying object names of - * the MBeans that caused the notification and the specified notification type. - * - * @param type A string denoting the type of the - * notification. Set it to one these values: {@link - * #REGISTRATION_NOTIFICATION}, {@link - * #UNREGISTRATION_NOTIFICATION}. - * @param source The MBeanServerNotification object responsible - * for forwarding MBean server notification. - * @param sequenceNumber A sequence number that can be used to order - * received notifications. - * @param objectName The object name of the MBean that caused the notification. - * - */ - public MBeanServerNotification(String type, Object source, long sequenceNumber, ObjectName objectName ) { - super (type,source,sequenceNumber) ; - this.objectName = objectName ; - } - - /** - * Returns the object name of the MBean that caused the notification. - * - * @return the object name of the MBean that caused the notification. - */ - public ObjectName getMBeanName() { - return objectName ; - } + } } diff --git a/jdk/src/share/classes/javax/management/MXBean.java b/jdk/src/share/classes/javax/management/MXBean.java index a577fd94ff5..f6691ccaeae 100644 --- a/jdk/src/share/classes/javax/management/MXBean.java +++ b/jdk/src/share/classes/javax/management/MXBean.java @@ -33,7 +33,6 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; // remaining imports are for Javadoc -import java.beans.ConstructorProperties; import java.io.InvalidObjectException; import java.lang.management.MemoryUsage; import java.lang.reflect.UndeclaredThrowableException; @@ -470,8 +469,8 @@ public class MemoryPool J, then J cannot be the type of a method parameter or return value in an MXBean interface.

    -

    If there is a way to convert opendata(J) back to - J then we say that J is +

    If there is a way to convert + opendata(J) back to J then we say that J is reconstructible. All method parameters in an MXBean interface must be reconstructible, because when the MXBean framework is invoking a method it will need to convert those @@ -865,7 +864,8 @@ public interface ModuleMXBean { J.

  • Otherwise, if J has at least one public - constructor with a {@link ConstructorProperties} annotation, then one + constructor with a {@link java.beans.ConstructorProperties + ConstructorProperties} annotation, then one of those constructors (not necessarily always the same one) will be called to reconstruct an instance of J. Every such annotation must list as many strings as the @@ -1081,9 +1081,10 @@ public interface Node { MXBean is determined as follows.

      -
    • If an {@link JMX.MBeanOptions} argument is supplied to +

    • If a {@link JMX.MBeanOptions} argument is supplied to the {@link StandardMBean} constructor that makes an MXBean, - or to the {@link JMX#newMXBeanProxy JMX.newMXBeanProxy} + or to the {@link JMX#newMBeanProxy(MBeanServerConnection, + ObjectName, Class, JMX.MBeanOptions) JMX.newMBeanProxy} method, and the {@code MBeanOptions} object defines a non-null {@code MXBeanMappingFactory}, then that is the value of f.

    • diff --git a/jdk/src/share/classes/javax/management/ManagedAttribute.java b/jdk/src/share/classes/javax/management/ManagedAttribute.java index a8a7299d6f9..3b10b77c5dd 100644 --- a/jdk/src/share/classes/javax/management/ManagedAttribute.java +++ b/jdk/src/share/classes/javax/management/ManagedAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/javax/management/ManagedOperation.java b/jdk/src/share/classes/javax/management/ManagedOperation.java index fa01ac2bff6..7f70e447c96 100644 --- a/jdk/src/share/classes/javax/management/ManagedOperation.java +++ b/jdk/src/share/classes/javax/management/ManagedOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/javax/management/NotificationBroadcasterSupport.java b/jdk/src/share/classes/javax/management/NotificationBroadcasterSupport.java index a358a7012a2..33df9606450 100644 --- a/jdk/src/share/classes/javax/management/NotificationBroadcasterSupport.java +++ b/jdk/src/share/classes/javax/management/NotificationBroadcasterSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/javax/management/NotificationInfo.java b/jdk/src/share/classes/javax/management/NotificationInfo.java index a899346c06b..29712c5b2d3 100644 --- a/jdk/src/share/classes/javax/management/NotificationInfo.java +++ b/jdk/src/share/classes/javax/management/NotificationInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/javax/management/NotificationInfos.java b/jdk/src/share/classes/javax/management/NotificationInfos.java index 9d7c497a78d..cc21d06d3a7 100644 --- a/jdk/src/share/classes/javax/management/NotificationInfos.java +++ b/jdk/src/share/classes/javax/management/NotificationInfos.java @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/javax/management/ObjectName.java b/jdk/src/share/classes/javax/management/ObjectName.java index b45e9406e2b..8185edc2742 100644 --- a/jdk/src/share/classes/javax/management/ObjectName.java +++ b/jdk/src/share/classes/javax/management/ObjectName.java @@ -27,6 +27,8 @@ package javax.management; import com.sun.jmx.mbeanserver.GetPropertyAction; import com.sun.jmx.mbeanserver.Util; +import com.sun.jmx.namespace.serial.JMXNamespaceContext; + import java.io.IOException; import java.io.InvalidObjectException; import java.io.ObjectInputStream; @@ -38,9 +40,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; -import javax.management.MBeanServer; -import javax.management.MalformedObjectNameException; -import javax.management.QueryExp; /** *

      Represents the object name of an MBean, or a pattern that can @@ -225,6 +224,17 @@ import javax.management.QueryExp; @SuppressWarnings("serial") // don't complain serialVersionUID not constant public class ObjectName implements Comparable, QueryExp { + /** + * The sequence of characters used to separate name spaces in a name space + * path. + * + * @see javax.management.namespace + * @since 1.7 + **/ + public static final String NAMESPACE_SEPARATOR = "//"; + private static final int NAMESPACE_SEPARATOR_LENGTH = + NAMESPACE_SEPARATOR.length(); + /** * A structure recording property structure and * proposing minimal services @@ -254,16 +264,17 @@ public class ObjectName implements Comparable, QueryExp { /** * Returns a key string for receiver key */ - String getKeyString(String name) { - return name.substring(_key_index, _key_index + _key_length); + String getKeyString(String name, int offset) { + final int start = _key_index+offset; + return name.substring(start, start + _key_length); } /** * Returns a value string for receiver key */ - String getValueString(String name) { - int in_begin = _key_index + _key_length + 1; - int out_end = in_begin + _value_length; + String getValueString(String name, int offset) { + final int in_begin = _key_index + offset + _key_length + 1; + final int out_end = in_begin + _value_length; return name.substring(in_begin, out_end); } } @@ -396,6 +407,45 @@ public class ObjectName implements Comparable, QueryExp { */ private transient boolean _property_value_pattern = false; + private ObjectName(String newDomain, ObjectName aname) + throws MalformedObjectNameException{ + copyToOtherDomain(newDomain,aname); + } + + private void copyToOtherDomain(String domain, ObjectName aname) + throws MalformedObjectNameException { + + // The domain cannot be null + if (domain == null) + throw new NullPointerException("domain cannot be null"); + + // The key property list cannot be null + if (aname == null) + throw new MalformedObjectNameException( + "key property list cannot be empty"); + + // checks domain validity. A side effect of this method is also to + // set the _domain_pattern flag. + if (!isDomain(domain)) + throw new MalformedObjectNameException("Invalid domain: " + domain); + + // init canonicalname + _domain_length = domain.length(); + + _canonicalName = (domain + + aname._canonicalName.substring(aname._domain_length)).intern(); + _kp_array = aname._kp_array; + _ca_array = aname._ca_array; + _propertyList = aname._propertyList; + _property_list_pattern = aname._property_list_pattern; + _property_value_pattern = aname._property_value_pattern; + // TODO remove this hack + // if (toString().endsWith("//javax.management.service:type1=event_client_delegeate_mbean,type2=default")) { + // Thread.currentThread().dumpStack(); + // throw new Error("************************ Gotcha!"); + //} + } + // Instance private fields <======================================= // Private fields <======================================== @@ -417,7 +467,7 @@ public class ObjectName implements Comparable, QueryExp { * is null. */ private void construct(String name) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { // The name cannot be null if (name == null) @@ -438,10 +488,10 @@ public class ObjectName implements Comparable, QueryExp { } // initialize parsing of the string - char[] name_chars = name.toCharArray(); - int len = name_chars.length; - char[] canonical_chars = new char[len]; // canonical form will be same - // length at most + final char[] name_chars = name.toCharArray(); + final int len = name_chars.length; + final char[] canonical_chars = new char[len]; // canonical form will + // be same length at most int cname_index = 0; int index = 0; char c, c1; @@ -640,10 +690,12 @@ public class ObjectName implements Comparable, QueryExp { // we got the key and value part, prepare a property for this if (!value_pattern) { - prop = new Property(key_index, key_length, value_length); + prop = new Property(key_index-_domain_length, + key_length, value_length); } else { _property_value_pattern = true; - prop = new PatternProperty(key_index, key_length, value_length); + prop = new PatternProperty(key_index-_domain_length, + key_length, value_length); } key_name = name.substring(key_index, key_index + key_length); @@ -677,7 +729,7 @@ public class ObjectName implements Comparable, QueryExp { * @exception NullPointerException One of the parameters is null. */ private void construct(String domain, Map props) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { // The domain cannot be null if (domain == null) @@ -728,12 +780,12 @@ public class ObjectName implements Comparable, QueryExp { boolean value_pattern = checkValue(value); sb.append(value); if (!value_pattern) { - prop = new Property(key_index, + prop = new Property(key_index-_domain_length, key.length(), value.length()); } else { _property_value_pattern = true; - prop = new PatternProperty(key_index, + prop = new PatternProperty(key_index-_domain_length, key.length(), value.length()); } @@ -813,9 +865,9 @@ public class ObjectName implements Comparable, QueryExp { prop = _ca_array[i]; // length of prop including '=' char prop_len = prop._key_length + prop._value_length + 1; - System.arraycopy(specified_chars, prop._key_index, + System.arraycopy(specified_chars, prop._key_index+_domain_length, canonical_chars, prop_index, prop_len); - prop.setKeyIndex(prop_index); + prop.setKeyIndex(prop_index-_domain_length); prop_index += prop_len; if (i != last_index) { canonical_chars[prop_index] = ','; @@ -1019,7 +1071,7 @@ public class ObjectName implements Comparable, QueryExp { * Check if the supplied key is a valid key. */ private static void checkKey(String key) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { if (key == null) throw new NullPointerException("Invalid key (null)"); @@ -1034,33 +1086,6 @@ public class ObjectName implements Comparable, QueryExp { k[endKey] + "'"); } - /* - * Tests whether string s is matched by pattern p. - * Supports "?", "*" each of which may be escaped with "\"; - * Not yet supported: internationalization; "\" inside brackets.

      - * Wildcard matching routine by Karl Heuer. Public Domain.

      - */ - private static boolean wildmatch(char[] s, char[] p, int si, int pi) { - char c; - final int slen = s.length; - final int plen = p.length; - - while (pi < plen) { // While still string - c = p[pi++]; - if (c == '?') { - if (++si > slen) return false; - } else if (c == '*') { // Wildcard - if (pi >= plen) return true; - do { - if (wildmatch(s,p,si,pi)) return true; - } while (++si < slen); - return false; - } else { - if (si >= slen || c != s[si++]) return false; - } - } - return (si == slen); - } // Category : Internal utilities <============================== @@ -1160,9 +1185,19 @@ public class ObjectName implements Comparable, QueryExp { // //in.defaultReadObject(); final ObjectInputStream.GetField fields = in.readFields(); + String propListString = + (String)fields.get("propertyListString", ""); + + // 6616825: take care of property patterns + final boolean propPattern = + fields.get("propertyPattern" , false); + if (propPattern) { + propListString = + (propListString.length()==0?"*":(propListString+",*")); + } + cn = (String)fields.get("domain", "default")+ - ":"+ - (String)fields.get("propertyListString", ""); + ":"+ propListString; } else { // Read an object serialized in the new serial form // @@ -1170,15 +1205,43 @@ public class ObjectName implements Comparable, QueryExp { cn = (String)in.readObject(); } + final JMXNamespaceContext ctxt = + JMXNamespaceContext.getDeserializationContext(); try { - construct(cn); + construct(changeContext(ctxt,cn)); } catch (NullPointerException e) { throw new InvalidObjectException(e.toString()); + } catch (IllegalArgumentException e) { + throw new InvalidObjectException(e.toString()); } catch (MalformedObjectNameException e) { throw new InvalidObjectException(e.toString()); } } + private String changeContext(JMXNamespaceContext context, String nameString) { + final String old = context.prefixToRemove; + final String nw = context.prefixToAdd; + final int ol = old.length(); + if (nameString.startsWith(NAMESPACE_SEPARATOR)) return nameString; + if (ol>0) { + if (!nameString.startsWith(old) || + !nameString.startsWith(NAMESPACE_SEPARATOR,ol)) + throw new IllegalArgumentException( + "Serialized ObjectName does not start with " + old + + ": " + nameString); + nameString = nameString.substring(ol+NAMESPACE_SEPARATOR_LENGTH); + } + if (!nw.equals("")) { + nameString = nw + NAMESPACE_SEPARATOR + nameString; + } + // TODO remove this hack + // if (nameString.endsWith("//javax.management.service:type1=event_client_delegeate_mbean,type2=default")) { + // System.err.println("old="+old+", nw="+nw); + // Thread.currentThread().dumpStack(); + // throw new Error("************************ Gotcha!"); + // } + return nameString; + } /** * Serializes an {@link ObjectName} to an {@link ObjectOutputStream}. @@ -1241,15 +1304,22 @@ public class ObjectName implements Comparable, QueryExp { private void writeObject(ObjectOutputStream out) throws IOException { + final JMXNamespaceContext ctxt = + JMXNamespaceContext.getSerializationContext(); + if (compat) { // Serializes this instance in the old serial form // Read CR 6441274 before making any changes to this code ObjectOutputStream.PutField fields = out.putFields(); - fields.put("domain", _canonicalName.substring(0, _domain_length)); + final String domain = + changeContext(ctxt,_canonicalName.substring(0, _domain_length)); + final String cn = + changeContext(ctxt,_canonicalName); + fields.put("domain", domain); fields.put("propertyList", getKeyPropertyList()); fields.put("propertyListString", getKeyPropertyListString()); - fields.put("canonicalName", _canonicalName); + fields.put("canonicalName", cn); fields.put("pattern", (_domain_pattern || _property_list_pattern)); fields.put("propertyPattern", _property_list_pattern); out.writeFields(); @@ -1259,7 +1329,8 @@ public class ObjectName implements Comparable, QueryExp { // Serializes this instance in the new serial form // out.defaultWriteObject(); - out.writeObject(getSerializedNameString()); + + out.writeObject(changeContext(ctxt,getSerializedNameString())); } } @@ -1288,9 +1359,10 @@ public class ObjectName implements Comparable, QueryExp { * @exception NullPointerException The name parameter * is null. * + * @see #valueOf(String) */ public static ObjectName getInstance(String name) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { return new ObjectName(name); } @@ -1315,10 +1387,11 @@ public class ObjectName implements Comparable, QueryExp { * follow the rules for quoting. * @exception NullPointerException One of the parameters is null. * + * @see #valueOf(String, String, String) */ public static ObjectName getInstance(String domain, String key, String value) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { return new ObjectName(domain, key, value); } @@ -1346,10 +1419,11 @@ public class ObjectName implements Comparable, QueryExp { * quoting. * @exception NullPointerException One of the parameters is null. * + * @see #valueOf(String, Hashtable) */ public static ObjectName getInstance(String domain, Hashtable table) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { return new ObjectName(domain, table); } @@ -1382,11 +1456,141 @@ public class ObjectName implements Comparable, QueryExp { * @exception NullPointerException The name is null. * */ - public static ObjectName getInstance(ObjectName name) - throws NullPointerException { + public static ObjectName getInstance(ObjectName name) { if (name.getClass().equals(ObjectName.class)) return name; - return Util.newObjectName(name.getSerializedNameString()); + return valueOf(name.getSerializedNameString()); + } + + /** + *

      Return an instance of ObjectName that can be used anywhere + * an object obtained with {@link #ObjectName(String) new + * ObjectName(name)} can be used. The returned object may be of + * a subclass of ObjectName. Calling this method twice with the + * same parameters may return the same object or two equal but + * not identical objects.

      + * + *

      This method is equivalent to {@link #getInstance(String)} except that + * it does not throw any checked exceptions.

      + * + * @param name A string representation of the object name. + * + * @return an ObjectName corresponding to the given String. + * + * @exception IllegalArgumentException The string passed as a + * parameter does not have the right format. The {@linkplain + * Throwable#getCause() cause} of this exception will be a + * {@link MalformedObjectNameException}. + * @exception NullPointerException The name parameter + * is null. + * + * @since 1.7 + */ + public static ObjectName valueOf(String name) { + try { + return getInstance(name); + } catch (MalformedObjectNameException e) { + throw new IllegalArgumentException(e.getMessage(), e); + // Just plain IllegalArgumentException(e) produces an exception + // message "javax.management.MalformedObjectNameException: ..." + // which is distracting. + } + } + + /** + *

      Return an instance of ObjectName that can be used anywhere + * an object obtained with {@link #ObjectName(String, String, + * String) new ObjectName(domain, key, value)} can be used. The + * returned object may be of a subclass of ObjectName. Calling + * this method twice with the same parameters may return the same + * object or two equal but not identical objects.

      + * + *

      This method is equivalent to {@link #getInstance(String, String, + * String)} except that it does not throw any checked exceptions.

      + * + * @param domain The domain part of the object name. + * @param key The attribute in the key property of the object name. + * @param value The value in the key property of the object name. + * + * @return an ObjectName corresponding to the given domain, + * key, and value. + * + * @exception IllegalArgumentException The + * domain, key, or value + * contains an illegal character, or value does not + * follow the rules for quoting. The {@linkplain + * Throwable#getCause() cause} of this exception will be a + * {@link MalformedObjectNameException}. + * @exception NullPointerException One of the parameters is null. + * + * @since 1.7 + */ + public static ObjectName valueOf(String domain, String key, String value) { + try { + return getInstance(domain, key, value); + } catch (MalformedObjectNameException e) { + throw new IllegalArgumentException(e.getMessage(), e); + } + } + + /** + *

      Return an instance of ObjectName that can be used anywhere + * an object obtained with {@link #ObjectName(String, Hashtable) + * new ObjectName(domain, table)} can be used. The returned + * object may be of a subclass of ObjectName. Calling this method + * twice with the same parameters may return the same object or + * two equal but not identical objects.

      + * + *

      This method is equivalent to {@link #getInstance(String, Hashtable)} + * except that it does not throw any checked exceptions.

      + * + * @param domain The domain part of the object name. + * @param table A hash table containing one or more key + * properties. The key of each entry in the table is the key of a + * key property in the object name. The associated value in the + * table is the associated value in the object name. + * + * @return an ObjectName corresponding to the given domain and + * key mappings. + * + * @exception IllegalArgumentException The domain + * contains an illegal character, or one of the keys or values in + * table contains an illegal character, or one of the + * values in table does not follow the rules for + * quoting. The {@linkplain Throwable#getCause() cause} of this exception + * will be a {@link MalformedObjectNameException}. + * @exception NullPointerException One of the parameters is null. + * + * @since 1.7 + */ + public static ObjectName valueOf(String domain, + Hashtable table) { + try { + return new ObjectName(domain, table); + } catch (MalformedObjectNameException e) { + throw new IllegalArgumentException(e.getMessage(), e); + } + } + + /** + * Returns an {@code ObjectName} that is the same as this one but + * with the specified domain. + * This method preserves the original key order in the new instance. + * If the provided name has a key property pattern, it will also be + * preserved in the returned instance. + * + * @param newDomain The new domain for the returned instance; + * must not be null. + * @return A new {@code ObjectName} that is the same as {@code this} + * except the domain is {@code newDomain}. + * @throws NullPointerException if {@code newDomain} is null. + * @throws MalformedObjectNameException if the new domain is syntactically + * illegal. + * @since 1.7 + **/ + public final ObjectName withDomain(String newDomain) + throws MalformedObjectNameException { + return new ObjectName(newDomain, this); } /** @@ -1398,9 +1602,11 @@ public class ObjectName implements Comparable, QueryExp { * parameter does not have the right format. * @exception NullPointerException The name parameter * is null. + * + * @see #valueOf(String) */ public ObjectName(String name) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { construct(name); } @@ -1416,9 +1622,11 @@ public class ObjectName implements Comparable, QueryExp { * contains an illegal character, or value does not * follow the rules for quoting. * @exception NullPointerException One of the parameters is null. + * + * @see #valueOf(String, String, String) */ public ObjectName(String domain, String key, String value) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { // If key or value are null a NullPointerException // will be thrown by the put method in Hashtable. // @@ -1441,9 +1649,11 @@ public class ObjectName implements Comparable, QueryExp { * values in table does not follow the rules for * quoting. * @exception NullPointerException One of the parameters is null. + * + * @see #valueOf(String, Hashtable) */ public ObjectName(String domain, Hashtable table) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { construct(domain, table); /* The exception for when a key or value in the table is not a String is now ClassCastException rather than @@ -1537,13 +1747,12 @@ public class ObjectName implements Comparable, QueryExp { * * @since 1.6 */ - public boolean isPropertyValuePattern(String property) - throws NullPointerException, IllegalArgumentException { + public boolean isPropertyValuePattern(String property) { if (property == null) throw new NullPointerException("key property can't be null"); for (int i = 0; i < _ca_array.length; i++) { Property prop = _ca_array[i]; - String key = prop.getKeyString(_canonicalName); + String key = prop.getKeyString(_canonicalName,_domain_length); if (key.equals(property)) return (prop instanceof PatternProperty); } @@ -1599,7 +1808,7 @@ public class ObjectName implements Comparable, QueryExp { * * @exception NullPointerException If property is null. */ - public String getKeyProperty(String property) throws NullPointerException { + public String getKeyProperty(String property) { return _getKeyPropertyList().get(property); } @@ -1623,8 +1832,10 @@ public class ObjectName implements Comparable, QueryExp { Property prop; for (int i = len - 1; i >= 0; i--) { prop = _ca_array[i]; - _propertyList.put(prop.getKeyString(_canonicalName), - prop.getValueString(_canonicalName)); + _propertyList.put(prop.getKeyString(_canonicalName, + _domain_length), + prop.getValueString(_canonicalName, + _domain_length)); } } } @@ -1709,7 +1920,8 @@ public class ObjectName implements Comparable, QueryExp { } } - return new String(dest_chars); + final String name = new String(dest_chars); + return name; } /** @@ -1727,7 +1939,7 @@ public class ObjectName implements Comparable, QueryExp { if (_kp_array.length == 0) return offset; final char[] dest_chars = data; - final char[] value = _canonicalName.toCharArray(); + final char[] value = canonicalChars; int index = offset; final int len = _kp_array.length; @@ -1735,7 +1947,7 @@ public class ObjectName implements Comparable, QueryExp { for (int i = 0; i < len; i++) { final Property prop = _kp_array[i]; final int prop_len = prop._key_length + prop._value_length + 1; - System.arraycopy(value, prop._key_index, dest_chars, index, + System.arraycopy(value, prop._key_index+_domain_length, dest_chars, index, prop_len); index += prop_len; if (i < last ) dest_chars[index++] = ','; @@ -1796,6 +2008,7 @@ public class ObjectName implements Comparable, QueryExp { * @return True if object is an ObjectName whose * canonical form is equal to that of this ObjectName. */ + @Override public boolean equals(Object object) { // same object case @@ -1808,7 +2021,7 @@ public class ObjectName implements Comparable, QueryExp { // (because usage of intern()) ObjectName on = (ObjectName) object; String on_string = on._canonicalName; - if (_canonicalName == on_string) return true; + if (_canonicalName == on_string) return true; // ES: OK // Because we are sharing canonical form between object names, // we have finished the comparison at this stage ==> unequal @@ -1819,6 +2032,7 @@ public class ObjectName implements Comparable, QueryExp { * Returns a hash code for this object name. * */ + @Override public int hashCode() { return _canonicalName.hashCode(); } @@ -1853,8 +2067,7 @@ public class ObjectName implements Comparable, QueryExp { * @exception NullPointerException if s is null. * */ - public static String quote(String s) - throws NullPointerException { + public static String quote(String s) { final StringBuilder buf = new StringBuilder("\""); final int len = s.length(); for (int i = 0; i < len; i++) { @@ -1898,8 +2111,7 @@ public class ObjectName implements Comparable, QueryExp { * @exception NullPointerException if q is null. * */ - public static String unquote(String q) - throws IllegalArgumentException, NullPointerException { + public static String unquote(String q) { final StringBuilder buf = new StringBuilder(); final int len = q.length(); if (len < 2 || q.charAt(0) != '"' || q.charAt(len - 1) != '"') @@ -1944,7 +2156,7 @@ public class ObjectName implements Comparable, QueryExp { * * @since 1.6 */ - public static final ObjectName WILDCARD = Util.newObjectName("*:*"); + public static final ObjectName WILDCARD = valueOf("*:*"); // Category : Utilities <=================================== @@ -1967,7 +2179,7 @@ public class ObjectName implements Comparable, QueryExp { * @exception NullPointerException if name is null. * */ - public boolean apply(ObjectName name) throws NullPointerException { + public boolean apply(ObjectName name) { if (name == null) throw new NullPointerException(); @@ -1988,9 +2200,9 @@ public class ObjectName implements Comparable, QueryExp { private final boolean matchDomains(ObjectName name) { if (_domain_pattern) { // wildmatch domains - final char[] dom_pattern = getDomain().toCharArray(); - final char[] dom_string = name.getDomain().toCharArray(); - return wildmatch(dom_string,dom_pattern,0,0); + // This ObjectName is the pattern + // The other ObjectName is the string. + return Util.wildpathmatch(name.getDomain(),getDomain()); } return getDomain().equals(name.getDomain()); } @@ -2016,7 +2228,7 @@ public class ObjectName implements Comparable, QueryExp { // index in receiver // final Property p = props[i]; - final String k = p.getKeyString(cn); + final String k = p.getKeyString(cn,_domain_length); final String v = nameProps.get(k); // Did we find a value for this key ? // @@ -2025,15 +2237,13 @@ public class ObjectName implements Comparable, QueryExp { // if (_property_value_pattern && (p instanceof PatternProperty)) { // wildmatch key property values - final char[] val_pattern = - p.getValueString(cn).toCharArray(); - final char[] val_string = v.toCharArray(); - if (wildmatch(val_string,val_pattern,0,0)) + // p is the property pattern, v is the string + if (Util.wildmatch(v,p.getValueString(cn,_domain_length))) continue; else return false; } - if (v.equals(p.getValueString(cn))) continue; + if (v.equals(p.getValueString(cn,_domain_length))) continue; return false; } return true; @@ -2100,6 +2310,10 @@ public class ObjectName implements Comparable, QueryExp { * @since 1.6 */ public int compareTo(ObjectName name) { + // Quick optimization: + // + if (name == this) return 0; + // (1) Compare domains // int domainValue = this.getDomain().compareTo(name.getDomain()); diff --git a/jdk/src/share/classes/javax/management/QueryNotificationFilter.java b/jdk/src/share/classes/javax/management/QueryNotificationFilter.java index 42451088f2e..7d1990fa2b9 100644 --- a/jdk/src/share/classes/javax/management/QueryNotificationFilter.java +++ b/jdk/src/share/classes/javax/management/QueryNotificationFilter.java @@ -170,7 +170,7 @@ public class QueryNotificationFilter implements NotificationFilter { private static final long serialVersionUID = -8408613922660635231L; private static final ObjectName DEFAULT_NAME = - Util.newObjectName(":type=Notification"); + ObjectName.valueOf(":type=Notification"); private static final QueryExp trueQuery; static { ValueExp zero = Query.value(0); diff --git a/jdk/src/share/classes/javax/management/QueryParser.java b/jdk/src/share/classes/javax/management/QueryParser.java index babf05c7a20..715f42070e1 100644 --- a/jdk/src/share/classes/javax/management/QueryParser.java +++ b/jdk/src/share/classes/javax/management/QueryParser.java @@ -312,7 +312,7 @@ class QueryParser { if (e > 0) ss = s.substring(0, e); ss = ss.replace("0", "").replace(".", ""); - if (!ss.isEmpty()) + if (!ss.equals("")) throw new NumberFormatException("Underflow: " + s); } return d; diff --git a/jdk/src/share/classes/javax/management/SendNotification.java b/jdk/src/share/classes/javax/management/SendNotification.java index e2875d4f121..497b51e6034 100644 --- a/jdk/src/share/classes/javax/management/SendNotification.java +++ b/jdk/src/share/classes/javax/management/SendNotification.java @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/javax/management/StandardEmitterMBean.java b/jdk/src/share/classes/javax/management/StandardEmitterMBean.java index c3faec374eb..da5f991f427 100644 --- a/jdk/src/share/classes/javax/management/StandardEmitterMBean.java +++ b/jdk/src/share/classes/javax/management/StandardEmitterMBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jdk/src/share/classes/javax/management/StringValueExp.java b/jdk/src/share/classes/javax/management/StringValueExp.java index 9f2ed4a3b45..cc092db3818 100644 --- a/jdk/src/share/classes/javax/management/StringValueExp.java +++ b/jdk/src/share/classes/javax/management/StringValueExp.java @@ -85,6 +85,7 @@ public class StringValueExp implements ValueExp { /* There is no need for this method, because if a query is being evaluated a StringValueExp can only appear inside a QueryExp, and that QueryExp will itself have done setMBeanServer. */ + @Deprecated public void setMBeanServer(MBeanServer s) { } /** diff --git a/jdk/src/share/classes/javax/management/event/EventClient.java b/jdk/src/share/classes/javax/management/event/EventClient.java new file mode 100644 index 00000000000..6f5c84eb2cd --- /dev/null +++ b/jdk/src/share/classes/javax/management/event/EventClient.java @@ -0,0 +1,1088 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.event; + +import com.sun.jmx.event.DaemonThreadFactory; +import com.sun.jmx.event.LeaseRenewer; +import com.sun.jmx.event.ReceiverBuffer; +import com.sun.jmx.event.RepeatedSingletonJob; +import com.sun.jmx.namespace.JMXNamespaceUtils; +import com.sun.jmx.mbeanserver.PerThreadGroupPool; +import com.sun.jmx.remote.util.ClassLogger; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.Executor; + +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; +import javax.management.InstanceNotFoundException; +import javax.management.ListenerNotFoundException; +import javax.management.MBeanNotificationInfo; +import javax.management.MBeanServerConnection; +import javax.management.Notification; +import javax.management.NotificationBroadcasterSupport; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.ObjectName; +import javax.management.remote.JMXConnector; +import javax.management.remote.NotificationResult; +import javax.management.remote.TargetedNotification; + +/** + *

      This class is used to manage its notification listeners on the client + * side in the same way as on the MBean server side. This class needs to work + * with an {@link EventClientDelegateMBean} on the server side.

      + * + *

      A user can specify an {@link EventRelay} object to specify how to receive + * notifications forwarded by the {@link EventClientDelegateMBean}. By default, + * the class {@link FetchingEventRelay} is used.

      + * + *

      A user can specify an {@link java.util.concurrent.Executor Executor} + * to distribute notifications to local listeners. If no executor is + * specified, the thread in the {@link EventRelay} which calls {@link + * EventReceiver#receive EventReceiver.receive} will be reused to distribute + * the notifications (in other words, to call the {@link + * NotificationListener#handleNotification handleNotification} method of the + * appropriate listeners). It is useful to make a separate thread do this + * distribution in some cases. For example, if network communication is slow, + * the forwarding thread can concentrate on communication while, locally, + * the distributing thread distributes the received notifications. Another + * usage is to share a thread pool between many clients, for scalability. + * Note, though, that if the {@code Executor} can create more than one thread + * then it is possible that listeners will see notifications in a different + * order from the order in which they were sent.

      + * + *

      An object of this class sends notifications to listeners added with + * {@link #addEventClientListener}. The {@linkplain Notification#getType() + * type} of each such notification is one of {@link #FAILED}, {@link #NONFATAL}, + * or {@link #NOTIFS_LOST}.

      + * + * @since JMX 2.0 + */ +public class EventClient implements EventConsumer, NotificationManager { + + /** + *

      A notification string type used by an {@code EventClient} object + * to inform a listener added by {@link #addEventClientListener} that + * it failed to get notifications from a remote server, and that it is + * possible that no more notifications will be delivered.

      + * + * @see #addEventClientListener + * @see EventReceiver#failed + */ + public static final String FAILED = "jmx.event.service.failed"; + + /** + *

      Reports that an unexpected exception has been received by the {@link + * EventRelay} object but that it is non-fatal. For example, a notification + * received is not serializable or its class is not found.

      + * + * @see #addEventClientListener + * @see EventReceiver#nonFatal + */ + public static final String NONFATAL = "jmx.event.service.nonfatal"; + + /** + *

      A notification string type used by an {@code EventClient} object to + * inform a listener added by {@code #addEventClientListener} that it + * has detected that notifications have been lost. The {@link + * Notification#getUserData() userData} of the notification is a Long which + * is an upper bound on the number of lost notifications that have just + * been detected.

      + * + * @see #addEventClientListener + */ + public static final String NOTIFS_LOST = "jmx.event.service.notifs.lost"; + + /** + * The default lease time, {@value}, in milliseconds. + * + * @see EventClientDelegateMBean#lease + */ + public static final long DEFAULT_LEASE_TIMEOUT = 300000; + + /** + *

      Constructs a default {@code EventClient} object.

      + * + *

      This object creates a {@link FetchingEventRelay} object to + * receive notifications forwarded by the {@link EventClientDelegateMBean}. + * The {@link EventClientDelegateMBean} that it works with is the + * one registered with the {@linkplain EventClientDelegate#OBJECT_NAME + * default ObjectName}. The thread from the {@link FetchingEventRelay} + * object that fetches the notifications is also used to distribute them. + * + * @param conn An {@link MBeanServerConnection} object used to communicate + * with an {@link EventClientDelegateMBean} MBean. + * + * @throws IllegalArgumentException If {@code conn} is null. + * @throws IOException If an I/O error occurs when communicating with the + * {@code EventClientDelegateMBean}. + */ + public EventClient(MBeanServerConnection conn) throws IOException { + this(EventClientDelegate.getProxy(conn)); + } + + /** + * Constructs an {@code EventClient} object with a specified + * {@link EventClientDelegateMBean}. + * + *

      This object creates a {@link FetchingEventRelay} object to receive + * notifications forwarded by the {@link EventClientDelegateMBean}. The + * thread from the {@link FetchingEventRelay} object that fetches the + * notifications is also used to distribute them. + * + * @param delegate An {@link EventClientDelegateMBean} object to work with. + * + * @throws IllegalArgumentException If {@code delegate} is null. + * @throws IOException If an I/O error occurs when communicating with the + * the {@link EventClientDelegateMBean}. + */ + public EventClient(EventClientDelegateMBean delegate) + throws IOException { + this(delegate, null, null, null, DEFAULT_LEASE_TIMEOUT); + } + + /** + * Constructs an {@code EventClient} object with the specified + * {@link EventClientDelegateMBean}, {@link EventRelay} + * object, and distributing thread. + * + * @param delegate An {@link EventClientDelegateMBean} object to work with. + * Usually, this will be a proxy constructed using + * {@link EventClientDelegate#getProxy}. + * @param eventRelay An object used to receive notifications + * forwarded by the {@link EventClientDelegateMBean}. If {@code null}, a + * {@link FetchingEventRelay} object will be used. + * @param distributingExecutor Used to distribute notifications to local + * listeners. If {@code null}, the thread that calls {@link + * EventReceiver#receive EventReceiver.receive} from the {@link EventRelay} + * object is used. + * @param leaseScheduler An object that will be used to schedule the + * periodic {@linkplain EventClientDelegateMBean#lease lease updates}. + * If {@code null}, a default scheduler will be used. + * @param requestedLeaseTime The lease time used to keep this client alive + * in the {@link EventClientDelegateMBean}. A value of zero is equivalent + * to the {@linkplain #DEFAULT_LEASE_TIMEOUT default value}. + * + * @throws IllegalArgumentException If {@code delegate} is null. + * @throws IOException If an I/O error occurs when communicating with the + * {@link EventClientDelegateMBean}. + */ + public EventClient(EventClientDelegateMBean delegate, + EventRelay eventRelay, + Executor distributingExecutor, + ScheduledExecutorService leaseScheduler, + long requestedLeaseTime) + throws IOException { + if (delegate == null) { + throw new IllegalArgumentException("Null EventClientDelegateMBean"); + } + + if (requestedLeaseTime == 0) + requestedLeaseTime = DEFAULT_LEASE_TIMEOUT; + else if (requestedLeaseTime < 0) { + throw new IllegalArgumentException( + "Negative lease time: " + requestedLeaseTime); + } + + eventClientDelegate = delegate; + + if (eventRelay != null) { + this.eventRelay = eventRelay; + } else { + try { + this.eventRelay = new FetchingEventRelay(delegate); + } catch (IOException ioe) { + throw ioe; + } catch (Exception e) { + // impossible? + final IOException ioee = new IOException(e.toString()); + ioee.initCause(e); + throw ioee; + } + } + + if (distributingExecutor == null) + distributingExecutor = callerExecutor; + this.distributingExecutor = distributingExecutor; + this.dispatchingJob = new DispatchingJob(); + + clientId = this.eventRelay.getClientId(); + + this.requestedLeaseTime = requestedLeaseTime; + if (leaseScheduler == null) + leaseScheduler = defaultLeaseScheduler(); + leaseRenewer = new LeaseRenewer(leaseScheduler, renewLease); + + if (logger.traceOn()) { + logger.trace("init", "New EventClient: "+clientId); + } + } + + private static ScheduledExecutorService defaultLeaseScheduler() { + // The default lease scheduler uses a ScheduledThreadPoolExecutor + // with a maximum of 20 threads. This means that if you have many + // EventClient instances and some of them get blocked (because of an + // unresponsive network, for example), then even the instances that + // are connected to responsive servers may have their leases expire. + // XXX check if the above is true and possibly fix. + PerThreadGroupPool.Create create = + new PerThreadGroupPool.Create() { + public ScheduledThreadPoolExecutor createThreadPool(ThreadGroup group) { + ThreadFactory daemonThreadFactory = new DaemonThreadFactory( + "JMX EventClient lease renewer %d"); + ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor( + 20, daemonThreadFactory); + exec.setKeepAliveTime(1, TimeUnit.SECONDS); + exec.allowCoreThreadTimeOut(true); + exec.setRemoveOnCancelPolicy(true); + return exec; + } + }; + return leaseRenewerThreadPool.getThreadPoolExecutor(create); + + } + + /** + *

      Closes this EventClient, removes all listeners and stops receiving + * notifications.

      + * + *

      This method calls {@link + * EventClientDelegateMBean#removeClient(String)} and {@link + * EventRelay#stop}. Both operations occur even if one of them + * throws an {@code IOException}. + * + * @throws IOException if an I/O error occurs when communicating with + * {@link EventClientDelegateMBean}, or if {@link EventRelay#stop} + * throws an {@code IOException}. + */ + public void close() throws IOException { + if (logger.traceOn()) { + logger.trace("close", clientId); + } + + synchronized(listenerInfoMap) { + if (closed) { + return; + } + + closed = true; + listenerInfoMap.clear(); + } + + if (leaseRenewer != null) + leaseRenewer.close(); + + IOException ioe = null; + try { + eventRelay.stop(); + } catch (IOException e) { + ioe = e; + logger.debug("close", "EventRelay.stop", e); + } + + try { + eventClientDelegate.removeClient(clientId); + } catch (Exception e) { + if (e instanceof IOException) + ioe = (IOException) e; + else + ioe = new IOException(e); + logger.debug("close", + "Got exception when removing "+clientId, e); + } + + if (ioe != null) + throw ioe; + } + + /** + *

      Determine if this {@code EventClient} is closed.

      + * + * @return True if the {@code EventClient} is closed. + */ + public boolean closed() { + return closed; + } + + /** + *

      Return the {@link EventRelay} associated with this + * {@code EventClient}.

      + * + * @return The {@link EventRelay} object used. + */ + public EventRelay getEventRelay() { + return eventRelay; + } + + /** + *

      Return the lease time that this {@code EventClient} requests + * on every lease renewal.

      + * + * @return The requested lease time. + * + * @see EventClientDelegateMBean#lease + */ + public long getRequestedLeaseTime() { + return requestedLeaseTime; + } + + /** + * @see javax.management.MBeanServerConnection#addNotificationListener( + * ObjectName, NotificationListener, NotificationFilter, Object). + */ + public void addNotificationListener(ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException, IOException { + if (logger.traceOn()) { + logger.trace("addNotificationListener", ""); + } + + checkState(); + + Integer listenerId; + try { + listenerId = + eventClientDelegate.addListener(clientId, name, filter); + } catch (EventClientNotFoundException ecnfe) { + final IOException ioe = new IOException(); + ioe.initCause(ecnfe); + throw ioe; + } + + synchronized(listenerInfoMap) { + listenerInfoMap.put(listenerId, new ListenerInfo( + name, + listener, + filter, + handback, + false)); + } + + startListening(); + } + + /** + * @see javax.management.MBeanServerConnection#removeNotificationListener( + * ObjectName, NotificationListener). + */ + public void removeNotificationListener(ObjectName name, + NotificationListener listener) + throws InstanceNotFoundException, + ListenerNotFoundException, + IOException { + if (logger.traceOn()) { + logger.trace("removeNotificationListener", ""); + } + checkState(); + + for (Integer id : getListenerInfo(name, listener, false)) { + removeListener(id); + } + } + + /** + * @see javax.management.MBeanServerConnection#removeNotificationListener( + * ObjectName, NotificationListener, NotificationFilter, Object). + */ + public void removeNotificationListener(ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException, + ListenerNotFoundException, + IOException { + if (logger.traceOn()) { + logger.trace("removeNotificationListener", "with all arguments."); + } + checkState(); + final Integer listenerId = + getListenerInfo(name, listener, filter, handback, false); + + removeListener(listenerId); + } + + /** + * @see javax.management.event.EventConsumer#unsubscribe( + * ObjectName, NotificationListener). + */ + public void unsubscribe(ObjectName name, + NotificationListener listener) + throws ListenerNotFoundException, IOException { + if (logger.traceOn()) { + logger.trace("unsubscribe", ""); + } + checkState(); + final Integer listenerId = + getMatchedListenerInfo(name, listener, true); + + synchronized(listenerInfoMap) { + if (listenerInfoMap.remove(listenerId) == null) { + throw new ListenerNotFoundException(); + } + } + + stopListening(); + + try { + eventClientDelegate.removeListenerOrSubscriber(clientId, listenerId); + } catch (InstanceNotFoundException e) { + logger.trace("unsubscribe", "removeSubscriber", e); + } catch (EventClientNotFoundException cnfe) { + logger.trace("unsubscribe", "removeSubscriber", cnfe); + } + } + + /** + * @see javax.management.event.EventConsumer#subscribe( + * ObjectName, NotificationListener, NotificationFilter, Object). + */ + public void subscribe(ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object handback) throws IOException { + if (logger.traceOn()) { + logger.trace("subscribe", ""); + } + + checkState(); + + Integer listenerId; + try { + listenerId = + eventClientDelegate.addSubscriber(clientId, name, filter); + } catch (EventClientNotFoundException ecnfe) { + final IOException ioe = new IOException(); + ioe.initCause(ecnfe); + throw ioe; + } + + synchronized(listenerInfoMap) { + listenerInfoMap.put(listenerId, new ListenerInfo( + name, + listener, + filter, + handback, + true)); + } + + startListening(); + } + + /** + *

      Adds a set of listeners to the remote MBeanServer. This method can + * be used to copy the listeners from one {@code EventClient} to another.

      + * + *

      A listener is represented by a {@link ListenerInfo} object. The listener + * is added by calling {@link #subscribe(ObjectName, + * NotificationListener, NotificationFilter, Object)} if the method + * {@link ListenerInfo#isSubscription() isSubscription} + * returns {@code true}; otherwise it is added by calling + * {@link #addNotificationListener(ObjectName, NotificationListener, + * NotificationFilter, Object)}.

      + * + *

      The method returns the listeners which were added successfully. The + * elements in the returned collection are a subset of the elements in + * {@code infoList}. If all listeners were added successfully, the two + * collections are the same. If no listener was added successfully, the + * returned collection is empty.

      + * + * @param listeners the listeners to add. + * + * @return The listeners that were added successfully. + * + * @throws IOException If an I/O error occurs. + * + * @see #getListeners() + */ + public Collection addListeners(Collection listeners) + throws IOException { + if (logger.traceOn()) { + logger.trace("addListeners", ""); + } + + checkState(); + + if (listeners == null || listeners.isEmpty()) + return Collections.emptySet(); + + final List list = new ArrayList(); + for (ListenerInfo l : listeners) { + try { + if (l.isSubscription()) { + subscribe(l.getObjectName(), + l.getListener(), + l.getFilter(), + l.getHandback()); + } else { + addNotificationListener(l.getObjectName(), + l.getListener(), + l.getFilter(), + l.getHandback()); + } + + list.add(l); + } catch (Exception e) { + if (logger.traceOn()) { + logger.trace("addListeners", "failed to add: "+l, e); + } + } + } + + return list; + } + + /** + * Returns the set of listeners that have been added through + * this {@code EventClient} and not subsequently removed. + * + * @return A collection of listener information. Empty if there are no + * current listeners or if this {@code EventClient} has been {@linkplain + * #close closed}. + * + * @see #addListeners + */ + public Collection getListeners() { + if (logger.traceOn()) { + logger.trace("getListeners", ""); + } + + synchronized(listenerInfoMap) { + return Collections.unmodifiableCollection(listenerInfoMap.values()); + } + } + + /** + * Adds a listener to receive the {@code EventClient} notifications specified in + * {@link #getEventClientNotificationInfo}. + * + * @param listener A listener to receive {@code EventClient} notifications. + * @param filter A filter to select which notifications are to be delivered + * to the listener, or {@code null} if all notifications are to be delivered. + * @param handback An object to be given to the listener along with each + * notification. Can be null. + * @throws NullPointerException If listener is null. + * @see #removeEventClientListener + */ + public void addEventClientListener(NotificationListener listener, + NotificationFilter filter, + Object handback) { + if (logger.traceOn()) { + logger.trace("addEventClientListener", ""); + } + broadcaster.addNotificationListener(listener, filter, handback); + } + + /** + * Removes a listener added to receive {@code EventClient} notifications specified in + * {@link #getEventClientNotificationInfo}. + * + * @param listener A listener to receive {@code EventClient} notifications. + * @throws NullPointerException If listener is null. + * @throws ListenerNotFoundException If the listener is not added to + * this {@code EventClient}. + */ + public void removeEventClientListener(NotificationListener listener) + throws ListenerNotFoundException { + if (logger.traceOn()) { + logger.trace("removeEventClientListener", ""); + } + broadcaster.removeNotificationListener(listener); + } + + /** + *

      Get the types of notification that an {@code EventClient} can send + * to listeners added with {@link #addEventClientListener + * addEventClientListener}.

      + * + * @return Types of notification emitted by this {@code EventClient}. + * + * @see #FAILED + * @see #NONFATAL + * @see #NOTIFS_LOST + */ + public MBeanNotificationInfo[] getEventClientNotificationInfo() { + return myInfo.clone(); + } + + private static boolean match(ListenerInfo li, + ObjectName name, + NotificationListener listener, + boolean subscribed) { + return li.getObjectName().equals(name) && + li.getListener() == listener && + li.isSubscription() == subscribed; + } + + private static boolean match(ListenerInfo li, + ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object handback, + boolean subscribed) { + return li.getObjectName().equals(name) && + li.getFilter() == filter && + li.getListener() == listener && + li.getHandback() == handback && + li.isSubscription() == subscribed; + } + +// --------------------------------------------------- +// private classes +// --------------------------------------------------- + private class DispatchingJob extends RepeatedSingletonJob { + public DispatchingJob() { + super(distributingExecutor); + } + + public boolean isSuspended() { + return closed || buffer.size() == 0; + } + + public void task() { + TargetedNotification[] tns ; + int lost = 0; + + synchronized(buffer) { + tns = buffer.removeNotifs(); + lost = buffer.removeLost(); + } + + if ((tns == null || tns.length == 0) + && lost == 0) { + return; + } + + // forwarding + if (tns != null && tns.length > 0) { + if (logger.traceOn()) { + logger.trace("DispatchingJob-task", + "Forwarding: "+tns.length); + } + for (TargetedNotification tn : tns) { + final ListenerInfo li = listenerInfoMap.get(tn.getListenerID()); + try { + li.getListener().handleNotification(tn.getNotification(), + li.getHandback()); + } catch (Exception e) { + logger.fine( + "DispatchingJob.task", "listener got exception", e); + } + } + } + + if (lost > 0) { + if (logger.traceOn()) { + logger.trace("DispatchingJob-task", + "lost: "+lost); + } + final Notification n = new Notification(NOTIFS_LOST, + EventClient.this, + myNotifCounter.getAndIncrement(), + System.currentTimeMillis(), + "Lost notifications."); + n.setUserData(new Long(lost)); + broadcaster.sendNotification(n); + } + } + } + + + private class EventReceiverImpl implements EventReceiver { + public void receive(NotificationResult nr) { + if (logger.traceOn()) { + logger.trace("MyEventReceiver-receive", ""); + } + + synchronized(buffer) { + buffer.addNotifs(nr); + + dispatchingJob.resume(); + } + } + + public void failed(Throwable t) { + if (logger.traceOn()) { + logger.trace("MyEventReceiver-failed", "", t); + } + final Notification n = new Notification(FAILED, + this, + myNotifCounter.getAndIncrement(), + System.currentTimeMillis()); + n.setSource(t); + broadcaster.sendNotification(n); + } + + public void nonFatal(Exception e) { + if (logger.traceOn()) { + logger.trace("MyEventReceiver-nonFatal", "", e); + } + + final Notification n = new Notification(NONFATAL, + this, + myNotifCounter.getAndIncrement(), + System.currentTimeMillis()); + n.setSource(e); + broadcaster.sendNotification(n); + } + } + +// ---------------------------------------------------- +// private class +// ---------------------------------------------------- + + +// ---------------------------------------------------- +// private methods +// ---------------------------------------------------- + private Integer getListenerInfo(ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object handback, + boolean subscribed) throws ListenerNotFoundException { + + synchronized(listenerInfoMap) { + for (Map.Entry entry : + listenerInfoMap.entrySet()) { + ListenerInfo li = entry.getValue(); + if (match(li, name, listener, filter, handback, subscribed)) { + return entry.getKey(); + } + } + } + + throw new ListenerNotFoundException(); + } + + private Integer getMatchedListenerInfo(ObjectName name, + NotificationListener listener, + boolean subscribed) throws ListenerNotFoundException { + + synchronized(listenerInfoMap) { + for (Map.Entry entry : + listenerInfoMap.entrySet()) { + ListenerInfo li = entry.getValue(); + if (li.getObjectName().equals(name) && + li.getListener() == listener && + li.isSubscription() == subscribed) { + return entry.getKey(); + } + } + } + + throw new ListenerNotFoundException(); + } + + private Collection getListenerInfo(ObjectName name, + NotificationListener listener, + boolean subscribed) throws ListenerNotFoundException { + + final ArrayList ids = new ArrayList(); + synchronized(listenerInfoMap) { + for (Map.Entry entry : + listenerInfoMap.entrySet()) { + ListenerInfo li = entry.getValue(); + if (match(li, name, listener, subscribed)) { + ids.add(entry.getKey()); + } + } + } + + if (ids.isEmpty()) { + throw new ListenerNotFoundException(); + } + + return ids; + } + + private void checkState() throws IOException { + synchronized(listenerInfoMap) { + if (closed) { + throw new IOException("Ended!"); + } + } + } + + private void startListening() throws IOException { + synchronized(listenerInfoMap) { + if (!startedListening && listenerInfoMap.size() > 0) { + eventRelay.setEventReceiver(myReceiver); + } + + startedListening = true; + + if (logger.traceOn()) { + logger.trace("startListening", "listening"); + } + } + } + + private void stopListening() throws IOException { + synchronized(listenerInfoMap) { + if (listenerInfoMap.size() == 0 && startedListening) { + eventRelay.setEventReceiver(null); + + startedListening = false; + + if (logger.traceOn()) { + logger.trace("stopListening", "non listening"); + } + } + } + } + + private void removeListener(Integer id) + throws InstanceNotFoundException, + ListenerNotFoundException, + IOException { + synchronized(listenerInfoMap) { + if (listenerInfoMap.remove(id) == null) { + throw new ListenerNotFoundException(); + } + + stopListening(); + } + + try { + eventClientDelegate.removeListenerOrSubscriber(clientId, id); + } catch (EventClientNotFoundException cnfe) { + logger.trace("removeListener", "ecd.removeListener", cnfe); + } + } + + +// ---------------------------------------------------- +// private variables +// ---------------------------------------------------- + private static final ClassLogger logger = + new ClassLogger("javax.management.event", "EventClient"); + + private final Executor distributingExecutor; + private final EventClientDelegateMBean eventClientDelegate; + private final EventRelay eventRelay; + private volatile String clientId = null; + private final long requestedLeaseTime; + + private final ReceiverBuffer buffer = new ReceiverBuffer(); + + private final EventReceiverImpl myReceiver = + new EventReceiverImpl(); + private final DispatchingJob dispatchingJob; + + private final HashMap listenerInfoMap = + new HashMap(); + + private volatile boolean closed = false; + + private volatile boolean startedListening = false; + + // Could change synchronization here. But at worst a race will mean + // sequence numbers are not contiguous, which may not matter much. + private final AtomicLong myNotifCounter = new AtomicLong(); + + private final static MBeanNotificationInfo[] myInfo = + new MBeanNotificationInfo[] { + new MBeanNotificationInfo( + new String[] {FAILED, NOTIFS_LOST}, + Notification.class.getName(), "")}; + + private final NotificationBroadcasterSupport broadcaster = + new NotificationBroadcasterSupport(); + + private final static Executor callerExecutor = new Executor() { + // DirectExecutor using caller thread + public void execute(Runnable r) { + r.run(); + } + }; + + private static void checkInit(final MBeanServerConnection conn, + final ObjectName delegateName) + throws IOException { + if (conn == null) { + throw new IllegalArgumentException("No connection specified"); + } + if (delegateName != null && + (!conn.isRegistered(delegateName))) { + throw new IllegalArgumentException( + delegateName + + ": not found"); + } + if (delegateName == null && + (!conn.isRegistered( + EventClientDelegate.OBJECT_NAME))) { + throw new IllegalArgumentException( + EventClientDelegate.OBJECT_NAME + + ": not found"); + } + } + +// ---------------------------------------------------- +// private event lease issues +// ---------------------------------------------------- + private Callable renewLease = new Callable() { + public Long call() throws IOException, EventClientNotFoundException { + return eventClientDelegate.lease(clientId, requestedLeaseTime); + } + }; + + private final LeaseRenewer leaseRenewer; + +// ------------------------------------------------------------------------ + /** + * Constructs an {@code MBeanServerConnection} that uses an {@code EventClient} object, + * if the underlying connection has an {@link EventClientDelegateMBean}. + *

      The {@code EventClient} object creates a default + * {@link FetchingEventRelay} object to + * receive notifications forwarded by the {@link EventClientDelegateMBean}. + * The {@link EventClientDelegateMBean} it works with is the + * default one registered with the ObjectName + * {@link EventClientDelegate#OBJECT_NAME + * OBJECT_NAME}. + * The thread from the {@link FetchingEventRelay} object that fetches the + * notifications is also used to distribute them. + * + * @param conn An {@link MBeanServerConnection} object used to communicate + * with an {@link EventClientDelegateMBean}. + * @throws IllegalArgumentException If the value of {@code conn} is null, + * or the default {@link EventClientDelegateMBean} is not registered. + * @throws IOException If an I/O error occurs. + */ + public static MBeanServerConnection getEventClientConnection( + final MBeanServerConnection conn) + throws IOException { + return getEventClientConnection(conn, null); + } + + /** + * Constructs an MBeanServerConnection that uses an {@code EventClient} + * object with a user-specific {@link EventRelay} + * object. + *

      + * The {@link EventClientDelegateMBean} which it works with is the + * default one registered with the ObjectName + * {@link EventClientDelegate#OBJECT_NAME + * OBJECT_NAME} + * The thread that calls {@link EventReceiver#receive + * EventReceiver.receive} from the {@link EventRelay} object is used + * to distribute notifications to their listeners. + * + * @param conn An {@link MBeanServerConnection} object used to communicate + * with an {@link EventClientDelegateMBean}. + * @param eventRelay A user-specific object used to receive notifications + * forwarded by the {@link EventClientDelegateMBean}. If null, the default + * {@link FetchingEventRelay} object is used. + * @throws IllegalArgumentException If the value of {@code conn} is null, + * or the default {@link EventClientDelegateMBean} is not registered. + * @throws IOException If an I/O error occurs. + */ + public static MBeanServerConnection getEventClientConnection( + final MBeanServerConnection conn, + final EventRelay eventRelay) + throws IOException { + + if (newEventConn == null) { + throw new IllegalArgumentException( + "Class not found: EventClientConnection"); + } + + checkInit(conn,null); + final Callable factory = new Callable() { + final public EventClient call() throws Exception { + EventClientDelegateMBean ecd = EventClientDelegate.getProxy(conn); + return new EventClient(ecd, eventRelay, null, null, + DEFAULT_LEASE_TIMEOUT); + } + }; + + try { + return (MBeanServerConnection)newEventConn.invoke(null, + conn, factory); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } + + private static Method newEventConn = null; + static { + try { + Class c = Class.forName( + "com.sun.jmx.remote.util.EventClientConnection", + false, Thread.currentThread().getContextClassLoader()); + newEventConn = c.getMethod("getEventConnectionFor", + MBeanServerConnection.class, Callable.class); + } catch (Exception e) { + // OK: we're running in a subset of our classes + } + } + + /** + *

      Get the client id of this {@code EventClient} in the + * {@link EventClientDelegateMBean}. + * + * @return the client id. + * + * @see EventClientDelegateMBean#addClient(String, Object[], String[]) + * EventClientDelegateMBean.addClient + */ + public String getClientId() { + return clientId; + } + + /** + * Returns a JMX Connector that will use an {@link EventClient} + * to subscribe for notifications. If the server doesn't have + * an {@link EventClientDelegateMBean}, then the connector will + * use the legacy notification mechanism instead. + * + * @param wrapped The underlying JMX Connector wrapped by the returned + * connector. + * + * @return A JMX Connector that will uses an {@link EventClient}, if + * available. + * + * @see EventClient#getEventClientConnection(MBeanServerConnection) + */ + public static JMXConnector withEventClient(final JMXConnector wrapped) { + return JMXNamespaceUtils.withEventClient(wrapped); + } + + private static final PerThreadGroupPool + leaseRenewerThreadPool = PerThreadGroupPool.make(); +} diff --git a/jdk/src/share/classes/javax/management/event/EventClientDelegate.java b/jdk/src/share/classes/javax/management/event/EventClientDelegate.java new file mode 100644 index 00000000000..8d144123a87 --- /dev/null +++ b/jdk/src/share/classes/javax/management/event/EventClientDelegate.java @@ -0,0 +1,784 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + * @since JMX 2.0 + */ + +package javax.management.event; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Collection; +import java.util.Collections; +import java.util.UUID; + +import javax.management.InstanceNotFoundException; +import javax.management.ListenerNotFoundException; +import javax.management.Notification; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.ObjectName; +import javax.management.remote.NotificationResult; +import com.sun.jmx.event.EventBuffer; +import com.sun.jmx.event.LeaseManager; +import com.sun.jmx.interceptor.SingleMBeanForwarder; +import com.sun.jmx.mbeanserver.Util; +import com.sun.jmx.remote.util.ClassLogger; +import java.lang.ref.WeakReference; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; +import java.security.AccessControlContext; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.PrivilegedExceptionAction; +import java.util.Arrays; +import java.util.Map; +import java.util.Set; +import java.util.WeakHashMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; +import javax.management.DynamicMBean; +import javax.management.MBeanException; +import javax.management.MBeanPermission; +import javax.management.MBeanServer; +import javax.management.MBeanServerConnection; +import javax.management.MBeanServerDelegate; +import javax.management.MBeanServerInvocationHandler; +import javax.management.MBeanServerNotification; +import javax.management.ObjectInstance; +import javax.management.StandardMBean; +import javax.management.remote.MBeanServerForwarder; + +/** + * This is the default implementation of the MBean + * {@link EventClientDelegateMBean}. + */ +public class EventClientDelegate implements EventClientDelegateMBean { + + private EventClientDelegate(MBeanServer server) { + if (server == null) { + throw new NullPointerException("Null MBeanServer."); + } + + if (logger.traceOn()) { + logger.trace("EventClientDelegate", "new one"); + } + mbeanServer = server; + eventSubscriber = EventSubscriber.getEventSubscriber(mbeanServer); + } + + /** + * Returns an {@code EventClientDelegate} instance for the given + * {@code MBeanServer}. Calling this method more than once with the same + * {@code server} argument may return the same object or a different object + * each time. See {@link EventClientDelegateMBean} for an example use of + * this method. + * + * @param server An MBean server instance to work with. + * @return An {@code EventClientDelegate} instance. + * @throws NullPointerException If {@code server} is null. + */ + public static EventClientDelegate getEventClientDelegate(MBeanServer server) { + EventClientDelegate delegate = null; + synchronized(delegateMap) { + final WeakReference wrf = delegateMap.get(server); + delegate = (wrf == null) ? null : (EventClientDelegate)wrf.get(); + + if (delegate == null) { + delegate = new EventClientDelegate(server); + try { + // TODO: this may not work with federated MBean, because + // the delegate will *not* emit notifications for those MBeans. + delegate.mbeanServer.addNotificationListener( + MBeanServerDelegate.DELEGATE_NAME, + delegate.cleanListener, null, null); + } catch (InstanceNotFoundException e) { + logger.fine( + "getEventClientDelegate", + "Could not add MBeanServerDelegate listener", e); + } + delegateMap.put(server, + new WeakReference(delegate)); + } + } + + return delegate; + } + + // Logic for the MBeanServerForwarder that simulates the existence of the + // EventClientDelegate MBean. Things are complicated by the fact that + // there may not be anything in the chain after this forwarder when it is + // created - the connection to a real MBeanServer might only come later. + // Recall that there are two ways of creating a JMXConnectorServer - + // either you specify its MBeanServer when you create it, or you specify + // no MBeanServer and register it in an MBeanServer later. In the latter + // case, the forwarder chain points nowhere until this registration + // happens. Since EventClientDelegate wants to add a listener to the + // MBeanServerDelegate, we can't create an EventClientDelegate until + // there is an MBeanServer. So the forwarder initially has + // a dummy ECD where every method throws an exception, and + // the real ECD is created as soon as doing so does not produce an + // exception. + // TODO: rewrite so that the switch from the dummy to the real ECD happens + // just before we would otherwise have thrown UnsupportedOperationException. + // This is more correct, because it's not guaranteed that we will see the + // moment where the real MBeanServer is attached, if it happens by virtue + // of a setMBeanServer on some other forwarder later in the chain. + + private static class Forwarder extends SingleMBeanForwarder { + + private static class UnsupportedInvocationHandler + implements InvocationHandler { + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable { + throw new UnsupportedOperationException( + "EventClientDelegate unavailable: no MBeanServer, or " + + "MBeanServer inaccessible"); + } + } + + private static DynamicMBean makeUnsupportedECD() { + EventClientDelegateMBean unsupported = (EventClientDelegateMBean) + Proxy.newProxyInstance( + EventClientDelegateMBean.class.getClassLoader(), + new Class[] {EventClientDelegateMBean.class}, + new UnsupportedInvocationHandler()); + return new StandardMBean( + unsupported, EventClientDelegateMBean.class, false); + } + + private volatile boolean madeECD; + + Forwarder() { + super(OBJECT_NAME, makeUnsupportedECD()); + } + + @Override + public synchronized void setMBeanServer(final MBeanServer mbs) { + super.setMBeanServer(mbs); + + if (!madeECD) { + try { + EventClientDelegate ecd = + AccessController.doPrivileged( + new PrivilegedAction() { + public EventClientDelegate run() { + return getEventClientDelegate(Forwarder.this); + } + }); + DynamicMBean mbean = new StandardMBean( + ecd, EventClientDelegateMBean.class, false); + setSingleMBean(mbean); + madeECD = true; + } catch (Exception e) { + // OK: assume no MBeanServer + logger.fine("setMBeanServer", "isRegistered", e); + } + } + } + } + + /** + *

      Create a new {@link MBeanServerForwarder} that simulates the existence + * of an {@code EventClientDelegateMBean} with the {@linkplain + * #OBJECT_NAME default name}. This forwarder intercepts MBean requests + * that are targeted for that MBean and handles them itself. All other + * requests are forwarded to the next element in the forwarder chain.

      + * + * @return a new {@code MBeanServerForwarder} that simulates the existence + * of an {@code EventClientDelegateMBean}. + */ + public static MBeanServerForwarder newForwarder() { + return new Forwarder(); + } + + /** + * Returns a proxy of the default {@code EventClientDelegateMBean}. + * + * @param conn An {@link MBeanServerConnection} to work with. + */ + @SuppressWarnings("cast") // cast for jdk 1.5 + public static EventClientDelegateMBean getProxy(MBeanServerConnection conn) { + return (EventClientDelegateMBean)MBeanServerInvocationHandler. + newProxyInstance(conn, + OBJECT_NAME, + EventClientDelegateMBean.class, + false); + } + + public String addClient(String className, Object[] params, String[] sig) + throws MBeanException { + return addClient(className, null, params, sig, true); + } + + public String addClient(String className, + ObjectName classLoader, + Object[] params, + String[] sig) throws MBeanException { + return addClient(className, classLoader, params, sig, false); + } + + private String addClient(String className, + ObjectName classLoader, + Object[] params, + String[] sig, + boolean classLoaderRepository) throws MBeanException { + try { + return addClientX( + className, classLoader, params, sig, classLoaderRepository); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new MBeanException(e); + } + } + + private String addClientX(String className, + ObjectName classLoader, + Object[] params, + String[] sig, + boolean classLoaderRepository) throws Exception { + if (className == null) { + throw new IllegalArgumentException("Null class name."); + } + + final Object o; + + // The special treatment of standard EventForwarders is so that no + // special permissions are necessary to use them. Otherwise you + // couldn't use EventClient if you didn't have permission to call + // MBeanServer.instantiate. We do require that permission for + // non-standard forwarders, because otherwise you could instantiate + // any class with possibly adverse consequences. We also avoid using + // MBeanInstantiator because it looks up constructors by loading each + // class in the sig array, which means a remote user could cause any + // class to be loaded. That's probably not hugely risky but still. + if (className.startsWith("javax.management.event.")) { + Class c = Class.forName( + className, false, this.getClass().getClassLoader()); + Constructor foundCons = null; + if (sig == null) + sig = new String[0]; + for (Constructor cons : c.getConstructors()) { + Class[] types = cons.getParameterTypes(); + String[] consSig = new String[types.length]; + for (int i = 0; i < types.length; i++) + consSig[i] = types[i].getName(); + if (Arrays.equals(sig, consSig)) { + foundCons = cons; + break; + } + } + if (foundCons == null) { + throw new NoSuchMethodException( + "Constructor for " + className + " with argument types " + + Arrays.toString(sig)); + } + o = foundCons.newInstance(params); + } else if (classLoaderRepository) { + o = mbeanServer.instantiate(className, params, sig); + } else { + o = mbeanServer.instantiate(className, classLoader, params, sig); + } + + if (!(o instanceof EventForwarder)) { + throw new IllegalArgumentException( + className+" is not an EventForwarder class."); + } + + final EventForwarder forwarder = (EventForwarder)o; + final String clientId = UUID.randomUUID().toString(); + ClientInfo clientInfo = new ClientInfo(clientId, forwarder); + + clientInfoMap.put(clientId, clientInfo); + + forwarder.setClientId(clientId); + + if (logger.traceOn()) { + logger.trace("addClient", clientId); + } + + return clientId; + } + + public Integer[] getListenerIds(String clientId) + throws IOException, EventClientNotFoundException { + ClientInfo clientInfo = getClientInfo(clientId); + + if (clientInfo == null) { + throw new EventClientNotFoundException("The client is not found."); + } + + Map listenerInfoMap = clientInfo.listenerInfoMap; + synchronized (listenerInfoMap) { + Set ids = listenerInfoMap.keySet(); + return ids.toArray(new Integer[ids.size()]); + } + } + + /** + * {@inheritDoc} + * + *

      The execution of this method includes a call to + * {@link MBeanServer#addNotificationListener(ObjectName, + * NotificationListener, NotificationFilter, Object)}.

      + */ + public Integer addListener(String clientId, + final ObjectName name, + NotificationFilter filter) + throws EventClientNotFoundException, InstanceNotFoundException { + + if (logger.traceOn()) { + logger.trace("addListener", ""); + } + + return getClientInfo(clientId).addListenerInfo(name, filter); + } + + /** + * {@inheritDoc} + * + *

      The execution of this method can include call to + * {@link MBeanServer#removeNotificationListener(ObjectName, + * NotificationListener, NotificationFilter, Object)}.

      + */ + public void removeListenerOrSubscriber(String clientId, Integer listenerId) + throws InstanceNotFoundException, + ListenerNotFoundException, + EventClientNotFoundException, + IOException { + if (logger.traceOn()) { + logger.trace("removeListener", ""+listenerId); + } + getClientInfo(clientId).removeListenerInfo(listenerId); + } + + /** + * {@inheritDoc} + * + *

      The execution of this method includes a call to + * {@link MBeanServer#addNotificationListener(ObjectName, + * NotificationListener, NotificationFilter, Object)} for + * every MBean matching {@code name}. If {@code name} is + * an {@code ObjectName} pattern, then the execution of this + * method will include a call to {@link MBeanServer#queryNames}.

      + */ + public Integer addSubscriber(String clientId, ObjectName name, + NotificationFilter filter) + throws EventClientNotFoundException, IOException { + if (logger.traceOn()) { + logger.trace("addSubscriber", ""); + } + return getClientInfo(clientId).subscribeListenerInfo(name, filter); + } + + public NotificationResult fetchNotifications(String clientId, + long startSequenceNumber, + int maxNotifs, + long timeout) + throws EventClientNotFoundException { + if (logger.traceOn()) { + logger.trace("fetchNotifications", "for "+clientId); + } + return getClientInfo(clientId).fetchNotifications(startSequenceNumber, + maxNotifs, + timeout); + } + + public void removeClient(String clientId) + throws EventClientNotFoundException { + if (clientId == null) + throw new EventClientNotFoundException("Null clientId"); + if (logger.traceOn()) { + logger.trace("removeClient", clientId); + } + ClientInfo ci = null; + ci = clientInfoMap.remove(clientId); + + if (ci == null) { + throw new EventClientNotFoundException("clientId is "+clientId); + } else { + ci.clean(); + } + } + + public long lease(String clientId, long timeout) + throws IOException, EventClientNotFoundException { + if (logger.traceOn()) { + logger.trace("lease", "for "+clientId); + } + return getClientInfo(clientId).lease(timeout); + } + + // ------------------------------------ + // private classes + // ------------------------------------ + private class ClientInfo { + String clientId; + EventBuffer buffer; + NotificationListener clientListener; + Map listenerInfoMap = + new HashMap(); + + ClientInfo(String clientId, EventForwarder forwarder) { + this.clientId = clientId; + this.forwarder = forwarder; + clientListener = + new ForwardingClientListener(listenerInfoMap, forwarder); + } + + Integer addOrSubscribeListenerInfo( + ObjectName name, NotificationFilter filter, boolean subscribe) + throws InstanceNotFoundException, IOException { + + final Integer listenerId = nextListenerId(); + AddedListener listenerInfo = new AddedListener( + listenerId, filter, name, subscribe); + if (subscribe) { + eventSubscriber.subscribe(name, + clientListener, + filter, + listenerInfo); + } else { + mbeanServer.addNotificationListener(name, + clientListener, + filter, + listenerInfo); + } + + synchronized(listenerInfoMap) { + listenerInfoMap.put(listenerId, listenerInfo); + } + + return listenerId; + } + + Integer addListenerInfo(ObjectName name, + NotificationFilter filter) throws InstanceNotFoundException { + try { + return addOrSubscribeListenerInfo(name, filter, false); + } catch (IOException e) { // can't happen + logger.warning( + "EventClientDelegate.addListenerInfo", + "unexpected exception", e); + throw new RuntimeException(e); + } + } + + Integer subscribeListenerInfo(ObjectName name, + NotificationFilter filter) throws IOException { + try { + return addOrSubscribeListenerInfo(name, filter, true); + } catch (InstanceNotFoundException e) { // can't happen + logger.warning( + "EventClientDelegate.subscribeListenerInfo", + "unexpected exception", e); + throw new RuntimeException(e); + } + } + + private final AtomicInteger nextListenerId = new AtomicInteger(); + + private Integer nextListenerId() { + return nextListenerId.getAndIncrement(); + } + + NotificationResult fetchNotifications(long startSequenceNumber, + int maxNotifs, + long timeout) { + + if (!(forwarder instanceof FetchingEventForwarder)) { + throw new IllegalArgumentException( + "This client is using Event Postal Service!"); + } + + return ((FetchingEventForwarder)forwarder). + fetchNotifications(startSequenceNumber, + maxNotifs, timeout); + } + + void removeListenerInfo(Integer listenerId) + throws InstanceNotFoundException, ListenerNotFoundException, IOException { + AddedListener listenerInfo; + synchronized(listenerInfoMap) { + listenerInfo = listenerInfoMap.remove(listenerId); + } + + if (listenerInfo == null) { + throw new ListenerNotFoundException("The listener is not found."); + } + + if (listenerInfo.subscription) { + eventSubscriber.unsubscribe(listenerInfo.name, + clientListener); + } else { + mbeanServer.removeNotificationListener(listenerInfo.name, + clientListener, + listenerInfo.filter, + listenerInfo); + } + } + + void clean(ObjectName name) { + synchronized(listenerInfoMap) { + for (Map.Entry entry : + listenerInfoMap.entrySet()) { + AddedListener li = entry.getValue(); + if (name.equals(li.name)) { + listenerInfoMap.remove(entry.getKey()); + } + } + } + } + + void clean() { + synchronized(listenerInfoMap) { + for (AddedListener li : listenerInfoMap.values()) { + try { + mbeanServer.removeNotificationListener(li.name, + clientListener); + } catch (Exception e) { + logger.trace("ClientInfo.clean", "removeNL", e); + } + } + listenerInfoMap.clear(); + } + + try { + forwarder.close(); + } catch (Exception e) { + logger.trace( + "ClientInfo.clean", "forwarder.close", e); + } + + if (leaseManager != null) { + leaseManager.stop(); + } + } + + long lease(long timeout) { + return leaseManager.lease(timeout); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (o instanceof ClientInfo && + clientId.equals(((ClientInfo)o).clientId)) { + return true; + } + + return false; + } + + @Override + public int hashCode() { + return clientId.hashCode(); + } + + private EventForwarder forwarder = null; + + private final Runnable leaseExpiryCallback = new Runnable() { + public void run() { + try { + removeClient(clientId); + } catch (Exception e) { + logger.trace( + "ClientInfo.leaseExpiryCallback", "removeClient", e); + } + } + }; + + private LeaseManager leaseManager = new LeaseManager(leaseExpiryCallback); + } + + private class ForwardingClientListener implements NotificationListener { + public ForwardingClientListener(Map listenerInfoMap, + EventForwarder forwarder) { + this.listenerInfoMap = listenerInfoMap; + this.forwarder = forwarder; + } + + public void handleNotification(Notification n, Object o) { + if (n == null || (!(o instanceof AddedListener))) { + if (logger.traceOn()) { + logger.trace("ForwardingClientListener-handleNotification", + "received a unknown notif"); + } + return; + } + + AddedListener li = (AddedListener) o; + + if (checkListenerPermission(li.name,li.acc)) { + try { + forwarder.forward(n, li.listenerId); + } catch (Exception e) { + if (logger.traceOn()) { + logger.trace( + "ForwardingClientListener-handleNotification", + "forwarding failed.", e); + } + } + } + } + + private final Map listenerInfoMap; + private final EventForwarder forwarder; + } + + private class AddedListener { + final int listenerId; + final NotificationFilter filter; + final ObjectName name; + final boolean subscription; + final AccessControlContext acc; + + public AddedListener( + int listenerId, + NotificationFilter filter, + ObjectName name, + boolean subscription) { + this.listenerId = listenerId; + this.filter = filter; + this.name = name; + this.subscription = subscription; + acc = AccessController.getContext(); + } + } + + private class CleanListener implements NotificationListener { + public void handleNotification(Notification notification, + Object handback) { + if (notification instanceof MBeanServerNotification) { + if (MBeanServerNotification.UNREGISTRATION_NOTIFICATION.equals( + notification.getType())) { + final ObjectName name = + ((MBeanServerNotification)notification).getMBeanName(); + + final Collection list = + Collections.unmodifiableCollection(clientInfoMap.values()); + + for (ClientInfo ci : list) { + ci.clean(name); + } + } + + } + } + } + + // ------------------------------------------------- + // private method + // ------------------------------------------------- + private ClientInfo getClientInfo(String clientId) + throws EventClientNotFoundException { + ClientInfo clientInfo = null; + clientInfo = clientInfoMap.get(clientId); + + if (clientInfo == null) { + throw new EventClientNotFoundException("The client is not found."); + } + + return clientInfo; + } + + /** + * Explicitly check the MBeanPermission for + * the current access control context. + */ + private boolean checkListenerPermission(final ObjectName name, + final AccessControlContext acc) { + if (logger.traceOn()) { + logger.trace("checkListenerPermission", ""); + } + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + try { + final String serverName = getMBeanServerName(); + + ObjectInstance oi = (ObjectInstance) + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Object run() + throws InstanceNotFoundException { + return mbeanServer.getObjectInstance(name); + } + }); + + String classname = oi.getClassName(); + MBeanPermission perm = new MBeanPermission( + serverName, + classname, + null, + name, + "addNotificationListener"); + sm.checkPermission(perm, acc); + } catch (Exception e) { + if (logger.debugOn()) { + logger.debug("checkListenerPermission", "refused.", e); + } + return false; + } + } + return true; + } + + private String getMBeanServerName() { + if (mbeanServerName != null) return mbeanServerName; + else return (mbeanServerName = getMBeanServerName(mbeanServer)); + } + + private static String getMBeanServerName(final MBeanServer server) { + final PrivilegedAction action = new PrivilegedAction() { + public String run() { + return Util.getMBeanServerSecurityName(server); + } + }; + return AccessController.doPrivileged(action); + } + + // ------------------------------------ + // private variables + // ------------------------------------ + private final MBeanServer mbeanServer; + private volatile String mbeanServerName = null; + private Map clientInfoMap = + new ConcurrentHashMap(); + + private final CleanListener cleanListener = new CleanListener(); + private final EventSubscriber eventSubscriber; + + private static final ClassLogger logger = + new ClassLogger("javax.management.event", "EventClientDelegate"); + + private static final + Map> delegateMap = + new WeakHashMap>(); +} diff --git a/jdk/src/share/classes/javax/management/event/EventClientDelegateMBean.java b/jdk/src/share/classes/javax/management/event/EventClientDelegateMBean.java new file mode 100644 index 00000000000..a9718a931dc --- /dev/null +++ b/jdk/src/share/classes/javax/management/event/EventClientDelegateMBean.java @@ -0,0 +1,318 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.event; + +import com.sun.jmx.mbeanserver.Util; +import java.io.IOException; +import javax.management.InstanceNotFoundException; +import javax.management.ListenerNotFoundException; +import javax.management.MBeanException; +import javax.management.NotificationFilter; +import javax.management.ObjectName; +import javax.management.remote.NotificationResult; + +/** + *

      This interface specifies necessary methods on the MBean server + * side for a JMX remote client to manage its notification listeners as + * if they are local. + * Users do not usually work directly with this MBean; instead, the {@link + * EventClient} class is designed to be used directly by the user.

      + * + *

      A default implementation of this interface can be added to an MBean + * Server in one of several ways.

      + * + *
        + *
      • The most usual is to insert an {@link + * javax.management.remote.MBeanServerForwarder MBeanServerForwarder} between + * the {@linkplain javax.management.remote.JMXConnectorServer Connector Server} + * and the MBean Server, that will intercept accesses to the Event Client + * Delegate MBean and treat them as the real MBean would. This forwarder is + * inserted by default with the standard RMI Connector Server, and can also + * be created explicitly using {@link EventClientDelegate#newForwarder()}. + * + *

      • A variant on the above is to replace the MBean Server that is + * used locally with a forwarder as described above. Since + * {@code MBeanServerForwarder} extends {@code MBeanServer}, you can use + * a forwarder anywhere you would have used the original MBean Server. The + * code to do this replacement typically looks something like this:

        + * + *
        + * MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();  // or whatever
        + * MBeanServerForwarder mbsf = EventClientDelegate.newForwarder();
        + * mbsf.setMBeanServer(mbs);
        + * mbs = mbsf;
        + * // now use mbs just as you did before, but it will have an EventClientDelegate
        + * 
        + * + *
      • The final way is to create an instance of {@link EventClientDelegate} + * and register it in the MBean Server under the standard {@linkplain + * #OBJECT_NAME name}:

        + * + *
        + * MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();  // or whatever
        + * EventClientDelegate ecd = EventClientDelegate.getEventClientDelegate(mbs);
        + * mbs.registerMBean(ecd, EventClientDelegateMBean.OBJECT_NAME);
        + * 
        + * 
      + * + * @since JMX 2.0 + */ +public interface EventClientDelegateMBean { + /** + * The string representation of {@link #OBJECT_NAME}. + */ + // This shouldn't really be necessary but an apparent javadoc bug + // meant that the {@value} tags didn't work if this was a + // field in EventClientDelegate, even a public field. + public static final String OBJECT_NAME_STRING = + "javax.management.event:type=EventClientDelegate"; + + /** + * The standard ObjectName used to register the default + * EventClientDelegateMBean. The name is + * {@value #OBJECT_NAME_STRING}. + */ + public final static ObjectName OBJECT_NAME = + ObjectName.valueOf(OBJECT_NAME_STRING); + + /** + * A unique listener identifier specified for an EventClient. + * Any notification associated with this id is intended for + * the EventClient which receives the notification, rather than + * a listener added using that EventClient. + */ + public static final int EVENT_CLIENT_LISTENER_ID = -100; + + /** + * Adds a new client to the EventClientDelegateMBean with + * a user-specified + * {@link EventForwarder} to forward notifications to the client. The + * EventForwarder is created by calling + * {@link javax.management.MBeanServer#instantiate(String, Object[], + * String[])}. + * + * @param className The class name used to create an + * {@code EventForwarder}. + * @param params An array containing the parameters of the constructor to + * be invoked. + * @param sig An array containing the signature of the constructor to be + * invoked + * @return A client identifier. + * @exception IOException Reserved for a remote call to throw on the client + * side. + * @exception MBeanException An exception thrown when creating the user + * specified EventForwarder. + */ + public String addClient(String className, Object[] params, String[] sig) + throws IOException, MBeanException; + + /** + * Adds a new client to the EventClientDelegateMBean with + * a user-specified + * {@link EventForwarder} to forward notifications to the client. The + * EventForwarder is created by calling + * {@link javax.management.MBeanServer#instantiate(String, ObjectName, + * Object[], String[])}. A user-specified class loader is used to create + * this EventForwarder. + * + * @param className The class name used to create an + * {@code EventForwarder}. + * @param classLoader An ObjectName registered as a + * ClassLoader MBean. + * @param params An array containing the parameters of the constructor to + * be invoked. + * @param sig An array containing the signature of the constructor to be + * invoked + * @return A client identifier. + * @exception IOException Reserved for a remote call to throw on the client + * side. + * @exception MBeanException An exception thrown when creating the user + * specified EventForwarder. + */ + public String addClient(String className, + ObjectName classLoader, + Object[] params, + String[] sig) throws IOException, MBeanException; + + /** + * Removes an added client. Calling this method will remove all listeners + * added with the client. + * + * @exception EventClientNotFoundException If the {@code clientId} is + * not found. + * @exception IOException Reserved for a remote call to throw on the client + * side. + */ + public void removeClient(String clientID) + throws EventClientNotFoundException, IOException; + + /** + * Returns the identifiers of listeners added or subscribed to with the + * specified client identifier. + *

      If no listener is currently registered with the client, an empty + * array is returned. + * @param clientID The client identifier with which the listeners are + * added or subscribed to. + * @return An array of listener identifiers. + * @exception EventClientNotFoundException If the {@code clientId} is + * not found. + * @exception IOException Reserved for a remote call to throw on the client + * side. + */ + public Integer[] getListenerIds(String clientID) + throws EventClientNotFoundException, IOException; + + /** + * Adds a listener to receive notifications from an MBean and returns + * a non-negative integer as the identifier of the listener. + *

      This method is called by an {@link EventClient} to implement the + * method {@link EventClient#addNotificationListener(ObjectName, + * NotificationListener, NotificationFilter, Object)}. + * + * @param name The name of the MBean onto which the listener should be added. + * @param filter The filter object. If {@code filter} is null, + * no filtering will be performed before handling notifications. + * @param clientId The client identifier with which the listener is added. + * @return A listener identifier. + * @throws EventClientNotFoundException Thrown if the {@code clientId} is + * not found. + * @throws InstanceNotFoundException Thrown if the MBean is not found. + * @throws IOException Reserved for a remote call to throw on the client + * side. + */ + public Integer addListener(String clientId, + ObjectName name, + NotificationFilter filter) + throws InstanceNotFoundException, EventClientNotFoundException, + IOException; + + + /** + *

      Subscribes a listener to receive notifications from an MBean or a + * set of MBeans represented by an {@code ObjectName} pattern. (It is + * not an error if no MBeans match the pattern at the time this method is + * called.)

      + * + *

      Returns a non-negative integer as the identifier of the listener.

      + * + *

      This method is called by an {@link EventClient} to execute its + * method {@link EventClient#subscribe(ObjectName, NotificationListener, + * NotificationFilter, Object)}.

      + * + * @param clientId The remote client's identifier. + * @param name The name of an MBean or an {@code ObjectName} pattern + * representing a set of MBeans to which the listener should listen. + * @param filter The filter object. If {@code filter} is null, no + * filtering will be performed before notifications are handled. + * + * @return A listener identifier. + * + * @throws IllegalArgumentException If the {@code name} or + * {@code listener} is null. + * @throws EventClientNotFoundException If the client ID is not found. + * @throws IOException Reserved for a remote client to throw if + * an I/O error occurs. + * + * @see EventConsumer#subscribe(ObjectName, NotificationListener, + * NotificationFilter,Object) + * @see #removeListenerOrSubscriber(String, Integer) + */ + public Integer addSubscriber(String clientId, ObjectName name, + NotificationFilter filter) + throws EventClientNotFoundException, IOException; + + /** + * Removes a listener, to stop receiving notifications. + *

      This method is called by an {@link EventClient} to execute its + * methods {@link EventClient#removeNotificationListener(ObjectName, + * NotificationListener, NotificationFilter, Object)}, + * {@link EventClient#removeNotificationListener(ObjectName, + * NotificationListener)}, and {@link EventClient#unsubscribe}. + * + * @param clientId The client identifier with which the listener was added. + * @param listenerId The listener identifier to be removed. This must be + * an identifier returned by a previous {@link #addListener addListener} + * or {@link #addSubscriber addSubscriber} call. + * + * @throws InstanceNotFoundException if the MBean on which the listener + * was added no longer exists. + * @throws ListenerNotFoundException if there is no listener with the + * given {@code listenerId}. + * @throws EventClientNotFoundException if the {@code clientId} is + * not found. + * @throws IOException Reserved for a remote call to throw on the client + * side. + */ + public void removeListenerOrSubscriber(String clientId, Integer listenerId) + throws InstanceNotFoundException, ListenerNotFoundException, + EventClientNotFoundException, IOException; + + /** + * Called by a client to fetch notifications that are to be sent to its + * listeners. + * + * @param clientId The client's identifier. + * @param startSequenceNumber The first sequence number to + * consider. + * @param timeout The maximum waiting time. + * @param maxNotifs The maximum number of notifications to return. + * + * @throws EventClientNotFoundException Thrown if the {@code clientId} is + * not found. + * @throws IllegalArgumentException if the client was {@linkplain + * #addClient(String, Object[], String[]) added} with an {@link + * EventForwarder} that is not a {@link FetchingEventForwarder}. + * @throws IOException Reserved for a remote call to throw on the client + * side. + */ + public NotificationResult fetchNotifications(String clientId, + long startSequenceNumber, + int maxNotifs, + long timeout) + throws EventClientNotFoundException, IOException; + + /** + * An {@code EventClient} calls this method to keep its {@code clientId} + * alive in this MBean. The client will be removed if the lease times out. + * + * @param clientId The client's identifier. + * @param timeout The time in milliseconds by which the lease is to be + * extended. The value zero has no special meaning, so it will cause the + * lease to time out immediately. + * + * @return The new lifetime of the lease in milliseconds. This may be + * different from the requested time. + * + * @throws EventClientNotFoundException if the {@code clientId} is + * not found. + * @throws IOException reserved for a remote call to throw on the client + * side. + * @throws IllegalArgumentException if {@code clientId} is null or + * {@code timeout} is negative. + */ + public long lease(String clientId, long timeout) + throws IOException, EventClientNotFoundException; +} diff --git a/jdk/src/share/classes/javax/management/event/EventClientNotFoundException.java b/jdk/src/share/classes/javax/management/event/EventClientNotFoundException.java new file mode 100644 index 00000000000..22f22d7313f --- /dev/null +++ b/jdk/src/share/classes/javax/management/event/EventClientNotFoundException.java @@ -0,0 +1,79 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.event; + +import javax.management.JMException; + +/** + * Thrown if an event client identifier is unknown. + */ +public class EventClientNotFoundException extends JMException { + + /* Serial version */ + private static final long serialVersionUID = -3910667345840643089L; + + /** + *Constructs a {@code ClientNotFoundException} without a detail message. + */ + public EventClientNotFoundException() { + super(); + } + + /** + * Constructs a {@code ClientNotFoundException} with the specified detail message. + * @param message The message. + */ + public EventClientNotFoundException(String message) { + super(message); + } + + /** + * Constructs a {@code ClientNotFoundException} with the specified detail message + * and cause. + * + * @param message The message. + * @param cause The cause (which is saved for later retrieval by the + * {@code Throwable.getCause()} method). A null value is permitted, and indicates + * that the cause is non-existent or unknown. + */ + public EventClientNotFoundException(String message, Throwable cause) { + super(message); + + initCause(cause); + } + + /** + * Constructs a new exception with the specified cause. + * @param cause The cause (which is saved for later retrieval by the + * {@code Throwable.getCause()} method). A null value is permitted, and indicates + * that the cause is non-existent or unknown. + */ + public EventClientNotFoundException(Throwable cause) { + super(); + + initCause(cause); + } +} diff --git a/jdk/src/share/classes/javax/management/event/EventConsumer.java b/jdk/src/share/classes/javax/management/event/EventConsumer.java new file mode 100644 index 00000000000..c2617764e86 --- /dev/null +++ b/jdk/src/share/classes/javax/management/event/EventConsumer.java @@ -0,0 +1,98 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.event; + +import java.io.IOException; +import javax.management.ListenerNotFoundException; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.ObjectName; + +/** + * This interface specifies methods to subscribe a listener to receive events + * from an MBean or a set of MBeans. The MBeans can already be registered in + * an MBean server, or they can be pending registration, or they can be MBeans + * that will never be registered, or they can be MBeans that will be registered + * then unregistered. + * @since JMX 2.0 + */ +public interface EventConsumer { + /** + *

      Subscribes a listener to receive events from an MBean or a set + * of MBeans represented by an {@code ObjectName} pattern.

      + * + *

      An event emitted by an MBean is forwarded to every listener that was + * subscribed with the name of that MBean, or with a pattern that matches + * that name.

      + * + * @param name The name of an MBean or an {@code ObjectName} pattern + * representing a set of MBeans to which the listener should listen. + * @param listener The listener object that will handle the + * notifications emitted by the MBeans. + * @param filter The filter object. If {@code filter} is null, no + * filtering will be performed before notification handling. + * @param handback The context to be sent to the listener when a + * notification is emitted. + * + * @throws IllegalArgumentException If the {@code name} or + * {@code listener} is null. + * @throws IOException for a remote client, thrown if + * an I/O error occurs. + * @see #unsubscribe(ObjectName, NotificationListener) + */ + public void subscribe(ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object handback) + throws IOException; + + /** + *

      Unsubscribes a listener which is listening to an MBean or a set of + * MBeans represented by an {@code ObjectName} pattern.

      + * + *

      The listener to be removed must have been added by the {@link + * #subscribe subscribe} method with the given {@code name}. If the {@code + * name} is a pattern, then the {@code subscribe} must have used the same + * pattern. If the same listener has been subscribed more than once to the + * {@code name}, perhaps with different filters or handbacks, then all such + * listeners are removed.

      + * + * @param name The name of the MBean or an {@code ObjectName} pattern + * representing a set of MBeans to which the listener was subscribed. + * @param listener A listener that was previously subscribed to the + * MBean(s). + * + * @throws ListenerNotFoundException The given {@code listener} was not + * subscribed to the given {@code name}. + * @throws IOException for a remote client, thrown if + * an I/O error occurs. + * + * @see #subscribe + */ + public void unsubscribe(ObjectName name, + NotificationListener listener) + throws ListenerNotFoundException, IOException; +} diff --git a/jdk/src/share/classes/javax/management/event/EventForwarder.java b/jdk/src/share/classes/javax/management/event/EventForwarder.java new file mode 100644 index 00000000000..3dff0a7bcf1 --- /dev/null +++ b/jdk/src/share/classes/javax/management/event/EventForwarder.java @@ -0,0 +1,63 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.event; + +import java.io.IOException; +import javax.management.Notification; + +/** + * This interface can be used to specify a custom forwarding mechanism for + * {@code EventClientDelegateMBean} to forward events to the client. + * + * @see Custom notification + * transports + */ +public interface EventForwarder { + /** + * Forwards a notification. + * @param n The notification to be forwarded to a remote listener. + * @param listenerId The identifier of the listener to receive the notification. + * @throws IOException If it is closed or an I/O error occurs. + */ + public void forward(Notification n, Integer listenerId) + throws IOException; + + /** + * Informs the {@code EventForwarder} to shut down. + *

      After this method is called, any call to the method + * {@link #forward forward(Notification, Integer)} may get an {@code IOException}. + * @throws IOException If an I/O error occurs. + */ + public void close() throws IOException; + + /** + * Sets an event client identifier created by {@link EventClientDelegateMBean}. + *

      This method will be called just after this {@code EventForwarder} + * is constructed and before calling the {@code forward} method to forward any + * notifications. + */ + public void setClientId(String clientId) throws IOException; +} diff --git a/jdk/src/share/classes/javax/management/event/EventReceiver.java b/jdk/src/share/classes/javax/management/event/EventReceiver.java new file mode 100644 index 00000000000..7cdd38b7fb9 --- /dev/null +++ b/jdk/src/share/classes/javax/management/event/EventReceiver.java @@ -0,0 +1,77 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.event; + +import javax.management.remote.NotificationResult; + +/** + * An object implementing this interface is passed by an {@link EventClient} + * to its {@link EventRelay}, to allow the {@code EventRelay} to communicate + * received notifications to the {@code EventClient}. + * + * @see Custom notification + * transports + */ +public interface EventReceiver { + + /** + * This method is implemented by {@code EventClient} as a callback to + * receive notifications from {@code EventRelay}. + *

      The notifications are included in an object specified by the class + * {@link NotificationResult}. In + * addition to a set of notifications, the class object also contains two values: + * {@code earliestSequenceNumber} and {@code nextSequenceNumber}. + * These two values determine whether any notifications have been lost. + * The {@code nextSequenceNumber} value of the last time is compared + * to the received value {@code earliestSequenceNumber}. If the + * received {@code earliesSequenceNumber} is greater, than the difference + * signifies the number of lost notifications. A sender should + * ensure the sequence of notifications sent, meaning that the value + * {@code earliestSequenceNumber} of the next return should be always equal to + * or greater than the value {@code nextSequenceNumber} of the last return. + * + * @param nr the received notifications and sequence numbers. + */ + public void receive(NotificationResult nr); + + /** + * Allows the {@link EventRelay} to report when it receives an unexpected + * exception, which may be fatal and which may make it stop receiving + * notifications. + * + * @param t The unexpected exception received while {@link EventRelay} was running. + */ + public void failed(Throwable t); + + /** + * Allows the {@link EventRelay} to report when it receives an unexpected + * exception that is not fatal. For example, a notification received is not + * serializable or its class is not found. + * + * @param e The unexpected exception received while notifications are being received. + */ + public void nonFatal(Exception e); +} diff --git a/jdk/src/share/classes/javax/management/event/EventRelay.java b/jdk/src/share/classes/javax/management/event/EventRelay.java new file mode 100644 index 00000000000..d723bb04c4e --- /dev/null +++ b/jdk/src/share/classes/javax/management/event/EventRelay.java @@ -0,0 +1,80 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.event; + +import java.io.IOException; +import java.util.concurrent.Executors; // for javadoc +import java.util.concurrent.ScheduledFuture; + +/** + * This interface is used to specify a way to receive + * notifications from a remote MBean server and then to forward the notifications + * to an {@link EventClient}. + * + * @see Custom notification + * transports + */ +public interface EventRelay { + /** + * Returns an identifier that is used by this {@code EventRelay} to identify + * the client when communicating with the {@link EventClientDelegateMBean}. + *

      This identifier is obtained by calling + * {@link EventClientDelegateMBean#addClient(String, Object[], String[]) + * EventClientDelegateMBean.addClient}. + *

      It is the {@code EventRelay} that calls {@code EventClientDelegateMBean} to obtain + * the client identifier because it is the {@code EventRelay} that decides + * how to get notifications from the {@code EventClientDelegateMBean}, + * by creating the appropriate {@link EventForwarder}. + * + * @return A client identifier. + * @throws IOException If an I/O error occurs when communicating with + * the {@code EventClientDelegateMBean}. + */ + public String getClientId() throws IOException; + + /** + * This method is called by {@link EventClient} to register a callback + * to receive notifications from an {@link EventClientDelegateMBean} object. + * A {@code null} value is allowed, which means that the {@code EventClient} suspends + * reception of notifications, so that the {@code EventRelay} can decide to stop receiving + * notifications from its {@code EventForwarder}. + * + * @param eventReceiver An {@link EventClient} callback to receive + * events. + */ + public void setEventReceiver(EventReceiver eventReceiver); + + /** + * Stops receiving and forwarding notifications and performs any necessary + * cleanup. After calling this method, the {@link EventClient} will never + * call any other methods of this object. + * + * @throws IOException If an I/O exception appears. + * + * @see EventClient#close + */ + public void stop() throws IOException; +} diff --git a/jdk/src/share/classes/javax/management/event/EventSubscriber.java b/jdk/src/share/classes/javax/management/event/EventSubscriber.java new file mode 100644 index 00000000000..9948810bfeb --- /dev/null +++ b/jdk/src/share/classes/javax/management/event/EventSubscriber.java @@ -0,0 +1,377 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.event; + +import com.sun.jmx.remote.util.ClassLogger; +import java.io.IOException; +import java.lang.ref.WeakReference; +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.WeakHashMap; +import javax.management.InstanceNotFoundException; +import javax.management.ListenerNotFoundException; +import javax.management.MBeanServer; +import javax.management.MBeanServerConnection; +import javax.management.MBeanServerDelegate; +import javax.management.MBeanServerNotification; +import javax.management.Notification; +import javax.management.NotificationBroadcaster; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.ObjectName; +import javax.management.Query; +import javax.management.QueryEval; +import javax.management.QueryExp; + +/** + *

      An object that can be used to subscribe for notifications from all MBeans + * in an MBeanServer that match a pattern. For example, to listen for + * notifications from all MBeans in the MBeanServer {@code mbs} that match + * {@code com.example:type=Controller,name=*} you could write:

      + * + *
      + * EventSubscriber subscriber = EventSubscriber.getEventSubscriber(mbs);
      + * ObjectName pattern = new ObjectName("com.example:type=Controller,name=*");
      + * NotificationListener myListener = ...;
      + * NotificationFilter myFilter = null;  // or whatever
      + * Object handback = null;              // or whatever
      + * subscriber.subscribe(pattern, myListener, myFilter, myHandback);
      + * 
      + */ +public class EventSubscriber implements EventConsumer { + /** + * Returns an {@code EventSubscriber} object to subscribe for notifications + * from the given {@code MBeanServer}. Calling this method more + * than once with the same parameter may or may not return the same object. + * + * @param mbs the {@code MBeanServer} containing MBeans to be subscribed to. + * @return An {@code EventSubscriber} object. + * + * @throws NullPointerException if mbs is null. + */ + public static EventSubscriber getEventSubscriber(MBeanServer mbs) { + if (mbs == null) + throw new NullPointerException("Null MBeanServer"); + + EventSubscriber eventSubscriber = null; + synchronized (subscriberMap) { + final WeakReference wrf = subscriberMap.get(mbs); + eventSubscriber = (wrf == null) ? null : wrf.get(); + + if (eventSubscriber == null) { + eventSubscriber = new EventSubscriber(mbs); + + subscriberMap.put(mbs, + new WeakReference(eventSubscriber)); + } + } + + return eventSubscriber; + } + + private EventSubscriber(final MBeanServer mbs) { + logger.trace("EventSubscriber", "create a new one"); + this.mbeanServer = mbs; + + Exception x = null; + try { + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Void run() throws Exception { + mbs.addNotificationListener( + MBeanServerDelegate.DELEGATE_NAME, + myMBeanServerListener, null, null); + return null; + } + }); + } catch (PrivilegedActionException ex) { + x = ex.getException(); + } + + // handle possible exceptions. + // + // Fail unless x is null or x is instance of InstanceNotFoundException + // The logic here is that if the MBeanServerDelegate is not present, + // we will assume that the connection will not emit any + // MBeanServerNotifications. + // + if (x != null && !(x instanceof InstanceNotFoundException)) { + if (x instanceof RuntimeException) + throw (RuntimeException) x; + throw new RuntimeException( + "Can't add listener to MBean server delegate: " + x, x); + } + } + + public void subscribe(ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object handback) + throws IOException { + + if (logger.traceOn()) + logger.trace("subscribe", "" + name); + + if (name == null) + throw new IllegalArgumentException("Null MBean name"); + + if (listener == null) + throw new IllegalArgumentException("Null listener"); + + final MyListenerInfo li = new MyListenerInfo(listener, filter, handback); + List list; + + Map> map; + Set names; + if (name.isPattern()) { + map = patternSubscriptionMap; + names = mbeanServer.queryNames(name, notificationBroadcasterExp); + } else { + map = exactSubscriptionMap; + names = Collections.singleton(name); + } + + synchronized (map) { + list = map.get(name); + if (list == null) { + list = new ArrayList(); + map.put(name, list); + } + list.add(li); + } + + for (ObjectName mbeanName : names) { + try { + mbeanServer.addNotificationListener(mbeanName, + listener, + filter, + handback); + } catch (Exception e) { + logger.fine("subscribe", "addNotificationListener", e); + } + } + } + + public void unsubscribe(ObjectName name, + NotificationListener listener) + throws ListenerNotFoundException, IOException { + if (logger.traceOn()) + logger.trace("unsubscribe", "" + name); + + if (name == null) + throw new IllegalArgumentException("Null MBean name"); + + if (listener == null) + throw new ListenerNotFoundException(); + + Map> map; + Set names; + + if (name.isPattern()) { + map = patternSubscriptionMap; + names = mbeanServer.queryNames(name, notificationBroadcasterExp); + } else { + map = exactSubscriptionMap; + names = Collections.singleton(name); + } + + List toRemove = new ArrayList(); + synchronized (map) { + List list = map.get(name); + if (list == null) { + throw new ListenerNotFoundException(); + } + + for (MyListenerInfo info : list) { + if (info.listener == listener) { + toRemove.add(info); + } + } + + if (toRemove.isEmpty()) { + throw new ListenerNotFoundException(); + } + + for (MyListenerInfo info : toRemove) { + list.remove(info); + } + + if (list.isEmpty()) + map.remove(name); + } + + for (ObjectName mbeanName : names) { + for (MyListenerInfo i : toRemove) { + try { + mbeanServer.removeNotificationListener(mbeanName, + i.listener, i.filter, i.handback); + } catch (Exception e) { + logger.fine("unsubscribe", "removeNotificationListener", e); + } + } + } + } + + // --------------------------------- + // private stuff + // --------------------------------- + // used to receive MBeanServerNotification + private NotificationListener myMBeanServerListener = + new NotificationListener() { + public void handleNotification(Notification n, Object hb) { + if (!(n instanceof MBeanServerNotification) || + !MBeanServerNotification. + REGISTRATION_NOTIFICATION.equals(n.getType())) { + return; + } + + final ObjectName name = + ((MBeanServerNotification)n).getMBeanName(); + try { + if (!mbeanServer.isInstanceOf(name, + NotificationBroadcaster.class.getName())) { + return; + } + } catch (Exception e) { + // The only documented exception is InstanceNotFoundException, + // which could conceivably happen if the MBean is unregistered + // immediately after being registered. + logger.fine("myMBeanServerListener.handleNotification", + "isInstanceOf", e); + return; + } + + final List listeners = new ArrayList(); + + // If there are subscribers for the exact name that has just arrived + // then add their listeners to the list. + synchronized (exactSubscriptionMap) { + List exactListeners = exactSubscriptionMap.get(name); + if (exactListeners != null) + listeners.addAll(exactListeners); + } + + // For every subscription pattern that matches the new name, + // add all the listeners for that pattern to "listeners". + synchronized (patternSubscriptionMap) { + for (ObjectName on : patternSubscriptionMap.keySet()) { + if (on.apply(name)) { + listeners.addAll(patternSubscriptionMap.get(on)); + } + } + } + + // Add all the listeners just found to the new MBean. + for (MyListenerInfo li : listeners) { + try { + mbeanServer.addNotificationListener( + name, + li.listener, + li.filter, + li.handback); + } catch (Exception e) { + logger.fine("myMBeanServerListener.handleNotification", + "addNotificationListener", e); + } + } + } + }; + + private static class MyListenerInfo { + public final NotificationListener listener; + public final NotificationFilter filter; + public final Object handback; + + public MyListenerInfo(NotificationListener listener, + NotificationFilter filter, + Object handback) { + + if (listener == null) + throw new IllegalArgumentException("Null listener"); + + this.listener = listener; + this.filter = filter; + this.handback = handback; + } + } + + // --------------------------------- + // private methods + // --------------------------------- + // --------------------------------- + // private variables + // --------------------------------- + private final MBeanServer mbeanServer; + + private final Map> exactSubscriptionMap = + new HashMap>(); + private final Map> patternSubscriptionMap = + new HashMap>(); + + + + // trace issues + private static final ClassLogger logger = + new ClassLogger("javax.management.event", "EventSubscriber"); + + // Compatibility code, so we can run on Tiger: + private static final QueryExp notificationBroadcasterExp; + static { + QueryExp broadcasterExp; + try { + final Method m = Query.class.getMethod("isInstanceOf", + new Class[] {String.class}); + broadcasterExp = (QueryExp)m.invoke(Query.class, + new Object[] {NotificationBroadcaster.class.getName()}); + } catch (Exception e) { + broadcasterExp = new BroadcasterQueryExp(); + } + notificationBroadcasterExp = broadcasterExp; + } + private static class BroadcasterQueryExp extends QueryEval implements QueryExp { + private static final long serialVersionUID = 1234L; + public boolean apply(ObjectName name) { + try { + return getMBeanServer().isInstanceOf( + name, NotificationBroadcaster.class.getName()); + } catch (Exception e) { + return false; + } + } + } + + private static final + Map> subscriberMap = + new WeakHashMap>(); +} diff --git a/jdk/src/share/classes/javax/management/event/FetchingEventForwarder.java b/jdk/src/share/classes/javax/management/event/FetchingEventForwarder.java new file mode 100644 index 00000000000..fd0ae6de3e2 --- /dev/null +++ b/jdk/src/share/classes/javax/management/event/FetchingEventForwarder.java @@ -0,0 +1,151 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.event; + +import com.sun.jmx.event.EventBuffer; +import com.sun.jmx.remote.util.ClassLogger; +import java.io.IOException; +import java.util.List; +import javax.management.Notification; +import javax.management.remote.NotificationResult; +import javax.management.remote.TargetedNotification; + +/** + * This class is used by {@link FetchingEventRelay}. When + * {@link FetchingEventRelay} calls {@link + * EventClientDelegateMBean#addClient(String, Object[], String[])} to get a new + * client identifier, it uses + * this class name as the first argument to ask {@code EventClientDelegateMBean} + * to create an object of this class. + * Then {@code EventClientDelegateMBean} forwards client notifications + * to this object. + * When {@link FetchingEventRelay} calls + * {@link EventClientDelegateMBean#fetchNotifications(String, long, int, long)} + * to fetch notifications, the {@code EventClientDelegateMBean} will forward + * the call to this object. + */ +public class FetchingEventForwarder implements EventForwarder { + + /** + * Construct a new {@code FetchingEventForwarder} with the given + * buffer size. + * @param bufferSize the size of the buffer that will store notifications + * until they have been fetched and acknowledged by the client. + */ + public FetchingEventForwarder(int bufferSize) { + if (logger.traceOn()) { + logger.trace("Constructor", "buffer size is "+bufferSize); + } + + buffer = new EventBuffer(bufferSize); + this.bufferSize = bufferSize; + } + + /** + * Called by an {@link EventClientDelegateMBean} to forward a user call + * {@link EventClientDelegateMBean#fetchNotifications(String, long, int, long)}. + * A call of this method is considered to acknowledge reception of all + * notifications whose sequence numbers are less the + * {@code startSequenceNumber}, so all these notifications can be deleted + * from this object. + * + * @param startSequenceNumber The first sequence number to + * consider. + * @param timeout The maximum waiting time in milliseconds. + * If no notifications have arrived after this period of time, the call + * will return with an empty list of notifications. + * @param maxNotifs The maximum number of notifications to return. + */ + public NotificationResult fetchNotifications(long startSequenceNumber, + int maxNotifs, long timeout) { + if (logger.traceOn()) { + logger.trace("fetchNotifications", + startSequenceNumber+" "+ + maxNotifs+" "+ + timeout); + } + + return buffer.fetchNotifications(startSequenceNumber, + timeout, + maxNotifs); + } + + /** + * {@inheritDoc} + * In this implementation, the notification is stored in the local buffer + * waiting for {@link #fetchNotifications fetchNotifications} to pick + * it up. + */ + public void forward(Notification n, Integer listenerId) throws IOException { + if (logger.traceOn()) { + logger.trace("forward", n+" "+listenerId); + } + + buffer.add(new TargetedNotification(n, listenerId)); + } + + public void close() throws IOException { + if (logger.traceOn()) { + logger.trace("close", ""); + } + + buffer.close(); + } + + public void setClientId(String clientId) throws IOException { + if (logger.traceOn()) { + logger.trace("setClientId", clientId); + } + this.clientId = clientId; + } + + /** + * Sets a user specific list to save notifications in server side + * before forwarding to an FetchingEventRelay in client side. + *

      This method should be called before any notification is + * forwarded to this forwader. + * + * @param list a user specific list to save notifications + */ + protected void setList(List list) { + if (logger.traceOn()) { + logger.trace("setList", ""); + } + + if (clientId == null) { + buffer = new EventBuffer(bufferSize, list); + } else { + throw new IllegalStateException(); + } + } + + private EventBuffer buffer; + private int bufferSize; + private String clientId; + + private static final ClassLogger logger = + new ClassLogger("javax.management.event", "FetchingEventForwarder"); +} diff --git a/jdk/src/share/classes/javax/management/event/FetchingEventRelay.java b/jdk/src/share/classes/javax/management/event/FetchingEventRelay.java new file mode 100644 index 00000000000..2a456ec44c7 --- /dev/null +++ b/jdk/src/share/classes/javax/management/event/FetchingEventRelay.java @@ -0,0 +1,383 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.event; + +import com.sun.jmx.event.DaemonThreadFactory; +import com.sun.jmx.event.RepeatedSingletonJob; +import com.sun.jmx.remote.util.ClassLogger; +import java.io.IOException; +import java.io.NotSerializableException; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import javax.management.MBeanException; +import javax.management.remote.NotificationResult; + +/** + * This class is an implementation of the {@link EventRelay} interface. It calls + * {@link EventClientDelegateMBean#fetchNotifications + * fetchNotifications(String, long, int, long)} to get + * notifications and then forwards them to an {@link EventReceiver} object. + * + * @since JMX 2.0 + */ +public class FetchingEventRelay implements EventRelay { + /** + * The default buffer size: {@value #DEFAULT_BUFFER_SIZE}. + */ + public final static int DEFAULT_BUFFER_SIZE = 1000; + + /** + * The default waiting timeout: {@value #DEFAULT_WAITING_TIMEOUT} + * in millseconds when fetching notifications from + * an {@code EventClientDelegateMBean}. + */ + public final static long DEFAULT_WAITING_TIMEOUT = 60000; + + /** + * The default maximum notifications to fetch every time: + * {@value #DEFAULT_MAX_NOTIFICATIONS}. + */ + public final static int DEFAULT_MAX_NOTIFICATIONS = DEFAULT_BUFFER_SIZE; + + /** + * Constructs a default {@code FetchingEventRelay} object by using the default + * configuration: {@code DEFAULT_BUFFER_SIZE}, {@code DEFAULT_WAITING_TIMEOUT} + * {@code DEFAULT_MAX_NOTIFICATIONS}. A single thread is created + * to do fetching. + * + * @param delegate The {@code EventClientDelegateMBean} to work with. + * @throws IOException If failed to work with the {@code delegate}. + * @throws MBeanException if unable to add a client to the remote + * {@code EventClientDelegateMBean} (see {@link + * EventClientDelegateMBean#addClient(String, Object[], String[]) + * EventClientDelegateMBean.addClient}). + * @throws IllegalArgumentException If {@code delegate} is {@code null}. + */ + public FetchingEventRelay(EventClientDelegateMBean delegate) + throws IOException, MBeanException { + this(delegate, null); + } + + /** + * Constructs a {@code FetchingEventRelay} object by using the default + * configuration: {@code DEFAULT_BUFFER_SIZE}, {@code DEFAULT_WAITING_TIMEOUT} + * {@code DEFAULT_MAX_NOTIFICATIONS}, with a user-specific executor to do + * the fetching. + * + * @param delegate The {@code EventClientDelegateMBean} to work with. + * @param executor Used to do the fetching. A new thread is created if + * {@code null}. + * @throws IOException If failed to work with the {@code delegate}. + * @throws MBeanException if unable to add a client to the remote + * {@code EventClientDelegateMBean} (see {@link + * EventClientDelegateMBean#addClient(String, Object[], String[]) + * EventClientDelegateMBean.addClient}). + * @throws IllegalArgumentException If {@code delegate} is {@code null}. + */ + public FetchingEventRelay(EventClientDelegateMBean delegate, + Executor executor) throws IOException, MBeanException { + this(delegate, + DEFAULT_BUFFER_SIZE, + DEFAULT_WAITING_TIMEOUT, + DEFAULT_MAX_NOTIFICATIONS, + executor); + } + + /** + * Constructs a {@code FetchingEventRelay} object with user-specific + * configuration and executor to fetch notifications via the + * {@link EventClientDelegateMBean}. + * + * @param delegate The {@code EventClientDelegateMBean} to work with. + * @param bufferSize The buffer size for saving notifications in + * {@link EventClientDelegateMBean} before they are fetched. + * @param timeout The waiting time in millseconds when fetching + * notifications from an {@code EventClientDelegateMBean}. + * @param maxNotifs The maximum notifications to fetch every time. + * @param executor Used to do the fetching. A new thread is created if + * {@code null}. + * @throws IOException if failed to communicate with the {@code delegate}. + * @throws MBeanException if unable to add a client to the remote + * {@code EventClientDelegateMBean} (see {@link + * EventClientDelegateMBean#addClient(String, Object[], String[]) + * EventClientDelegateMBean.addClient}). + * @throws IllegalArgumentException If {@code delegate} is {@code null}. + */ + public FetchingEventRelay(EventClientDelegateMBean delegate, + int bufferSize, + long timeout, + int maxNotifs, + Executor executor) throws IOException, MBeanException { + this(delegate, + bufferSize, + timeout, + maxNotifs, + executor, + FetchingEventForwarder.class.getName(), + new Object[] {bufferSize}, + new String[] {int.class.getName()}); + } + + /** + * Constructs a {@code FetchingEventRelay} object with user-specific + * configuration and executor to fetch notifications via the + * {@link EventClientDelegateMBean}. + * + * @param delegate The {@code EventClientDelegateMBean} to work with. + * @param bufferSize The buffer size for saving notifications in + * {@link EventClientDelegateMBean} before they are fetched. + * @param timeout The waiting time in millseconds when fetching + * notifications from an {@code EventClientDelegateMBean}. + * @param maxNotifs The maximum notifications to fetch every time. + * @param executor Used to do the fetching. + * @param forwarderName the class name of a user specific EventForwarder + * to create in server to forward notifications to this object. The class + * should be a subclass of the class {@link FetchingEventForwarder}. + * @param params the parameters passed to create {@code forwarderName} + * @param sig the signature of the {@code params} + * @throws IOException if failed to communicate with the {@code delegate}. + * @throws MBeanException if unable to add a client to the remote + * {@code EventClientDelegateMBean} (see {@link + * EventClientDelegateMBean#addClient(String, Object[], String[]) + * EventClientDelegateMBean.addClient}). + * @throws IllegalArgumentException if {@code bufferSize} or + * {@code maxNotifs} is less than {@code 1} + * @throws NullPointerException if {@code delegate} is {@code null}. + */ + public FetchingEventRelay(EventClientDelegateMBean delegate, + int bufferSize, + long timeout, + int maxNotifs, + Executor executor, + String forwarderName, + Object[] params, + String[] sig) throws IOException, MBeanException { + + if (logger.traceOn()) { + logger.trace("FetchingEventRelay", "delegateMBean "+ + bufferSize+" "+ + timeout+" "+ + maxNotifs+" "+ + executor+" "+ + forwarderName+" "); + } + + if(delegate == null) { + throw new NullPointerException("Null EventClientDelegateMBean!"); + } + + + if (bufferSize<=1) { + throw new IllegalArgumentException( + "The bufferSize cannot be less than 1, no meaning."); + } + + if (maxNotifs<=1) { + throw new IllegalArgumentException( + "The maxNotifs cannot be less than 1, no meaning."); + } + + clientId = delegate.addClient( + forwarderName, + params, + sig); + + this.delegate = delegate; + this.timeout = timeout; + this.maxNotifs = maxNotifs; + + if (executor == null) { + ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(1, + daemonThreadFactory); + stpe.setKeepAliveTime(1, TimeUnit.SECONDS); + stpe.allowCoreThreadTimeOut(true); + executor = stpe; + this.defaultExecutor = stpe; + } else + this.defaultExecutor = null; + this.executor = executor; + + startSequenceNumber = 0; + fetchingJob = new MyJob(); + } + + public synchronized void setEventReceiver(EventReceiver eventReceiver) { + if (logger.traceOn()) { + logger.trace("setEventReceiver", ""+eventReceiver); + } + + EventReceiver old = this.eventReceiver; + this.eventReceiver = eventReceiver; + if (old == null && eventReceiver != null) + fetchingJob.resume(); + } + + public String getClientId() { + return clientId; + } + + public synchronized void stop() { + if (logger.traceOn()) { + logger.trace("stop", ""); + } + if (stopped) { + return; + } + + stopped = true; + clientId = null; + if (defaultExecutor != null) + defaultExecutor.shutdown(); + } + + private class MyJob extends RepeatedSingletonJob { + public MyJob() { + super(executor); + } + + public boolean isSuspended() { + boolean b; + synchronized(FetchingEventRelay.this) { + b = stopped || + (eventReceiver == null) || + (clientId == null); + } + + if (logger.traceOn()) { + logger.trace("-MyJob-isSuspended", ""+b); + } + return b; + } + + public void task() { + logger.trace("MyJob-task", ""); + long fetchTimeout = timeout; + NotificationResult nr = null; + Throwable failedExcep = null; + try { + nr = delegate.fetchNotifications( + clientId, + startSequenceNumber, + maxNotifs, + fetchTimeout); + } catch (Exception e) { + if (isSerialOrClassNotFound(e)) { + try { + nr = fetchOne(); + } catch (Exception ee) { + failedExcep = e; + } + } else { + failedExcep = e; + } + } + + if (failedExcep != null && + !isSuspended()) { + logger.fine("MyJob-task", + "Failed to fetch notification, stopping...", failedExcep); + try { + eventReceiver.failed(failedExcep); + } catch (Exception e) { + logger.trace( + "MyJob-task", "exception from eventReceiver.failed", e); + } + + stop(); + } else if (nr != null) { + try { + eventReceiver.receive(nr); + } catch (RuntimeException e) { + logger.trace( + "MyJob-task", + "exception delivering notifs to EventClient", e); + } finally { + startSequenceNumber = nr.getNextSequenceNumber(); + } + } + } + } + + private NotificationResult fetchOne() throws Exception { + logger.trace("fetchOne", ""); + + while (true) { + try { + // 1 notif to skip possible missing class + return delegate.fetchNotifications( + clientId, + startSequenceNumber, + 1, + timeout); + } catch (Exception e) { + if (isSerialOrClassNotFound(e)) { // skip and continue + if (logger.traceOn()) { + logger.trace("fetchOne", "Ignore", e); + } + eventReceiver.nonFatal(e); + startSequenceNumber++; + } else { + throw e; + } + } + } + } + + static boolean isSerialOrClassNotFound(Exception e) { + Throwable cause = e.getCause(); + + while (cause != null && + !(cause instanceof ClassNotFoundException) && + !(cause instanceof NotSerializableException)) { + cause = cause.getCause(); + } + + return (cause instanceof ClassNotFoundException || + cause instanceof NotSerializableException); + } + + private long startSequenceNumber = 0; + private EventReceiver eventReceiver = null; + private final EventClientDelegateMBean delegate; + private String clientId; + private boolean stopped = false; + + private final Executor executor; + private final ExecutorService defaultExecutor; + private final MyJob fetchingJob; + + private final long timeout; + private final int maxNotifs; + + private static final ClassLogger logger = + new ClassLogger("javax.management.event", + "FetchingEventRelay"); + private static final ThreadFactory daemonThreadFactory = + new DaemonThreadFactory("JMX FetchingEventRelay executor %d"); +} diff --git a/jdk/src/share/classes/javax/management/event/ListenerInfo.java b/jdk/src/share/classes/javax/management/event/ListenerInfo.java new file mode 100644 index 00000000000..9c7a8fc5933 --- /dev/null +++ b/jdk/src/share/classes/javax/management/event/ListenerInfo.java @@ -0,0 +1,169 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.event; + +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.ObjectName; + +/** + * This class specifies all the information required to register a user listener into + * a remote MBean server. This class is not serializable because a user listener + * is not serialized in order to be sent to the remote server. + * + * @since JMX 2.0 + */ +public class ListenerInfo { + + /** + * Constructs a {@code ListenerInfo} object. + * + * @param name The name of the MBean to which the listener should + * be added. + * @param listener The listener object which will handle the + * notifications emitted by the MBean. + * @param filter The filter object. If the filter is null, no + * filtering will be performed before notifications are handled. + * @param handback The context to be sent to the listener when a + * notification is emitted. + * @param isSubscription If true, the listener is subscribed via + * an {@code EventManager}. Otherwise it is added to a registered MBean. + */ + public ListenerInfo(ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object handback, + boolean isSubscription) { + this.name = name; + this.listener = listener; + this.filter = filter; + this.handback = handback; + this.isSubscription = isSubscription; + } + + /** + * Returns an MBean or an MBean pattern that the listener listens to. + * + * @return An MBean or an MBean pattern. + */ + public ObjectName getObjectName() { + return name; + } + + /** + * Returns the listener. + * + * @return The listener. + */ + public NotificationListener getListener() { + return listener; + } + + /** + * Returns the listener filter. + * + * @return The filter. + */ + public NotificationFilter getFilter() { + return filter; + } + + /** + * Returns the listener handback. + * + * @return The handback. + */ + public Object getHandback() { + return handback; + } + + /** + * Returns true if this is a subscription listener. + * + * @return True if this is a subscription listener. + * + * @see EventClient#addListeners + */ + public boolean isSubscription() { + return isSubscription; + } + + /** + *

      Indicates whether some other object is "equal to" this one. + * The return value is true if and only if {@code o} is an instance of + * {@code ListenerInfo} and has equal values for all of its properties.

      + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (!(o instanceof ListenerInfo)) { + return false; + } + + ListenerInfo li = (ListenerInfo)o; + + boolean ret = name.equals(li.name) && + (listener == li.listener) && + (isSubscription == li.isSubscription); + + if (filter != null) { + ret &= filter.equals(li.filter); + } else { + ret &= (li.filter == null); + } + + if (handback != null) { + ret &= handback.equals(li.handback); + } else { + ret &= (li.handback == null); + } + + return ret; + } + + @Override + public int hashCode() { + return name.hashCode() + listener.hashCode(); + } + + @Override + public String toString() { + return name.toString() + "_" + + listener + "_" + + filter + "_" + + handback + "_" + + isSubscription; + } + + private final ObjectName name; + private final NotificationListener listener; + private final NotificationFilter filter; + private final Object handback; + private final boolean isSubscription; +} diff --git a/jdk/src/share/classes/javax/management/event/NotificationManager.java b/jdk/src/share/classes/javax/management/event/NotificationManager.java new file mode 100644 index 00000000000..89edf9ba9d6 --- /dev/null +++ b/jdk/src/share/classes/javax/management/event/NotificationManager.java @@ -0,0 +1,136 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.event; + +import java.io.IOException; +import javax.management.InstanceNotFoundException; +import javax.management.ListenerNotFoundException; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.ObjectName; + +/** + * This interface specifies methods to add and remove notification listeners + * on named MBeans. + */ +public interface NotificationManager { + /** + *

      Adds a listener to a registered MBean. + * Notifications emitted by the MBean will be forwarded + * to the listener. + * + * @param name The name of the MBean on which the listener should + * be added. + * @param listener The listener object which will handle the + * notifications emitted by the registered MBean. + * @param filter The filter object. If filter is null, no + * filtering will be performed before handling notifications. + * @param handback The context to be sent to the listener when a + * notification is emitted. + * + * @exception InstanceNotFoundException The MBean name provided + * does not match any of the registered MBeans. + * @exception IOException A communication problem occurred when + * talking to the MBean server. + * + * @see #removeNotificationListener(ObjectName, NotificationListener) + * @see #removeNotificationListener(ObjectName, NotificationListener, + * NotificationFilter, Object) + */ + public void addNotificationListener(ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException, + IOException; + + /** + *

      Removes a listener from a registered MBean.

      + * + *

      If the listener is registered more than once, perhaps with + * different filters or callbacks, this method will remove all + * those registrations. + * + * @param name The name of the MBean on which the listener should + * be removed. + * @param listener The listener to be removed. + * + * @exception InstanceNotFoundException The MBean name provided + * does not match any of the registered MBeans. + * @exception ListenerNotFoundException The listener is not + * registered in the MBean. + * @exception IOException A communication problem occurred when + * talking to the MBean server. + * + * @see #addNotificationListener(ObjectName, NotificationListener, + * NotificationFilter, Object) + */ + public void removeNotificationListener(ObjectName name, + NotificationListener listener) + throws InstanceNotFoundException, + ListenerNotFoundException, + IOException; + + /** + *

      Removes a listener from a registered MBean.

      + * + *

      The MBean must have a listener that exactly matches the + * given listener, filter, and + * handback parameters. If there is more than one + * such listener, only one is removed.

      + * + *

      The filter and handback parameters + * may be null if and only if they are null in a listener to be + * removed.

      + * + * @param name The name of the MBean on which the listener should + * be removed. + * @param listener The listener to be removed. + * @param filter The filter that was specified when the listener + * was added. + * @param handback The handback that was specified when the + * listener was added. + * + * @exception InstanceNotFoundException The MBean name provided + * does not match any of the registered MBeans. + * @exception ListenerNotFoundException The listener is not + * registered in the MBean, or it is not registered with the given + * filter and handback. + * @exception IOException A communication problem occurred when + * talking to the MBean server. + * + * @see #addNotificationListener(ObjectName, NotificationListener, + * NotificationFilter, Object) + * + */ + public void removeNotificationListener(ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException, + ListenerNotFoundException, + IOException; +} diff --git a/jdk/src/share/classes/javax/management/event/RMIPushEventForwarder.java b/jdk/src/share/classes/javax/management/event/RMIPushEventForwarder.java new file mode 100644 index 00000000000..636f2e57aaa --- /dev/null +++ b/jdk/src/share/classes/javax/management/event/RMIPushEventForwarder.java @@ -0,0 +1,198 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.event; + +import com.sun.jmx.event.DaemonThreadFactory; +import com.sun.jmx.event.RepeatedSingletonJob; +import com.sun.jmx.remote.util.ClassLogger; +import java.rmi.RemoteException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import javax.management.Notification; +import javax.management.remote.NotificationResult; +import javax.management.remote.TargetedNotification; + + +/** + * This class is used by {@link RMIPushEventRelay}. When + * {@link RMIPushEventRelay} calls {@link + * EventClientDelegateMBean#addClient(String, Object[], String[])} to get a new + * client identifier, it uses this class name as the + * first argument to ask {@code EventClientDelegateMBean} to create an object of + * this class. + * Then {@code EventClientDelegateMBean} forwards client notifications + * to this object. This object then continues forwarding the notifications + * to the {@code RMIPushEventRelay}. + */ +public class RMIPushEventForwarder implements EventForwarder { + private static final int DEFAULT_BUFFER_SIZE = 6000; + + /** + * Creates a new instance of {@code RMIPushEventForwarder}. + * + * @param receiver An RMI stub exported to receive notifications + * from this object for its {@link RMIPushEventRelay}. + * + * @param bufferSize The maximum number of notifications to store + * while waiting for the last remote send to complete. + */ + public RMIPushEventForwarder(RMIPushServer receiver, int bufferSize) { + if (logger.traceOn()) { + logger.trace("RMIEventForwarder", "new one"); + } + + if (bufferSize < 0) { + throw new IllegalArgumentException( + "Negative buffer size: " + bufferSize); + } else if (bufferSize == 0) + bufferSize = DEFAULT_BUFFER_SIZE; + + if (receiver == null) { + throw new NullPointerException(); + } + + this.receiver = receiver; + this.buffer = new ArrayBlockingQueue(bufferSize); + } + + public void forward(Notification n, Integer listenerId) { + if (logger.traceOn()) { + logger.trace("forward", "to the listener: "+listenerId); + } + synchronized(sendingJob) { + TargetedNotification tn = new TargetedNotification(n, listenerId); + while (!buffer.offer(tn)) { + buffer.remove(); + passed++; + } + sendingJob.resume(); + } + } + + public void close() { + if (logger.traceOn()) { + logger.trace("close", "called"); + } + + synchronized(sendingJob) { + ended = true; + buffer.clear(); + } + } + + public void setClientId(String clientId) { + if (logger.traceOn()) { + logger.trace("setClientId", clientId); + } + } + + private class SendingJob extends RepeatedSingletonJob { + public SendingJob() { + super(executor); + } + + public boolean isSuspended() { + return ended || buffer.isEmpty(); + } + + public void task() { + final long earliest = passed; + + List tns = + new ArrayList(buffer.size()); + synchronized(sendingJob) { + buffer.drainTo(tns); + passed += tns.size(); + } + + if (logger.traceOn()) { + logger.trace("SendingJob-task", "sending: "+tns.size()); + } + + if (!tns.isEmpty()) { + try { + TargetedNotification[] tnArray = + new TargetedNotification[tns.size()]; + tns.toArray(tnArray); + receiver.receive(new NotificationResult(earliest, passed, tnArray)); + } catch (RemoteException e) { + if (logger.debugOn()) { + logger.debug("SendingJob-task", + "Got exception to forward notifs.", e); + } + + long currentLost = passed - earliest; + if (FetchingEventRelay.isSerialOrClassNotFound(e)) { + // send one by one + long tmpPassed = earliest; + for (TargetedNotification tn : tns) { + try { + receiver.receive(new NotificationResult(earliest, + ++tmpPassed, new TargetedNotification[]{tn})); + } catch (RemoteException ioee) { + logger.trace( + "SendingJob-task", "send to remote", ioee); + // sends nonFatal notifs? + } + } + + currentLost = passed - tmpPassed; + } + + if (currentLost > 0) { // inform of the lost. + try { + receiver.receive(new NotificationResult( + passed, passed, + new TargetedNotification[]{})); + } catch (RemoteException ee) { + logger.trace( + "SendingJob-task", "receiver.receive", ee); + } + } + } + } + } + } + + private long passed = 0; + + private static final ExecutorService executor = + Executors.newCachedThreadPool( + new DaemonThreadFactory("JMX RMIEventForwarder Executor")); + private final SendingJob sendingJob = new SendingJob(); + + private final BlockingQueue buffer; + + private final RMIPushServer receiver; + private boolean ended = false; + + private static final ClassLogger logger = + new ClassLogger("javax.management.event", "RMIEventForwarder"); +} diff --git a/jdk/src/share/classes/javax/management/event/RMIPushEventRelay.java b/jdk/src/share/classes/javax/management/event/RMIPushEventRelay.java new file mode 100644 index 00000000000..1cc55095573 --- /dev/null +++ b/jdk/src/share/classes/javax/management/event/RMIPushEventRelay.java @@ -0,0 +1,161 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.event; + +import com.sun.jmx.remote.util.ClassLogger; +import java.io.IOException; +import java.rmi.NoSuchObjectException; +import java.rmi.RemoteException; +import java.rmi.server.UnicastRemoteObject; +import java.rmi.server.RMIClientSocketFactory; +import java.rmi.server.RMIServerSocketFactory; +import javax.management.MBeanException; +import javax.management.remote.NotificationResult; + +/** + * This class is an implementation of the {@link EventRelay} interface, using + * push mode. It exports an RMI object that {@link RMIPushEventForwarder} uses + * to forward notifications. + * + * @since JMX 2.0 + */ +public class RMIPushEventRelay implements EventRelay { + /** + * Constructs a default {@code RMIPushEventRelay} object + * and exports its {@linkplain RMIPushServer notification + * receiver} on any free port. This constructor is equivalent + * to {@link #RMIPushEventRelay(EventClientDelegateMBean, + * int, RMIClientSocketFactory, RMIServerSocketFactory, int) + * RMIPushEventRelay(delegate, 0, null, null, <default buffer + * size>)}. + * + * @param delegate The {@link EventClientDelegateMBean} proxy to work with. + * @throws IOException if failed to communicate with + * {@link EventClientDelegateMBean}. + * @throws MBeanException if the {@link EventClientDelegateMBean} failed + * to create an {@code EventForwarder} for this object. + */ + public RMIPushEventRelay(EventClientDelegateMBean delegate) + throws IOException, MBeanException { + this(delegate, 0, null, null, 0); + } + + /** + * Constructs a {@code RMIPushEventRelay} object and exports its + * {@linkplain RMIPushServer notification receiver} on a specified port. + * + * @param delegate The {@link EventClientDelegateMBean} proxy to work with. + * @param port The port used to export an RMI object to receive notifications + * from a server. If the port is zero, an anonymous port is used. + * @param csf The client socket factory used to export the RMI object. + * Can be null. + * @param ssf The server socket factory used to export the RMI object. + * Can be null. + * @param bufferSize The number of notifications held on the server + * while waiting for the previous transmission to complete. A value of + * zero means the default buffer size. + * + * @throws IOException if failed to communicate with + * {@link EventClientDelegateMBean}. + * @throws MBeanException if the {@link EventClientDelegateMBean} failed + * to create an {@code EventForwarder} for this object. + * + * @see RMIPushEventForwarder#RMIPushEventForwarder(RMIPushServer, int) + */ + public RMIPushEventRelay(EventClientDelegateMBean delegate, + int port, + RMIClientSocketFactory csf, + RMIServerSocketFactory ssf, + int bufferSize) + throws IOException, MBeanException { + + UnicastRemoteObject.exportObject(exportedReceiver, port, csf, ssf); + + clientId = delegate.addClient( + RMIPushEventForwarder.class.getName(), + new Object[] {exportedReceiver, bufferSize}, + new String[] {RMIPushServer.class.getName(), + int.class.getName()}); + } + + public String getClientId() { + return clientId; + } + + public void setEventReceiver(EventReceiver receiver) { + if (logger.traceOn()) { + logger.trace("setEventReceiver", ""+receiver); + } + synchronized(lock) { + this.receiver = receiver; + } + } + + public void stop() { + if (logger.traceOn()) { + logger.trace("stop", ""); + } + synchronized(lock) { + if (stopped) { + return; + } else { + stopped = true; + } + + if (clientId == null) { + return; + } + + try { + UnicastRemoteObject.unexportObject(exportedReceiver, true); + } catch (NoSuchObjectException nsoe) { + logger.fine("RMIPushEventRelay.stop", "unexport", nsoe); + // OK: we wanted it unexported, and apparently it already is + } + } + } + + private volatile String clientId; + private volatile EventReceiver receiver; + + private RMIPushServer exportedReceiver = new RMIPushServer() { + public void receive(NotificationResult nr) throws RemoteException { + if (logger.traceOn()) { + logger.trace("EventPusherImpl-receive",""); + } + receiver.receive(nr); + // Any exception will be sent back to the client. + } + }; + + private boolean stopped = false; + + private final int[] lock = new int[0]; + + private static final ClassLogger logger = + new ClassLogger("javax.management.event", + "PushEventRelay"); +} diff --git a/jdk/src/share/classes/javax/management/event/RMIPushServer.java b/jdk/src/share/classes/javax/management/event/RMIPushServer.java new file mode 100644 index 00000000000..253498459a1 --- /dev/null +++ b/jdk/src/share/classes/javax/management/event/RMIPushServer.java @@ -0,0 +1,48 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.event; + +import java.rmi.Remote; +import java.rmi.RemoteException; +import javax.management.remote.NotificationResult; + +/** + * The {@link RMIPushEventRelay} exports an RMI object of this class and + * sends a client stub for that object to the associated + * {@link RMIPushEventForwarder} in a remote MBean server. The + * {@code RMIPushEventForwarder} then sends notifications to the + * RMI object. + */ +public interface RMIPushServer extends Remote { + /** + *

      Dispatch the notifications in {@code nr} to the {@link RMIPushEventRelay} + * associated with this object.

      + * @param nr the notification result to dispatch. + * @throws java.rmi.RemoteException if the remote invocation of this method + * failed. + */ + public void receive(NotificationResult nr) throws RemoteException; +} diff --git a/jdk/src/share/classes/javax/management/event/package-info.java b/jdk/src/share/classes/javax/management/event/package-info.java new file mode 100644 index 00000000000..c4c7dbed63d --- /dev/null +++ b/jdk/src/share/classes/javax/management/event/package-info.java @@ -0,0 +1,312 @@ +/** + *

      Defines the Event Service, which provides extended support + * for JMX notifications.

      + * + *

      The Event Service provides greater control over + * notification handling than the default technique using {@link + * javax.management.MBeanServer#addNotificationListener(ObjectName, + * NotificationListener, NotificationFilter, Object) + * MBeanServer.addNotificationListener} or {@link + * javax.management.MBeanServerConnection#addNotificationListener(ObjectName, + * NotificationListener, NotificationFilter, Object) + * MBeanServerConnection.addNotificationListener}.

      + * + *

      Here are some reasons you may want to use the Event Service:

      + * + *
        + *
      • To receive notifications from a set of MBeans defined by an + * ObjectName pattern, such as {@code com.example.config:type=Cache,*}. + * + *
      • When the notification-handling behavior of the connector you are + * using does not match your requirements. For example, with the standard + * RMI connector you can lose notifications if there are very many of them + * in the MBean Server you are connected to, even if you are only listening + * for a small proportion of them. + * + *
      • To change the threading behavior of notification dispatch. + * + *
      • To define a different transport for notifications, for example to + * arrange for them to be delivered through the Java Message Service (JMS). The Event Service comes with + * one alternative transport as standard, a "push-mode" RMI transport. + * + *
      • To handle notifications on behalf of MBeans (often virtual) in a + * namespace. + *
      + * + *

      The Event Service is new in version 2.0 of the JMX API, which is the + * version introduced in version 7 of the Java SE platform. It is not usually + * possible to use the Event Service when connecting remotely to an + * MBean Server that is running an earlier version.

      + * + * + *

      Handling remote notifications with the Event + * Service

      + * + *

      Prior to version 2.0 of the JMX API, every connector + * had to include logic to handle notifications. The standard {@linkplain + * javax.management.remote.rmi RMI} and JMXMP connectors defined by JSR 160 handle notifications + * in a way that is not always appropriate for applications. Specifically, + * the connector server adds one listener to every MBean that might emit + * notifications, and adds all received notifications to a fixed-size + * buffer. This means that if there are very many notifications, a + * remote client may miss some, even if it is only registered for a + * very small subset of notifications. Furthermore, since every {@link + * javax.management.NotificationBroadcaster NotificationBroadcaster} MBean + * gets a listener from the connector server, MBeans cannot usefully optimize + * by only sending notifications when there is a listener. Finally, since + * the connector server uses just one listener per MBean, MBeans cannot + * impose custom behavior per listener, such as security checks or localized + * notifications.

      + * + *

      The Event Service does not have these restrictions. The RMI connector + * that is included in this version of the JMX API uses the Event Service by + * default, although it can be configured to have the previous behavior if + * required.

      + * + *

      The Event Service can be used with any connector via the + * method {@link javax.management.event.EventClient#getEventClientConnection + * EventClient.getEventClientConnection}, like this:

      + * + *
      + * JMXConnector conn = ...;
      + * MBeanServerConnection mbsc = conn.getMBeanServerConnection();
      + * MBeanServerConnection eventMbsc = EventClient.getEventClientConnection(mbsc);
      + * 
      + * + *

      If you add listeners using {@code eventMbsc.addNotificationListener} + * instead of {@code mbsc.addNotificationListener}, then they will be handled + * by the Event Service rather than by the connector's notification system.

      + * + *

      For the Event Service to work, either the {@link + * javax.management.event.EventClientDelegateMBean EventClientDelegateMBean} + * must be registered in the MBean Server, or the connector server must + * be configured to simulate the existence of this MBean, for example + * using {@link javax.management.event.EventClientDelegate#newForwarder() + * EventClientDelegate.newForwarder()}. The standard RMI connector is so + * configured by default. The {@code EventClientDelegateMBean} documentation + * has further details.

      + * + * + *

      Receiving notifications from a set of MBeans

      + * + *

      The Event Server allows you to receive notifications from every MBean + * that matches an {@link javax.management.ObjectName ObjectName} pattern. + * For local clients (in the same JVM as the MBean Server), the {@link + * javax.management.event.EventSubscriber EventSubscriber} class can be used for + * this. For remote clients, or if the same code is to be used locally and + * remotely, use an + * {@link javax.management.event.EventClient EventClient}.

      + * + *

      EventSubscriber and EventClient correctly handle the case where a new + * MBean is registered under a name that matches the pattern. Notifications + * from the new MBean will also be received.

      + * + *

      Here is how to receive notifications from all MBeans in a local + * {@code MBeanServer} that match {@code com.example.config:type=Cache,*}:

      + * + *
      + * MBeanServer mbs = ...;
      + * NotificationListener listener = ...;
      + * ObjectName pattern = new ObjectName("com.example.config:type=Cache,*");
      + * EventSubscriber esub = EventSubscriber.getEventSubscriber(mbs);
      + * esub.{@link javax.management.event.EventSubscriber#subscribe
      + * subscribe}(pattern, listener, null, null);
      + * 
      + * + *

      Here is how to do the same thing remotely:

      + * + *
      + * MBeanServerConnection mbsc = jmxConnector.getMBeanServerConnection();
      + * EventClient events = new EventClient(mbsc);
      + * NotificationListener listener = ...;
      + * ObjectName pattern = new ObjectName("com.example.config:type=Cache,*");
      + * events.{@link javax.management.event.EventClient#subscribe
      + * subscribe}(pattern, listener, null, null);
      + * 
      + * + * + *

      Controlling threading behavior for notification + * dispatch

      + * + *

      The EventClient class can be used to control threading of listener + * dispatch. For example, to arrange for all listeners to be invoked + * in the same thread, you can create an {@code EventClient} like this:

      + * + *
      + * MBeanServerConnection mbsc = ...;
      + * Executor singleThreadExecutor = {@link
      + * java.util.concurrent.Executors#newSingleThreadExecutor()
      + * Executors.newSingleThreadExecutor}();
      + * EventClient events = new EventClient(
      + *         mbsc, null, singleThreadExecutor, EventClient.DEFAULT_LEASE_TIMEOUT);
      + * events.addNotificationListener(...);
      + * events.subscribe(...);
      + * 
      + * + * + *

      Leasing

      + * + *

      The {@code EventClient} uses a lease mechanism to ensure + * that resources are eventually released on the server even if the client + * does not explicitly clean up. (This can happen through network + * partitioning, for example.)

      + * + *

      When an {@code EventClient} registers with the {@code + * EventClientDelegateMBean} using one of the {@code addClient} methods, + * an initial lease is created with a default expiry time. The {@code + * EventClient} requests an explicit lease shortly after that, with a + * configurable expiry time. Then the {@code EventClient} periodically + * renews the lease before it expires, typically about half way + * through the lifetime of the lease. If at any point the lease reaches + * the expiry time of the last renewal then it expires, and {@code + * EventClient} is unregistered as if it had called the {@link + * javax.management.event.EventClientDelegateMBean#removeClient removeClient} + * method.

      + * + * + *

      Custom notification transports

      + * + *

      When you create an {@code EventClient}, you can define the transport + * that it uses to deliver notifications. The transport might use the + * Java Message Service (JMS) or + * any other communication system. Specifying a transport is useful for + * example when you want different network behavior from the default, or + * different reliability guarantees. The default transport calls {@link + * javax.management.event.EventClientDelegateMBean#fetchNotifications + * EventClientDelegateMBean.fetchNotifications} repeatedly, which usually means + * that there must be a network connection permanently open between the client + * and the server. If the same client is connected to many servers this can + * cause scalability problems. If notifications are relatively rare, then + * JMS or the {@linkplain javax.management.event.RMIPushEventRelay push-mode + * RMI transport} may be more suitable.

      + * + *

      A transport is implemented by an {@link javax.management.event.EventRelay + * EventRelay} on the client side and a corresponding {@link + * javax.management.event.EventForwarder EventForwarder} + * on the server side. An example is the {@link + * javax.management.event.RMIPushEventRelay RMIPushEventRelay} and its + * {@link javax.management.event.RMIPushEventForwarder RMIPushEventForwarder}.

      + * + *

      To use a given transport with an {@code EventClient}, you first create + * an instance of its {@code EventRelay}. Typically the {@code EventRelay}'s + * constructor will have a parameter of type {@code MBeanServerConnection} + * or {@code EventClientDelegateMBean}, so that it can communicate with the + * {@code EventClientDelegateMBean} in the server. For example, the {@link + * javax.management.event.RMIPushEventForwarder RMIPushEventForwarder}'s constructors + * all take an {@code EventClientDelegateMBean} parameter, which is expected to + * be a {@linkplain javax.management.JMX#newMBeanProxy(MBeanServerConnection, + * ObjectName, Class) proxy} for the {@code EventClientDelegateMBean} in the + * server.

      + * + *

      When it is created, the {@code EventRelay} will call + * {@link javax.management.event.EventClientDelegateMBean#addClient(String, + * Object[], String[]) EventClientDelegateMBean.addClient}. It passes the + * name of the {@code EventForwarder} class and its constructor parameters. + * The {@code EventClientDelegateMBean} will instantiate this class using + * {@link javax.management.MBeanServer#instantiate(String, Object[], String[]) + * MBeanServer.instantiate}, and it will return a unique client id.

      + * + *

      Then you pass the newly-created {@code EventRelay} to one of the {@code + * EventClient} constructors, and you have an {@code EventClient} that uses the + * chosen transport.

      + * + *

      For example, when you create an {@code RMIPushEventRelay}, it + * uses {@code MBeanServerDelegateMBean.addClient} to create an {@code + * RMIEventForwarder} in the server. Notifications will then be delivered + * through an RMI communication from the {@code RMIEventForwarder} to the + * {@code RMIPushEventRelay}.

      + * + * + *

      Writing a custom transport

      + * + *

      To write a custom transport, you need to understand the sequence + * of events when an {@code EventRelay} and its corresponding {@code + * EventForwarder} are created, and when a notification is sent from the {@code + * EventForwarder} to the {@code EventRelay}.

      + * + *

      When an {@code EventRelay} is created:

      + * + *
        + *
      • The {@code EventRelay} must call {@code + * EventClientDelegateMBean.addClient} with the name of the {@code + * EventForwarder} and the constructor parameters.

        + * + *
      • {@code EventClientDelegateMBean.addClient} will do the following + * steps:

        + * + *
          + *
        • create the {@code EventForwarder} using {@code MBeanServer.instantiate}; + *
        • allocate a unique client id; + *
        • call the new {@code EventForwarder}'s {@link + * javax.management.event.EventForwarder#setClientId setClientId} method with + * the new client id; + *
        • return the client id to the caller. + *
        + * + *
      + * + *

      When an {@code EventClient} is created with an {@code EventRelay} + * parameter, it calls {@link javax.management.event.EventRelay#setEventReceiver + * EventRelay.setEventReceiver} with an {@code EventReceiver} that the + * {@code EventRelay} will use to deliver notifications.

      + * + *

      When a listener is added using the {@code EventClient}, the + * {@code EventRelay} and {@code EventForwarder} are not involved.

      + * + *

      When an MBean emits a notification and a listener has been added + * to that MBean using the {@code EventClient}:

      + * + *
        + *
      • The {@code EventForwarder}'s + * {@link javax.management.event.EventForwarder#forward forward} method + * is called with the notification and a listener id.

        + * + *
      • The {@code EventForwarder} sends the notification and listener id + * to the {@code EventRelay} using the custom transport.

        + * + *
      • The {@code EventRelay} delivers the notification by calling + * {@link javax.management.event.EventReceiver#receive EventReceiver.receive}.

        + *
      + * + *

      When the {@code EventClient} is closed ({@link + * javax.management.event.EventClient#close EventClient.close}):

      + * + *
        + *
      • The {@code EventClient} calls {@link + * javax.management.event.EventRelay#stop EventRelay.stop}.

        + * + *
      • The {@code EventClient} calls {@link + * javax.management.event.EventClientDelegateMBean#removeClient + * EventClientDelegateMBean.removeClient}.

        + * + *
      • The {@code EventClientDelegateMBean} removes any listeners it + * had added on behalf of this {@code EventClient}.

        + * + *
      • The {@code EventClientDelegateMBean} calls + * {@link javax.management.event.EventForwarder#close EventForwarder.close}.

        + *
      + * + * + *

      Threading and buffering

      + * + *

      The {@link javax.management.event.EventForwarder#forward + * EventForwarder.forward} method may be called in the thread that the + * source MBean is using to send its notification. MBeans can expect + * that notification sending does not block. Therefore a {@code forward} + * method will typically add the notification to a queue, with a separate + * thread that takes notifications off the queue and sends them.

      + * + *

      An {@code EventRelay} does not usually need to buffer notifications + * before giving them to + * {@link javax.management.event.EventReceiver#receive EventReceiver.receive}. + * Although by default each such notification will be sent to potentially-slow + * listeners, if this is a problem then an {@code Executor} can be given to + * the {@code EventClient} constructor to cause the listeners to be called + * in a different thread.

      + * + * @since 1.7 + */ + +package javax.management.event; diff --git a/jdk/src/share/classes/javax/management/loading/MLet.java b/jdk/src/share/classes/javax/management/loading/MLet.java index ba27646df6a..d6540591e98 100644 --- a/jdk/src/share/classes/javax/management/loading/MLet.java +++ b/jdk/src/share/classes/javax/management/loading/MLet.java @@ -1154,21 +1154,29 @@ public class MLet extends java.net.URLClassLoader */ private synchronized String loadLibraryAsResource(String libname) { try { - InputStream is = getResourceAsStream(libname.replace(File.separatorChar,'/')); + InputStream is = getResourceAsStream( + libname.replace(File.separatorChar,'/')); if (is != null) { - File directory = new File(libraryDirectory); - directory.mkdirs(); - File file = File.createTempFile(libname + ".", null, directory); - file.deleteOnExit(); - FileOutputStream fileOutput = new FileOutputStream(file); - int c; - while ((c = is.read()) != -1) { - fileOutput.write(c); - } - is.close(); - fileOutput.close(); - if (file.exists()) { - return file.getAbsolutePath(); + try { + File directory = new File(libraryDirectory); + directory.mkdirs(); + File file = File.createTempFile(libname + ".", null, + directory); + file.deleteOnExit(); + FileOutputStream fileOutput = new FileOutputStream(file); + try { + int c; + while ((c = is.read()) != -1) { + fileOutput.write(c); + } + } finally { + fileOutput.close(); + } + if (file.exists()) { + return file.getAbsolutePath(); + } + } finally { + is.close(); } } } catch (Exception e) { diff --git a/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanInfoSupport.java b/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanInfoSupport.java index 6e4a3ed6368..3655daadd1f 100644 --- a/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanInfoSupport.java +++ b/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanInfoSupport.java @@ -373,7 +373,7 @@ public class ModelMBeanInfoSupport extends MBeanInfo implements ModelMBeanInfo { "getDescriptors(String)", "Entry"); } - if ((inDescriptorType == null) || (inDescriptorType.isEmpty())) { + if ((inDescriptorType == null) || (inDescriptorType.equals(""))) { inDescriptorType = "all"; } @@ -616,7 +616,7 @@ public class ModelMBeanInfoSupport extends MBeanInfo implements ModelMBeanInfo { inDescriptor = new DescriptorSupport(); } - if ((inDescriptorType == null) || (inDescriptorType.isEmpty())) { + if ((inDescriptorType == null) || (inDescriptorType.equals(""))) { inDescriptorType = (String) inDescriptor.getFieldValue("descriptorType"); diff --git a/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java b/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java index 3c09c3ff2cc..7d99fba0021 100644 --- a/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java +++ b/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java @@ -1123,7 +1123,7 @@ public class RequiredModelMBean if (tracing) { MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(),"resolveMethod", - "resolving " + targetClass + "." + opMethodName); + "resolving " + targetClass.getName() + "." + opMethodName); } final Class[] argClasses; diff --git a/jdk/src/share/classes/javax/management/namespace/JMXDomain.java b/jdk/src/share/classes/javax/management/namespace/JMXDomain.java new file mode 100644 index 00000000000..bff3c137062 --- /dev/null +++ b/jdk/src/share/classes/javax/management/namespace/JMXDomain.java @@ -0,0 +1,382 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.namespace; + +import java.io.IOException; +import javax.management.ListenerNotFoundException; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import static javax.management.namespace.JMXNamespaces.NAMESPACE_SEPARATOR; + + +import javax.management.InstanceNotFoundException; +import javax.management.MBeanServer; +import javax.management.MBeanServerDelegate; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; + +/** + * A special {@link JMXNamespace} that can handle part of + * the MBeanServer local name space. + *

      + * A {@code JMXDomain} makes a domain X of a + * {@linkplain #getSourceServer() source MBean server} appear in the same domain + * X of a containing {@code MBeanServer} in which the + * {@code JMXDomain} MBean {@linkplain #getMBeanServer() is registered}. + *

      + *

      + * The JMX infrastructure of the containing {@code MBeanServer} takes care of + * routing all calls to MBeans whose names have domain X to the + * {@linkplain #getSourceServer() source MBean server} exported by the + * {@code JMXDomain} MBean in charge of domain X. + *

      + *

      + * The {@linkplain #getSourceServer() source MBean server} of a {@code JMXDomain} + * can, but need not be a regular {@code MBeanServer} created through + * the {@link javax.management.MBeanServerFactory}. It could also be, + * for instance, an instance of a subclass of {@link MBeanServerSupport}, + * or a custom object implementing the {@link MBeanServer} interface. + *

      + * + *

      Differences between {@code JMXNamespace} and {@code JMXDomain}

      + * + *

      + * A {@code JMXDomain} is a special kind of {@code JMXNamespace}. + * A {@code JMXNamespace} such as {@code foo//} is triggered by an + * {@code ObjectName} that begins with the string {@code foo//}, for example + * {@code foo//bar:type=Baz}. A {@code JMXDomain} such as {@code foo} is + * triggered by an {@code ObjectName} with that exact domain, for example + * {@code foo:type=Baz}. A client can immediately see that an MBean is + * handled by a {@code JMXNamespace} because of the {@code //} in the name. + * A client cannot see whether a name such as {@code foo:type=Baz} is an + * ordinary MBean or is handled by a {@code JMXDomain}. + *

      + * + *

      + * A {@linkplain MBeanServer#queryNames query} on the containing {@code + * MBeanserver} will return all MBeans from the {@code JMXDomain} that match + * the query. In particular, {@code queryNames(null, null)} will return all + * MBeans including those from {@code JMXDomain} domains. On the other hand, + * a query will not include MBeans from a {@code JMXNamespace} unless the + * {@code ObjectName} pattern in the query starts with the name of that + * namespace. + *

      + * + *

      Permission checks

      + * + *

      + * When a JMXDomain MBean is registered in a containing + * MBean server created through the default {@link + * javax.management.MBeanServerBuilder}, and if a {@link + * SecurityManager SecurityManager} is + * {@linkplain System#getSecurityManager() present}, the containing MBeanServer will + * check an {@link javax.management.MBeanPermission} before invoking + * any method on the {@linkplain #getSourceServer() source MBeanServer} of the + * JMXDomain. + *

      + * + *

      First, if there is no security manager ({@link + * System#getSecurityManager()} is null), that containing + * {@code MBeanServer} is free not to make any checks. + *

      + * + *

      + * Assuming that there is a security manager, or that the + * implementation chooses to make checks anyway, the containing + * {@code MBeanServer} will perform + * {@link javax.management.MBeanPermission MBeanPermission} checks + * for access to the MBeans in domain X handled by a {@code JMXDomain} + * in the same way that it would do for MBeans registered in its own local + * repository, and as described in + * the MBeanServer interface, with the following exceptions: + *

      + * + *

      + * For those permissions that require a {@code className}, the + * className is the + * string returned by {@link #getSourceServer() getSourceServer()}. + * {@link MBeanServer#getObjectInstance(ObjectName) + * getObjectInstance(mbeanName)}. + * {@link javax.management.ObjectInstance#getClassName() getClassName()}, + * except for {@code createMBean} and {@code registerMBean} operations, + * for which the permission checks are performed as follows: + *

      + *
        + *
      • For {@code createMBean} operations, the {@code className} of the + * permission you need is the {@code className} passed as first parameter + * to {@code createMBean}.

        + * + *
      • For {@code registerMBean} operations, the {@code className} of the + * permission you need is the name of the class of the mbean object, as + * returned by {@code mbean.getClass().getClassName()}, where + * {@code mbean} is the mbean reference passed as first parameter + * to {@code registerMBean}.

        + * + *
      • In addition, for {@code createMBean} and {@code registerMBean}, the + * permission you need is checked with the {@linkplain ObjectName object name} of + * the mbean that is passed as second parameter to the {@code createMBean} or + * {@code registerMBean} operation. + *

        + * + *
      • Contrarily to what is done for regular MBeans registered in the + * MBeanServer local repository, the containing MBeanServer will not + * check the {@link javax.management.MBeanTrustPermission#MBeanTrustPermission(String) + * MBeanTrustPermission("register")} against the protection domain + * of the MBean's class. This check can be performed by the + * {@linkplain #getSourceServer source MBean server} implementation, + * if necessary. + *

        + *
      + * + *

      If a security check fails, the method throws {@link + * SecurityException}.

      + * + *

      For methods that can throw {@link InstanceNotFoundException}, + * this exception is thrown for a non-existent MBean, regardless of + * permissions. This is because a non-existent MBean has no + * className.

      + * + * All these checks are performed by the containing {@code MBeanServer}, + * before accessing the JMXDomain {@linkplain #getSourceServer source MBean server}. + * The implementation of the JMXDomain {@linkplain #getSourceServer source MBean + * server} is free to make any additional checks. In fact, if the JMXDomain + * {@linkplain #getSourceServer source MBean server} is an {@code MBeanServer} + * obtained through the {@link javax.management.MBeanServerFactory}, it will + * again make permission checks as described in the + * MBeanServer interface. + * + *

      See the MBeanServer interface + * for more details on permission checks.

      + * + * @since 1.7 + */ +public class JMXDomain extends JMXNamespace { + + + /** + * This constant contains the value of the {@code type} + * key used in defining a standard JMXDomain MBean object name. + * By definition, a standard JMXDomain MBean object name must be of + * the form: + *
      +     * {@code ":"}+{@value javax.management.namespace.JMXDomain#TYPE_ASSIGNMENT}
      +     * 
      + */ + public static final String TYPE = "JMXDomain"; + + /** + * This constant contains the value of the standard + * {@linkplain javax.management.ObjectName#getKeyPropertyListString() key + * property list string} for JMXDomain MBean object names. + * By definition, a standard JMXDomain MBean object name must be of + * the form: + *
      +     * {@code }+":"+{@value javax.management.namespace.JMXDomain#TYPE_ASSIGNMENT}
      +     * 
      + */ + public static final String TYPE_ASSIGNMENT = "type="+TYPE; + + + + /** + * Creates a new instance of JMXDomain. The MBeans contained in this + * domain are handled by the {@code virtualServer} object given to + * this constructor. Frequently, this will be an instance of + * {@link MBeanServerSupport}. + * @param virtualServer The virtual server that acts as a container for + * the MBeans handled by this JMXDomain object. Frequently, this will + * be an instance of {@link MBeanServerSupport} + * @see JMXNamespace#JMXNamespace(MBeanServer) + */ + public JMXDomain(MBeanServer virtualServer) { + super(virtualServer); + } + + /** + * Return the name of domain handled by this JMXDomain. + * @return the domain handled by this JMXDomain. + * @throws IOException - if the domain cannot be determined, + * for instance, if the MBean is not registered yet. + */ + @Override + public final String getDefaultDomain() { + final ObjectName name = getObjectName(); + if (name == null) + throw new IllegalStateException("DefaultDomain is not yet known"); + final String dom = name.getDomain(); + return dom; + } + + /** + * Returns a singleton array, containing the only domain handled by + * this JMXDomain object. This is + * {@code new String[] {getDefaultDomain()}}. + * @return the only domain handled by this JMXDomain. + * @throws IOException if the domain cannot be determined, + * for instance, if the MBean is not registered yet. + * @see #getDefaultDomain() + */ + @Override + public final String[] getDomains() { + return new String[] {getDefaultDomain()}; + } + + /** + * This method returns the number of MBeans in the domain handled + * by this JMXDomain object. The default implementation is: + *
      +     *    getSourceServer().queryNames(
      +     *        new ObjectName(getObjectName().getDomain()+":*"), null).size();
      +     * 
      + * If this JMXDomain is not yet registered, this method returns 0. + * Subclasses can override the above behavior and provide a better + * implementation. + *

      + * The getMBeanCount() method is called when computing the number + * of MBeans in the {@linkplain #getMBeanServer() containing MBeanServer}. + * @return the number of MBeans in this domain, or 0. + */ + @Override + public Integer getMBeanCount() { + final ObjectName name = getObjectName(); + if (name == null) return 0; + try { + return getSourceServer(). + queryNames(ObjectName.WILDCARD.withDomain(name.getDomain()), + null).size(); + } catch (RuntimeException x) { + throw x; + } catch (Exception x) { + throw new RuntimeException("Unexpected exception: "+x,x); + } + } + + + + /** + * Return a canonical handler name for the provided local + * domain name, or null if the provided domain name is + * {@code null}. + * If not null, the handler name returned will be + * {@code domain+":type="+}{@link #TYPE TYPE}, for example + * {@code foo:type=JMXDomain}. + * @param domain A domain name + * @return a canonical ObjectName for a domain handler. + * @throws IllegalArgumentException if the provided + * domain is not valid - e.g it contains "//". + */ + public static ObjectName getDomainObjectName(String domain) { + if (domain == null) return null; + if (domain.contains(NAMESPACE_SEPARATOR)) + throw new IllegalArgumentException(domain); + try { + return ObjectName.getInstance(domain, "type", TYPE); + } catch (MalformedObjectNameException x) { + throw new IllegalArgumentException(domain,x); + } + } + + + /** + * Validate the ObjectName supplied to preRegister. + * This method is introduced to allow standard subclasses to use + * an alternate naming scheme. For instance - if we want to + * reuse JMXNamespace in order to implement sessions... + * It is however only available for subclasses in this package. + **/ + @Override + ObjectName validateHandlerName(ObjectName suppliedName) { + if (suppliedName == null) + throw new IllegalArgumentException("Must supply a valid name"); + final String dirName = JMXNamespaces. + normalizeNamespaceName(suppliedName.getDomain()); + final ObjectName handlerName = getDomainObjectName(dirName); + if (!suppliedName.equals(handlerName)) + throw new IllegalArgumentException("invalid name space name: "+ + suppliedName); + + return suppliedName; + } + + /** + * This method is called by the JMX framework to register a + * NotificationListener that will forward {@linkplain + * javax.management.MBeanServerNotification mbean server notifications} + * through the delegate of the {@linkplain #getMBeanServer() + * containing MBeanServer}. + * The default implementation of this method is to call + *

      +     *    getSourceServer().addNotificationListener(
      +     *           MBeanServerDelegate.DELEGATE_NAME, listener, filter, null);
      +     * 
      + * Subclasses can redefine this behavior if needed. In particular, + * subclasses can send their own instances of {@link + * javax.management.MBeanServerNotification} by calling + * {@code listener.handleNotification()}. + * + * @param listener The MBeanServerNotification listener for this domain. + * @param filter A notification filter. + */ + public void addMBeanServerNotificationListener( + NotificationListener listener, NotificationFilter filter) { + try { + getSourceServer().addNotificationListener( + MBeanServerDelegate.DELEGATE_NAME, listener, filter, null); + } catch(InstanceNotFoundException x) { + throw new UnsupportedOperationException( + "Unexpected exception: " + + "Emission of MBeanServerNotification disabled.", x); + } + } + + /** + * This method is called by the JMX framework to remove the + * NotificationListener that was added with {@link + * #addMBeanServerNotificationListener addMBeanServerNotificationListener}. + * The default implementation of this method is to call + *
      +     *    getSourceServer().removeNotificationListener(
      +     *           MBeanServerDelegate.DELEGATE_NAME, listener);
      +     * 
      + * Subclasses can redefine this behavior if needed. + * + * @param listener The MBeanServerNotification listener for this domain. + * @throws ListenerNotFoundException if the listener is not found. + */ + public void removeMBeanServerNotificationListener( + NotificationListener listener) + throws ListenerNotFoundException { + try { + getSourceServer().removeNotificationListener( + MBeanServerDelegate.DELEGATE_NAME, listener); + } catch(InstanceNotFoundException x) { + throw new UnsupportedOperationException( + "Unexpected exception: " + + "Emission of MBeanServerNotification disabled.", x); + } + } + +} diff --git a/jdk/src/share/classes/javax/management/namespace/JMXNamespace.java b/jdk/src/share/classes/javax/management/namespace/JMXNamespace.java new file mode 100644 index 00000000000..23f3004ebe5 --- /dev/null +++ b/jdk/src/share/classes/javax/management/namespace/JMXNamespace.java @@ -0,0 +1,666 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.namespace; + + +import java.io.IOException; + +import java.util.UUID; +import javax.management.MBeanRegistration; +import javax.management.MBeanServer; +import javax.management.ObjectName; + +/** + * MBean Servers can be federated into a single hierarchical name space: + * A JMXNamespace is an MBean that handles a sub name space in that + * hierarchical name space. + *

      + * A name space is created simply by registering a {@code JMXNamespace} + * MBean in the MBean Server. The name of the created name space is defined + * by the {@linkplain JMXNamespaces#getNamespaceObjectName name of the JMXNamespace} + * that handles it. A name space is equivalent to + * an MBean Server within an MBean Server. When creating a {@code JMXNamespace}, + * the MBean Server within is passed to the constructor. + *

      + *

      + * The {@code JMXNamespace} class is the base class for implementing + * all name space handlers. All name space handlers must be instances of + * {@code JMXNamespace} or a subclass of it. + *

      + *

      + * A concrete example of a {@code JMXNamespace} MBean subclass + * is the {@link JMXRemoteNamespace JMXRemoteNamespace} MBean which + * is able to mirror all MBeans contained in a remote MBean server known by its + * {@link javax.management.remote.JMXServiceURL}. + *

      + *

      + * You can create a local namespace by supplying a newly created MBean Server + * to an instance of {@code JMXNamespace}. For instance: + *

      + * final String namespace = "foo";
      + * final ObjectName namespaceName = {@link JMXNamespaces#getNamespaceObjectName
      + *       JMXNamespaces.getNamespaceObjectName(namespace)};
      + * server.registerMBean(new JMXNamespace(MBeanServerFactory.newMBeanServer()),
      + *                      namespaceName);
      + * 
      + *

      + *

      + * Note: A JMXNamespace MBean cannot be registered + * simultaneously in two different + * MBean servers, or indeed in the same MBean Server with two + * different names. It is however possible to give the same MBeanServer + * instance to two different JMXNamespace MBeans, and thus create a graph + * rather than a tree. + *

      + * + *

      To view the content of a namespace, you will usually use an + * instance of {@link JMXNamespaceView}. For instance, given the + * namespace {@code "foo"} created above, you would do: + *

      + *
      + * final JMXNamespaceView view = new JMXNamespaceView(server);
      + * System.out.println("List of namespaces: "+Arrays.toString({@link JMXNamespaceView#list() view.list()}));
      + *
      + * final JMXNamespaceView foo  = {@link JMXNamespaceView#down view.down("foo")};
      + * System.out.println({@link JMXNamespaceView#where() foo.where()}+" contains: " +
      + *        {@link JMXNamespaceView#getMBeanServerConnection foo.getMBeanServerConnection()}.queryNames(null,null));
      + * 
      + * + *

      JMX Namespace Permission Checks

      + * + *

      A special {@link JMXNamespacePermission} is defined to check access + * to MBean within namespaces.

      + *

      When a JMXNamespace MBean is registered in an + * MBean server created through the default {@link + * javax.management.MBeanServerBuilder}, and if a {@link + * SecurityManager SecurityManager} is + * {@linkplain System#getSecurityManager() present}, the MBeanServer will + * check a {@link JMXNamespacePermission} before invoking + * any method on the {@linkplain #getSourceServer source MBeanServer} of the + * JMXNamespace. + * {@linkplain JMXNamespacePermission JMX Namespace Permissions} are similar to + * {@linkplain javax.management.MBeanPermission MBean Permissions}, except + * that you usually cannot specify an MBean class name. You can however + * specify object name patterns - which will allow you for example to only grant + * permissions for MBeans having a specific {@code type=} key + * in their object name. + *

      + * Another difference is that {@link JMXNamespacePermission + * JMXNamespacePermission} also specifies from which namespace and which + * MBean server the permission is granted. + *

      + *

      In the rest of this document, the following terms are used:

      + *
        + *
      • {@code server name} is the + * name of the + * MBeanServer in which the permission is granted. + * The name of an {@code MBeanServer} can be obtained by calling {@link + * javax.management.MBeanServerFactory#getMBeanServerName + * MBeanServerFactory.getMBeanServerName(mbeanServer)} + *

        + *
      • {@code namespace} is the name of the namespace + * in the named MBean server for which the + * permission is granted. It doesn't contain any + * {@link JMXNamespaces#NAMESPACE_SEPARATOR namespace separator}. + *

        + *
      • {@code mbean} is the name + * of the MBean in that {@code namespace}. This is the name of the MBean + * in the namespace's {@link JMXNamespace#getSourceServer() source mbean server}. + * It might contain no, one, or several {@link + * JMXNamespaces#NAMESPACE_SEPARATOR namespace separators}. + *

        + *
      + * + *

      For instance let's assume that some piece of code calls:

      + *
      + *     final MBeanServer mbeanServer = ...;
      + *     final ObjectName  name   = new ObjectName("a//b//c//D:k=v");
      + *     mbeanServer.getAttribute(name,"Foo");
      + * 
      + *

      + * Assuming that there is a security manager, or that the + * implementation chooses to make checks anyway, the checks that will + * be made in that case are: + *

      + *
        + *
      1. + * JMXNamespacePermission(mbeanServerName, "Foo", "a//b//c//D:k=v", + * "getAttribute") + * (where {@code mbeanServerName=MBeanServerFactory.getMBeanServerName(mbeanServer)}, + * namespace="a", and {@code mbean="b//c//D:k=v"}) + *
      2. + *
      3. and in addition if namespace {@code "a"} is local, + * JMXNamespacePermission(aSourceServerName,"Foo","b//c//D:k=v", + * "getAttribute")} + * (where + * {@code aSourceServerName=MBeanServerFactory.getMBeanServerName(sourceServer(a))}, + * namespace="b", and {@code mbean="c//D:k=v"}), + *
      4. + *
      5. and in addition if namespace {@code "b"} is also local, + * JMXNamespacePermission(bSourceServerName,"Foo","c//D:k=v", + * "getAttribute")} + * (where + * {@code bSourceServerName=MBeanServerFactory.getMBeanServerName(sourceServer(b))}, + * namespace="c", and {@code mbean="D:k=v"}), + *
      6. + *
      7. and in addition if the source mbean server of namespace + * {@code "c"} is a also a local MBeanServer in this JVM, + * {@code MBeanPermission(cSourceServerName,,"Foo","D:k=v","getAttrinute")}, + * (where + * {@code cSourceServerName=MBeanServerFactory.getMBeanServerName(sourceServer(c))}). + *
      8. + *
      + *

      For any of these MBean servers, if no name was supplied when + * creating that MBeanServer the {@link JMXNamespacePermission} is + * created with an {@code mbeanServerName} equal to + * {@value javax.management.MBeanServerFactory#DEFAULT_MBEANSERVER_NAME}. + *

      + *

      If the namespace {@code a} is in fact a remote {@code MBeanServer}, + * for instance because namespace {@code a} is implemented by a {@link + * JMXRemoteNamespace} pointing to a distant MBeanServer located in + * another JMX agent, then checks 2, + * 3, and 4 will not + * be performed in the local JVM. They might or might not be performed in + * the remote agent, depending on how access control and permission + * checking are configured in the remote agent, and how authentication + * is configured in the connector used by the {@link + * JMXRemoteNamespace}. + *

      + *

      In all cases, {@linkplain JMXNamespacePermission JMX Namespace Permissions} + * are checked as follows:

      + *

      First, if there is no security manager ({@link + * System#getSecurityManager()} is null), then an implementation of + * of MBeanServer that supports JMX namespaces is free not to make any + * checks.

      + * + *

      Assuming that there is a security manager, or that the + * implementation chooses to make checks anyway, the checks are made + * as detailed below.

      + * + *

      If a security check fails, the method throws {@link + * SecurityException}.

      + * + *
        + * + *
      • For the {@link MBeanServer#invoke invoke} method, the caller's + * permissions must imply {@link + * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) + * JMXNamespacePermission(<mbean server name>, <operation name>, <namespace>//<mbean>, "invoke")}, + * where mbean server name is the name of the + * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of + * namespace is registered, and + * mbean is the name of the MBean on which the action + * is performed, in that namespace. + *

        + * + *
      • For the {@link MBeanServer#getAttribute getAttribute} method, the + * caller's permissions must imply {@link + * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) + * JMXNamespacePermission(<mbean server name>, <attribute>, <namespace>//<mbean>, "getAttribute")}. + *

        + * + *
      • For the {@link MBeanServer#getAttributes getAttributes} method, the + * caller's permissions must imply {@link + * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) + * JMXNamespacePermission(<mbean server name>, <null>, <namespace>//<mbean>, "getAttribute")}, + * where mbean server name is the name of the + * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of + * namespace is registered, and + * mbean is the name of the MBean on which the action + * is performed, in that namespace. + * Additionally, for each attribute att in the {@link + * javax.management.AttributeList}, if the caller's permissions do not + * imply {@link + * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) + * JMXNamespacePermission(<mbean server name>, att, + * <namespace>//<mbean>, "getAttribute")}, the + * MBean server will behave as if that attribute had not been in the + * supplied list.

        + * + *
      • For the {@link MBeanServer#setAttribute setAttribute} method, the + * caller's permissions must imply {@link + * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) + * JMXNamespacePermission(<mbean server name>, <attrName>, <namespace>//<mbean>, "setAttribute")}, + * where mbean server name is the name of the + * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of + * namespace is registered, and + * mbean is the name of the MBean on which the action + * is performed, in that namespace, and + * attrName is {@link javax.management.Attribute#getName() + * attribute.getName()}.

        + * + *
      • For the {@link MBeanServer#setAttributes setAttributes} method, the + * caller's permissions must imply {@link + * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) + * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>, "setAttribute")}, + * where mbean server name is the name of the + * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of + * namespace is registered, and + * mbean is the name of the MBean on which the action + * is performed, in that namespace. + * Additionally, for each attribute att in the {@link + * javax.management.AttributeList}, if the caller's permissions do not + * imply {@link + * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) + * JMXNamespacePermission(<mbean server name>, att, <namespace>//<mbean>, "setAttribute")}, + * the MBean server will behave as if that attribute had not been in the + * supplied list.

        + * + *
      • For the addNotificationListener methods, + * the caller's permissions must imply {@link + * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) + * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>, + * "addNotificationListener")}, + * where mbean server name is the name of the + * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of + * namespace is registered, and + * mbean is the name of the MBean on which the action + * is performed, in that namespace. + *

        + * + *
      • For the removeNotificationListener methods, + * the caller's permissions must imply {@link + * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) + * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>, + * "removeNotificationListener")}, + * where mbean server name is the name of the + * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of + * namespace is registered, and + * mbean is the name of the MBean on which the action + * is performed, in that namespace. + *

        + * + *
      • For the {@link MBeanServer#getMBeanInfo getMBeanInfo} method, the + * caller's permissions must imply {@link + * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) + * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>, + * "getMBeanInfo")}, + * where mbean server name is the name of the + * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of + * namespace is registered, and + * mbean is the name of the MBean on which the action + * is performed, in that namespace. + *

        + * + *
      • For the {@link MBeanServer#getObjectInstance getObjectInstance} method, + * the caller's permissions must imply {@link + * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) + * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>, + * "getObjectInstance")}, + * where mbean server name/a> is the name of the + * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of + * namespace is registered, and + * mbean is the name of the MBean on which the action + * is performed, in that namespace. + *

        + * + *
      • For the {@link MBeanServer#isInstanceOf isInstanceOf} method, the + * caller's permissions must imply {@link + * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) + * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>, + * "isInstanceOf")}, + * where mbean server name is the name of the + * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of + * namespace is registered, and + * mbean is the name of the MBean on which the action + * is performed, in that namespace. + *

        + * + *
      • For the {@link MBeanServer#queryMBeans queryMBeans} method, the + * caller's permissions must imply {@link + * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) + * JMXNamespacePermission(<mbean server name>, null, null, + * "queryMBeans")}. + * Additionally, for each MBean {@code mbean} that matches {@code pattern}, + * if the caller's permissions do not imply {@link + * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) + * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>, + * "queryMBeans")}, the + * MBean server will behave as if that MBean did not exist.

        + * + *

        Certain query elements perform operations on the MBean server. + * However these operations are usually performed by the MBeanServer at the + * bottom of the namespace path, and therefore, do not involve any + * {@link JMXNamespacePermission} permission check. They might involve + * {@link javax.management.MBeanPermission} checks depending on how security + * in the JVM in which the bottom MBeanServer resides is implemented. + * See {@link javax.management.MBeanServer} for more details. + *

        + * + *
      • For the {@link MBeanServer#queryNames queryNames} method, the checks + * are the same as for queryMBeans except that + * "queryNames" is used instead of + * "queryMBeans" in the JMXNamespacePermission + * objects. Note that a "queryMBeans" permission implies + * the corresponding "queryNames" permission.

        + * + *
      • For the {@link MBeanServer#getClassLoader getClassLoader} method, the + * caller's permissions must imply {@link + * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) + * JMXNamespacePermission(<mbean server name>, null, <namespace>//<loaderName>, + * "getClassLoader")}, + * where mbean server name/a> is the name of the + * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of + * namespace is registered, and + * loaderName is the name of the ClassLoader MBean + * which is accessed, in that namespace. + *

        + * + *
      • For the {@link MBeanServer#getClassLoaderFor getClassLoaderFor} method, + * the caller's permissions must imply {@link + * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) + * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>, + * "getClassLoaderFor")}, + * where mbean server name is the name of the + * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of + * namespace is registered, and + * mbean is the name of the MBean on which the action + * is performed, in that namespace. + *

        + * + *
      • For the {@link MBeanServer#registerMBean registerMBean} method, the + * caller's permissions must imply {@link + * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) + * JMXNamespacePermission(<mbean server name>, <class name>, <namespace>//<mbean>, + * "registerMBean")}. Here + * class name is the string returned by {@code + * obj.getClass().getName()} where {@code obj} is the mbean reference, + * is the name of the + * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of + * namespace is registered, and + * mbean is the name of the MBean which is being + * registered, relative to that namespace. + * + *

      • For the createMBean methods, the caller's + * permissions must imply {@link + * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) + * JMXNamespacePermission(<mbean server name>, <class name>, <namespace>//<mbean>, + * "instantiate")} and + * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) + * JMXNamespacePermission(<mbean server name>, <class name>, <namespace>//<mbean>, + * "registerMBean")}, where + * class name is the string passed as first argument to the {@code + * createMBean} method, + * mbean server name is the name of the + * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of + * namespace is registered, and + * mbean is the name of the MBean which is being + * created, relative to that namespace. + * + *

      • For the {@link MBeanServer#unregisterMBean unregisterMBean} method, + * the caller's permissions must imply {@link + * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) + * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>, + * "unregisterMBean")}, + * where mbean server name is the name of the + * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of + * namespace is registered, and + * mbean is the name of the MBean on which is + * being unregistered, relative to that namespace. + *

        + *
      + *

      + *

      It must be noted that if all namespaces are local, and all + * local namespaces are implemented by regular MBean servers, that is, there + * are no {@linkplain MBeanServerSupport Virtual Namespaces}, then + * simple {@linkplain javax.management.MBeanPermission MBean Permission} + * checks might be enough to secure an application. + * In that case, it is possible to specify the following {@link + * JMXNamespacePermission} permission in the policy file, which implies all + * other JMX namespace permissions: + *

      + *
      + *     permission javax.management.namespace.JMXNamespacePermission "*::*[]", "*";
      + * 
      + * + * @since 1.7 + */ +public class JMXNamespace + implements JMXNamespaceMBean, MBeanRegistration { + + /** + * The standard value of the {@code type} + * property key that must be used to construct valid {@link + * JMXNamespaceMBean} ObjectNames.
      + * This is {@value #TYPE}. + **/ + public static final String TYPE = "JMXNamespace"; + + /** + * The {@link ObjectName#getKeyPropertyListString keyPropertyListString} + * that must be used to construct valid {@link JMXNamespaceMBean} + * ObjectNames.
      + * This is + * {@value #TYPE_ASSIGNMENT}. + **/ + public static final String TYPE_ASSIGNMENT = "type="+TYPE; + + private volatile MBeanServer mbeanServer; // the mbean server in which + // this MBean is registered. + private volatile ObjectName objectName; // the ObjectName of this MBean. + private final MBeanServer sourceServer; // the MBeanServer within = the + // name space (or the MBean server + // that contains it). + private final String uuid; + + /** + * Creates a new JMXNamespace implemented by means of an MBean Server. + * A namespace is equivalent to an MBeanServer within an MBean Server. + * The {@code sourceServer} provided to this constructor is the MBean Server + * within. + * @param sourceServer the MBean server that implemented by this namespace. + * @see #getSourceServer + */ + public JMXNamespace(MBeanServer sourceServer) { + this.sourceServer = sourceServer; + this.uuid = UUID.randomUUID().toString(); + } + + /** + * This method is part of the {@link MBeanRegistration} interface. + * The {@link JMXNamespace} class uses the {@link MBeanRegistration} + * interface in order to get a reference to the MBean server in which it is + * registered. It also checks the validity of its own ObjectName. + *

      + * This method is called by the MBean server. + * Application classes should never call this method directly. + *

      + * If this method is overridden, the overriding method should call + * {@code super.preRegister(server,name)}. + * @see MBeanRegistration#preRegister MBeanRegistration + * @see JMXNamespaces#getNamespaceObjectName getNamespaceObjectName + * @param name The object name of the MBean. name must be a + * syntactically valid JMXNamespace name, as returned by + * {@link JMXNamespaces#getNamespaceObjectName(java.lang.String) + * getNamespaceObjectName(namespace)}. + * @return The name under which the MBean is to be registered. + * @throws IllegalArgumentException if the name supplied is not valid. + * @throws Exception can be thrown by subclasses. + */ + public ObjectName preRegister(MBeanServer server, ObjectName name) + throws Exception { + // need to synchronize to protect against multiple registration. + synchronized(this) { + if (objectName != null && ! objectName.equals(name)) + throw new IllegalStateException( + "Already registered under another name: " + objectName); + objectName = validateHandlerName(name); + mbeanServer = server; + } + return name; + } + + /** + * Validate the ObjectName supplied to preRegister. + * This method is introduced to allow standard subclasses to use + * an alternate naming scheme. For instance - if we want to + * reuse JMXNamespace in order to implement sessions... + * It is however only available for subclasses in this package. + **/ + ObjectName validateHandlerName(ObjectName suppliedName) { + if (suppliedName == null) + throw new IllegalArgumentException("Must supply a valid name"); + final String dirName = JMXNamespaces. + normalizeNamespaceName(suppliedName.getDomain()); + final ObjectName handlerName = + JMXNamespaces.getNamespaceObjectName(dirName); + if (!suppliedName.equals(handlerName)) + throw new IllegalArgumentException("invalid name space name: "+ + suppliedName); + return suppliedName; + } + + /** + * This method is part of the {@link MBeanRegistration} interface. + * The {@link JMXNamespace} class uses the {@link MBeanRegistration} + * interface in order to get a reference to the MBean server in which it is + * registered. + *

      + * This method is called by the MBean server. Application classes should + * not call this method directly. Subclasses are free to override this + * method with their own specific behavior - but the overriding method + * shoud still call {@code super.postRegister(registrationDone)}. + * @see MBeanRegistration#postRegister MBeanRegistration + */ + public void postRegister(Boolean registrationDone) { + // nothing to do + } + + /** + * This method is part of the {@link MBeanRegistration} interface. + * The {@link JMXNamespace} class uses the {@link MBeanRegistration} + * interface in order to get a reference to the MBean server in which it is + * registered. + *

      + * This method is called by the MBean server. Application classes should + * not call this method directly. Subclasses are free to override this + * method with their own specific behavior - but the overriding method + * shoud still call {@code super.preDeregister()}. + * @see MBeanRegistration#preDeregister MBeanRegistration + */ + public void preDeregister() throws Exception { + // nothing to do + } + + /** + * This method is part of the {@link MBeanRegistration} interface. + * It allows the {@code JMXNamespace} MBean to perform any operations + * needed after having been unregistered in the MBean server. + *

      + * This method is called by the MBean server. Application classes should + * not call this method directly. If a subclass overrides this + * method, the overriding method shoud call {@code super.postDeregister()}. + * @see MBeanRegistration#postDeregister MBeanRegistration + */ + public void postDeregister() { + // need to synchronize to protect against multiple registration. + synchronized(this) { + mbeanServer = null; + objectName = null; + } + } + + + /** + * Returns the MBeanServer in which this MBean is registered, + * or null. Chiefly of interest for subclasses. + * @return the MBeanServer supplied to {@link #preRegister}. + **/ + public final MBeanServer getMBeanServer() { + return mbeanServer; + } + + /** + * Returns the MBeanServer that contains or emulates the source + * namespace. When a JMXNamespace MBean is registered in an + * MBean server created through the default {@link + * javax.management.MBeanServerBuilder}, the MBeanServer will + * check {@link JMXNamespacePermission} before invoking + * any method on the source MBeanServer of the JMXNamespace. + * See JMX Namespace Permission Checks + * above. + * @return an MBeanServer view of the source namespace + **/ + public MBeanServer getSourceServer() { + return sourceServer; + } + + /** + * Returns the ObjectName with which this MBean was registered, + * or null. Chiefly of interest for subclasses. + * @return the ObjectName supplied to {@link #preRegister}. + **/ + public final ObjectName getObjectName() { + return objectName; + } + + /** + * HandlerName used in traces. + **/ + String getHandlerName() { + final ObjectName name = getObjectName(); + if (name != null) return name.toString(); + return this.toString(); + } + + /** + * In this class, this method returns {@link #getSourceServer + * getSourceServer()}.{@link javax.management.MBeanServer#getMBeanCount + * getMBeanCount()}. + *
      This default behaviour may be redefined in subclasses. + * @throws java.io.IOException can be thrown by subclasses. + */ + public Integer getMBeanCount() throws IOException { + return getSourceServer().getMBeanCount(); + } + + /** + * In this class, this method returns {@link #getSourceServer + * getSourceServer()}.{@link javax.management.MBeanServer#getDomains + * getDomains()}. + *
      This default behaviour may be redefined in subclasses. + * @throws java.io.IOException can be thrown by subclasses. + */ + public String[] getDomains() throws IOException { + return getSourceServer().getDomains(); + } + + /** + * In this class, this method returns {@link #getSourceServer + * getSourceServer()}.{@link javax.management.MBeanServer#getDefaultDomain + * getDefaultDomain()}. + *
      This default behaviour may be redefined in subclasses. + * @throws java.io.IOException can be thrown by subclasses. + */ + public String getDefaultDomain() throws IOException { + return getSourceServer().getDefaultDomain(); + } + + public final String getUUID() { + return uuid; + } + +} diff --git a/jdk/src/share/classes/javax/management/namespace/JMXNamespaceMBean.java b/jdk/src/share/classes/javax/management/namespace/JMXNamespaceMBean.java new file mode 100644 index 00000000000..4632b410ae7 --- /dev/null +++ b/jdk/src/share/classes/javax/management/namespace/JMXNamespaceMBean.java @@ -0,0 +1,96 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.namespace; + +import java.io.IOException; +import java.util.UUID; + +/** + * A {@link JMXNamespace} is an MBean that handles a name space in the + * MBeanServer hierarchical name space. + * @see JMXNamespace + * @since 1.7 + */ +public interface JMXNamespaceMBean { + + // Note: since getDomains(), getDefaultDomain(), and getMBeanCount() + // don't take any ObjectName parameters, the only efficient way + // to get these data is to call the corresponding method on the + // JMXNamespaceMBean that handles the name space. + // + // We need these methods to implement 'cd' (JMXNamespaces.narrowToNamespace) + // correctly. + // + + /** + * Returns the list of domains currently implemented in the name space + * handled by this {@link JMXNamespace}. + * @throws IOException if the domain list cannot be obtained due to + * I/O problems (communication failures etc...). + * @return the list of domains currently implemented in the name space + * handled by this {@link JMXNamespace}. + * @see javax.management.MBeanServerConnection#getDomains + * MBeanServerConnection.getDomains + **/ + public String[] getDomains() throws IOException; + + /** + * Returns the default domain for the name space handled by + * this {@link JMXNamespace}. + * @throws IOException if the default domain cannot be obtained due to + * I/O problems (communication failures etc...). + * @return the default domain for the name space handled by + * this {@link JMXNamespace}. + * @see javax.management.MBeanServerConnection#getDefaultDomain + * MBeanServerConnection.getDefaultDomain + **/ + public String getDefaultDomain() throws IOException; + + /** + * Returns the number of MBeans registered in the name space handled by + * this {@link JMXNamespace}. + * + * @return the number of MBeans registered in the name space handled by + * this {@link JMXNamespace}. + * + * @throws IOException if the MBean count cannot be obtained due to + * I/O problems (communication failures etc...). + * @see javax.management.MBeanServerConnection#getMBeanCount + * MBeanServerConnection.getMBeanCount + */ + public Integer getMBeanCount() throws IOException; + + /** + * Returns a {@link java.util.UUID UUID string} which uniquely identifies + * this {@linkplain JMXNamespace} MBean. + * This information can be used to detect loops in the JMX name space graph. + * @return A unique ID identifying this MBean. + * @throws IOException if the MBean UUID cannot be obtained due to + * I/O problems (communication failures etc...). + */ + public String getUUID() throws IOException; + +} diff --git a/jdk/src/share/classes/javax/management/namespace/JMXNamespacePermission.java b/jdk/src/share/classes/javax/management/namespace/JMXNamespacePermission.java new file mode 100644 index 00000000000..5dd012672b3 --- /dev/null +++ b/jdk/src/share/classes/javax/management/namespace/JMXNamespacePermission.java @@ -0,0 +1,1474 @@ +/* + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.namespace; + +import javax.management.*; +import com.sun.jmx.mbeanserver.Util; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.security.Permission; + +/** + *

      A permission controlling access to MBeans located in namespaces. + * If a security manager has been set using {@link + * System#setSecurityManager}, most operations on an MBean mounted in a + * namespace require that the caller's permissions imply a + * JMXNamespacePermission appropriate for the operation. + * This is described in detail in the + * documentation for the + * JMXNamespace + * class.

      + * + *

      As with other {@link Permission} objects, + * a JMXNamespacePermission can represent either a permission that + * you have or a permission that you need. + * When a sensitive operation is being checked for permission, + * a JMXNamespacePermission is constructed + * representing the permission you need. The operation is only + * allowed if the permissions you have {@linkplain #implies imply} the + * permission you need.

      + * + *

      A JMXNamespacePermission contains four items of information:

      + * + *
        + * + *
      • The action.

        + *

        For a permission you need, + * this is one of the actions in the list below. For a permission you have, this is + * a comma-separated list of those actions, or *, + * representing all actions.

        + * + *

        The action is returned by {@link #getActions()}.

        + * + *
      • The MBean Server name.

        + * + *

        For a permission you need, this is the {@linkplain + * javax.management.MBeanServerFactory#getMBeanServerName + * name of the MBeanServer} + * from which the MBean is accessed.

        + * + *

        For a permission you have, this is either the {@linkplain + * javax.management.MBeanServerFactory#getMBeanServerName + * name of the MBeanServer} from which the MBean + * for which you have this permission is accessed, + * or a pattern against which that MBean Server name will be matched.
        + * An {@code mbeanServername} pattern can also be empty, or the single + * character {@code "*"}, both of which match any {@code MBeanServer} name. + * The string {@code "-"} doesn't match any MBeanServer name. + *

        + * + *

        Example:

        + *
        + *   // grant permission to invoke the operation "stop" on any MBean
        + *   // whose name matches "a//**//*:type=JMXConnectorServer" when
        + *   // accessed from any MBeanServer whose name matches myapp.*"
        + *   permission javax.management.namespace.JMXNamespacePermission "myapp.*::stop[a//**//*:type=JMXConnectorServer]", "invoke";
        + * 
        + * + *
      • The member.

        + * + *

        For a permission you need, this is the name of the attribute or + * operation you are accessing. For operations that do not reference + * an attribute or operation, the member is null.

        + * + *

        For a permission you have, this is either the name of an attribute + * or operation you can access, or it is empty or the single character + * "*", both of which grant access to any member.

        + * + *

        There is a special case for actions {@code registerMBean} and + * {@code instantiate}, where for a permission you need, {@code member} + * indicates the name of the class for which you are trying + * to create, instantiate, or register an MBean instance. For a + * permission you have, it is a pattern that will be matched against + * the full class name of the MBean being created, instantiated, or + * registered. + *

        + * + * + *
      • The object name.

        + * + *

        For a permission you need, this is the {@link ObjectName} of the + * MBean you are accessing. It is of the form {@code //} + * where {@code } is the name of the name space for which the + * permission is checked, and {@code } is the name of the MBean + * within that namespace. + *
        + * For operations that do not reference a + * single MBean, the object name is null. It is never an object + * name pattern. + *

        + * + *

        For a permission you have, this is the {@link ObjectName} of the + * MBean or MBeans you can access. It is of the form + * {@code //} + * where {@code } is the name of the name space for which the + * permission is checked, and + * {@code } is the name of the MBean + * within that namespace. Both {@code } and {@code } + * can be patterns. The object name + * may also be empty, which grants access to all MBeans whatever their + * name and namespace. + * When included in a namespace path the special path element + * ** matches any number of sub namespaces + * recursively, but only if used as a complete namespace path element, + * as in **//b//c//D:k=v or a//**//c//D:k=v + * - see below. + *

        + * + * + *
      + * + *

      If you have a JMXNamespacePermission, it allows operations only + * if all four of the items match.

      + * + *

      The MBeanServer name, + * member, and object name + * can be written together + * as a single string, which is the name of this permission. + * The name of the permission is the string returned by {@link + * java.security.Permission#getName() getName()}. + * The format of the string is:

      + * + *
      + * {@code ::[//]} + *
      + * + *

      + * The {@code } is optional. If omitted, {@code "*"} is + * assumed, and these three permission names + * are thus equivalent: + *

      + *
      + * {@code *::[//]}
      + * {@code ::[//]}
      + * {@code [//]}
      + *
      + *

      + * The {@code //} string can be in the form + * of a traditional ObjectName + * pattern - meaning that ? will match any single + * character, and * will match any sequence of characters, + * except {@value + * javax.management.namespace.JMXNamespaces#NAMESPACE_SEPARATOR} + * In addition, when included in a namespace path the special + * path element ** matches any number of sub namespaces + * recursively. + * A {@code //} string of the form + * **//*:* thus means that the permission is + * granted for all MBeans in all namespaces, recursively (see + * below for more details. + *

      + *

      Namespace permission checking may be tricky to configure, depending + * on whether the namespaces crossed to reach the MBean are local or + * remote.
      + * For instance, let a//b//D:k=v be an MBean exposing an + * attribute Foo. + * If namespace a is a plain JMXNamespace pointing to + * a local MBeanServer in the same JVM, then the permissions you need + * to get the attribute Foo will be: + *

      + *
      + *    // granting permission to access attribute 'Foo' of MBean a//b//D:k=v
      + *    // from MBeanServer named 'srv1'
      + *    // This permission will be checked by the MBeanServer that contains 'a'.
      + *    srv1::Foo[a//b//D:k=v]
      + *
      + *    // Since a is local, you also need the following additional permission,
      + *    // which will be checked by the MBeanServer 'srv2' that contains 'b':
      + *    //
      + *    // granting permission to access attribute 'Foo' of MBean b//D:k=v from
      + *    // 'srv2'
      + *    srv2::Foo[b//D:k=v]
      + * 
      + *

      On the other hand, if namespace a is a JMXRemoteNamespace + * pointing to an MBeanServer in a remote JVM, then the only permission you + * need to get the attribute Foo will be: + *

      + *
      + *    // granting permission to access attribute 'Foo' of MBean a//b//D:k=v
      + *    // from 'srv1'
      + *    srv1::Foo[a//b//D:k=v]
      + * 
      + *

      The namespace b resides in the remote JVM, and + * therefore the permissions concerning access to MBeans from + * namespace 'b' will only be checked in the remote JVM, if that JVM is + * configured to do so. + *

      + * + *

      The {@code } is written using the usual syntax for {@link + * ObjectName}. It may contain any legal characters, including + * ]. It is terminated by a ] character + * that is the last character in the string. + *

      + *

      Below are some examples of permission names:

      + *
      + *    // allows access to Foo in 'a//b//*:*' from any MBeanServer in the JVM.
      + *    Foo[a//b//*:*]
      + *
      + *    // allows access to Foo in all subnamespaces of 'a//b', but only for
      + *    // MBeanServers whose name matches 'myapp.*'
      + *    myapp.*::Foo[a//b//**//*:*]
      + *
      + *    // allows access to Foo from all namespaces in the MBeanServer named
      + *    // 'myapp.srv1' - but not recursively.
      + *    myapp.srv1::Foo[*//*:*]
      + * 
      + *

      For instance, the first two permissions listed above + * will let through {@code getAttribute("a//b//D:k=v","Foo");} in + * all MBeanServers, but will block access to + * {@code getAttribute("a//b//c//D:k=v","Foo");} in MBeanServers whose + * name do not start with {@code "myapp."}. + *

      + *

      Depending on how your namespace hierarchy + * is defined some of these wildcard permission names can be useful:

      + *
      + *    // allows access to Foo in all namespaces, recursively.
      + *    //
      + *    *::Foo[**//*:*]
      + *
      + *    // This permission name is the equivalent to the permission names above:
      + *    // Foo[**//*:*] and Foo[] are equivalent.
      + *    //
      + *    Foo[]
      + *
      + *    // This permission name is the equivalent to the two permission names
      + *    // above:
      + *    // Foo[**//*:*], Foo[], Foo are equivalent.
      + *    //
      + *    Foo
      + *
      + *    // allows access to Foo from all namespaces - but not recursively.
      + *    // This wildcard permission complements the previous one: it allows
      + *    // access to 'Foo' from an MBean directly registered in any local namespace.
      + *    //
      + *    Foo[*//*:*]
      + *
      + * 
      + *

      Note on wildcards: In an object name pattern, a path element + * of exactly ** corresponds to a meta + * wildcard that will match any number of sub namespaces. Hence:

      + *
        + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
        patternmatchesdoesn't match
        **//D:k=va//D:k=v
        + * a//b//D:k=v
        + * a//b//c//D:k=v
        D:k=v
        a//**//D:k=va//b//D:k=v
        + * a//b//c//D:k=v
        b//b//c//D:k=v
        + * a//D:k=v
        + * D:k=v
        a//**//e//D:k=va//b//e//D:k=v
        + * a//b//c//e//D:k=v
        a//b//c//c//D:k=v
        + * b//b//c//e//D:k=v
        + * a//e//D:k=v
        + * e//D:k=v
        a//b**//e//D:k=va//b//e//D:k=va//b//c//e//D:k=v
        + * because in that case b**
        + * is not a meta-wildcard - and b**
        + * is thus equivalent to b*.
        + *
      + * + *

      If {@code ::} is omitted, then one of + * member or object name may be omitted. + * If the object name is omitted, + * the [] may be too (but does not have to be). It is + * not legal to omit all items, that is to have a name + * which is the empty string.

      + *

      If {@code } is present, it must be followed by + * the {@code "::"} separator - otherwise it will be interpreted as + * a {@code member name}. + *

      + * + *

      + * One or more of the MBean Server name, + * member + * or object name may be the character "-", + * which is equivalent to a null value. A null value is implied by + * any value (including another null value) but does not imply any + * other value. + *

      + * + *

      The possible actions are these:

      + * + *
        + *
      • addNotificationListener
      • + *
      • getAttribute
      • + *
      • getClassLoader
      • + *
      • getClassLoaderFor
      • + *
      • getClassLoaderRepository
      • + *
      • getMBeanInfo
      • + *
      • getObjectInstance
      • + *
      • instantiate
      • + *
      • invoke
      • + *
      • isInstanceOf
      • + *
      • queryMBeans
      • + *
      • queryNames
      • + *
      • registerMBean
      • + *
      • removeNotificationListener
      • + *
      • setAttribute
      • + *
      • unregisterMBean
      • + *
      + * + *

      In a comma-separated list of actions, spaces are allowed before + * and after each action.

      + * + * @since 1.7 + */ +public class JMXNamespacePermission extends Permission { + + private static final long serialVersionUID = -2416928705275160661L; + + private static final String WILDPATH = "**" + + JMXNamespaces.NAMESPACE_SEPARATOR + "*"; + + /** + * Actions list. + */ + private static final int AddNotificationListener = 0x00001; + private static final int GetAttribute = 0x00002; + private static final int GetClassLoader = 0x00004; + private static final int GetClassLoaderFor = 0x00008; + private static final int GetClassLoaderRepository = 0x00010; + // No GetDomains because it is not possible to route a call to + // getDomains() on a NamespaceInterceptor - getDomains() doesn't + // have any ObjectName. + // private static final int GetDomains = 0x00020; + private static final int GetMBeanInfo = 0x00040; + private static final int GetObjectInstance = 0x00080; + private static final int Instantiate = 0x00100; + private static final int Invoke = 0x00200; + private static final int IsInstanceOf = 0x00400; + private static final int QueryMBeans = 0x00800; + private static final int QueryNames = 0x01000; + private static final int RegisterMBean = 0x02000; + private static final int RemoveNotificationListener = 0x04000; + private static final int SetAttribute = 0x08000; + private static final int UnregisterMBean = 0x10000; + + /** + * No actions. + */ + private static final int NONE = 0x00000; + + /** + * All actions. + */ + // No GetDomains because it is not possible to route a call to + // getDomains() on a NamespaceInterceptor - getDomains() doesn't + // have any ObjectName. + // + private static final int ALL = + AddNotificationListener | + GetAttribute | + GetClassLoader | + GetClassLoaderFor | + GetClassLoaderRepository | + GetMBeanInfo | + GetObjectInstance | + Instantiate | + Invoke | + IsInstanceOf | + QueryMBeans | + QueryNames | + RegisterMBean | + RemoveNotificationListener | + SetAttribute | + UnregisterMBean; + + /** + * The actions string. + */ + private String actions; + + /** + * The actions mask. + */ + private transient int mask; + + /** + * The name of the MBeanServer in which this permission is checked, or + * granted. If null, is implied by any MBean server name + * but does not imply any non-null MBean server name. + */ + private transient String mbeanServerName; + + /** + * The member that must match. If null, is implied by any member + * but does not imply any non-null member. + */ + private transient String member; + + /** + * The objectName that must match. If null, is implied by any + * objectName but does not imply any non-null objectName. + */ + private transient ObjectName objectName; + + /** + * If objectName is missing from name, then allnames will be + * set to true. + */ + private transient boolean allnames = false; + + /** + * Parse actions parameter. + */ + private void parseActions() { + + int amask; + + if (actions == null) + throw new IllegalArgumentException("JMXNamespaceAccessPermission: " + + "actions can't be null"); + if (actions.equals("")) + throw new IllegalArgumentException("JMXNamespaceAccessPermission: " + + "actions can't be empty"); + + amask = getMask(actions); + + if ((amask & ALL) != amask) + throw new IllegalArgumentException("Invalid actions mask"); + if (amask == NONE) + throw new IllegalArgumentException("Invalid actions mask"); + this.mask = amask; + } + + /** + * Parse name parameter. + */ + private void parseName() { + String name = getName(); + + if (name == null) + throw new IllegalArgumentException("JMXNamespaceAccessPermission name " + + "cannot be null"); + + if (name.equals("")) + throw new IllegalArgumentException("JMXNamespaceAccessPermission name " + + "cannot be empty"); + final int sepIndex = name.indexOf("::"); + if (sepIndex < 0) { + setMBeanServerName("*"); + } else { + setMBeanServerName(name.substring(0,sepIndex)); + } + + /* The name looks like "mbeanServerName::member[objectname]". + We subtract elements from the right as we parse, so after + parsing the objectname we have "class#member" and after parsing the + member we have "class". Each element is optional. */ + + // Parse ObjectName + + final int start = (sepIndex<0)?0:sepIndex+2; + int openingBracket = name.indexOf("[",start); + if (openingBracket == -1) { + // If "[on]" missing then ObjectName("*:*") + // + objectName = null; + allnames = true; + openingBracket=name.length(); + } else { + if (!name.endsWith("]")) { + throw new IllegalArgumentException("JMXNamespaceAccessPermission: " + + "The ObjectName in the " + + "target name must be " + + "included in square " + + "brackets"); + } else { + // Create ObjectName + // + String on = name.substring(openingBracket + 1, + name.length() - 1); + try { + // If "[]" then allnames are implied + // + final ObjectName target; + final boolean all; + if (on.equals("")) { + target = null; + all = true; + } else if (on.equals("-")) { + target = null; + all = false; + } else { + target = new ObjectName(on); + all = false; + } + setObjectName(target,all); + } catch (MalformedObjectNameException e) { + throw new IllegalArgumentException( + "JMXNamespaceAccessPermission: " + + "The target name does " + + "not specify a valid " + + "ObjectName", e); + } + } + } + + final String memberName = name.substring(start,openingBracket); + setMember(memberName); + } + + private void setObjectName(ObjectName target, boolean all) { + if (target != null && + !Util.wildpathmatch(target.getDomain(), WILDPATH)) { + throw new IllegalArgumentException( + "The target name does not contain " + + "any namespace: "+String.valueOf(target)); + } else if (target != null) { + final String domain = target.getDomain(); + final int seplen = JMXNamespaces.NAMESPACE_SEPARATOR.length(); + final int sepc = domain.indexOf(JMXNamespaces.NAMESPACE_SEPARATOR); + if (sepc < 0 || (sepc+seplen)==domain.length()) { + throw new IllegalArgumentException(String.valueOf(target)+ + ": no namespace in domain"); + } + } + objectName = target; + allnames = all; + } + + /** + * Assign fields based on className, member, and objectName + * parameters. + */ +// private void initName(String namespaceName, String member, +// ObjectName objectName, boolean allnames) { +// setNamespace(namespaceName); + private void initName(String mbeanServerName, String member, + ObjectName mbeanName, boolean all) { + setMBeanServerName(mbeanServerName); + setMember(member); + setObjectName(mbeanName, all); + } + + private void setMBeanServerName(String mbeanServerName) { + if (mbeanServerName == null || mbeanServerName.equals("-")) { + this.mbeanServerName = null; + } else if (mbeanServerName.equals("")) { + this.mbeanServerName = "*"; + } else { + this.mbeanServerName = mbeanServerName; + } + } + + private void setMember(String member) { + if (member == null || member.equals("-")) + this.member = null; + else if (member.equals("")) + this.member = "*"; + else + this.member = member; + } + + /** + *

      Create a new JMXNamespacePermission object with the + * specified target name and actions.

      + * + *

      The target name is of the form + * "mbeanServerName::member[objectName]" where each part is + * optional. This target name must not be empty or null. + * If objectName is present, it is of + * the form namespace//MBeanName. + *

      + *

      + * For a permission you need, {@code mbeanServerName} is the + * name of the MBeanServer from + * which {@code objectName} is being accessed. + *

      + *

      + * For a permission you have, {@code mbeanServerName} is the + * name of the MBeanServer from + * which access to {@code objectName} is granted. + * It can also be a pattern, and if omitted, {@code "*"} is assumed, + * meaning that access to {@code objectName} is granted in all + * MBean servers in the JVM. + *

      + * + *

      The actions parameter contains a comma-separated list of the + * desired actions granted on the target name. It must not be + * empty or null.

      + * + * @param name the triplet "mbeanServerName::member[objectName]". + * If objectName is present, it is of + * the form namespace//MBeanName. + * @param actions the action string. + * + * @exception IllegalArgumentException if the name or + * actions is invalid. + */ + public JMXNamespacePermission(String name, String actions) { + super(name); + + parseName(); + + this.actions = actions; + parseActions(); + } + + /** + *

      Create a new JMXNamespacePermission object with the specified + * target name (namespace name, member, object name) and actions.

      + * + *

      The {@code MBeanServer} name, member and object name + * parameters define a target name of the form + * "mbeanServerName::member[objectName]" where each + * part is optional. This will be the result of {@link #getName()} on the + * resultant JMXNamespacePermission. + * If the mbeanServerName is empty or exactly {@code "*"}, then + * "{@code mbeanServerName::}" is omitted in that result. + *

      + * + *

      The actions parameter contains a comma-separated list of the + * desired actions granted on the target name. It must not be + * empty or null.

      + * + * @param mbeanServerName the name of the {@code MBeanServer} to which this + * permission applies. + * May be null or "-", which represents an MBeanServer name + * that is implied by any MBeanServer name but does not imply any other + * MBeanServer name. + * @param member the member to which this permission applies. May + * be null or "-", which represents a member that is + * implied by any member but does not imply any other member. + * @param objectName the object name to which this permission + * applies. + * May be null, which represents an object name that is + * implied by any object name but does not imply any other object + * name. If not null, the {@code objectName} must be of the + * form {@code //} - where {@code } + * can be a domain pattern, and {@code } can be an ObjectName + * pattern. + * For a permission you need, {@code } is the name of the + * name space for which the permission is checked, and {@code } + * is the name of the MBean in that namespace. + * The composed name {@code //} thus represents the + * name of the MBean as seen by the {@code mbeanServerName} containing + * {@code }. + * + * @param actions the action string. + */ + public JMXNamespacePermission( + String mbeanServerName, + String member, + ObjectName objectName, + String actions) { + this(mbeanServerName, member, objectName, false, actions); +// this(member, objectName, false, actions); + } + + /** + *

      Create a new JMXNamespacePermission object with the specified + * MBean Server name, member, and actions.

      + * + *

      The {@code MBeanServer} name and member + * parameters define a target name of the form + * "mbeanServerName::member[]" where each + * part is optional. This will be the result of {@link #getName()} on the + * resultant JMXNamespacePermission. + * If the mbeanServerName is empty or exactly {@code "*"}, then + * "{@code mbeanServerName::}" is omitted in that result. + *

      + * + *

      The actions parameter contains a comma-separated list of the + * desired actions granted on the target name. It must not be + * empty or null.

      + * + * @param mbeanServerName the name of the {@code MBeanServer} to which this + * permission applies. + * May be null or "-", which represents an MBeanServer name + * that is implied by any MBeanServer name but does not imply any other + * MBeanServer name. + * @param member the member to which this permission applies. May + * be null or "-", which represents a member that is + * implied by any member but does not imply any other member. + * @param actions the action string. + */ + public JMXNamespacePermission(String mbeanServerName, + String member, + String actions) { + this(mbeanServerName,member,null,true,actions); + // this(member,null,allnames,actions); + } + + /** + *

      Create a new JMXNamespacePermission object with the specified + * target name (namespace name, member, object name) and actions.

      + * + *

      The MBean Server name, member and object name parameters define a + * target name of the form + * "mbeanServerName::member[objectName]" where each part is + * optional. This will be the result of {@link + * java.security.Permission#getName() getName()} on the + * resultant JMXNamespacePermission.

      + * + *

      The actions parameter contains a comma-separated list of the + * desired actions granted on the target name. It must not be + * empty or null.

      + * + * @param mbeanServerName the name of the {@code MBeanServer} to which this + * permission applies. + * May be null or "-", which represents an MBeanServer name + * that is implied by any MBeanServer name but does not imply any other + * MBeanServer name. + * @param member the member to which this permission applies. May + * be null or "-", which represents a member that is + * implied by any member but does not imply any other member. + * @param objectName the object name to which this permission + * applies. If null, and allnames is false, represents an object + * name that is implied by any object name but does not imply any + * other object name. Otherwise, if allnames is true, it represents + * a meta wildcard that matches all object names. It is equivalent to + * a missing objectName ("[]") in the {@link + * java.security.Permission#getName() name} property. + * @param allnames represent a meta wildcard indicating that the + * objectName was not specified. This implies all objectnames + * that match "*:*" and all object names that match + * "**//*:*" + * @param actions the action string. + */ + private JMXNamespacePermission(String mbeanServerName, + String member, + ObjectName objectName, + boolean allnames, + String actions) { + + super(makeName(mbeanServerName, + member, objectName, allnames)); + initName(mbeanServerName, + member, objectName, allnames); + + this.actions = actions; + parseActions(); + } + + private static String makeName(String mbeanServerName, + String memberName, ObjectName objName, boolean allMBeans) { + final StringBuilder name = new StringBuilder(); + if (mbeanServerName == null) + mbeanServerName = "-"; + if (!mbeanServerName.equals("") && !mbeanServerName.equals("*")) + name.append(mbeanServerName).append("::"); + if (memberName == null) + memberName = "-"; + name.append(memberName); + if (objName == null) { + if (allMBeans) + name.append("[]"); + else + name.append("[-]"); + } else { + final String domain = objName.getDomain(); + final int seplen = JMXNamespaces.NAMESPACE_SEPARATOR.length(); + final int sepc = domain.indexOf(JMXNamespaces.NAMESPACE_SEPARATOR); + if (sepc < 0 || (sepc+seplen)==domain.length()) { + throw new IllegalArgumentException(String.valueOf(objName)+ + ": no namespace in domain"); + } + final String can = objName.getCanonicalName(); + name.append("[").append(can).append("]"); + } + return name.toString(); + } + + /** + * Returns the "canonical string representation" of the actions. That is, + * this method always returns actions in alphabetical order. + * + * @return the canonical string representation of the actions. + */ + public String getActions() { + + if (actions == null) + actions = getActions(this.mask); + + return actions; + } + + /** + * Returns the "canonical string representation" + * of the actions from the mask. + */ + private static String getActions(int mask) { + final StringBuilder sb = new StringBuilder(); + boolean comma = false; + + if ((mask & AddNotificationListener) == AddNotificationListener) { + comma = true; + sb.append("addNotificationListener"); + } + + if ((mask & GetAttribute) == GetAttribute) { + if (comma) sb.append(','); + else comma = true; + sb.append("getAttribute"); + } + + if ((mask & GetClassLoader) == GetClassLoader) { + if (comma) sb.append(','); + else comma = true; + sb.append("getClassLoader"); + } + + if ((mask & GetClassLoaderFor) == GetClassLoaderFor) { + if (comma) sb.append(','); + else comma = true; + sb.append("getClassLoaderFor"); + } + + if ((mask & GetClassLoaderRepository) == GetClassLoaderRepository) { + if (comma) sb.append(','); + else comma = true; + sb.append("getClassLoaderRepository"); + } + + if ((mask & GetMBeanInfo) == GetMBeanInfo) { + if (comma) sb.append(','); + else comma = true; + sb.append("getMBeanInfo"); + } + + if ((mask & GetObjectInstance) == GetObjectInstance) { + if (comma) sb.append(','); + else comma = true; + sb.append("getObjectInstance"); + } + + if ((mask & Instantiate) == Instantiate) { + if (comma) sb.append(','); + else comma = true; + sb.append("instantiate"); + } + + if ((mask & Invoke) == Invoke) { + if (comma) sb.append(','); + else comma = true; + sb.append("invoke"); + } + + if ((mask & IsInstanceOf) == IsInstanceOf) { + if (comma) sb.append(','); + else comma = true; + sb.append("isInstanceOf"); + } + + if ((mask & QueryMBeans) == QueryMBeans) { + if (comma) sb.append(','); + else comma = true; + sb.append("queryMBeans"); + } + + if ((mask & QueryNames) == QueryNames) { + if (comma) sb.append(','); + else comma = true; + sb.append("queryNames"); + } + + if ((mask & RegisterMBean) == RegisterMBean) { + if (comma) sb.append(','); + else comma = true; + sb.append("registerMBean"); + } + + if ((mask & RemoveNotificationListener) == RemoveNotificationListener) { + if (comma) sb.append(','); + else comma = true; + sb.append("removeNotificationListener"); + } + + if ((mask & SetAttribute) == SetAttribute) { + if (comma) sb.append(','); + else comma = true; + sb.append("setAttribute"); + } + + if ((mask & UnregisterMBean) == UnregisterMBean) { + if (comma) sb.append(','); + else comma = true; + sb.append("unregisterMBean"); + } + + // No GetDomains because it is not possible to route a call to + // getDomains() on a NamespaceInterceptor - getDomains() doesn't + // have any ObjectName. + + return sb.toString(); + } + + @Override + public int hashCode() { + return this.getName().hashCode() + this.getActions().hashCode(); + } + + /** + * Converts an action String to an integer action mask. + * + * @param action the action string. + * @return the action mask. + */ + private static int getMask(String action) { + + /* + * BE CAREFUL HERE! PARSING ORDER IS IMPORTANT IN THIS ALGORITHM. + * + * The 'string length' test must be performed for the lengthiest + * strings first. + * + * In this permission if the "unregisterMBean" string length test is + * performed after the "registerMBean" string length test the algorithm + * considers the 'unregisterMBean' action as being the 'registerMBean' + * action and a parsing error is returned. + */ + + int mask = NONE; + + if (action == null) { + return mask; + } + + if (action.equals("*")) { + return ALL; + } + + char[] a = action.toCharArray(); + + int i = a.length - 1; + if (i < 0) + return mask; + + while (i != -1) { + char c; + + // skip whitespace + while ((i!=-1) && ((c = a[i]) == ' ' || + c == '\r' || + c == '\n' || + c == '\f' || + c == '\t')) + i--; + + // check for the known strings + int matchlen; + + // No GetDomains because it is not possible to route a call to + // getDomains() on a NamespaceInterceptor - getDomains() doesn't + // have any ObjectName. + + if (i >= 25 && /* removeNotificationListener */ + (a[i-25] == 'r') && + (a[i-24] == 'e') && + (a[i-23] == 'm') && + (a[i-22] == 'o') && + (a[i-21] == 'v') && + (a[i-20] == 'e') && + (a[i-19] == 'N') && + (a[i-18] == 'o') && + (a[i-17] == 't') && + (a[i-16] == 'i') && + (a[i-15] == 'f') && + (a[i-14] == 'i') && + (a[i-13] == 'c') && + (a[i-12] == 'a') && + (a[i-11] == 't') && + (a[i-10] == 'i') && + (a[i-9] == 'o') && + (a[i-8] == 'n') && + (a[i-7] == 'L') && + (a[i-6] == 'i') && + (a[i-5] == 's') && + (a[i-4] == 't') && + (a[i-3] == 'e') && + (a[i-2] == 'n') && + (a[i-1] == 'e') && + (a[i] == 'r')) { + matchlen = 26; + mask |= RemoveNotificationListener; + } else if (i >= 23 && /* getClassLoaderRepository */ + (a[i-23] == 'g') && + (a[i-22] == 'e') && + (a[i-21] == 't') && + (a[i-20] == 'C') && + (a[i-19] == 'l') && + (a[i-18] == 'a') && + (a[i-17] == 's') && + (a[i-16] == 's') && + (a[i-15] == 'L') && + (a[i-14] == 'o') && + (a[i-13] == 'a') && + (a[i-12] == 'd') && + (a[i-11] == 'e') && + (a[i-10] == 'r') && + (a[i-9] == 'R') && + (a[i-8] == 'e') && + (a[i-7] == 'p') && + (a[i-6] == 'o') && + (a[i-5] == 's') && + (a[i-4] == 'i') && + (a[i-3] == 't') && + (a[i-2] == 'o') && + (a[i-1] == 'r') && + (a[i] == 'y')) { + matchlen = 24; + mask |= GetClassLoaderRepository; + } else if (i >= 22 && /* addNotificationListener */ + (a[i-22] == 'a') && + (a[i-21] == 'd') && + (a[i-20] == 'd') && + (a[i-19] == 'N') && + (a[i-18] == 'o') && + (a[i-17] == 't') && + (a[i-16] == 'i') && + (a[i-15] == 'f') && + (a[i-14] == 'i') && + (a[i-13] == 'c') && + (a[i-12] == 'a') && + (a[i-11] == 't') && + (a[i-10] == 'i') && + (a[i-9] == 'o') && + (a[i-8] == 'n') && + (a[i-7] == 'L') && + (a[i-6] == 'i') && + (a[i-5] == 's') && + (a[i-4] == 't') && + (a[i-3] == 'e') && + (a[i-2] == 'n') && + (a[i-1] == 'e') && + (a[i] == 'r')) { + matchlen = 23; + mask |= AddNotificationListener; + } else if (i >= 16 && /* getClassLoaderFor */ + (a[i-16] == 'g') && + (a[i-15] == 'e') && + (a[i-14] == 't') && + (a[i-13] == 'C') && + (a[i-12] == 'l') && + (a[i-11] == 'a') && + (a[i-10] == 's') && + (a[i-9] == 's') && + (a[i-8] == 'L') && + (a[i-7] == 'o') && + (a[i-6] == 'a') && + (a[i-5] == 'd') && + (a[i-4] == 'e') && + (a[i-3] == 'r') && + (a[i-2] == 'F') && + (a[i-1] == 'o') && + (a[i] == 'r')) { + matchlen = 17; + mask |= GetClassLoaderFor; + } else if (i >= 16 && /* getObjectInstance */ + (a[i-16] == 'g') && + (a[i-15] == 'e') && + (a[i-14] == 't') && + (a[i-13] == 'O') && + (a[i-12] == 'b') && + (a[i-11] == 'j') && + (a[i-10] == 'e') && + (a[i-9] == 'c') && + (a[i-8] == 't') && + (a[i-7] == 'I') && + (a[i-6] == 'n') && + (a[i-5] == 's') && + (a[i-4] == 't') && + (a[i-3] == 'a') && + (a[i-2] == 'n') && + (a[i-1] == 'c') && + (a[i] == 'e')) { + matchlen = 17; + mask |= GetObjectInstance; + } else if (i >= 14 && /* unregisterMBean */ + (a[i-14] == 'u') && + (a[i-13] == 'n') && + (a[i-12] == 'r') && + (a[i-11] == 'e') && + (a[i-10] == 'g') && + (a[i-9] == 'i') && + (a[i-8] == 's') && + (a[i-7] == 't') && + (a[i-6] == 'e') && + (a[i-5] == 'r') && + (a[i-4] == 'M') && + (a[i-3] == 'B') && + (a[i-2] == 'e') && + (a[i-1] == 'a') && + (a[i] == 'n')) { + matchlen = 15; + mask |= UnregisterMBean; + } else if (i >= 13 && /* getClassLoader */ + (a[i-13] == 'g') && + (a[i-12] == 'e') && + (a[i-11] == 't') && + (a[i-10] == 'C') && + (a[i-9] == 'l') && + (a[i-8] == 'a') && + (a[i-7] == 's') && + (a[i-6] == 's') && + (a[i-5] == 'L') && + (a[i-4] == 'o') && + (a[i-3] == 'a') && + (a[i-2] == 'd') && + (a[i-1] == 'e') && + (a[i] == 'r')) { + matchlen = 14; + mask |= GetClassLoader; + } else if (i >= 12 && /* registerMBean */ + (a[i-12] == 'r') && + (a[i-11] == 'e') && + (a[i-10] == 'g') && + (a[i-9] == 'i') && + (a[i-8] == 's') && + (a[i-7] == 't') && + (a[i-6] == 'e') && + (a[i-5] == 'r') && + (a[i-4] == 'M') && + (a[i-3] == 'B') && + (a[i-2] == 'e') && + (a[i-1] == 'a') && + (a[i] == 'n')) { + matchlen = 13; + mask |= RegisterMBean; + } else if (i >= 11 && /* getAttribute */ + (a[i-11] == 'g') && + (a[i-10] == 'e') && + (a[i-9] == 't') && + (a[i-8] == 'A') && + (a[i-7] == 't') && + (a[i-6] == 't') && + (a[i-5] == 'r') && + (a[i-4] == 'i') && + (a[i-3] == 'b') && + (a[i-2] == 'u') && + (a[i-1] == 't') && + (a[i] == 'e')) { + matchlen = 12; + mask |= GetAttribute; + } else if (i >= 11 && /* getMBeanInfo */ + (a[i-11] == 'g') && + (a[i-10] == 'e') && + (a[i-9] == 't') && + (a[i-8] == 'M') && + (a[i-7] == 'B') && + (a[i-6] == 'e') && + (a[i-5] == 'a') && + (a[i-4] == 'n') && + (a[i-3] == 'I') && + (a[i-2] == 'n') && + (a[i-1] == 'f') && + (a[i] == 'o')) { + matchlen = 12; + mask |= GetMBeanInfo; + } else if (i >= 11 && /* isInstanceOf */ + (a[i-11] == 'i') && + (a[i-10] == 's') && + (a[i-9] == 'I') && + (a[i-8] == 'n') && + (a[i-7] == 's') && + (a[i-6] == 't') && + (a[i-5] == 'a') && + (a[i-4] == 'n') && + (a[i-3] == 'c') && + (a[i-2] == 'e') && + (a[i-1] == 'O') && + (a[i] == 'f')) { + matchlen = 12; + mask |= IsInstanceOf; + } else if (i >= 11 && /* setAttribute */ + (a[i-11] == 's') && + (a[i-10] == 'e') && + (a[i-9] == 't') && + (a[i-8] == 'A') && + (a[i-7] == 't') && + (a[i-6] == 't') && + (a[i-5] == 'r') && + (a[i-4] == 'i') && + (a[i-3] == 'b') && + (a[i-2] == 'u') && + (a[i-1] == 't') && + (a[i] == 'e')) { + matchlen = 12; + mask |= SetAttribute; + } else if (i >= 10 && /* instantiate */ + (a[i-10] == 'i') && + (a[i-9] == 'n') && + (a[i-8] == 's') && + (a[i-7] == 't') && + (a[i-6] == 'a') && + (a[i-5] == 'n') && + (a[i-4] == 't') && + (a[i-3] == 'i') && + (a[i-2] == 'a') && + (a[i-1] == 't') && + (a[i] == 'e')) { + matchlen = 11; + mask |= Instantiate; + } else if (i >= 10 && /* queryMBeans */ + (a[i-10] == 'q') && + (a[i-9] == 'u') && + (a[i-8] == 'e') && + (a[i-7] == 'r') && + (a[i-6] == 'y') && + (a[i-5] == 'M') && + (a[i-4] == 'B') && + (a[i-3] == 'e') && + (a[i-2] == 'a') && + (a[i-1] == 'n') && + (a[i] == 's')) { + matchlen = 11; + mask |= QueryMBeans; + } else if (i >= 9 && /* queryNames */ + (a[i-9] == 'q') && + (a[i-8] == 'u') && + (a[i-7] == 'e') && + (a[i-6] == 'r') && + (a[i-5] == 'y') && + (a[i-4] == 'N') && + (a[i-3] == 'a') && + (a[i-2] == 'm') && + (a[i-1] == 'e') && + (a[i] == 's')) { + matchlen = 10; + mask |= QueryNames; + } else if (i >= 5 && /* invoke */ + (a[i-5] == 'i') && + (a[i-4] == 'n') && + (a[i-3] == 'v') && + (a[i-2] == 'o') && + (a[i-1] == 'k') && + (a[i] == 'e')) { + matchlen = 6; + mask |= Invoke; + } else { + // parse error + throw new IllegalArgumentException("Invalid permission: " + + action); + } + + // make sure we didn't just match the tail of a word + // like "ackbarfaccept". Also, skip to the comma. + boolean seencomma = false; + while (i >= matchlen && !seencomma) { + switch(a[i-matchlen]) { + case ',': + seencomma = true; + break; + case ' ': case '\r': case '\n': + case '\f': case '\t': + break; + default: + throw new IllegalArgumentException("Invalid permission: " + + action); + } + i--; + } + + // point i at the location of the comma minus one (or -1). + i -= matchlen; + } + + return mask; + } + + /** + *

      Checks if this JMXNamespacePermission object "implies" the + * specified permission.

      + * + *

      More specifically, this method returns true if:

      + * + *
        + * + *
      • p is an instance of JMXNamespacePermission; and
      • + * + *
      • p has a null mbeanServerName or p's mbeanServerName + * matches this object's mbeanServerName; and
      • + * + *
      • p has a null member or p's member matches this + * object's member; and
      • + * + *
      • p has a null object name or p's + * object name matches this object's object name; and
      • + * + *
      • p's actions are a subset of this object's actions
      • + * + *
      + * + *

      If this object's mbeanServerName is a pattern, then p's + * mbeanServerName is matched against that pattern. An empty + * mbeanServerName is equivalent to "{@code *}". A null + * mbeanServerName is equivalent to "{@code -}".

      + *

      If this object's mbeanServerName is "*" or is + * empty, p's mbeanServerName always matches it.

      + * + *

      If this object's member is "*", p's + * member always matches it.

      + * + *

      If this object's objectName n1 is an object name pattern, + * p's objectName n2 matches it if + * {@link ObjectName#equals n1.equals(n2)} or if + * {@link ObjectName#apply n1.apply(n2)}.

      + * + *

      A permission that includes the queryMBeans action + * is considered to include queryNames as well.

      + * + * @param p the permission to check against. + * @return true if the specified permission is implied by this object, + * false if not. + */ + public boolean implies(Permission p) { + if (!(p instanceof JMXNamespacePermission)) + return false; + + JMXNamespacePermission that = (JMXNamespacePermission) p; + + // Actions + // + // The actions in 'this' permission must be a + // superset of the actions in 'that' permission + // + + /* "queryMBeans" implies "queryNames" */ + if ((this.mask & QueryMBeans) == QueryMBeans) { + if (((this.mask | QueryNames) & that.mask) != that.mask) { + //System.out.println("action [with QueryNames] does not imply"); + return false; + } + } else { + if ((this.mask & that.mask) != that.mask) { + //System.out.println("action does not imply"); + return false; + } + } + + // Target name + // + // The 'mbeanServerName' check is true iff: + // 1) the mbeanServerName in 'this' permission is omitted or "*", or + // 2) the mbeanServerName in 'that' permission is omitted or "*", or + // 3) the mbeanServerName in 'this' permission does pattern + // matching with the mbeanServerName in 'that' permission. + // + // The 'member' check is true iff: + // 1) the member in 'this' member is omitted or "*", or + // 2) the member in 'that' member is omitted or "*", or + // 3) the member in 'this' permission equals the member in + // 'that' permission. + // + // The 'object name' check is true iff: + // 1) the object name in 'this' permission is omitted, or + // 2) the object name in 'that' permission is omitted, or + // 3) the object name in 'this' permission does pattern + // matching with the object name in 'that' permission. + // + + if (that.mbeanServerName == null) { + // bottom is implied + } else if (this.mbeanServerName == null) { + // bottom implies nothing but itself + return false; + } else if (that.mbeanServerName.equals(this.mbeanServerName)) { + // exact match + } else if (!Util.wildmatch(that.mbeanServerName,this.mbeanServerName)) { + return false; // no match + } + + /* Check if this.member implies that.member */ + + if (that.member == null) { + // bottom is implied + } else if (this.member == null) { + // bottom implies nothing but itself + return false; + } else if (this.member.equals("*")) { + // wildcard implies everything (including itself) + } else if (this.member.equals(that.member)) { + // exact match + } else if (!Util.wildmatch(that.member,this.member)) { + return false; // no match + } + + /* Check if this.objectName implies that.objectName */ + + if (that.objectName == null) { + // bottom is implied + } else if (this.objectName == null) { + // bottom implies nothing but itself + if (allnames == false) return false; + } else if (!this.objectName.apply(that.objectName)) { + /* ObjectName.apply returns false if that.objectName is a + wildcard so we also allow equals for that case. This + never happens during real permission checks, but means + the implies relation is reflexive. */ + if (!this.objectName.equals(that.objectName)) + return false; + } + + return true; + } + + /** + * Checks two JMXNamespacePermission objects for equality. Checks + * that obj is an JMXNamespacePermission, and has the same + * name and actions as this object. + *

      + * @param obj the object we are testing for equality with this object. + * @return true if obj is an JMXNamespacePermission, and has the + * same name and actions as this JMXNamespacePermission object. + */ + public boolean equals(Object obj) { + if (obj == this) + return true; + + if (! (obj instanceof JMXNamespacePermission)) + return false; + + JMXNamespacePermission that = (JMXNamespacePermission) obj; + + return (this.mask == that.mask) && + (this.getName().equals(that.getName())); + } + + /** + * Deserialize this object based on its name and actions. + */ + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException { + in.defaultReadObject(); + parseName(); + parseActions(); + } +} diff --git a/jdk/src/share/classes/javax/management/namespace/JMXNamespaceView.java b/jdk/src/share/classes/javax/management/namespace/JMXNamespaceView.java new file mode 100644 index 00000000000..eacc0f4bce7 --- /dev/null +++ b/jdk/src/share/classes/javax/management/namespace/JMXNamespaceView.java @@ -0,0 +1,300 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.namespace; + +import java.io.IOException; +import java.util.Set; +import javax.management.MBeanServer; +import javax.management.MBeanServerConnection; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; + +/** + * This class makes it possible to navigate easily within a hierarchical + * namespace view. + * + *

      + * MBeanServerConnnection rootConnection = ...;
      + *
      + * // create a view at the local root of the namespace hierarchy.
      + * //
      + * JMXNamespaceView view = new JMXNamespaceView(rootConnection);
      + *
      + * // list all top level namespaces
      + * String[] list = view.list();
      + *
      + * // select one namespace from the list
      + * String whereToGo = ... ;
      + *
      + * // go down to the selected namespace:
      + * view = view.down(whereToGo);
      + * System.out.println("I am now in: " + view.where());
      + * System.out.println("I can see these MBeans:" +
      + *    view.getMBeanServerConnection().queryNames(null,null));
      + *
      + * // list sub namespaces in current view ('whereToGo')
      + * list = view.list();
      + * System.out.println("Here are the sub namespaces of "+view.where()+": "+
      + *                    Arrays.toString(list));
      + *
      + * // go up one level
      + * view = view.up();
      + * System.out.println("I am now back to: " +
      + *    (view.isRoot() ? "root namespace" : view.where()));
      + * 
      + * @since 1.7 + */ +public class JMXNamespaceView { + + private static final ObjectName ALL_NAMESPACES; + static { + try { + ALL_NAMESPACES = ObjectName.getInstance("*" + + JMXNamespaces.NAMESPACE_SEPARATOR + ":"+ + JMXNamespace.TYPE_ASSIGNMENT); + } catch (MalformedObjectNameException x) { + throw new ExceptionInInitializerError(x); + } + } + private static final int NAMESPACE_SEPARATOR_LENGTH = + JMXNamespaces.NAMESPACE_SEPARATOR.length(); + + private final JMXNamespaceView parent; + private final MBeanServerConnection here; + private final String where; + + private static MBeanServerConnection checkRoot(MBeanServerConnection root) { + if (root == null) + throw new IllegalArgumentException( + "namespaceRoot: null is not a valid value"); + return root; + } + + /** + * Creates a view at the top of a JMX namespace hierarchy. + * @param namespaceRoot The {@code MBeanServerConnection} at the + * top of the hierarchy. + */ + public JMXNamespaceView(MBeanServerConnection namespaceRoot) { + this(null,checkRoot(namespaceRoot),""); + } + + // This constructor should remain private. A user can only create + // JMXNamespaceView at the top of the hierarchy. + // JMXNamespaceView sub nodes are created by their parent nodes. + private JMXNamespaceView(JMXNamespaceView parent, + MBeanServerConnection here, String where) { + this.parent = parent; + this.here = here; + this.where = where; + } + + /** + * Returns the path leading to the namespace in this view, from + * the top of the hierarchy. + * @return The path to the namespace in this view. + */ + public String where() { + return where; + } + + /** + * Lists all direct sub namespaces in this view. The returned strings + * do not contain the {@code //} separator. + * + * @return A list of direct sub name spaces accessible from this + * namespace. + * @throws IOException if the attempt to list the namespaces fails because + * of a communication problem. + */ + public String[] list() throws IOException { + final Set names = + here.queryNames(ALL_NAMESPACES,null); + final String[] res = new String[names.size()]; + int i = 0; + for (ObjectName dirName : names) { + final String dir = dirName.getDomain(); + res[i++]=dir.substring(0,dir.length()-NAMESPACE_SEPARATOR_LENGTH); + } + return res; + } + + /** + * Go down into a sub namespace. + * @param namespace the namespace to go down to. It can contain one or + * more {@code //} separators, to traverse intermediate namespaces, but + * it must not begin or end with {@code //} or contain an empty + * intermediate namespace. If it is the empty string, then {@code this} is + * returned. + * @return A view of the named sub namespace. + * @throws IllegalArgumentException if the {@code namespace} begins or + * ends with {@code //}. + */ + public JMXNamespaceView down(String namespace) { + if (namespace.equals("")) return this; + if (namespace.startsWith(JMXNamespaces.NAMESPACE_SEPARATOR)) + throw new IllegalArgumentException(namespace+": can't start with "+ + JMXNamespaces.NAMESPACE_SEPARATOR); + + // This is a convenience to handle paths like xxx//yyy + final String[] elts = + namespace.split(JMXNamespaces.NAMESPACE_SEPARATOR); + + // Go down the path, creating all sub namespaces along the way. + // Usually there will be a single element in the given namespace + // name, but we don't want to forbid things like + // down("xxx//yyy/www"); + // + JMXNamespaceView previous = this; + String cursor = where; + for (String elt : elts) { + // empty path elements are not allowed. It means we + // had something like "xxx////yyy" + if (elt.equals("")) + throw new IllegalArgumentException(namespace+ + ": invalid path element"); + + // compute the "where" for the child. + cursor = JMXNamespaces.concat(cursor, elt); + + // create the child... + final JMXNamespaceView next = + makeJMXNamespaceView(root(), previous, cursor); + + // the current child will be the parent of the next child... + previous = next; + } + + // We return the last child that was created. + return previous; + } + + /** + * Go back up one level. If this view is at the root of the + * hierarchy, returns {@code null}. + * @return A view of the parent namespace, or {@code null} if we're at + * the root of the hierarchy. + */ + public JMXNamespaceView up() { + return parent; + } + + /** + * Tells whether this view is at the root of the hierarchy. + * @return {@code true} if this view is at the root of the hierachy. + */ + public boolean isRoot() { + return parent == null; + } + + /** + * Returns the view at the root of the hierarchy. + * If we are already at the root, this is {@code this}. + * @return the view at the root of the hierarchy. + */ + public JMXNamespaceView root() { + if (parent == null) return this; + return parent.root(); + } + + /** + * A MBeanServerConnection to the namespace shown by this view. + * This is what would have been obtained by doing: + *
      +     *   JMX.narrowToNamespace(this.root().getMBeanServerConnection(),
      +     *       this.where());
      +     * 
      + * @return A MBeanServerConnection to the namespace shown by this view. + */ + public MBeanServerConnection getMBeanServerConnection() { + return here; + } + + /** + *

      Get the name of the JMXNamespaceMBean handling the namespace shown by + * this view, relative to the root of the hierarchy. If we are at the root + * of the hierarchy, this method returns {@code null}.

      + * + *

      You can use this method to make a proxy for the JMXNamespaceMBean + * as follows:

      + * + *
      +     * JMXNamespaceView view = ...;
      +     * ObjectName namespaceMBeanName = view.getJMXNamespaceMBeanName();
      +     * JMXNamespaceMBean namespaceMBean = JMX.newMBeanProxy(
      +     *     view.root().getMBeanServerConnection(), namespaceMBeanName,
      +     *     JMXNamespaceMBean.class);
      +     * 
      + * + * @return The name of the {@code JMXNamespaceMBean} handling the namespace + * shown by this view, or {@code null}. + */ + public ObjectName getJMXNamespaceMBeanName() { + if (parent == null) + return null; + else + return JMXNamespaces.getNamespaceObjectName(where); + } + + @Override + public int hashCode() { + return where.hashCode(); + } + + /** + * Returns true if this object is equal to the given object. The + * two objects are equal if the other object is also a {@code + * JMXNamespaceView} and both objects have the same {@linkplain #root root} + * MBeanServerConnection and the same {@linkplain #where path}. + * @param o the other object to compare to. + * @return true if both objects are equal. + */ + @Override + public boolean equals(Object o) { + if (o==this) return true; + if (! (o instanceof JMXNamespaceView)) return false; + if (!where.equals(((JMXNamespaceView)o).where)) return false; + return root().getMBeanServerConnection().equals( + ((JMXNamespaceView)o).root().getMBeanServerConnection()); + } + + private JMXNamespaceView makeJMXNamespaceView(final JMXNamespaceView root, + final JMXNamespaceView directParent, final String pathFromRoot) { + if (pathFromRoot.equals("")) return root; + + return new JMXNamespaceView(directParent, + narrowToNamespace(root.getMBeanServerConnection(), + pathFromRoot),pathFromRoot); + } + + private MBeanServerConnection narrowToNamespace(MBeanServerConnection root, + String path) { + if (root instanceof MBeanServer) + return JMXNamespaces.narrowToNamespace((MBeanServer)root, path); + return JMXNamespaces.narrowToNamespace(root, path); + } + +} diff --git a/jdk/src/share/classes/javax/management/namespace/JMXNamespaces.java b/jdk/src/share/classes/javax/management/namespace/JMXNamespaces.java new file mode 100644 index 00000000000..429a9d466d6 --- /dev/null +++ b/jdk/src/share/classes/javax/management/namespace/JMXNamespaces.java @@ -0,0 +1,378 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.namespace; + +import com.sun.jmx.defaults.JmxProperties; +import com.sun.jmx.namespace.JMXNamespaceUtils; +import com.sun.jmx.namespace.ObjectNameRouter; +import com.sun.jmx.namespace.serial.RewritingProcessor; +import com.sun.jmx.namespace.RoutingConnectionProxy; +import com.sun.jmx.namespace.RoutingServerProxy; + +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.management.MBeanServer; +import javax.management.MBeanServerConnection; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; +import javax.management.remote.JMXConnector; + +/** + * Static constants and utility methods to help work with + * JMX name spaces. There are no instances of this class. + * @since 1.7 + */ +public class JMXNamespaces { + + /** + * A logger for this class. + **/ + private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER; + + /** Creates a new instance of JMXNamespaces */ + private JMXNamespaces() { + } + + /** + * The name space separator. This is an alias for {@link + * ObjectName#NAMESPACE_SEPARATOR}. + **/ + public static final String NAMESPACE_SEPARATOR = + ObjectName.NAMESPACE_SEPARATOR; + private static final int NAMESPACE_SEPARATOR_LENGTH = + NAMESPACE_SEPARATOR.length(); + + + /** + * Returns a connector connected to a sub name space exposed through + * the parent connector. + * @param parent the parent connector. + * @param namespace the {@linkplain javax.management.namespace name space} + * to which the returned connector is + * connected. + * @return A connector connected to a sub name space exposed through + * the parent connector. + **/ + public static JMXConnector narrowToNamespace(final JMXConnector parent, + final String namespace) + throws IOException { + + return JMXNamespaceUtils.cd(parent,namespace,true); + } + + /** + * Creates a new {@code MBeanServerConnection} proxy on a + * {@linkplain javax.management.namespace sub name space} + * of the given parent. + * + * @param parent The parent {@code MBeanServerConnection} that contains + * the name space. + * @param namespace The {@linkplain javax.management.namespace + * name space} in which to narrow. + * @return A new {@code MBeanServerConnection} proxy that shows the content + * of that name space. + * @throws IllegalArgumentException if the name space does not exist, or + * if a proxy for that name space cannot be created. + */ + public static MBeanServerConnection narrowToNamespace( + MBeanServerConnection parent, + String namespace) { + if (LOG.isLoggable(Level.FINER)) + LOG.finer("Making MBeanServerConnection for: " +namespace); + return RoutingConnectionProxy.cd(parent,namespace); + } + + /** + * Creates a new {@code MBeanServer} proxy on a + * {@linkplain javax.management.namespace sub name space} + * of the given parent. + * + * @param parent The parent {@code MBeanServer} that contains + * the name space. + * @param namespace The {@linkplain javax.management.namespace + * name space} in which to narrow. + * @return A new {@code MBeanServer} proxy that shows the content + * of that name space. + * @throws IllegalArgumentException if either argument is null, + * or the name space does not exist, or if a proxy for that name space + * cannot be created. + */ + public static MBeanServer narrowToNamespace(MBeanServer parent, + String namespace) { + if (LOG.isLoggable(Level.FINER)) + LOG.finer("Making NamespaceServerProxy for: " +namespace); + return RoutingServerProxy.cd(parent,namespace); + } + + /** + * Returns an object that is the same as the given object except that + * any {@link ObjectName} it might contain has its domain modified. + * The returned object might be identical to the given object if it + * does not contain any {@code ObjectName} values or if none of them + * were modified. + * This method will replace a prefix ({@code toRemove}) from the path of + * the ObjectNames contained in {@code obj} by another prefix + * ({@code toAdd}). + * Therefore, all contained ObjectNames must have a path that start with + * the given {@code toRemove} prefix. If one of them doesn't, an {@link + * IllegalArgumentException} is thrown. + *

      + * For instance, if {@code obj} contains the ObjectName + * {@code x//y//z//d:k=x}, and {@code toAdd} is {@code v//w}, and + * {@code toRemove} + * is {@code x//y} this method will return a copy of {@code obj} that + * contains {@code v//w//z//d:k=x}.
      + * On the other hand, if {@code obj} contains the ObjectName + * {@code x//y//z//d:k=x}, and {@code toAdd} is {@code v//w}, and + * {@code toRemove} is {@code v} this method + * will raise an exception, because {@code x//y//z//d:k=x} doesn't start + * with {@code v} + *

      + *

      Note: the default implementation of this method can use the + * Java serialization framework to clone and replace ObjectNames in the + * provided {@code obj}. It will usually fail if {@code obj} is not + * Java serializable, or contains objects which are not Java + * serializable. + *

      + * @param obj The object to deep-rewrite + * @param toRemove a prefix already present in contained ObjectNames. + * If {@code toRemove} is the empty string {@code ""}, nothing + * will be removed from the contained ObjectNames. + * @param toAdd the prefix that will replace (@code toRemove} in contained + * ObjectNames. + * If {@code toAdd} is the empty string {@code ""}, nothing + * will be added to the contained ObjectNames. + * @return the rewritten object, or possibly {@code obj} if nothing needed + * to be changed. + * @throws IllegalArgumentException if {@code obj} couldn't be rewritten or + * if {@code toRemove} or {@code toAdd} is null. + **/ + public static T deepReplaceHeadNamespace(T obj, String toRemove, String toAdd) { + final RewritingProcessor processor = + RewritingProcessor.newRewritingProcessor(toAdd,toRemove); + return processor.rewriteOutput(obj); + } + + /** + * Appends {@code namespace} to {@code path}. + * This methods appends {@code namespace} to {@code path} to obtain a + * a full path, and normalizes the result thus obtained: + *
        + *
      • If {@code path} is empty, the full path is + * {@code namespace}.
      • + *
      • Otherwise, if {@code namespace} is empty, + * the full path is {@code path}
      • + *
      • Otherwise, and this is the regular case, the full path is the + * result of the concatenation of + * {@code path}+{@value #NAMESPACE_SEPARATOR}+{@code namespace}
      • + *
      • finally, the full path is normalized: multiple consecutive + * occurrences of {@value #NAMESPACE_SEPARATOR} are replaced by a + * single {@value #NAMESPACE_SEPARATOR} in the result, and trailing + * occurences of {@value #NAMESPACE_SEPARATOR} are removed. + *
      • + *
      + * @param path a name space path prefix + * @param namespace a name space name to append to the path + * @return a syntactically valid name space path, or "" if both parameters + * are null or empty. + * @throws IllegalArgumentException if either argument is null or ends with + * an odd number of {@code /} characters. + **/ + public static String concat(String path, String namespace) { + if (path == null || namespace == null) + throw new IllegalArgumentException("Null argument"); + checkTrailingSlashes(path); + checkTrailingSlashes(namespace); + final String result; + if (path.equals("")) result=namespace; + else if (namespace.equals("")) result=path; + else result=path+NAMESPACE_SEPARATOR+namespace; + return ObjectNameRouter.normalizeNamespacePath(result,false,true,false); + } + + /** + * Returns a syntactically valid name space path. + * If the provided {@code namespace} ends with {@code "//"}, + * recursively strips trailing {@code "//"}. Each sequence of an + * even number of {@code "/"} characters is also replaced by {@code "//"}, + * for example {@code "foo//bar////baz/////buh"} will become + * {@code "foo//bar//baz///buh"}. + * + * @param namespace A name space path + * @return {@code ""} - if the provided {@code namespace} resolves to + * the empty string; otherwise a syntactically valid name space string + * stripped of trailing and redundant {@code "//"}. + * @throws IllegalArgumentException if {@code namespace} is null or + * is not syntactically valid (e.g. it contains + * invalid characters like ':', or it ends with an odd + * number of '/'). + */ + public static String normalizeNamespaceName(String namespace) { + if (namespace == null) + throw new IllegalArgumentException("Null namespace"); + final String sourcePath = + ObjectNameRouter.normalizeNamespacePath(namespace,false,true,false); + if (sourcePath.equals("")) return sourcePath; + + // Will throw an IllegalArgumentException if the namespace name + // is not syntactically valid... + // + getNamespaceObjectName(sourcePath); + return sourcePath; + } + + + /** + * Return a canonical handler name for the provided {@code namespace}, + * The handler name returned will be + * {@link #normalizeNamespaceName normalizeNamespaceName}{@code (namespace) + + * "//:type=JMXNamespace"}. + * + * @param namespace A name space path + * @return a canonical ObjectName for a name space handler. + * @see #normalizeNamespaceName + * @throws IllegalArgumentException if the provided + * {@code namespace} is null or not valid. + */ + public static ObjectName getNamespaceObjectName(String namespace) { + if (namespace == null || namespace.equals("")) + throw new IllegalArgumentException("Null or empty namespace"); + final String sourcePath = + ObjectNameRouter.normalizeNamespacePath(namespace,false, + true,false); + try { + // We could use Util.newObjectName here - but throwing an + // IllegalArgumentException that contains just the supplied + // namespace instead of the whole ObjectName seems preferable. + return ObjectName.getInstance(sourcePath+ + NAMESPACE_SEPARATOR+":"+ + JMXNamespace.TYPE_ASSIGNMENT); + } catch (MalformedObjectNameException x) { + throw new IllegalArgumentException("Invalid namespace: " + + namespace,x); + } + } + + /** + * Returns an ObjectName pattern that can be used to query for all MBeans + * contained in the given name space. + * For instance, if {@code namespace="foo//bar"}, this method will + * return {@code "foo//bar//*:*"} + * @return an ObjectName pattern that selects all MBeans in the given + * name space. + **/ + public static ObjectName getWildcardFor(String namespace) { + return insertPath(namespace,ObjectName.WILDCARD); + } + + + /** + * Returns an ObjectName that can be used to access an MBean + * contained in the given name space. + * For instance, if {@code path="foo//bar"}, and + * {@code to="domain:type=Thing"} this method will + * return {@code "foo//bar//domain:type=Thing"} + * @return an ObjectName that can be used to invoke an MBean located in a + * sub name space. + * @throws IllegalArgumentException if {@code path} ends with an + * odd number of {@code /} characters. + **/ + public static ObjectName insertPath(String path, ObjectName to) { + if (path == null || to == null) + throw new IllegalArgumentException("Null argument"); + checkTrailingSlashes(path); + try { + String prefix = path; + if (!prefix.equals("")) prefix = + ObjectNameRouter.normalizeNamespacePath( + prefix + NAMESPACE_SEPARATOR,false,false,false); + return to.withDomain( + ObjectNameRouter.normalizeDomain( + prefix+to.getDomain(),false)); + } catch (MalformedObjectNameException x) { + throw new IllegalArgumentException(path+": "+x,x); + } + } + + /** + * Returns the normalized name space path of the name space expected to + * contain {@code ObjectName}. + * For instance, for {@code "foo//domain:type=Thing"} this will be + * {@code "foo"}. For {@code "//foo//bar//domain:type=Thing"} this will be + * {@code "foo//bar"}. For {@code //foo//bar//baz//domain:type=Thing} + * this will be {@code "foo//bar//baz"}. For + * {@code //foo//bar//baz//:type=JMXNamespace} + * this will be {@code "foo//bar"}. + * + * @param name an {@code ObjectName} + * @return the name space path of the name space that could contain such + * a name. If {@code name} has no name space, returns {@code ""}. + * @throws IllegalArgumentException if {@code name} is null. + **/ + public static String getContainingNamespace(ObjectName name) { + return getNormalizedPath(name,true); + } + + + static String getNormalizedPath(ObjectName name, + boolean removeLeadingSep) { + if (name == null) + throw new IllegalArgumentException("Null name"); + String domain = + ObjectNameRouter.normalizeDomain(name.getDomain(),removeLeadingSep); + int end = domain.length(); + + // special case of domain part being a single '/' + // + if (domain.endsWith(NAMESPACE_SEPARATOR+"/")) + return domain.substring(0,end-NAMESPACE_SEPARATOR_LENGTH-1); + + // special case of namespace handler + // + if (domain.endsWith(NAMESPACE_SEPARATOR)) + domain = domain.substring(0,end-NAMESPACE_SEPARATOR_LENGTH); + + int last = domain.lastIndexOf(NAMESPACE_SEPARATOR); + if (last < 0) return ""; + if (last == 0) return domain; + + // special case of domain part starting with '/' + // last=0 is not possible - we took care of this above. + if (domain.charAt(last-1) == '/') last--; + + return domain.substring(0,last); + } + + private static void checkTrailingSlashes(String path) { + int i; + for (i = path.length() - 1; i >= 0 && path.charAt(i) == '/'; i--) + continue; + if (path.length() - i % 2 == 0) + throw new IllegalArgumentException("Path ends with odd number of /"); + } +} diff --git a/jdk/src/share/classes/javax/management/namespace/JMXRemoteNamespace.java b/jdk/src/share/classes/javax/management/namespace/JMXRemoteNamespace.java new file mode 100644 index 00000000000..6958f57f2d7 --- /dev/null +++ b/jdk/src/share/classes/javax/management/namespace/JMXRemoteNamespace.java @@ -0,0 +1,734 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.namespace; + +import com.sun.jmx.defaults.JmxProperties; +import com.sun.jmx.mbeanserver.Util; +import com.sun.jmx.namespace.JMXNamespaceUtils; +import com.sun.jmx.remote.util.EnvHelp; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicLong; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.management.AttributeChangeNotification; + +import javax.management.InstanceNotFoundException; +import javax.management.ListenerNotFoundException; +import javax.management.MBeanNotificationInfo; +import javax.management.MBeanServerConnection; +import javax.management.Notification; +import javax.management.NotificationBroadcasterSupport; +import javax.management.NotificationEmitter; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.ObjectName; +import javax.management.event.EventClient; +import javax.management.remote.JMXConnectionNotification; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXServiceURL; + +/** + * A {@link JMXNamespace} that will connect to a remote MBeanServer + * by creating a {@link javax.management.remote.JMXConnector} from a + * {@link javax.management.remote.JMXServiceURL}. + *

      + * You can call {@link #connect() connect()} and {@link #close close()} + * several times. This MBean will emit an {@link AttributeChangeNotification} + * when the value of its {@link #isConnected Connected} attribute changes. + *

      + *

      + * The JMX Remote Namespace MBean is not connected until {@link + * #connect() connect()} is explicitly called. The usual sequence of code to + * create a JMX Remote Namespace is thus: + *

      + *
      + *     final String namespace = "mynamespace";
      + *     final ObjectName name = {@link JMXNamespaces#getNamespaceObjectName
      + *       JMXNamespaces.getNamespaceObjectName(namespace)};
      + *     final JMXServiceURL remoteServerURL = .... ;
      + *     final Map optionsMap = .... ;
      + *     final MBeanServer masterMBeanServer = .... ;
      + *     final JMXRemoteNamespace namespaceMBean = {@link #newJMXRemoteNamespace
      + *        JMXRemoteNamespace.newJMXRemoteNamespace(remoteServerURL, optionsMap)};
      + *     masterMBeanServer.registerMBean(namespaceMBean, name);
      + *     namespaceMBean.connect();
      + *     // or: masterMBeanServer.invoke(name, {@link #connect() "connect"}, null, null);
      + * 
      + *

      + * The JMX Remote Namespace MBean will register for {@linkplain + * JMXConnectionNotification JMX Connection Notifications} with its underlying + * {@link JMXConnector}. When a JMX Connection Notification indicates that + * the underlying connection has failed, the JMX Remote Namespace MBean + * closes its underlying connector and switches its {@link #isConnected + * Connected} attribute to false, emitting an {@link + * AttributeChangeNotification}. + *

      + *

      + * At this point, a managing application (or an administrator connected + * through a management console) can attempt to reconnect the + * JMX Remote Namespace MBean by calling its {@link #connect() connect()} method + * again. + *

      + *

      Note that when the connection with the remote namespace fails, or when + * {@link #close} is called, then any notification subscription to + * MBeans registered in that namespace will be lost - unless a custom + * {@linkplain javax.management.event event service} supporting connection-less + * mode was used. + *

      + * @since 1.7 + */ +public class JMXRemoteNamespace + extends JMXNamespace + implements JMXRemoteNamespaceMBean, NotificationEmitter { + + /** + * A logger for this class. + */ + private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER; + + + // This connection listener is used to listen for connection events from + // the underlying JMXConnector. It is used in particular to maintain the + // "connected" state in this MBean. + // + private class ConnectionListener implements NotificationListener { + private ConnectionListener() { + } + public void handleNotification(Notification notification, + Object handback) { + if (!(notification instanceof JMXConnectionNotification)) + return; + final JMXConnectionNotification cn = + (JMXConnectionNotification)notification; + final String type = cn.getType(); + if (JMXConnectionNotification.CLOSED.equals(type) + || JMXConnectionNotification.FAILED.equals(type)) { + checkState(this,cn,(JMXConnector)handback); + } + } + } + + // When the JMXRemoteNamespace is originally created, it is not connected, + // which means that the source MBeanServer should be one that throws + // exceptions for most methods. When it is subsequently connected, + // the methods should be forwarded to the MBeanServerConnection. + // We handle this using MBeanServerConnectionWrapper. The + // MBeanServerConnection that is supplied to the constructor of + // MBeanServerConnectionWrapper is ignored (and in fact it is null) + // because the one that is actually used is the one supplied by the + // override of getMBeanServerConnection(). + private static class JMXRemoteNamespaceDelegate + extends MBeanServerConnectionWrapper { + private volatile JMXRemoteNamespace parent=null; + + JMXRemoteNamespaceDelegate() { + super(null,null); + } + @Override + public MBeanServerConnection getMBeanServerConnection() { + return parent.getMBeanServerConnection(); + } + @Override + public ClassLoader getDefaultClassLoader() { + return parent.getDefaultClassLoader(); + } + + // Because this class is instantiated in the super() call from the + // constructor of JMXRemoteNamespace, it cannot be an inner class. + // This method achieves the effect that an inner class would have + // had, of giving the class a reference to the outer "this". + synchronized void initParentOnce(JMXRemoteNamespace parent) { + if (this.parent != null) + throw new UnsupportedOperationException("parent already set"); + this.parent=parent; + + } + + } + + private static final MBeanNotificationInfo connectNotification = + new MBeanNotificationInfo(new String[] { + AttributeChangeNotification.ATTRIBUTE_CHANGE}, + "Connected", + "Emitted when the Connected state of this object changes"); + + private static AtomicLong seqNumber = new AtomicLong(0); + + private final NotificationBroadcasterSupport broadcaster; + private final ConnectionListener listener; + private final JMXServiceURL jmxURL; + private final Map optionsMap; + + private volatile MBeanServerConnection server = null; + private volatile JMXConnector conn = null; + private volatile ClassLoader defaultClassLoader = null; + + /** + * Creates a new instance of {@code JMXRemoteNamespace}. + *

      + * This constructor is provided for subclasses. + * To create a new instance of {@code JMXRemoteNamespace} call + * {@link #newJMXRemoteNamespace + * JMXRemoteNamespace.newJMXRemoteNamespace(sourceURL, optionsMap)}. + *

      + * @param sourceURL a JMX service URL that can be used to {@linkplain + * #connect() connect} to the + * source MBean Server. The source MBean Server is the remote + * MBean Server which contains the MBeans that will be mirrored + * in this namespace. + * @param optionsMap the options map that will be passed to the + * {@link JMXConnectorFactory} when {@linkplain + * JMXConnectorFactory#newJMXConnector creating} the + * {@link JMXConnector} used to {@linkplain #connect() connect} + * to the remote source MBean Server. Can be null, which is + * equivalent to an empty map. + * @see #newJMXRemoteNamespace JMXRemoteNamespace.newJMXRemoteNamespace + * @see #connect + */ + protected JMXRemoteNamespace(JMXServiceURL sourceURL, + Map optionsMap) { + super(new JMXRemoteNamespaceDelegate()); + ((JMXRemoteNamespaceDelegate)super.getSourceServer()). + initParentOnce(this); + + // URL must not be null. + this.jmxURL = JMXNamespaceUtils.checkNonNull(sourceURL,"url"); + this.broadcaster = + new NotificationBroadcasterSupport(connectNotification); + + // handles options + this.optionsMap = JMXNamespaceUtils.unmodifiableMap(optionsMap); + + // handles (dis)connection events + this.listener = new ConnectionListener(); + } + + /** + * Returns the {@code JMXServiceURL} that is (or will be) used to + * connect to the remote name space.

      + * @see #connect + * @return The {@code JMXServiceURL} used to connect to the remote + * name space. + */ + public JMXServiceURL getJMXServiceURL() { + return jmxURL; + } + + /** + * In this class, this method never returns {@code null}, and the + * address returned is the {@link #getJMXServiceURL JMXServiceURL} + * that is used by this object to {@linkplain #connect} to the remote + * name space.

      + * This behaviour might be overriden by subclasses, if needed. + * For instance, a subclass might want to return {@code null} if it + * doesn't want to expose that JMXServiceURL. + */ + public JMXServiceURL getAddress() { + return getJMXServiceURL(); + } + + private Map getEnvMap() { + return optionsMap; + } + + public void addNotificationListener(NotificationListener listener, + NotificationFilter filter, Object handback) { + broadcaster.addNotificationListener(listener, filter, handback); + } + + /** + * A subclass that needs to send its own notifications must override + * this method in order to return an {@link MBeanNotificationInfo + * MBeanNotificationInfo[]} array containing both its own notification + * infos and the notification infos of its super class.

      + * The implementation should probably look like: + *

      +     *      final MBeanNotificationInfo[] myOwnNotifs = { .... };
      +     *      final MBeanNotificationInfo[] parentNotifs =
      +     *            super.getNotificationInfo();
      +     *      final Set mergedResult =
      +     *            new HashSet();
      +     *      mergedResult.addAll(Arrays.asList(myOwnNotifs));
      +     *      mergedResult.addAll(Arrays.asList(parentNotifs));
      +     *      return mergeResult.toArray(
      +     *             new MBeanNotificationInfo[mergedResult.size()]);
      +     * 
      + */ + public MBeanNotificationInfo[] getNotificationInfo() { + return broadcaster.getNotificationInfo(); + } + + public void removeNotificationListener(NotificationListener listener) + throws ListenerNotFoundException { + broadcaster.removeNotificationListener(listener); + } + + public void removeNotificationListener(NotificationListener listener, + NotificationFilter filter, Object handback) + throws ListenerNotFoundException { + broadcaster.removeNotificationListener(listener, filter, handback); + } + + private static long getNextSeqNumber() { + return seqNumber.getAndIncrement(); + } + + + /** + * Sends a notification to registered listeners. Before the notification + * is sent, the following steps are performed: + *
      • + * If {@code n.getSequenceNumber() <= 0} set it to the next available + * sequence number.
      • + *
      • If {@code n.getSource() == null}, set it to the value returned by {@link + * #getObjectName getObjectName()}. + *
      + *

      This method can be called by subclasses in order to send their own + * notifications. + * In that case, these subclasses might also need to override + * {@link #getNotificationInfo} in order to declare their own + * {@linkplain MBeanNotificationInfo notification types}. + *

      + * @param n The notification to send to registered listeners. + * @see javax.management.NotificationBroadcasterSupport + * @see #getNotificationInfo + **/ + protected void sendNotification(Notification n) { + if (n.getSequenceNumber()<=0) + n.setSequenceNumber(getNextSeqNumber()); + if (n.getSource()==null) + n.setSource(getObjectName()); + broadcaster.sendNotification(n); + } + + private void checkState(ConnectionListener listener, + JMXConnectionNotification cn, + JMXConnector emittingConnector) { + + // Due to the asynchronous handling of notifications, it is + // possible that this method is called for a JMXConnector + // (or connection) which is already closed and replaced by a newer + // one. + // + // This method attempts to determine the real state of the + // connection - which might be different from what the notification + // says. + // + // This is quite complex logic - because we try not to hold any + // lock while evaluating the true value of the connected state, + // while anyone might also call close() or connect() from a + // different thread. + // The method switchConnection() (called from here too) also has the + // same kind of complex logic: + // + // We use the JMXConnector has a handback to the notification listener + // (emittingConnector) in order to be able to determine whether the + // notification concerns the current connector in use, or an older + // one. The 'emittingConnector' is the connector from which the + // notification originated. This could be an 'old' connector - as + // closed() and connect() could already have been called before the + // notification arrived. So what we do is to compare the + // 'emittingConnector' with the current connector, to see if the + // notification actually comes from the curent connector. + // + boolean remove = false; + + // whether the emittingConnector is already 'removed' + synchronized (this) { + if (this.conn != emittingConnector || + JMXConnectionNotification.FAILED.equals(cn.getType())) + remove = true; + } + + // We need to unregister our listener from this 'removed' connector. + // This is the only place where we remove the listener. + // + if (remove) { + try { + // This may fail if the connector is already closed. + // But better unregister anyway... + // + emittingConnector.removeConnectionNotificationListener( + listener,null, + emittingConnector); + } catch (Exception x) { + LOG.log(Level.FINE, + "Failed to unregister connection listener"+x); + LOG.log(Level.FINEST, + "Failed to unregister connection listener",x); + } + try { + // This may fail if the connector is already closed. + // But better call close twice and get an exception than + // leaking... + // + emittingConnector.close(); + } catch (Exception x) { + LOG.log(Level.FINEST, + "Failed to close old connector " + + "(failure was expected): "+x); + } + } + + // Now we checked whether our current connector is still alive. + // + boolean closed = false; + final JMXConnector thisconn = this.conn; + try { + if (thisconn != null) + thisconn.getConnectionId(); + } catch (IOException x) { + LOG.finest("Connector already closed: "+x); + closed = true; + } + + // We got an IOException - the connector is not connected. + // Need to forget it and switch our state to closed. + // + if (closed) { + switchConnection(thisconn,null,null); + try { + // Usually this will fail... Better call close twice + // and get an exception than leaking... + // + if (thisconn != emittingConnector || !remove) + thisconn.close(); + } catch (IOException x) { + LOG.log(Level.FINEST, + "Failed to close connector (failure was expected): " + +x); + } + } + } + + private final void switchConnection(JMXConnector oldc, + JMXConnector newc, + MBeanServerConnection mbs) { + boolean connect = false; + boolean close = false; + synchronized (this) { + if (oldc != conn) { + if (newc != null) { + try { + newc.close(); + } catch (IOException x) { + LOG.log(Level.FINEST, + "Failed to close connector",x); + } + } + return; + } + if (conn == null && newc != null) connect=true; + if (newc == null && conn != null) close = true; + conn = newc; + server = mbs; + } + if (connect || close) { + boolean oldstate = close; + boolean newstate = connect; + final ObjectName myName = getObjectName(); + + // In the uncommon case where the MBean is connected before + // being registered, myName can be null... + // If myName is null - we use 'this' as the source instead... + // + final Object source = (myName==null)?this:myName; + final AttributeChangeNotification acn = + new AttributeChangeNotification(source, + getNextSeqNumber(),System.currentTimeMillis(), + String.valueOf(source)+ + (newstate?" connected":" closed"), + "Connected", + "boolean", + Boolean.valueOf(oldstate), + Boolean.valueOf(newstate)); + sendNotification(acn); + } + } + + private void close(JMXConnector c) { + try { + if (c != null) c.close(); + } catch (Exception x) { + // OK: we're gonna throw the original exception later. + LOG.finest("Ignoring exception when closing connector: "+x); + } + } + + JMXConnector connect(JMXServiceURL url, Map env) + throws IOException { + final JMXConnector c = newJMXConnector(jmxURL, env); + c.connect(env); + return c; + } + + /** + * Creates a new JMXConnector with the specified {@code url} and + * {@code env} options map. + *

      + * This method first calls {@link JMXConnectorFactory#newJMXConnector + * JMXConnectorFactory.newJMXConnector(jmxURL, env)} to obtain a new + * JMX connector, and returns that. + *

      + *

      + * A subclass of {@link JMXRemoteNamespace} can provide an implementation + * that connects to a sub namespace of the remote server by subclassing + * this class in the following way: + *

      +     * class JMXRemoteSubNamespace extends JMXRemoteNamespace {
      +     *    private final String subnamespace;
      +     *    JMXRemoteSubNamespace(JMXServiceURL url,
      +     *              Map{@code } env, String subnamespace) {
      +     *        super(url,options);
      +     *        this.subnamespace = subnamespace;
      +     *    }
      +     *    protected JMXConnector newJMXConnector(JMXServiceURL url,
      +     *              Map env) throws IOException {
      +     *        final JMXConnector inner = super.newJMXConnector(url,env);
      +     *        return {@link JMXNamespaces#narrowToNamespace(JMXConnector,String)
      +     *               JMXNamespaces.narrowToNamespace(inner,subnamespace)};
      +     *    }
      +     * }
      +     * 
      + *

      + *

      + * Some connectors, like the JMXMP connector server defined by the + * version 1.2 of the JMX API may not have been upgraded to use the + * new {@linkplain javax.management.event Event Service} defined in this + * version of the JMX API. + *

      + * In that case, and if the remote server to which this JMXRemoteNamespace + * connects also contains namespaces, it may be necessary to configure + * explicitly an {@linkplain + * javax.management.event.EventClientDelegate#newForwarder() + * Event Client Forwarder} on the remote server side, and to force the use + * of an {@link EventClient} on this client side. + *
      + * A subclass of {@link JMXRemoteNamespace} can provide an implementation + * of {@code newJMXConnector} that will force notification subscriptions + * to flow through an {@link EventClient} over a legacy protocol by + * overriding this method in the following way: + *

      + *
      +     * class JMXRemoteEventClientNamespace extends JMXRemoteNamespace {
      +     *    JMXRemoteSubNamespaceConnector(JMXServiceURL url,
      +     *              Map env) {
      +     *        super(url,options);
      +     *    }
      +     *    protected JMXConnector newJMXConnector(JMXServiceURL url,
      +     *              Map env) throws IOException {
      +     *        final JMXConnector inner = super.newJMXConnector(url,env);
      +     *        return {@link EventClient#withEventClient(
      +     *                JMXConnector) EventClient.withEventClient(inner)};
      +     *    }
      +     * }
      +     * 
      + *

      + * Note that the remote server also needs to provide an {@link + * javax.management.event.EventClientDelegateMBean}: only configuring + * the client side (this object) is not enough.
      + * In summary, this technique should be used if the remote server + * supports JMX namespaces, but uses a JMX Connector Server whose + * implementation does not transparently use the new Event Service + * (as would be the case with the JMXMPConnectorServer implementation + * from the reference implementation of the JMX Remote API 1.0 + * specification). + *

      + * @param url The JMXServiceURL of the remote server. + * @param optionsMap An unmodifiable options map that will be passed to the + * {@link JMXConnectorFactory} when {@linkplain + * JMXConnectorFactory#newJMXConnector creating} the + * {@link JMXConnector} that can connect to the remote source + * MBean Server. + * @return An unconnected JMXConnector to use to connect to the remote + * server + * @throws java.io.IOException if the connector could not be created. + * @see JMXConnectorFactory#newJMXConnector(javax.management.remote.JMXServiceURL, java.util.Map) + * @see #JMXRemoteNamespace + */ + protected JMXConnector newJMXConnector(JMXServiceURL url, + Map optionsMap) throws IOException { + final JMXConnector c = + JMXConnectorFactory.newJMXConnector(jmxURL, optionsMap); +// TODO: uncomment this when contexts are added +// return ClientContext.withDynamicContext(c); + return c; + } + + public void connect() throws IOException { + LOG.fine("connecting..."); + final Map env = + new HashMap(getEnvMap()); + try { + // XXX: We should probably document this... + // This allows to specify a loader name - which will be + // retrieved from the paret MBeanServer. + defaultClassLoader = + EnvHelp.resolveServerClassLoader(env,getMBeanServer()); + } catch (InstanceNotFoundException x) { + final IOException io = + new IOException("ClassLoader not found"); + io.initCause(x); + throw io; + } + env.put(JMXConnectorFactory.DEFAULT_CLASS_LOADER,defaultClassLoader); + final JMXServiceURL url = getJMXServiceURL(); + final JMXConnector aconn = connect(url,env); + final MBeanServerConnection msc; + try { + msc = aconn.getMBeanServerConnection(); + aconn.addConnectionNotificationListener(listener,null,aconn); + } catch (IOException io) { + close(aconn); + throw io; + } catch (RuntimeException x) { + close(aconn); + throw x; + } + + switchConnection(conn,aconn,msc); + + LOG.fine("connected."); + } + + public void close() throws IOException { + if (conn == null) return; + LOG.fine("closing..."); + // System.err.println(toString()+": closing..."); + conn.close(); + // System.err.println(toString()+": connector closed"); + switchConnection(conn,null,null); + LOG.fine("closed."); + // System.err.println(toString()+": closed"); + } + + MBeanServerConnection getMBeanServerConnection() { + if (conn == null) + throw newRuntimeIOException("getMBeanServerConnection: not connected"); + return server; + } + + // Better than throwing UndeclaredThrowableException ... + private RuntimeException newRuntimeIOException(String msg) { + final IllegalStateException illegal = new IllegalStateException(msg); + return Util.newRuntimeIOException(new IOException(msg,illegal)); + } + + /** + * Returns the default class loader used by the underlying + * {@link JMXConnector}. + * @return the default class loader used when communicating with the + * remote source MBean server. + **/ + ClassLoader getDefaultClassLoader() { + if (conn == null) + throw newRuntimeIOException("getMBeanServerConnection: not connected"); + return defaultClassLoader; + } + + public boolean isConnected() { + // This is a pleonasm + return (conn != null) && (server != null); + } + + + /** + * This name space handler will automatically {@link #close} its + * connection with the remote source in {@code preDeregister}. + **/ + @Override + public void preDeregister() throws Exception { + try { + close(); + } catch (IOException x) { + LOG.fine("Failed to close properly - exception ignored: " + x); + LOG.log(Level.FINEST, + "Failed to close properly - exception ignored",x); + } + super.preDeregister(); + } + + /** + * This method calls {@link + * javax.management.MBeanServerConnection#getMBeanCount + * getMBeanCount()} on the remote namespace. + * @throws java.io.IOException if an {@link IOException} is raised when + * communicating with the remote source namespace. + */ + @Override + public Integer getMBeanCount() throws IOException { + return getMBeanServerConnection().getMBeanCount(); + } + + /** + * This method returns the result of calling {@link + * javax.management.MBeanServerConnection#getDomains + * getDomains()} on the remote namespace. + * @throws java.io.IOException if an {@link IOException} is raised when + * communicating with the remote source namespace. + */ + @Override + public String[] getDomains() throws IOException { + return getMBeanServerConnection().getDomains(); + } + + /** + * This method returns the result of calling {@link + * javax.management.MBeanServerConnection#getDefaultDomain + * getDefaultDomain()} on the remote namespace. + * @throws java.io.IOException if an {@link IOException} is raised when + * communicating with the remote source namespace. + */ + @Override + public String getDefaultDomain() throws IOException { + return getMBeanServerConnection().getDefaultDomain(); + } + + /** + * Creates a new instance of {@code JMXRemoteNamespace}. + * @param sourceURL a JMX service URL that can be used to connect to the + * source MBean Server. The source MBean Server is the remote + * MBean Server which contains the MBeans that will be mirrored + * in this namespace. + * @param optionsMap An options map that will be passed to the + * {@link JMXConnectorFactory} when {@linkplain + * JMXConnectorFactory#newJMXConnector creating} the + * {@link JMXConnector} used to connect to the remote source + * MBean Server. Can be null, which is equivalent to an empty map. + * @see #JMXRemoteNamespace JMXRemoteNamespace(sourceURL,optionsMap) + * @see JMXConnectorFactory#newJMXConnector(javax.management.remote.JMXServiceURL, java.util.Map) + */ + public static JMXRemoteNamespace newJMXRemoteNamespace( + JMXServiceURL sourceURL, + Map optionsMap) { + return new JMXRemoteNamespace(sourceURL, optionsMap); + } +} diff --git a/jdk/src/share/classes/javax/management/namespace/JMXRemoteNamespaceMBean.java b/jdk/src/share/classes/javax/management/namespace/JMXRemoteNamespaceMBean.java new file mode 100644 index 00000000000..18b0fb86dfe --- /dev/null +++ b/jdk/src/share/classes/javax/management/namespace/JMXRemoteNamespaceMBean.java @@ -0,0 +1,96 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.namespace; + +import java.io.IOException; +import javax.management.remote.JMXServiceURL; + +/** + * A {@link JMXNamespaceMBean} that will connect to a remote MBeanServer + * by creating a {@link javax.management.remote.JMXConnector} from a + * {@link javax.management.remote.JMXServiceURL}. + * You can call {@link #connect connect()} and {@link #close close()} + * several times. + * @since 1.7 + */ +public interface JMXRemoteNamespaceMBean + extends JMXNamespaceMBean { + + /** + * Connects to the underlying remote source name space, if not already + * {@link #isConnected connected}. + * If connected, do nothing. Otherwise, creates a new connector from the + * {@link javax.management.remote.JMXServiceURL JMXServiceURL} provided at + * creation time, and connects to the remote source name space. + *

      + * The source MBeans will not appear in the target name space until the + * JMXRemoteNamespaceMBean is connected. + *

      + * It is possible to call {@code connect()}, {@link #close close()}, and + * {@code connect()} again. + * However, closing the connection with the remote name space may cause + * notification listeners to be lost, unless the client explicitly uses + * the new {@linkplain javax.management.event JMX event service}. + *

      + * @throws IOException if connection to the remote source name space fails. + * @see #isConnected isConnected + **/ + public void connect() + throws IOException; + + /** + * Closes the connection with the remote source name space. + * If the connection is already closed, do nothing. + * Otherwise, closes the underlying {@link + * javax.management.remote.JMXConnector}. + *

      Once closed, it is possible to reopen the connection by + * calling {@link #connect connect}. + *

      + * @throws IOException if the connection to the remote source name space + * can't be closed properly. + * @see #isConnected isConnected + **/ + public void close() + throws IOException; + + /** + * Tells whether the connection to the remote source name space is opened. + * @see #connect connect + * @see #close close + * @return {@code true} if connected. + **/ + public boolean isConnected(); + + /** + * Returns the {@link JMXServiceURL} address that points to the remote name + * space mirrored by this {@link JMXNamespaceMBean JMXNamespace MBean}, + * if available. + * @return The {@link JMXServiceURL} address that points to the remote name + * space mirrored by this {@link JMXNamespaceMBean JMXNamespace MBean}, + * or {@code null}. + */ + public JMXServiceURL getAddress(); +} diff --git a/jdk/src/share/classes/javax/management/namespace/MBeanServerConnectionWrapper.java b/jdk/src/share/classes/javax/management/namespace/MBeanServerConnectionWrapper.java new file mode 100644 index 00000000000..7eeda961e31 --- /dev/null +++ b/jdk/src/share/classes/javax/management/namespace/MBeanServerConnectionWrapper.java @@ -0,0 +1,702 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.namespace; + +import com.sun.jmx.mbeanserver.Util; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.util.Set; + +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.AttributeNotFoundException; +import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; +import javax.management.IntrospectionException; +import javax.management.InvalidAttributeValueException; +import javax.management.ListenerNotFoundException; +import javax.management.MBeanException; +import javax.management.MBeanInfo; +import javax.management.MBeanRegistrationException; +import javax.management.MBeanServer; +import javax.management.MBeanServerConnection; +import javax.management.NotCompliantMBeanException; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.ObjectInstance; +import javax.management.ObjectName; +import javax.management.OperationsException; +import javax.management.QueryExp; +import javax.management.ReflectionException; +import javax.management.loading.ClassLoaderRepository; + +/** + *

      An object of this class implements the MBeanServer interface + * and, for each of its methods forwards the request to a wrapped + * {@link MBeanServerConnection} object. + * Some methods of the {@link MBeanServer} interface do not have + * any equivalent in {@link MBeanServerConnection}. In that case, an + * {@link UnsupportedOperationException} will be thrown. + * + *

      A typical use of this class is to apply a {@link QueryExp} object locally, + * on an MBean that resides in a remote MBeanServer. Since an + * MBeanServerConnection is not an MBeanServer, it cannot be passed + * to the setMBeanServer() method of the {@link QueryExp} + * object. However, this object can.

      + * + * @since 1.7 + */ +public class MBeanServerConnectionWrapper + implements MBeanServer { + + private final MBeanServerConnection wrapped; + private final ClassLoader defaultCl; + + /** + * Construct a new object that implements {@link MBeanServer} by + * forwarding its methods to the given {@link MBeanServerConnection}. + * This constructor is equivalent to {@link #MBeanServerConnectionWrapper( + * MBeanServerConnection, ClassLoader) MBeanServerConnectionWrapper(wrapped, + * null)}. + * + * @param wrapped the {@link MBeanServerConnection} to which methods + * are to be forwarded. This parameter can be null, in which case the + * {@code MBeanServerConnection} will typically be supplied by overriding + * {@link #getMBeanServerConnection}. + */ + public MBeanServerConnectionWrapper(MBeanServerConnection wrapped) { + this(wrapped, null); + } + + /** + * Construct a new object that implements {@link MBeanServer} by + * forwarding its methods to the given {@link MBeanServerConnection}. + * The {@code defaultCl} parameter specifies the value to be returned + * by {@link #getDefaultClassLoader}. A null value is equivalent to + * {@link Thread#getContextClassLoader()}. + * + * @param wrapped the {@link MBeanServerConnection} to which methods + * are to be forwarded. This parameter can be null, in which case the + * {@code MBeanServerConnection} will typically be supplied by overriding + * {@link #getMBeanServerConnection}. + * @param defaultCl the value to be returned by {@link + * #getDefaultClassLoader}. A null value is equivalent to the current + * thread's {@linkplain Thread#getContextClassLoader()}. + */ + public MBeanServerConnectionWrapper(MBeanServerConnection wrapped, + ClassLoader defaultCl) { + this.wrapped = wrapped; + this.defaultCl = (defaultCl == null) ? + Thread.currentThread().getContextClassLoader() : defaultCl; + } + + /** + * Returns an MBeanServerConnection. This method is called each time + * an operation must be invoked on the underlying MBeanServerConnection. + * The default implementation returns the MBeanServerConnection that + * was supplied to the constructor of this MBeanServerConnectionWrapper. + **/ + protected MBeanServerConnection getMBeanServerConnection() { + return wrapped; + } + + /** + * Returns the default class loader passed to the constructor. If the + * value passed was null, then the returned value will be the + * {@linkplain Thread#getContextClassLoader() context class loader} at the + * time this object was constructed. + * + * @return the ClassLoader that was passed to the constructor. + **/ + public ClassLoader getDefaultClassLoader() { + return defaultCl; + } + + /** + *

      This method is called each time an IOException is raised when + * trying to forward an operation to the underlying + * MBeanServerConnection, as a result of calling + * {@link #getMBeanServerConnection()} or as a result of invoking the + * operation on the returned connection. Since the methods in + * {@link MBeanServer} are not declared to throw {@code IOException}, + * this method must return a {@code RuntimeException} to be thrown + * instead. Typically, the original {@code IOException} will be in the + * {@linkplain Throwable#getCause() cause chain} of the {@code + * RuntimeException}.

      + * + *

      Subclasses may redefine this method if they need to perform any + * specific handling of IOException (logging etc...).

      + * + * @param x The raised IOException. + * @param method The name of the method in which the exception was + * raised. This is one of the methods of the MBeanServer + * interface. + * + * @return A RuntimeException that should be thrown by the caller. + * In this default implementation, this is a + * {@link RuntimeException} wrapping x. + **/ + protected RuntimeException wrapIOException(IOException x, String method) { + return Util.newRuntimeIOException(x); + } + + // Take care of getMBeanServerConnection returning null. + // + private synchronized MBeanServerConnection connection() + throws IOException { + final MBeanServerConnection c = getMBeanServerConnection(); + if (c == null) + throw new IOException("MBeanServerConnection unavailable"); + return c; + } + + //-------------------------------------------- + //-------------------------------------------- + // + // Implementation of the MBeanServer interface + // + //-------------------------------------------- + //-------------------------------------------- + + /** + * Forward this method to the + * wrapped object. + */ + public void addNotificationListener(ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException { + try { + connection().addNotificationListener(name, listener, + filter, handback); + } catch (IOException x) { + throw wrapIOException(x,"addNotificationListener"); + } + } + + /** + * Forward this method to the + * wrapped object. + */ + public void addNotificationListener(ObjectName name, + ObjectName listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException { + try { + connection().addNotificationListener(name, listener, + filter, handback); + } catch (IOException x) { + throw wrapIOException(x,"addNotificationListener"); + } + } + + /** + * Forward this method to the + * wrapped object. + */ + public ObjectInstance createMBean(String className, ObjectName name) + throws + ReflectionException, + InstanceAlreadyExistsException, + MBeanRegistrationException, + MBeanException, + NotCompliantMBeanException { + try { + return connection().createMBean(className, name); + } catch (IOException x) { + throw wrapIOException(x,"createMBean"); + } + } + + /** + * Forward this method to the + * wrapped object. + */ + public ObjectInstance createMBean(String className, ObjectName name, + Object params[], String signature[]) + throws + ReflectionException, + InstanceAlreadyExistsException, + MBeanRegistrationException, + MBeanException, + NotCompliantMBeanException { + try { + return connection().createMBean(className, name, + params, signature); + } catch (IOException x) { + throw wrapIOException(x,"createMBean"); + } + } + + /** + * Forward this method to the + * wrapped object. + */ + public ObjectInstance createMBean(String className, + ObjectName name, + ObjectName loaderName) + throws + ReflectionException, + InstanceAlreadyExistsException, + MBeanRegistrationException, + MBeanException, + NotCompliantMBeanException, + InstanceNotFoundException { + try { + return connection().createMBean(className, name, loaderName); + } catch (IOException x) { + throw wrapIOException(x,"createMBean"); + } + } + + /** + * Forward this method to the + * wrapped object. + */ + public ObjectInstance createMBean(String className, + ObjectName name, + ObjectName loaderName, + Object params[], + String signature[]) + throws + ReflectionException, + InstanceAlreadyExistsException, + MBeanRegistrationException, + MBeanException, + NotCompliantMBeanException, + InstanceNotFoundException { + try { + return connection().createMBean(className, name, loaderName, + params, signature); + } catch (IOException x) { + throw wrapIOException(x,"createMBean"); + } + } + + /** + * Throws an {@link UnsupportedOperationException}. This behavior can + * be changed by subclasses. + * @deprecated see {@link MBeanServer#deserialize(ObjectName,byte[]) + * MBeanServer} + */ + @Deprecated + public ObjectInputStream deserialize(ObjectName name, byte[] data) + throws InstanceNotFoundException, OperationsException { + throw new UnsupportedOperationException("deserialize"); + } + + /** + * Throws an {@link UnsupportedOperationException}. This behavior can + * be changed by subclasses. + * @deprecated see {@link MBeanServer#deserialize(String,byte[]) + * MBeanServer} + */ + @Deprecated + public ObjectInputStream deserialize(String className, byte[] data) + throws OperationsException, ReflectionException { + throw new UnsupportedOperationException("deserialize"); + } + + /** + * Throws an {@link UnsupportedOperationException}. This behavior can + * be changed by subclasses. + * @deprecated see {@link MBeanServer#deserialize(String,ObjectName,byte[]) + * MBeanServer} + */ + @Deprecated + public ObjectInputStream deserialize(String className, + ObjectName loaderName, + byte[] data) + throws + InstanceNotFoundException, + OperationsException, + ReflectionException { + throw new UnsupportedOperationException("deserialize"); + } + + /** + * Forward this method to the + * wrapped object. + */ + public Object getAttribute(ObjectName name, String attribute) + throws + MBeanException, + AttributeNotFoundException, + InstanceNotFoundException, + ReflectionException { + try { + return connection().getAttribute(name, attribute); + } catch (IOException x) { + throw wrapIOException(x,"getAttribute"); + } + } + + /** + * Forward this method to the + * wrapped object. + */ + public AttributeList getAttributes(ObjectName name, String[] attributes) + throws InstanceNotFoundException, ReflectionException { + try { + return connection().getAttributes(name, attributes); + } catch (IOException x) { + throw wrapIOException(x,"getAttributes"); + } + } + + /** + * Throws an {@link UnsupportedOperationException}. This behavior can + * be changed by subclasses. + */ + public ClassLoader getClassLoader(ObjectName loaderName) + throws InstanceNotFoundException { + throw new UnsupportedOperationException("getClassLoader"); + } + + /** + * Returns the {@linkplain #getDefaultClassLoader() default class loader}. + * This behavior can be changed by subclasses. + */ + public ClassLoader getClassLoaderFor(ObjectName mbeanName) + throws InstanceNotFoundException { + return getDefaultClassLoader(); + } + + /** + *

      Returns a {@link ClassLoaderRepository} based on the class loader + * returned by {@link #getDefaultClassLoader()}.

      + * @return a {@link ClassLoaderRepository} that contains a single + * class loader, returned by {@link #getDefaultClassLoader()}. + **/ + public ClassLoaderRepository getClassLoaderRepository() { + // We return a new ClassLoaderRepository each time this method is + // called. This is by design, because there's no guarantee that + // getDefaultClassLoader() will always return the same class loader. + return Util.getSingleClassLoaderRepository(getDefaultClassLoader()); + } + + /** + * Forward this method to the + * wrapped object. + */ + public String getDefaultDomain() { + try { + return connection().getDefaultDomain(); + } catch (IOException x) { + throw wrapIOException(x,"getDefaultDomain"); + } + } + + /** + * Forward this method to the + * wrapped object. + */ + public String[] getDomains() { + try { + return connection().getDomains(); + } catch (IOException x) { + throw wrapIOException(x,"getDomains"); + } + } + + /** + * Forward this method to the + * wrapped object. + */ + public Integer getMBeanCount() { + try { + return connection().getMBeanCount(); + } catch (IOException x) { + throw wrapIOException(x,"getMBeanCount"); + } + } + + /** + * Forward this method to the + * wrapped object. + */ + public MBeanInfo getMBeanInfo(ObjectName name) + throws + InstanceNotFoundException, + IntrospectionException, + ReflectionException { + try { + return connection().getMBeanInfo(name); + } catch (IOException x) { + throw wrapIOException(x,"getMBeanInfo"); + } + } + + /** + * Forward this method to the + * wrapped object. + */ + public ObjectInstance getObjectInstance(ObjectName name) + throws InstanceNotFoundException { + try { + return connection().getObjectInstance(name); + } catch (IOException x) { + throw wrapIOException(x,"getObjectInstance"); + } + } + + /** + * Throws an {@link UnsupportedOperationException}. This behavior can + * be changed by subclasses. + */ + public Object instantiate(String className) + throws ReflectionException, MBeanException { + throw new UnsupportedOperationException("instantiate"); + } + + /** + * Throws an {@link UnsupportedOperationException}. This behavior can + * be changed by subclasses. + */ + public Object instantiate(String className, + Object params[], + String signature[]) + throws ReflectionException, MBeanException { + throw new UnsupportedOperationException("instantiate"); + } + + /** + * Throws an {@link UnsupportedOperationException}. This behavior can + * be changed by subclasses. + */ + public Object instantiate(String className, ObjectName loaderName) + throws ReflectionException, MBeanException, + InstanceNotFoundException { + throw new UnsupportedOperationException("instantiate"); + } + + /** + * Throws an {@link UnsupportedOperationException}. This behavior can + * be changed by subclasses. + */ + public Object instantiate(String className, ObjectName loaderName, + Object params[], String signature[]) + throws ReflectionException, MBeanException, + InstanceNotFoundException { + throw new UnsupportedOperationException("instantiate"); + } + + /** + * Forward this method to the + * wrapped object. + */ + public Object invoke(ObjectName name, String operationName, + Object params[], String signature[]) + throws + InstanceNotFoundException, + MBeanException, + ReflectionException { + try { + return connection().invoke(name,operationName,params,signature); + } catch (IOException x) { + throw wrapIOException(x,"invoke"); + } + } + + /** + * Forward this method to the + * wrapped object. + */ + public boolean isInstanceOf(ObjectName name, String className) + throws InstanceNotFoundException { + try { + return connection().isInstanceOf(name, className); + } catch (IOException x) { + throw wrapIOException(x,"isInstanceOf"); + } + } + + /** + * Forward this method to the + * wrapped object. + */ + public boolean isRegistered(ObjectName name) { + try { + return connection().isRegistered(name); + } catch (IOException x) { + throw wrapIOException(x,"isRegistered"); + } + } + + /** + * Forward this method to the + * wrapped object. + * If an IOException is raised, returns an empty Set. + */ + public Set queryMBeans(ObjectName name, QueryExp query) { + try { + return connection().queryMBeans(name, query); + } catch (IOException x) { + throw wrapIOException(x,"queryMBeans"); + //return Collections.emptySet(); + } + } + + /** + * Forward this method to the + * wrapped object. + * If an IOException is raised, returns an empty Set. + */ + public Set queryNames(ObjectName name, QueryExp query) { + try { + return connection().queryNames(name, query); + } catch (IOException x) { + throw wrapIOException(x,"queryNames"); + //return Collections.emptySet(); + } + } + + /** + * Throws an {@link UnsupportedOperationException}. This behavior can + * be changed by subclasses. + */ + public ObjectInstance registerMBean(Object object, ObjectName name) + throws + InstanceAlreadyExistsException, + MBeanRegistrationException, + NotCompliantMBeanException { + throw new UnsupportedOperationException("registerMBean"); + } + + /** + * Forward this method to the + * wrapped object. + */ + public void removeNotificationListener(ObjectName name, + NotificationListener listener) + throws InstanceNotFoundException, ListenerNotFoundException { + try { + connection().removeNotificationListener(name, listener); + } catch (IOException x) { + throw wrapIOException(x,"removeNotificationListener"); + } + } + + /** + * Forward this method to the + * wrapped object. + */ + public void removeNotificationListener(ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException, ListenerNotFoundException { + try { + connection().removeNotificationListener(name, listener, + filter, handback); + } catch (IOException x) { + throw wrapIOException(x,"removeNotificationListener"); + } + } + + /** + * Forward this method to the + * wrapped object. + */ + public void removeNotificationListener(ObjectName name, + ObjectName listener) + throws InstanceNotFoundException, ListenerNotFoundException { + try { + connection().removeNotificationListener(name, listener); + } catch (IOException x) { + throw wrapIOException(x,"removeNotificationListener"); + } + } + + /** + * Forward this method to the + * wrapped object. + */ + public void removeNotificationListener(ObjectName name, + ObjectName listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException, ListenerNotFoundException { + try { + connection().removeNotificationListener(name, listener, + filter, handback); + } catch (IOException x) { + throw wrapIOException(x,"removeNotificationListener"); + } + } + + /** + * Forward this method to the + * wrapped object. + */ + public void setAttribute(ObjectName name, Attribute attribute) + throws + InstanceNotFoundException, + AttributeNotFoundException, + InvalidAttributeValueException, + MBeanException, + ReflectionException { + try { + connection().setAttribute(name, attribute); + } catch (IOException x) { + throw wrapIOException(x,"setAttribute"); + } + } + + /** + * Forward this method to the + * wrapped object. + */ + public AttributeList setAttributes(ObjectName name, + AttributeList attributes) + throws InstanceNotFoundException, ReflectionException { + try { + return connection().setAttributes(name, attributes); + } catch (IOException x) { + throw wrapIOException(x,"setAttributes"); + } + } + + /** + * Forward this method to the + * wrapped object. + */ + public void unregisterMBean(ObjectName name) + throws InstanceNotFoundException, MBeanRegistrationException { + try { + connection().unregisterMBean(name); + } catch (IOException x) { + throw wrapIOException(x,"unregisterMBean"); + } + } + + //---------------- + // PRIVATE METHODS + //---------------- + +} diff --git a/jdk/src/share/classes/javax/management/namespace/MBeanServerSupport.java b/jdk/src/share/classes/javax/management/namespace/MBeanServerSupport.java new file mode 100644 index 00000000000..903be3c308f --- /dev/null +++ b/jdk/src/share/classes/javax/management/namespace/MBeanServerSupport.java @@ -0,0 +1,1331 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +package javax.management.namespace; + +import com.sun.jmx.defaults.JmxProperties; +import com.sun.jmx.mbeanserver.Util; +import java.io.ObjectInputStream; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.TreeSet; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.AttributeNotFoundException; +import javax.management.DynamicMBean; +import javax.management.DynamicWrapperMBean; +import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; +import javax.management.IntrospectionException; +import javax.management.InvalidAttributeValueException; +import javax.management.JMRuntimeException; +import javax.management.ListenerNotFoundException; +import javax.management.MBeanException; +import javax.management.MBeanInfo; +import javax.management.MBeanRegistrationException; +import javax.management.MBeanServer; +import javax.management.NotCompliantMBeanException; +import javax.management.NotificationBroadcaster; +import javax.management.NotificationEmitter; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.ObjectInstance; +import javax.management.ObjectName; +import javax.management.OperationsException; +import javax.management.QueryEval; +import javax.management.QueryExp; +import javax.management.ReflectionException; +import javax.management.RuntimeOperationsException; +import javax.management.loading.ClassLoaderRepository; + +/** + *

      Base class for custom implementations of the {@link MBeanServer} + * interface. The commonest use of this class is as the {@linkplain + * JMXNamespace#getSourceServer() source server} for a {@link + * JMXNamespace}, although this class can be used anywhere an {@code + * MBeanServer} instance is required. Note that the usual ways to + * obtain an {@code MBeanServer} instance are either to use {@link + * java.lang.management.ManagementFactory#getPlatformMBeanServer() + * ManagementFactory.getPlatformMBeanServer()} or to use the {@code + * newMBeanServer} or {@code createMBeanServer} methods from {@link + * javax.management.MBeanServerFactory MBeanServerFactory}. {@code + * MBeanServerSupport} is for certain cases where those are not + * appropriate.

      + * + *

      There are two main use cases for this class: special-purpose MBeanServer implementations, + * and namespaces containing Virtual MBeans. The next + * sections explain these use cases.

      + * + *

      In the simplest case, a subclass needs to implement only two methods:

      + * + *
        + *
      • + * {@link #getNames getNames} which returns the name of + * all MBeans handled by this {@code MBeanServer}. + *
      • + *
      • + * {@link #getDynamicMBeanFor getDynamicMBeanFor} which returns a + * {@link DynamicMBean} that can be used to invoke operations and + * obtain meta data (MBeanInfo) on a given MBean. + *
      • + *
      + * + *

      Subclasses can create such {@link DynamicMBean} MBeans on the fly - for + * instance, using the class {@link javax.management.StandardMBean}, just for + * the duration of an MBeanServer method call.

      + * + *

      Special-purpose MBeanServer implementations

      + * + *

      In some cases + * the general-purpose {@code MBeanServer} that you get from + * {@link javax.management.MBeanServerFactory MBeanServerFactory} is not + * appropriate. You might need different security checks, or you might + * want a mock {@code MBeanServer} suitable for use in tests, or you might + * want a simplified and optimized {@code MBeanServer} for a special purpose.

      + * + *

      As an example of a special-purpose {@code MBeanServer}, the class {@link + * javax.management.QueryNotificationFilter QueryNotificationFilter} constructs + * an {@code MBeanServer} instance every time it filters a notification, + * with just one MBean that represents the notification. Although it could + * use {@code MBeanServerFactory.newMBeanServer}, a special-purpose {@code + * MBeanServer} will be quicker to create, use less memory, and have simpler + * methods that execute faster.

      + * + *

      Here is an example of a special-purpose {@code MBeanServer} + * implementation that contains exactly one MBean, which is specified at the + * time of creation.

      + * + *
      + * public class SingletonMBeanServer extends MBeanServerSupport {
      + *     private final ObjectName objectName;
      + *     private final DynamicMBean mbean;
      + *
      + *     public SingletonMBeanServer(ObjectName objectName, DynamicMBean mbean) {
      + *         this.objectName = objectName;
      + *         this.mbean = mbean;
      + *     }
      + *
      + *     @Override
      + *     protected {@code Set} {@link #getNames getNames}() {
      + *         return Collections.singleton(objectName);
      + *     }
      + *
      + *     @Override
      + *     public DynamicMBean {@link #getDynamicMBeanFor
      + *                                getDynamicMBeanFor}(ObjectName name)
      + *             throws InstanceNotFoundException {
      + *         if (objectName.equals(name))
      + *             return mbean;
      + *         else
      + *             throw new InstanceNotFoundException(name);
      + *     }
      + * }
      + * 
      + * + *

      Using this class, you could make an {@code MBeanServer} that contains + * a {@link javax.management.timer.Timer Timer} MBean like this:

      + * + *
      + *     Timer timer = new Timer();
      + *     DynamicMBean mbean = new {@link javax.management.StandardMBean
      + *                                     StandardMBean}(timer, TimerMBean.class);
      + *     ObjectName name = new ObjectName("com.example:type=Timer");
      + *     MBeanServer timerMBS = new SingletonMBeanServer(name, mbean);
      + * 
      + * + *

      When {@code getDynamicMBeanFor} always returns the same object for the + * same name, as here, notifications work in the expected way: if the object + * is a {@link NotificationEmitter} then listeners can be added using + * {@link MBeanServer#addNotificationListener(ObjectName, NotificationListener, + * NotificationFilter, Object) MBeanServer.addNotificationListener}. If + * {@code getDynamicMBeanFor} does not always return the same object for the + * same name, more work is needed to make notifications work, as described + * below.

      + * + *

      Namespaces containing Virtual MBeans

      + * + *

      Virtual MBeans are MBeans that do not exist as Java objects, + * except transiently while they are being accessed. This is useful when + * there might be very many of them, or when keeping track of their creation + * and deletion might be expensive or hard. For example, you might have one + * MBean per system process. With an ordinary {@code MBeanServer}, you would + * have to list the system processes in order to create an MBean object for + * each one, and you would have to track the arrival and departure of system + * processes in order to create or delete the corresponding MBeans. With + * Virtual MBeans, you only need the MBean for a given process at the exact + * point where it is referenced with a call such as + * {@link MBeanServer#getAttribute MBeanServer.getAttribute}.

      + * + *

      Here is an example of an {@code MBeanServer} implementation that has + * one MBean for every system property. The system property {@code "java.home"} + * is represented by the MBean called {@code + * com.example:type=Property,name="java.home"}, with an attribute called + * {@code Value} that is the value of the property.

      + * + *
      + * public interface PropertyMBean {
      + *     public String getValue();
      + * }
      + *
      + * public class PropsMBS extends MBeanServerSupport {
      + *     public static class PropertyImpl implements PropertyMBean {
      + *         private final String name;
      + *
      + *         public PropertyImpl(String name) {
      + *             this.name = name;
      + *         }
      + *
      + *         public String getValue() {
      + *             return System.getProperty(name);
      + *         }
      + *     }
      + *
      + *     @Override
      + *     public DynamicMBean {@link #getDynamicMBeanFor
      + *                                getDynamicMBeanFor}(ObjectName name)
      + *             throws InstanceNotFoundException {
      + *
      + *         // Check that the name is a legal one for a Property MBean
      + *         ObjectName namePattern = ObjectName.valueOf(
      + *                     "com.example:type=Property,name=\"*\"");
      + *         if (!namePattern.apply(name))
      + *             throw new InstanceNotFoundException(name);
      + *
      + *         // Extract the name of the property that the MBean corresponds to
      + *         String propName = ObjectName.unquote(name.getKeyProperty("name"));
      + *         if (System.getProperty(propName) == null)
      + *             throw new InstanceNotFoundException(name);
      + *
      + *         // Construct and return a transient MBean object
      + *         PropertyMBean propMBean = new PropertyImpl(propName);
      + *         return new StandardMBean(propMBean, PropertyMBean.class, false);
      + *     }
      + *
      + *     @Override
      + *     protected {@code Set} {@link #getNames getNames}() {
      + *         {@code Set names = new TreeSet();}
      + *         Properties props = System.getProperties();
      + *         for (String propName : props.stringPropertyNames()) {
      + *             ObjectName objectName = ObjectName.valueOf(
      + *                     "com.example:type=Property,name=" +
      + *                     ObjectName.quote(propName));
      + *             names.add(objectName);
      + *         }
      + *         return names;
      + *     }
      + * }
      + * 
      + * + *

      Because the {@code getDynamicMBeanFor} method + * returns a different object every time it is called, the default handling + * of notifications will not work, as explained below. + * In this case it does not matter, because the object returned by {@code + * getDynamicMBeanFor} is not a {@code NotificationEmitter}, so {@link + * MBeanServer#addNotificationListener(ObjectName, NotificationListener, + * NotificationFilter, Object) MBeanServer.addNotificationListener} will + * always fail. But if we wanted to extend {@code PropsMBS} so that the MBean + * for property {@code "foo"} emitted a notification every time that property + * changed, we would need to do it as shown below. (Because there is no API to + * be informed when a property changes, this code assumes that some other code + * calls the {@code propertyChanged} method every time a property changes.)

      + * + *
      + * public class PropsMBS {
      + *     ...as above...
      + *
      + *     private final {@link VirtualEventManager} vem = new VirtualEventManager();
      + *
      + *     @Override
      + *     public NotificationEmitter {@link #getNotificationEmitterFor
      + *                                       getNotificationEmitterFor}(
      + *             ObjectName name) throws InstanceNotFoundException {
      + *         getDynamicMBeanFor(name);  // check that the name is valid
      + *         return vem.{@link VirtualEventManager#getNotificationEmitterFor
      + *                           getNotificationEmitterFor}(name);
      + *     }
      + *
      + *     public void propertyChanged(String name, String newValue) {
      + *         ObjectName objectName = ObjectName.valueOf(
      + *                 "com.example:type=Property,name=" + ObjectName.quote(name));
      + *         Notification n = new Notification(
      + *                 "com.example.property.changed", objectName, 0L,
      + *                 "Property " + name + " changed");
      + *         n.setUserData(newValue);
      + *         vem.{@link VirtualEventManager#publish publish}(objectName, n);
      + *     }
      + * }
      + * 
      + * + *

      MBean creation and deletion

      + * + *

      MBean creation through {@code MBeanServer.createMBean} is disabled + * by default. Subclasses which need to support MBean creation + * through {@code createMBean} need to implement a single method {@link + * #createMBean(String, ObjectName, ObjectName, Object[], String[], + * boolean)}.

      + * + *

      Similarly MBean registration and unregistration through {@code + * registerMBean} and {@code unregisterMBean} are disabled by default. + * Subclasses which need to support MBean registration and + * unregistration will need to implement {@link #registerMBean registerMBean} + * and {@link #unregisterMBean unregisterMBean}.

      + * + *

      Notifications

      + * + *

      By default {@link MBeanServer#addNotificationListener(ObjectName, + * NotificationListener, NotificationFilter, Object) addNotificationListener} + * is accepted for an MBean {@code name} if {@link #getDynamicMBeanFor + * getDynamicMBeanFor}(name) returns an object that is a + * {@link NotificationEmitter}. That is appropriate if + * {@code getDynamicMBeanFor}(name) always returns the + * same object for the same {@code name}. But with + * Virtual MBeans, every call to {@code getDynamicMBeanFor} returns a new object, + * which is discarded as soon as the MBean request has finished. + * So a listener added to that object would be immediately forgotten.

      + * + *

      The simplest way for a subclass that defines Virtual MBeans + * to support notifications is to create a private {@link VirtualEventManager} + * and override the method {@link + * #getNotificationEmitterFor getNotificationEmitterFor} as follows:

      + * + *
      + *     private final VirtualEventManager vem = new VirtualEventManager();
      + *
      + *     @Override
      + *     public NotificationEmitter getNotificationEmitterFor(
      + *             ObjectName name) throws InstanceNotFoundException {
      + *         // Check that the name is a valid Virtual MBean.
      + *         // This is the easiest way to do that, but not always the
      + *         // most efficient:
      + *         getDynamicMBeanFor(name);
      + *
      + *         // Return an object that supports add/removeNotificationListener
      + *         // through the VirtualEventManager.
      + *         return vem.getNotificationEmitterFor(name);
      + *     }
      + * 
      + * + *

      A notification {@code n} can then be sent from the Virtual MBean + * called {@code name} by calling {@link VirtualEventManager#publish + * vem.publish}(name, n). See the example + * above.

      + * + * @since 1.7 + */ +public abstract class MBeanServerSupport implements MBeanServer { + + /** + * A logger for this class. + */ + private static final Logger LOG = + JmxProperties.NAMESPACE_LOGGER; + + /** + *

      Make a new {@code MBeanServerSupport} instance.

      + */ + protected MBeanServerSupport() { + } + + /** + *

      Returns a dynamically created handle that makes it possible to + * access the named MBean for the duration of a method call.

      + * + *

      An easy way to create such a {@link DynamicMBean} handle is, for + * instance, to create a temporary MXBean instance and to wrap it in + * an instance of + * {@link javax.management.StandardMBean}. + * This handle should remain valid for the duration of the call + * but can then be discarded.

      + * @param name the name of the MBean for which a request was received. + * @return a {@link DynamicMBean} handle that can be used to invoke + * operations on the named MBean. + * @throws InstanceNotFoundException if no such MBean is supposed + * to exist. + */ + public abstract DynamicMBean getDynamicMBeanFor(ObjectName name) + throws InstanceNotFoundException; + + /** + *

      Subclasses should implement this method to return + * the names of all MBeans handled by this object instance.

      + * + *

      The object returned by getNames() should be safely {@linkplain + * Set#iterator iterable} even in the presence of other threads that may + * cause the set of names to change. Typically this means one of the + * following:

      + * + *
        + *
      • the returned set of names is always the same; or + *
      • the returned set of names is an object such as a {@link + * java.util.concurrent.CopyOnWriteArraySet CopyOnWriteArraySet} that is + * safely iterable even if the set is changed by other threads; or + *
      • a new Set is constructed every time this method is called. + *
      + * + * @return the names of all MBeans handled by this object. + */ + protected abstract Set getNames(); + + /** + *

      List names matching the given pattern. + * The default implementation of this method calls {@link #getNames()} + * and returns the subset of those names matching {@code pattern}.

      + * + * @param pattern an ObjectName pattern + * @return the list of MBean names that match the given pattern. + */ + protected Set getMatchingNames(ObjectName pattern) { + return Util.filterMatchingNames(pattern, getNames()); + } + + /** + *

      Returns a {@link NotificationEmitter} which can be used to + * subscribe or unsubscribe for notifications with the named + * mbean.

      + * + *

      The default implementation of this method calls {@link + * #getDynamicMBeanFor getDynamicMBeanFor(name)} and returns that object + * if it is a {@code NotificationEmitter}, otherwise null. See above for further discussion of notification + * handling.

      + * + * @param name The name of the MBean whose notifications are being + * subscribed, or unsuscribed. + * + * @return A {@link NotificationEmitter} that can be used to subscribe or + * unsubscribe for notifications emitted by the named MBean, or {@code + * null} if the MBean does not emit notifications and should not be + * considered as a {@code NotificationEmitter}. + * + * @throws InstanceNotFoundException if {@code name} is not the name of + * an MBean in this {@code MBeanServer}. + */ + public NotificationEmitter getNotificationEmitterFor(ObjectName name) + throws InstanceNotFoundException { + DynamicMBean mbean = getDynamicMBeanFor(name); + if (mbean instanceof NotificationEmitter) + return (NotificationEmitter) mbean; + else + return null; + } + + private NotificationEmitter getNonNullNotificationEmitterFor( + ObjectName name) + throws InstanceNotFoundException { + NotificationEmitter emitter = getNotificationEmitterFor(name); + if (emitter == null) { + IllegalArgumentException iae = new IllegalArgumentException( + "Not a NotificationEmitter: " + name); + throw new RuntimeOperationsException(iae); + } + return emitter; + } + + /** + *

      Creates a new MBean in the MBean name space. + * This operation is not supported in this base class implementation.

      + * The default implementation of this method always throws an {@link + * UnsupportedOperationException} + * wrapped in a {@link RuntimeOperationsException}.

      + * + *

      Subclasses may redefine this method to provide an implementation. + * All the various flavors of {@code MBeanServer.createMBean} methods + * will eventually call this method. A subclass that wishes to + * support MBean creation through {@code createMBean} thus only + * needs to provide an implementation for this one method. + * + * @param className The class name of the MBean to be instantiated. + * @param name The object name of the MBean. May be null. + * @param params An array containing the parameters of the + * constructor to be invoked. + * @param signature An array containing the signature of the + * constructor to be invoked. + * @param loaderName The object name of the class loader to be used. + * @param useCLR This parameter is {@code true} when this method + * is called from one of the {@code MBeanServer.createMBean} methods + * whose signature does not include the {@code ObjectName} of an + * MBean class loader to use for loading the MBean class. + * + * @return An ObjectInstance, containing the + * ObjectName and the Java class name of the newly + * instantiated MBean. If the contained ObjectName + * is n, the contained Java class name is + * {@link javax.management.MBeanServer#getMBeanInfo + * getMBeanInfo(n)}.getClassName(). + * + * @exception ReflectionException Wraps a + * java.lang.ClassNotFoundException or a + * java.lang.Exception that occurred when trying to + * invoke the MBean's constructor. + * @exception InstanceAlreadyExistsException The MBean is already + * under the control of the MBean server. + * @exception MBeanRegistrationException The + * preRegister (MBeanRegistration + * interface) method of the MBean has thrown an exception. The + * MBean will not be registered. + * @exception MBeanException The constructor of the MBean has + * thrown an exception + * @exception NotCompliantMBeanException This class is not a JMX + * compliant MBean + * @exception InstanceNotFoundException The specified class loader + * is not registered in the MBean server. + * @exception RuntimeOperationsException Wraps either: + *

        + *
      • a java.lang.IllegalArgumentException: The className + * passed in parameter is null, the ObjectName passed in + * parameter contains a pattern or no ObjectName is specified + * for the MBean; or
      • + *
      • an {@code UnsupportedOperationException} if creating MBeans is not + * supported by this {@code MBeanServer} implementation. + *
      + */ + public ObjectInstance createMBean(String className, + ObjectName name, ObjectName loaderName, Object[] params, + String[] signature, boolean useCLR) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, InstanceNotFoundException { + throw newUnsupportedException("createMBean"); + } + + + /** + *

      Attempts to determine whether the named MBean should be + * considered as an instance of a given class. The default implementation + * of this method calls {@link #getDynamicMBeanFor getDynamicMBeanFor(name)} + * to get an MBean object. Then its behaviour is the same as the standard + * {@link MBeanServer#isInstanceOf MBeanServer.isInstanceOf} method.

      + * + * {@inheritDoc} + */ + public boolean isInstanceOf(ObjectName name, String className) + throws InstanceNotFoundException { + + final DynamicMBean instance = nonNullMBeanFor(name); + + try { + final String mbeanClassName = instance.getMBeanInfo().getClassName(); + + if (mbeanClassName.equals(className)) + return true; + + final Object resource; + final ClassLoader cl; + if (instance instanceof DynamicWrapperMBean) { + DynamicWrapperMBean d = (DynamicWrapperMBean) instance; + resource = d.getWrappedObject(); + cl = d.getWrappedClassLoader(); + } else { + resource = instance; + cl = instance.getClass().getClassLoader(); + } + + final Class classNameClass = Class.forName(className, false, cl); + + if (classNameClass.isInstance(resource)) + return true; + + if (classNameClass == NotificationBroadcaster.class || + classNameClass == NotificationEmitter.class) { + try { + getNotificationEmitterFor(name); + return true; + } catch (Exception x) { + LOG.finest("MBean " + name + + " is not a notification emitter. Ignoring: "+x); + return false; + } + } + + final Class resourceClass = Class.forName(mbeanClassName, false, cl); + return classNameClass.isAssignableFrom(resourceClass); + } catch (Exception x) { + /* Could be SecurityException or ClassNotFoundException */ + LOG.logp(Level.FINEST, + MBeanServerSupport.class.getName(), + "isInstanceOf", "Exception calling isInstanceOf", x); + return false; + } + } + + /** + * {@inheritDoc} + * + *

      The default implementation of this method returns the string + * "DefaultDomain".

      + */ + public String getDefaultDomain() { + return "DefaultDomain"; + } + + /** + * {@inheritDoc} + * + *

      The default implementation of this method returns + * {@link #getNames()}.size().

      + */ + public Integer getMBeanCount() { + return getNames().size(); + } + + /** + * {@inheritDoc} + * + *

      The default implementation of this method first calls {@link #getNames + * getNames()} to get a list of all MBean names, + * and from this set of names, derives the set of domains which contain + * MBeans.

      + */ + public String[] getDomains() { + final Set names = getNames(); + final Set res = new TreeSet(); + for (ObjectName n : names) { + if (n == null) continue; // not allowed but you never know. + res.add(n.getDomain()); + } + return res.toArray(new String[res.size()]); + } + + + /** + * {@inheritDoc} + * + *

      The default implementation of this method will first + * call {@link + * #getDynamicMBeanFor getDynamicMBeanFor(name)} to obtain a handle + * to the named MBean, + * and then call {@link DynamicMBean#getAttribute getAttribute} + * on that {@link DynamicMBean} handle.

      + * + * @throws RuntimeOperationsException {@inheritDoc} + */ + public Object getAttribute(ObjectName name, String attribute) + throws MBeanException, AttributeNotFoundException, + InstanceNotFoundException, ReflectionException { + final DynamicMBean mbean = nonNullMBeanFor(name); + return mbean.getAttribute(attribute); + } + + /** + * {@inheritDoc} + * + *

      The default implementation of this method will first + * call {@link #getDynamicMBeanFor getDynamicMBeanFor(name)} + * to obtain a handle to the named MBean, + * and then call {@link DynamicMBean#setAttribute setAttribute} + * on that {@link DynamicMBean} handle.

      + * + * @throws RuntimeOperationsException {@inheritDoc} + */ + public void setAttribute(ObjectName name, Attribute attribute) + throws InstanceNotFoundException, AttributeNotFoundException, + InvalidAttributeValueException, MBeanException, + ReflectionException { + final DynamicMBean mbean = nonNullMBeanFor(name); + mbean.setAttribute(attribute); + } + + /** + * {@inheritDoc} + * + *

      The default implementation of this method will first + * call {@link #getDynamicMBeanFor getDynamicMBeanFor(name)} to obtain a + * handle to the named MBean, + * and then call {@link DynamicMBean#getAttributes getAttributes} + * on that {@link DynamicMBean} handle.

      + * + * @throws RuntimeOperationsException {@inheritDoc} + */ + public AttributeList getAttributes(ObjectName name, + String[] attributes) throws InstanceNotFoundException, + ReflectionException { + final DynamicMBean mbean = nonNullMBeanFor(name); + return mbean.getAttributes(attributes); + } + + /** + * {@inheritDoc} + * + *

      The default implementation of this method will first + * call {@link #getDynamicMBeanFor getDynamicMBeanFor(name)} to obtain a + * handle to the named MBean, + * and then call {@link DynamicMBean#setAttributes setAttributes} + * on that {@link DynamicMBean} handle.

      + * + * @throws RuntimeOperationsException {@inheritDoc} + */ + public AttributeList setAttributes(ObjectName name, AttributeList attributes) + throws InstanceNotFoundException, ReflectionException { + final DynamicMBean mbean = nonNullMBeanFor(name); + return mbean.setAttributes(attributes); + } + + /** + * {@inheritDoc} + * + *

      The default implementation of this method will first + * call {@link #getDynamicMBeanFor getDynamicMBeanFor(name)} to obtain a + * handle to the named MBean, + * and then call {@link DynamicMBean#invoke invoke} + * on that {@link DynamicMBean} handle.

      + */ + public Object invoke(ObjectName name, String operationName, + Object[] params, String[] signature) + throws InstanceNotFoundException, MBeanException, + ReflectionException { + final DynamicMBean mbean = nonNullMBeanFor(name); + return mbean.invoke(operationName, params, signature); + } + + /** + * {@inheritDoc} + * + *

      The default implementation of this method will first + * call {@link #getDynamicMBeanFor getDynamicMBeanFor(name)} to obtain a + * handle to the named MBean, + * and then call {@link DynamicMBean#getMBeanInfo getMBeanInfo} + * on that {@link DynamicMBean} handle.

      + */ + public MBeanInfo getMBeanInfo(ObjectName name) + throws InstanceNotFoundException, IntrospectionException, + ReflectionException { + final DynamicMBean mbean = nonNullMBeanFor(name); + return mbean.getMBeanInfo(); + } + + /** + * {@inheritDoc} + * + *

      The default implementation of this method will call + * {@link #getDynamicMBeanFor getDynamicMBeanFor(name)}.{@link DynamicMBean#getMBeanInfo getMBeanInfo()}.{@link MBeanInfo#getClassName getClassName()} to get the + * class name to combine with {@code name} to produce a new + * {@code ObjectInstance}.

      + */ + public ObjectInstance getObjectInstance(ObjectName name) + throws InstanceNotFoundException { + final DynamicMBean mbean = nonNullMBeanFor(name); + final String className = mbean.getMBeanInfo().getClassName(); + return new ObjectInstance(name, className); + } + + /** + * {@inheritDoc} + * + *

      The default implementation of this method will first call {@link + * #getDynamicMBeanFor getDynamicMBeanFor(name)} to obtain a handle to the + * named MBean. If {@code getDynamicMBeanFor} returns an object, {@code + * isRegistered} will return true. If {@code getDynamicMBeanFor} returns + * null or throws {@link InstanceNotFoundException}, {@code isRegistered} + * will return false.

      + * + * @throws RuntimeOperationsException {@inheritDoc} + */ + public boolean isRegistered(ObjectName name) { + try { + final DynamicMBean mbean = getDynamicMBeanFor(name); + return mbean!=null; + } catch (InstanceNotFoundException x) { + if (LOG.isLoggable(Level.FINEST)) + LOG.finest("MBean "+name+" is not registered: "+x); + return false; + } + } + + + /** + * {@inheritDoc} + * + *

      The default implementation of this method will first + * call {@link #queryNames queryNames} + * to get a list of all matching MBeans, and then, for each returned name, + * call {@link #getObjectInstance getObjectInstance(name)}.

      + */ + public Set queryMBeans(ObjectName pattern, QueryExp query) { + final Set names = queryNames(pattern, query); + if (names.isEmpty()) return Collections.emptySet(); + final Set mbeans = new HashSet(); + for (ObjectName name : names) { + try { + mbeans.add(getObjectInstance(name)); + } catch (SecurityException x) { // DLS: OK + continue; + } catch (InstanceNotFoundException x) { // DLS: OK + continue; + } + } + return mbeans; + } + + /** + * {@inheritDoc} + * + *

      The default implementation of this method calls {@link #getMatchingNames + * getMatchingNames(pattern)} to obtain a list of MBeans matching + * the given name pattern. If the {@code query} parameter is null, + * this will be the result. Otherwise, it will evaluate the + * {@code query} parameter for each of the returned names, exactly + * as an {@code MBeanServer} would. This might result in + * {@link #getDynamicMBeanFor getDynamicMBeanFor} being called + * several times for each returned name.

      + */ + public Set queryNames(ObjectName pattern, QueryExp query) { + try { + final Set res = getMatchingNames(pattern); + return filterListOfObjectNames(res, query); + } catch (Exception x) { + LOG.fine("Unexpected exception raised in queryNames: "+x); + LOG.log(Level.FINEST, "Unexpected exception raised in queryNames", x); + } + // We reach here only when an exception was raised. + // + return Collections.emptySet(); + } + + private final static boolean apply(final QueryExp query, + final ObjectName on, + final MBeanServer srv) { + boolean res = false; + MBeanServer oldServer = QueryEval.getMBeanServer(); + query.setMBeanServer(srv); + try { + res = query.apply(on); + } catch (Exception e) { + LOG.finest("QueryExp.apply threw exception, returning false." + + " Cause: "+e); + res = false; + } finally { + /* + * query.setMBeanServer is probably + * QueryEval.setMBeanServer so put back the old + * value. Since that method uses a ThreadLocal + * variable, this code is only needed for the + * unusual case where the user creates a custom + * QueryExp that calls a nested query on another + * MBeanServer. + */ + query.setMBeanServer(oldServer); + } + return res; + } + + /** + * Filters a {@code Set} according to a pattern and a query. + * This might be quite inefficient for virtual name spaces. + */ + Set + filterListOfObjectNames(Set list, + QueryExp query) { + if (list.isEmpty() || query == null) + return list; + + // create a new result set + final Set result = new HashSet(); + + for (ObjectName on : list) { + // if on doesn't match query exclude it. + if (apply(query, on, this)) + result.add(on); + } + return result; + } + + + // Don't use {@inheritDoc}, because we don't want to say that the + // MBeanServer replaces a reference to the MBean by its ObjectName. + /** + *

      Adds a listener to a registered MBean. A notification emitted by + * the MBean will be forwarded to the listener.

      + * + *

      This implementation calls + * {@link #getNotificationEmitterFor getNotificationEmitterFor} + * and invokes {@code addNotificationListener} on the + * {@link NotificationEmitter} it returns. + * + * @see #getDynamicMBeanFor getDynamicMBeanFor + * @see #getNotificationEmitterFor getNotificationEmitterFor + */ + public void addNotificationListener(ObjectName name, + NotificationListener listener, NotificationFilter filter, + Object handback) throws InstanceNotFoundException { + final NotificationEmitter emitter = + getNonNullNotificationEmitterFor(name); + emitter.addNotificationListener(listener, filter, handback); + } + + /** + * {@inheritDoc} + * + *

      This implementation calls + * {@link #getNotificationEmitterFor getNotificationEmitterFor} + * and invokes {@code removeNotificationListener} on the + * {@link NotificationEmitter} it returns. + * @see #getDynamicMBeanFor getDynamicMBeanFor + * @see #getNotificationEmitterFor getNotificationEmitterFor + */ + public void removeNotificationListener(ObjectName name, + NotificationListener listener) + throws InstanceNotFoundException, ListenerNotFoundException { + final NotificationEmitter emitter = + getNonNullNotificationEmitterFor(name); + emitter.removeNotificationListener(listener); + } + + /** + * {@inheritDoc} + * + *

      This implementation calls + * {@link #getNotificationEmitterFor getNotificationEmitterFor} + * and invokes {@code removeNotificationListener} on the + * {@link NotificationEmitter} it returns. + * @see #getDynamicMBeanFor getDynamicMBeanFor + * @see #getNotificationEmitterFor getNotificationEmitterFor + */ + public void removeNotificationListener(ObjectName name, + NotificationListener listener, NotificationFilter filter, + Object handback) + throws InstanceNotFoundException, ListenerNotFoundException { + NotificationEmitter emitter = + getNonNullNotificationEmitterFor(name); + emitter.removeNotificationListener(listener); + } + + + /** + *

      Adds a listener to a registered MBean.

      + * + *

      The default implementation of this method first calls + * {@link #getDynamicMBeanFor getDynamicMBeanFor(listenerName)}. + * If that successfully returns an object, call it {@code + * mbean}, then (a) if {@code mbean} is an instance of {@link + * NotificationListener} then this method calls {@link + * #addNotificationListener(ObjectName, NotificationListener, + * NotificationFilter, Object) addNotificationListener(name, mbean, filter, + * handback)}, otherwise (b) this method throws an exception as specified + * for this case.

      + * + *

      This default implementation is not appropriate for Virtual MBeans, + * although that only matters if the object returned by {@code + * getDynamicMBeanFor} can be an instance of + * {@code NotificationListener}.

      + * + * @throws RuntimeOperationsException {@inheritDoc} + */ + public void addNotificationListener(ObjectName name, ObjectName listenerName, + NotificationFilter filter, Object handback) + throws InstanceNotFoundException { + NotificationListener listener = getListenerMBean(listenerName); + addNotificationListener(name, listener, filter, handback); + } + + /** + * {@inheritDoc} + * + *

      This operation is not supported in this base class implementation. + * The default implementation of this method always throws + * {@link RuntimeOperationsException} wrapping + * {@link UnsupportedOperationException}.

      + * + * @throws javax.management.RuntimeOperationsException wrapping + * {@link UnsupportedOperationException} + */ + public void removeNotificationListener(ObjectName name, + ObjectName listenerName) + throws InstanceNotFoundException, ListenerNotFoundException { + NotificationListener listener = getListenerMBean(listenerName); + removeNotificationListener(name, listener); + } + + /** + * {@inheritDoc} + * + *

      This operation is not supported in this base class implementation. + * The default implementation of this method always throws + * {@link RuntimeOperationsException} wrapping + * {@link UnsupportedOperationException}.

      + * + * @throws javax.management.RuntimeOperationsException wrapping + * {@link UnsupportedOperationException} + */ + public void removeNotificationListener(ObjectName name, + ObjectName listenerName, NotificationFilter filter, + Object handback) + throws InstanceNotFoundException, ListenerNotFoundException { + NotificationListener listener = getListenerMBean(listenerName); + removeNotificationListener(name, listener, filter, handback); + } + + private NotificationListener getListenerMBean(ObjectName listenerName) + throws InstanceNotFoundException { + Object mbean = getDynamicMBeanFor(listenerName); + if (mbean instanceof NotificationListener) + return (NotificationListener) mbean; + else { + throw newIllegalArgumentException( + "MBean is not a NotificationListener: " + listenerName); + } + } + + + /** + * {@inheritDoc} + * + *

      This operation is not supported in this base class implementation. + * The default implementation of this method always throws + * {@link InstanceNotFoundException} wrapping + * {@link UnsupportedOperationException}.

      + * + * @return the default implementation of this method never returns. + * @throws javax.management.RuntimeOperationsException wrapping + * {@link UnsupportedOperationException} + */ + public ClassLoader getClassLoader(ObjectName loaderName) + throws InstanceNotFoundException { + final UnsupportedOperationException failed = + new UnsupportedOperationException("getClassLoader"); + final InstanceNotFoundException x = + new InstanceNotFoundException(String.valueOf(loaderName)); + x.initCause(failed); + throw x; + } + + /** + * {@inheritDoc} + * + *

      The default implementation of this method calls + * {@link #getDynamicMBeanFor getDynamicMBeanFor(mbeanName)} and applies + * the logic just described to the result.

      + */ + public ClassLoader getClassLoaderFor(ObjectName mbeanName) + throws InstanceNotFoundException { + final DynamicMBean mbean = nonNullMBeanFor(mbeanName); + if (mbean instanceof DynamicWrapperMBean) + return ((DynamicWrapperMBean) mbean).getWrappedClassLoader(); + else + return mbean.getClass().getClassLoader(); + } + + /** + * {@inheritDoc} + * + *

      The default implementation of this method returns a + * {@link ClassLoaderRepository} containing exactly one loader, + * the {@linkplain Thread#getContextClassLoader() context class loader} + * for the current thread. + * Subclasses can override this method to return a different + * {@code ClassLoaderRepository}.

      + */ + public ClassLoaderRepository getClassLoaderRepository() { + // We return a new ClassLoaderRepository each time this + // method is called. This is by design, because the + // SingletonClassLoaderRepository is a very small object and + // getClassLoaderRepository() will not be called very often + // (the connector server calls it once) - in the context of + // MBeanServerSupport there's a very good chance that this method will + // *never* be called. + ClassLoader ccl = Thread.currentThread().getContextClassLoader(); + return Util.getSingleClassLoaderRepository(ccl); + } + + + /** + * {@inheritDoc} + * + *

      This operation is not supported in this base class implementation. + * The default implementation of this method always throws + * {@link RuntimeOperationsException} wrapping + * {@link UnsupportedOperationException}.

      + * @throws javax.management.RuntimeOperationsException wrapping + * {@link UnsupportedOperationException} + */ + public ObjectInstance registerMBean(Object object, ObjectName name) + throws InstanceAlreadyExistsException, MBeanRegistrationException, + NotCompliantMBeanException { + throw newUnsupportedException("registerMBean"); + } + + /** + * {@inheritDoc} + * + *

      This operation is not supported in this base class implementation. + * The default implementation of this method always throws + * {@link RuntimeOperationsException} wrapping + * {@link UnsupportedOperationException}. + * @throws javax.management.RuntimeOperationsException wrapping + * {@link UnsupportedOperationException} + */ + public void unregisterMBean(ObjectName name) + throws InstanceNotFoundException, MBeanRegistrationException { + throw newUnsupportedException("unregisterMBean"); + } + + /** + * Calls {@link #createMBean(String, ObjectName, + * ObjectName, Object[], String[], boolean) + * createMBean(className, name, null, params, signature, true)}; + */ + public final ObjectInstance createMBean(String className, ObjectName name, + Object[] params, String[] signature) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException { + try { + return safeCreateMBean(className, name, null, params, signature, true); + } catch (InstanceNotFoundException ex) { + // should not happen! + throw new MBeanException(ex, "Unexpected exception: " + ex); + } + } + + /** + * Calls {@link #createMBean(String, ObjectName, + * ObjectName, Object[], String[], boolean) + * createMBean(className,name, loaderName, params, signature, false)}; + */ + public final ObjectInstance createMBean(String className, ObjectName name, + ObjectName loaderName, Object[] params, String[] signature) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, InstanceNotFoundException { + return safeCreateMBean(className, name, loaderName, params, signature, false); + } + + /** + * Calls {@link #createMBean(String, ObjectName, + * ObjectName, Object[], String[], boolean) + * createMBean(className, name, null, null, null, true)}; + */ + public final ObjectInstance createMBean(String className, ObjectName name) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException { + try { + return safeCreateMBean(className, name, null, null, null, true); + } catch (InstanceNotFoundException ex) { + // should not happen! + throw new MBeanException(ex, "Unexpected exception: " + ex); + } + } + + /** + * Calls {@link #createMBean(String, ObjectName, + * ObjectName, Object[], String[], boolean) + * createMBean(className, name, loaderName, null, null, false)}; + */ + public final ObjectInstance createMBean(String className, ObjectName name, + ObjectName loaderName) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, InstanceNotFoundException { + return safeCreateMBean(className, name, loaderName, null, null, false); + } + + // make sure all exceptions are correctly wrapped in a JMXException + private ObjectInstance safeCreateMBean(String className, + ObjectName name, ObjectName loaderName, Object[] params, + String[] signature, boolean useRepository) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, InstanceNotFoundException { + try { + return createMBean(className, name, loaderName, params, + signature, useRepository); + } catch (ReflectionException x) { throw x; + } catch (InstanceAlreadyExistsException x) { throw x; + } catch (MBeanRegistrationException x) { throw x; + } catch (MBeanException x) { throw x; + } catch (NotCompliantMBeanException x) { throw x; + } catch (InstanceNotFoundException x) { throw x; + } catch (SecurityException x) { throw x; + } catch (JMRuntimeException x) { throw x; + } catch (RuntimeException x) { + throw new RuntimeOperationsException(x, x.toString()); + } catch (Exception x) { + throw new MBeanException(x, x.toString()); + } + } + + + /** + * {@inheritDoc} + * + *

      This operation is not supported in this base class implementation. + * The default implementation of this method always throws + * {@link RuntimeOperationsException} wrapping + * {@link UnsupportedOperationException}.

      + * + * @throws javax.management.RuntimeOperationsException wrapping + * {@link UnsupportedOperationException} + */ + public Object instantiate(String className) + throws ReflectionException, MBeanException { + throw new UnsupportedOperationException("Not applicable."); + } + + /** + * {@inheritDoc} + * + *

      This operation is not supported in this base class implementation. + * The default implementation of this method always throws + * {@link RuntimeOperationsException} wrapping + * {@link UnsupportedOperationException}.

      + * + * @throws javax.management.RuntimeOperationsException wrapping + * {@link UnsupportedOperationException} + */ + public Object instantiate(String className, ObjectName loaderName) + throws ReflectionException, MBeanException, + InstanceNotFoundException { + throw new UnsupportedOperationException("Not applicable."); + } + + /** + * {@inheritDoc} + * + *

      This operation is not supported in this base class implementation. + * The default implementation of this method always throws + * {@link RuntimeOperationsException} wrapping + * {@link UnsupportedOperationException}.

      + * + * @throws javax.management.RuntimeOperationsException wrapping + * {@link UnsupportedOperationException} + */ + public Object instantiate(String className, Object[] params, + String[] signature) throws ReflectionException, MBeanException { + throw new UnsupportedOperationException("Not applicable."); + } + + /** + * {@inheritDoc} + * + *

      This operation is not supported in this base class implementation. + * The default implementation of this method always throws + * {@link RuntimeOperationsException} wrapping + * {@link UnsupportedOperationException}.

      + * + * @throws javax.management.RuntimeOperationsException wrapping + * {@link UnsupportedOperationException} + */ + public Object instantiate(String className, ObjectName loaderName, + Object[] params, String[] signature) + throws ReflectionException, MBeanException, + InstanceNotFoundException { + throw new UnsupportedOperationException("Not applicable."); + } + + + /** + * {@inheritDoc} + * + *

      This operation is not supported in this base class implementation. + * The default implementation of this method always throws + * {@link RuntimeOperationsException} wrapping + * {@link UnsupportedOperationException}.

      + * + * @throws javax.management.RuntimeOperationsException wrapping + * {@link UnsupportedOperationException} + */ + @Deprecated + public ObjectInputStream deserialize(ObjectName name, byte[] data) + throws InstanceNotFoundException, OperationsException { + throw new UnsupportedOperationException("Not applicable."); + } + + /** + * {@inheritDoc} + * + *

      This operation is not supported in this base class implementation. + * The default implementation of this method always throws + * {@link RuntimeOperationsException} wrapping + * {@link UnsupportedOperationException}.

      + * + * @throws javax.management.RuntimeOperationsException wrapping + * {@link UnsupportedOperationException} + */ + @Deprecated + public ObjectInputStream deserialize(String className, byte[] data) + throws OperationsException, ReflectionException { + throw new UnsupportedOperationException("Not applicable."); + } + + /** + * {@inheritDoc} + * + *

      This operation is not supported in this base class implementation. + * The default implementation of this method always throws + * {@link RuntimeOperationsException} wrapping + * {@link UnsupportedOperationException}.

      + * + * @throws javax.management.RuntimeOperationsException wrapping + * {@link UnsupportedOperationException} + */ + @Deprecated + public ObjectInputStream deserialize(String className, + ObjectName loaderName, byte[] data) + throws InstanceNotFoundException, OperationsException, + ReflectionException { + throw new UnsupportedOperationException("Not applicable."); + } + + + // Calls getDynamicMBeanFor, and throws an InstanceNotFoundException + // if the returned mbean is null. + // The DynamicMBean returned by this method is thus guaranteed to be + // non null. + // + private DynamicMBean nonNullMBeanFor(ObjectName name) + throws InstanceNotFoundException { + if (name == null) + throw newIllegalArgumentException("Null ObjectName"); + if (name.getDomain().equals("")) { + String defaultDomain = getDefaultDomain(); + try { + name = name.withDomain(getDefaultDomain()); + } catch (Exception e) { + throw newIllegalArgumentException( + "Illegal default domain: " + defaultDomain); + } + } + final DynamicMBean mbean = getDynamicMBeanFor(name); + if (mbean!=null) return mbean; + throw new InstanceNotFoundException(String.valueOf(name)); + } + + static RuntimeException newUnsupportedException(String operation) { + return new RuntimeOperationsException( + new UnsupportedOperationException( + operation+": Not supported in this namespace")); + } + + static RuntimeException newIllegalArgumentException(String msg) { + return new RuntimeOperationsException( + new IllegalArgumentException(msg)); + } + +} diff --git a/jdk/src/share/classes/javax/management/namespace/VirtualEventManager.java b/jdk/src/share/classes/javax/management/namespace/VirtualEventManager.java new file mode 100644 index 00000000000..336f37565cb --- /dev/null +++ b/jdk/src/share/classes/javax/management/namespace/VirtualEventManager.java @@ -0,0 +1,378 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management.namespace; + +import com.sun.jmx.remote.util.ClassLogger; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import javax.management.InstanceNotFoundException; +import javax.management.ListenerNotFoundException; +import javax.management.MBeanNotificationInfo; +import javax.management.Notification; +import javax.management.NotificationEmitter; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.ObjectName; +import javax.management.event.EventConsumer; + +/** + *

      This class maintains a list of subscribers for ObjectName patterns and + * allows a notification to be sent to all subscribers for a given ObjectName. + * It is typically used in conjunction with {@link MBeanServerSupport} + * to implement a namespace with Virtual MBeans that can emit notifications. + * The {@code VirtualEventManager} keeps track of the listeners that have been + * added to each Virtual MBean. When an event occurs that should trigger a + * notification from a Virtual MBean, the {@link #publish publish} method can + * be used to send it to the appropriate listeners.

      + * @since 1.7 + */ +public class VirtualEventManager implements EventConsumer { + /** + *

      Create a new {@code VirtualEventManager}.

      + */ + public VirtualEventManager() { + } + + public void subscribe( + ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object handback) { + + if (logger.traceOn()) + logger.trace("subscribe", "" + name); + + if (name == null) + throw new IllegalArgumentException("Null MBean name"); + + if (listener == null) + throw new IllegalArgumentException("Null listener"); + + Map> map = + name.isPattern() ? patternSubscriptionMap : exactSubscriptionMap; + + final ListenerInfo li = new ListenerInfo(listener, filter, handback); + List list; + + synchronized (map) { + list = map.get(name); + if (list == null) { + list = new ArrayList(); + map.put(name, list); + } + list.add(li); + } + } + + public void unsubscribe( + ObjectName name, NotificationListener listener) + throws ListenerNotFoundException { + + if (logger.traceOn()) + logger.trace("unsubscribe2", "" + name); + + if (name == null) + throw new IllegalArgumentException("Null MBean name"); + + if (listener == null) + throw new ListenerNotFoundException(); + + Map> map = + name.isPattern() ? patternSubscriptionMap : exactSubscriptionMap; + + final ListenerInfo li = new ListenerInfo(listener, null, null); + List list; + synchronized (map) { + list = map.get(name); + if (list == null || !list.remove(li)) + throw new ListenerNotFoundException(); + + if (list.isEmpty()) + map.remove(name); + } + } + + /** + *

      Unsubscribes a listener which is listening to an MBean or a set of + * MBeans represented by an {@code ObjectName} pattern.

      + * + *

      The listener to be removed must have been added by the {@link + * #subscribe subscribe} method with the given {@code name}, {@code filter}, + * and {@code handback}. If the {@code + * name} is a pattern, then the {@code subscribe} must have used the same + * pattern. If the same listener has been subscribed more than once to the + * {@code name} with the same filter and handback, only one listener is + * removed.

      + * + * @param name The name of the MBean or an {@code ObjectName} pattern + * representing a set of MBeans to which the listener was subscribed. + * @param listener A listener that was previously subscribed to the + * MBean(s). + * + * @throws ListenerNotFoundException The given {@code listener} was not + * subscribed to the given {@code name}. + * + * @see #subscribe + */ + public void unsubscribe( + ObjectName name, NotificationListener listener, + NotificationFilter filter, Object handback) + throws ListenerNotFoundException { + + if (logger.traceOn()) + logger.trace("unsubscribe4", "" + name); + + if (name == null) + throw new IllegalArgumentException("Null MBean name"); + + if (listener == null) + throw new ListenerNotFoundException(); + + Map> map = + name.isPattern() ? patternSubscriptionMap : exactSubscriptionMap; + + List list; + synchronized (map) { + list = map.get(name); + boolean removed = false; + for (Iterator it = list.iterator(); it.hasNext(); ) { + ListenerInfo li = it.next(); + if (li.equals(listener, filter, handback)) { + it.remove(); + removed = true; + break; + } + } + if (!removed) + throw new ListenerNotFoundException(); + + if (list.isEmpty()) + map.remove(name); + } + } + + /** + *

      Sends a notification to the subscribers for a given MBean.

      + * + *

      For each listener subscribed with an {@code ObjectName} that either + * is equal to {@code emitterName} or is a pattern that matches {@code + * emitterName}, if the associated filter accepts the notification then it + * is forwarded to the listener.

      + * + * @param emitterName The name of the MBean emitting the notification. + * @param n The notification being sent by the MBean called + * {@code emitterName}. + * + * @throws IllegalArgumentException If the emitterName of the + * notification is null or is an {@code ObjectName} pattern. + */ + public void publish(ObjectName emitterName, Notification n) { + if (logger.traceOn()) + logger.trace("publish", "" + emitterName); + + if (n == null) + throw new IllegalArgumentException("Null notification"); + + if (emitterName == null) { + throw new IllegalArgumentException( + "Null emitter name"); + } else if (emitterName.isPattern()) { + throw new IllegalArgumentException( + "The emitter must not be an ObjectName pattern"); + } + + final List listeners = new ArrayList(); + + // If there are listeners for this exact name, add them. + synchronized (exactSubscriptionMap) { + List exactListeners = + exactSubscriptionMap.get(emitterName); + if (exactListeners != null) + listeners.addAll(exactListeners); + } + + // Loop over subscription patterns, and add all listeners for each + // one that matches the emitterName name. + synchronized (patternSubscriptionMap) { + for (ObjectName on : patternSubscriptionMap.keySet()) { + if (on.apply(emitterName)) + listeners.addAll(patternSubscriptionMap.get(on)); + } + } + + // Send the notification to all the listeners we found. + sendNotif(listeners, n); + } + + /** + *

      Returns a {@link NotificationEmitter} object which can be used to + * subscribe or unsubscribe for notifications with the named + * mbean. The returned object implements {@link + * NotificationEmitter#addNotificationListener + * addNotificationListener(listener, filter, handback)} as + * {@link #subscribe this.subscribe(name, listener, filter, handback)} + * and the two {@code removeNotificationListener} methods from {@link + * NotificationEmitter} as the corresponding {@code unsubscribe} methods + * from this class.

      + * + * @param name The name of the MBean whose notifications are being + * subscribed, or unsuscribed. + * + * @return A {@link NotificationEmitter} + * that can be used to subscribe or unsubscribe for + * notifications emitted by the named MBean, or {@code null} if + * the MBean does not emit notifications and should not + * be considered as a {@code NotificationBroadcaster}. This class + * never returns null but a subclass is allowed to. + * + * @throws InstanceNotFoundException if {@code name} does not exist. + * This implementation never throws {@code InstanceNotFoundException} but + * a subclass is allowed to override this method to do so. + */ + public NotificationEmitter + getNotificationEmitterFor(final ObjectName name) + throws InstanceNotFoundException { + final NotificationEmitter emitter = new NotificationEmitter() { + public void addNotificationListener(NotificationListener listener, + NotificationFilter filter, Object handback) + throws IllegalArgumentException { + subscribe(name, listener, filter, handback); + } + + public void removeNotificationListener( + NotificationListener listener) + throws ListenerNotFoundException { + unsubscribe(name, listener); + } + + public void removeNotificationListener(NotificationListener listener, + NotificationFilter filter, + Object handback) + throws ListenerNotFoundException { + unsubscribe(name, listener, filter, handback); + } + + public MBeanNotificationInfo[] getNotificationInfo() { + // Never called. + return null; + } + }; + return emitter; + } + + // --------------------------------- + // private stuff + // --------------------------------- + + private static class ListenerInfo { + public final NotificationListener listener; + public final NotificationFilter filter; + public final Object handback; + + public ListenerInfo(NotificationListener listener, + NotificationFilter filter, + Object handback) { + + if (listener == null) { + throw new IllegalArgumentException("Null listener."); + } + + this.listener = listener; + this.filter = filter; + this.handback = handback; + } + + /* Two ListenerInfo instances are equal if they have the same + * NotificationListener. This means that we can use List.remove + * to implement the two-argument removeNotificationListener. + */ + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + + if (!(o instanceof ListenerInfo)) { + return false; + } + + return listener.equals(((ListenerInfo)o).listener); + } + + /* Method that compares all four fields, appropriate for the + * four-argument removeNotificationListener. + */ + boolean equals( + NotificationListener listener, + NotificationFilter filter, + Object handback) { + return (this.listener == listener && same(this.filter, filter) + && same(this.handback, handback)); + } + + private static boolean same(Object x, Object y) { + if (x == y) + return true; + if (x == null) + return false; + return x.equals(y); + } + + @Override + public int hashCode() { + return listener.hashCode(); + } + } + + private static void sendNotif(List listeners, Notification n) { + for (ListenerInfo li : listeners) { + if (li.filter == null || + li.filter.isNotificationEnabled(n)) { + try { + li.listener.handleNotification(n, li.handback); + } catch (Exception e) { + logger.trace("sendNotif", "handleNotification", e); + } + } + } + } + + // --------------------------------- + // private variables + // --------------------------------- + + private final Map> exactSubscriptionMap = + new HashMap>(); + private final Map> patternSubscriptionMap = + new HashMap>(); + + // trace issue + private static final ClassLogger logger = + new ClassLogger("javax.management.event", "EventManager"); +} diff --git a/jdk/src/share/classes/javax/management/namespace/package-info.java b/jdk/src/share/classes/javax/management/namespace/package-info.java new file mode 100644 index 00000000000..df8354bab63 --- /dev/null +++ b/jdk/src/share/classes/javax/management/namespace/package-info.java @@ -0,0 +1,597 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + *

      The javax.management.namespace package makes it possible + * to federate MBeanServers into a hierarchical name space.

      + * + *

      What Is a Name Space?

      + *

      + * A name space is like an {@link javax.management.MBeanServer} within + * an {@code MBeanServer}. Just as a file system folder can contain + * another file system folder, an {@code MBeanServer} can contain another + * {@code MBeanServer}. Similarly, just as a remote folder on a remote + * disk can be mounted on a parent folder on a local disk, a remote name + * space in a remote {@code MBeanServer} can be mounted on a name + * space in a local parent {@code MBeanServer}. + *

      + *

      + * The javax.management.namespace API thus makes it possible to + * create a hierarchy of MBean servers federated in a hierarchical name + * space inside a single {@code MBeanServer}. + *

      + *

      How To Create a Name Space?

      + *

      + * To create a name space, you only need to register a + * {@link javax.management.namespace.JMXNamespace} MBean in + * an MBean server. We have seen that a namespace is like + * an {@code MBeanServer} within an {@code MBeanServer}, and + * therefore, it is possible to create a namespace that shows the + * content of another {@code MBeanServer}. The simplest case is + * when that {@code MBeanServer} is another {@code MBeanServer} + * created by the {@link javax.management.MBeanServerFactory} as + * shown in the extract below: + *

      + *
      + *  final MBeanServer server = ....;
      + *  final String namespace = "foo";
      + *  final ObjectName namespaceName = {@link javax.management.namespace.JMXNamespaces#getNamespaceObjectName
      + *        JMXNamespaces.getNamespaceObjectName(namespace)};
      + *  server.registerMBean(new JMXNamespace(MBeanServerFactory.newMBeanServer()),
      + *                      namespaceName);
      + *  
      + *

      + * To navigate in namespaces and view their content, the easiest way is + * to use an instance of {@link javax.management.namespace.JMXNamespaceView}. For instance, given + * the {@code server} above, in which we created a namespace {@code "foo"}, + * it is possible to create a {@code JMXNamespaceView} that will make it + * possible to navigate easily in the namespaces and sub-namespaces of that + * server: + *

      + *
      + *  // create a namespace view for 'server'
      + *  final JMXNamespaceView view = new JMXNamespaceView(server);
      + *
      + *  // list all top level namespaces in 'server'
      + *  System.out.println("List of namespaces: " + Arrays.toString({@link javax.management.namespace.JMXNamespaceView#list() view.list()}));
      + *
      + *  // go down into namespace 'foo': provides a namespace view of 'foo' and its
      + *  // sub namespaces...
      + *  final JMXNamespaceView foo = {@link javax.management.namespace.JMXNamespaceView#down view.down("foo")};
      + *
      + *  // list all MBeans contained in namespace 'foo'
      + *  System.out.println({@link javax.management.namespace.JMXNamespaceView#where() foo.where()} + " contains: " +
      + *         {@link javax.management.namespace.JMXNamespaceView#getMBeanServerConnection foo.getMBeanServerConnection()}.queryNames(null,null));
      + *  
      + *

      + * It is also possible to create more complex namespaces, such as namespaces + * that point to MBean servers located in remote JVMs. + *

      + *

      + * For instance, to mount the MBeanServer accessible + * at service:jmx:rmi:///jndi/rmi://localhost:9000/jmxrmi + * in a name space {@code "foo"} inside the {@linkplain + * java.lang.management.ManagementFactory#getPlatformMBeanServer platform + * MBeanServer} you would write the following piece of code: + *

      + *
      + *      final JMXServiceURL sourceURL =
      + *         new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9000/jmxrmi");
      + *      final MBeanServer platform = ManagementFactory.getPlatformMBeanServer();
      + *      final Map<String,Object> options = Collections.emptyMap();
      + *      final JMXRemoteNamespace mbean = {@link
      + *            javax.management.namespace.JMXRemoteNamespace JMXRemoteNamespace}.
      + *         {@link javax.management.namespace.JMXRemoteNamespace#newJMXRemoteNamespace newJMXRemoteNamespace(sourceURL, options)};
      + *      final ObjectName name = {@link javax.management.namespace.JMXNamespaces JMXNamespaces}.{@link javax.management.namespace.JMXNamespaces#getNamespaceObjectName(String) getNamespaceObjectName("foo")};
      + *      final ObjectInstance ref = platform.registerMBean(mbean,name);
      + *      platform.invoke(ref.getObjectName(),"connect",null,null);
      + *  
      + * + *

      What Does a Name Space Look Like?

      + * + *

      + * We have seen that {@link javax.management.namespace.JMXNamespaceView} class + * provides an easy way to navigate within namespaces. It is however also + * possible to interact with namespaces directly from the top level + * {@code MBeanServer} in which they have been created. + * From the outside, a name space only appears as a special MBean in + * the MBean server. There's nothing much you can do with this MBean + * directly. + *

      + *

      + * For instance, let's assume you have registered a {@link + * javax.management.namespace.JMXRemoteNamespaceMBean + * JMXRemoteNamespaceMBean} to manage the name space {@code "foo"}. + *
      If you query for + * platform.queryNames("*//:*",null), then you will see + * one MBean named {@code "foo//:type=JMXNamespace"}. + *
      This is the {@link javax.management.namespace.JMXNamespace} + * MBean which is in charge of handling the namespace {@code "foo"}. + *

      + *

      + * In fact, name space handler MBeans are instances of + * the class {@link javax.management.namespace.JMXNamespace} - or + * instances of a subclass of that class. + * They have a special {@link javax.management.ObjectName} defined by + * {@link javax.management.namespace.JMXNamespaces#getNamespaceObjectName + * JMXNamespaces.getNamespaceObjectName}.
      + * {@link javax.management.namespace.JMXNamespace} instances are able + * to return an {@link + * javax.management.namespace.JMXNamespace#getSourceServer MBeanServer} + * which corresponds to the MBeanServer within (= the name space itself). + *

      + *

      + * So how does it work? How can you see the MBeans contained in the new + * name space? + *

      + *

      In order to address scalability issues, MBeans registered in + * namespaces (such as our namespace {@code "foo"} above) can not be + * seen with {@code mbeanServer.queryNames("*:*",null)}. To see the MBeans + * contained in a namespace, you can use one of these methods: + *

      + *
        + *
      1. + * You can use the {@link javax.management.namespace.JMXNamespaceView} + * class shown above, + *
      2. + *
      3. + * or you can directly look for MBeans + * whose names match + * {@code "foo//*:*"}, + *
      4. + *
      5. + * or you can narrow down to the namespace + * and obtain an MBeanServer + * proxy that corresponds to an MBeanServer view of that namespace. + * The JMXNamespaces class provides a static method that + * allows you to narrow down to a name space, by calling + * {@link javax.management.namespace.JMXNamespaces#narrowToNamespace(MBeanServer,String) + * JMXNamespaces.narrowToNamespace}. + *
      6. + *
      + * + *

      Using Name Space Prefixes

      + *

      + * As we have explained above, MBeans contained in name + * spaces are not returned by {@code server.queryNames(null,null)} - or + * server.queryNames({@link javax.management.ObjectName#WILDCARD ObjectName.WILDCARD},null). + *
      + * However, these MBeans can still be accessed from the top level + * {@code MBeanServer} interface, without using any API specific to the + * version 2.0 of the JMX API, simply by using object names with + * name space prefixes: + *
      To list MBeans contained in a namespace {@code "foo"} you can + * query for MBeans whose names match {@code "foo//*:*"}, as shown + * earlier in this document: + *

      + *         server.queryNames(new ObjectName("foo//*:*", null);
      + *         // or equivalently:
      + *         server.queryNames(JMXNamespaces.getWildcardFor("foo"), null);
      + *      
      + * This will return a list of MBean names whose domain name starts + * with {@code foo//}. + *

      + * Using these names, you can invoke any operation on the corresponding + * MBeans. For instance, to get the {@link javax.management.MBeanInfo + * MBeanInfo} of an MBean + * contained in name space {@code "foo"} (assuming + * the name of the MBean within its name space is domain:type=Thing, + * then simply call: + *

      + *         server.getMBeanInfo(new ObjectName("foo//domain:type=Thing"));
      + *      
      + * An easier way to access MBeans contained in a name space is to + * cd inside the name space, as shown in the following paragraph. + *

      + * + *

      Narrowing Down Into a Name Spaces

      + *

      + * As we have seen, name spaces are like MBean servers within MBean servers. + * Therefore, it is possible to view a name space just as if it were + * an other MBean server. This is similar to opening a sub + * folder from a parent folder.
      + * This operation is illustrated in the code extract below: + *

      + *          final MBeanServer foo =
      + *                JMXNamespaces.narrowToNamespace(platform, "foo");
      + *          final MBeanInfo info =
      + *                foo.getMBeanInfo(new ObjectName("domain:type=Thing"));
      + *      
      + * The {@code MBeanServer} returned by {@link + * javax.management.namespace.JMXNamespaces#narrowToNamespace(MBeanServer,String) + * JMXNamespaces.narrowToNamespace} is an {@code MBeanServer} view that + * narrows down into a given namespace. The MBeans contained inside that + * namespace can now be accessed by their regular local name.
      + * The MBean server obtained by narrowing down + * to name space {@code "foo"} behaves just like a regular MBean server. + * However, it may sometimes throw an {@link + * java.lang.UnsupportedOperationException UnsupportedOperationException} + * wrapped in a JMX exception if you try to call an operation which is not + * supported by the underlying name space handler. + *
      For instance, {@link javax.management.MBeanServer#registerMBean + * registerMBean} is not supported for name spaces mounted from remote + * MBean servers. + *

      + *

      + * Note: If you have a deep hierarchy of namespaces, and if you + * are switching from one namespace to another in the course of your + * application, it might be more convenient to use a + * {@link javax.management.namespace.JMXNamespaceView} + * in order to navigate in your namespaces. + *

      + * + *

      Different Types of Name Spaces

      + *

      + * This API lets you create several types of name spaces: + *

        + *
      • + * You can use the {@link + * javax.management.namespace.JMXRemoteNamespace + * JMXRemoteNamespace} to create + * remote name spaces, mounted from + * a remote sub {@code MBeanServer} source, as shown + * earlier in this document. + *
      • + *
      • + * You can also use {@link + * javax.management.namespace.JMXNamespace + * JMXNamespace} to create + * local name spaces, + * by providing a direct reference to another {@code MBeanServer} + * instance living in the same JVM. + *
      • + *
      • + * Finally, you can create + * name spaces containing virtual MBeans, + * by subclassing the {@link + * javax.management.namespace.MBeanServerSupport + * MBeanServerSupport}, and passing an instance of + * your own subclass to a {@link + * javax.management.namespace.JMXNamespace JMXNamespace}. + *
      • + *
      • + * If none of these classes suit your needs, you can also provide + * your own subclass of {@link + * javax.management.namespace.JMXNamespace + * JMXNamespace}. This is however discouraged. + *
      • + *
      + *

      + * + *

      Name Spaces And Special Operations

      + *

      + * MBean Naming considerations aside, Name Spaces are transparent for + * most {@code MBeanServer} operations. There are however a few + * exceptions: + *

      + *
        + *
      • + *

        MBeanServer only operations - these are the operations which are + * supported by {@link javax.management.MBeanServer MBeanServer} but + * are not present in {@link + * javax.management.MBeanServerConnection + * MBeanServerConnection}. Since a name space can be a local view of + * a remote {@code MBeanServer}, accessible only through an + * {@code MBeanServerConnection}, these + * kinds of operations are not always supported.

        + *
          + *
        • + *

          registerMBean:

          + *

          The {@link javax.management.MBeanServer#registerMBean + * registerMBean} + * operation is not supported by most name spaces. A call + * to + *

          + *   MBeanServer server = ....;
          + *   ThingMBean mbean = new Thing(...);
          + *   ObjectName name = new ObjectName("foo//domain:type=Thing");
          + *   server.registerMBean(mbean, name);
          + *                          
          + * will usually fail, unless the name space + * {@code "foo"} is a local name + * space. In the case where you attempt to cross + * multiple name spaces, then all name spaces in the + * path must support the {@code registerMBean} operation + * in order for it to succeed.
          + * To create an MBean inside a name space, it is + * usually safer to use {@code createMBean} - + * although some special + * considerations can also apply. + *

          + *

          + *
        • + *
        • + *

          getClassLoader:

          + *

          Similarly to registerMBean, + * and for the same reasons, {@link + * javax.management.MBeanServer#getClassLoader + * getClassLoader} will usually fail, unless the + * class loader is an MBean registered in a + * local name space.
          + *

          + *
        • + *
        • + *

          getClassLoaderFor:

          + *

          The implementation of {@link + * javax.management.MBeanServer#getClassLoaderFor + * getClassLoaderFor} also depends on which + * type of name space + * handler is used across the namespace path. + *

          + *

          + * A local name space will usually + * be able to implement this method just as a real + * {@code MBeanServer} would. A + * remote name space will usually + * return the default class loader configured on the + * internal {@link javax.management.remote.JMXConnector + * JMXConnector} used to connect to the remote server. + * When a {@link + * javax.management.namespace.JMXRemoteNamespace + * JMXRemoteNamespace} is used to connect to a + * remote server that contains MBeans which export + * custom types, the {@link + * javax.management.namespace.JMXRemoteNamespace + * JMXRemoteNamespace} must thus be configured with + * an options map such that the underlying connector + * can obtain a default class loader able + * to handle those types. + *

          + *

          + * Other types of name spaces + * may implement this method + * as best as they can. + *

          + *
        • + *
        + *
      • + *
      • + *

        MBean creation

        + *

        MBean creation through {@link + * javax.management.MBeanServerConnection#createMBean + * createMBean} might not be supported by all + * name spaces: local name spaces and + * remote name spaces will usually + * support it, but virtual name + * spaces and custom name + * spaces might not. + *

        + *

        + * In that case, they will throw an {@link + * java.lang.UnsupportedOperationException + * UnsupportedOperationException} usually wrapped into an {@link + * javax.management.MBeanRegistrationException}. + *

        + *
      • + *
      • + *

        Notifications

        + *

        Some namespaces might not support JMX Notifications. In that + * case, a call to add or remove notification listener for an + * MBean contained in that name space will raise a + * {@link javax.management.RuntimeOperationsException + * RuntimeOperationsException} wrapping an {@link + * java.lang.UnsupportedOperationException + * UnsupportedOperationException} exception. + *

        + *
      • + *
      + * + *

      Crossing Several Name Spaces

      + *

      + * Just as folders can contain other folders, name spaces can contain + * other name spaces. For instance, if an {@code MBeanServer} S1 + * containing a name space {@code "bar"} is mounted in another + * {@code MBeanServer} S2 with name space {@code "foo"}, then + * an MBean M1 named {@code "domain:type=Thing"} in namespace + * {@code "bar"} will appear as {@code "foo//bar//domain:type=Thing"} in + * {@code MBeanServer} S2. + *

      + *

      + * When accessing the MBean M1 from server S2, the + * method call will traverse in a cascade {@code MBeanServer} S2, + * then the name space handler for name space {@code "foo"}, then + * {@code MBeanServer} S1, before coming to the name space + * handler for name space {@code "bar"}. Any operation invoked + * on the MBean from a "top-level" name space will therefore need to + * traverse all the name spaces along the name space path until + * it eventually reaches the named MBean. This means that an operation + * like registerMBean for instance, + * can only succeed if all the name spaces along the path support it. + *

      + *

      + * Narrowing to a nested name space works just the same as narrowing + * to a top level name space: + *

      + *          final MBeanServer S2 = .... ;
      + *          final MBeanServer bar =
      + *                JMXNamespaces.narrowToNamespace(S2, "foo//bar");
      + *          final MBeanInfo info =
      + *                foo.getMBeanInfo(new ObjectName("domain:type=Thing"));
      + *      
      + *

      + * + *

      Name Spaces And Operation Results

      + *

      + * Operation results, as well as attribute values returned by an MBean + * contained in a name space must be interpreted in the context of that + * name space.
      + * In other words, if an MBean in name space "foo" has an attribute of + * type {@code ObjectName}, then it must be assumed that the + * {@code ObjectName} returned by that MBean is relative to + * name space "foo".
      + * The same rule aplies for MBean names that can be returned by + * operations invoked on such an MBean. If one of the MBean operations + * return, say, a {@code Set} then those MBean names must + * also be assumed to be relative to name space "foo".
      + *

      + *

      + * In the usual case, a JMX client will first + * narrow to a name space before invoking + * any operation on the MBeans it contains. In that case the names + * returned by the MBean invoked can be directly fed back to the + * narrowed connection. + *
      + * If however, the JMX client directly invoked the MBean from a higher + * name space, without having narrowed to that name space first, then + * the names that might be returned by that MBean will not be directly + * usable - the JMX client will need to either + * narrow to the name space before using the + * returned names, or convert the names to the higher level name space + * context. + *
      + * The {@link javax.management.namespace.JMXNamespaces JMXNamespaces} + * class provides methods that can be used to perform that conversion. + *

      + * + *

      Name Spaces And Notifications

      + *

      + * As already explained, name spaces are very + * similar to {@code MBeanServer}s. It is thus possible to get + * {@link javax.management.MBeanServerNotification MBeanServerNotifications} + * when MBeans are added or removed within a name space, by registering + * with the {@link javax.management.MBeanServerDelegate + * MBeanServerDelegate} MBean of the corresponding name space.
      + * However, it must be noted that the notifications emitted by a + * name space must be interpreted in the context of that name space. + * For instance, if an MBean {@code "domain:type=Thing"} contained in + * namespace "foo//bar" emits a notification, the source of the + * notification will be {@code "domain:type=Thing"}, not + * {@code "foo//bar//domain:type=Thing"}.
      + * It is therefore recommended to keep track of the name space + * information when registering a listener with an MBean contained in + * a name space, especially if the same listener is used to receive + * notifications from different name spaces. An easy solution is to + * use the handback, as illustrated in the code below. + *

      + *            final MBeanServer server = ...;
      + *            final NotificationListener listener = new NotificationListener() {
      + *                public void handleNotification(Notification n, Object handback) {
      + *                    if (!(n instanceof MBeanServerNotification)) {
      + *                        System.err.println("Error: expected MBeanServerNotification");
      + *                        return;
      + *                    }
      + *                    final MBeanServerNotification mbsn =
      + *                            (MBeanServerNotification) n;
      + *
      + *                    // We will pass the namespace path in the handback.
      + *                    //
      + *                    // The received notification must be interpreted in
      + *                    // the context of its source - therefore
      + *                    // mbsn.getMBeanName() does not include the name space
      + *                    // path...
      + *                    //
      + *                    final String namespace = (String) handback;
      + *                    System.out.println("Received " + mbsn.getType() +
      + *                            " for MBean " + mbsn.getMBeanName() +
      + *                            " from name space " + namespace);
      + *                }
      + *            };
      + *            server.addNotificationListener(JMXNamespaces.insertPath("foo//bar",
      + *                    MBeanServerDelegate.DELEGATE_NAME),listener,null,"foo//bar");
      + *            server.addNotificationListener(JMXNamespaces.insertPath("foo//joe",
      + *                    MBeanServerDelegate.DELEGATE_NAME),listener,null,"foo//joe");
      + *          
      + *

      + *

      + * JMX Connectors may require some configuration in order to be able + * to forward notifications from MBeans located in name spaces. + * The RMI JMX Connector Server + * in the Java SE 7 platform is configured by default to internally + * use the new {@linkplain javax.management.event event service} on + * the server side. + * When the connector server is configured in this way, JMX clients + * which use the old JMX Notifications mechanism (such as clients + * running on prior versions of the JDK) will be able to + * to receive notifications from MBeans located in sub name spaces. + * This is because the connector server will transparently delegate + * their subscriptions to the underlying {@linkplain + * javax.management.event event service}. In summary: + *

        + *
      • + * On the server side: When exporting an {@code MBeanServer} + * through a JMX Connector, you will need to make sure that the + * connector server uses the new {@linkplain javax.management.event + * event service} in order to register for notifications. If the + * connector server doesn't use the event service, only clients + * which explicitly use the new {@linkplain javax.management.event + * event service} will be able to register for notifications + * with MBeans located in sub name spaces. + *
      • + *
      • + * On the client side: if the JMX Connector server (on the remote + * server side) was configured to internally use the new + * {@linkplain javax.management.event + * event service}, then clients can continue to use the old + * {@code MBeanServerConnection} add / remove notification + * listener methods transparently. Otherwise, only clients which + * explicitly use the new {@linkplain javax.management.event + * event service} will be able to receive notifications from + * MBeans contained in sub name spaces. + *
      • + *
      + *

      + *

      + * These configuration issues apply at each node in the name space path, + * whenever the name space points to a remote server. The + * {@link javax.management.namespace.JMXRemoteNamespace + * JMXRemoteNamespace} can be configured in such a way that it will + * explicitly use an {@link javax.management.event.EventClient EventClient} + * when forwarding subscription to the remote side. Note that this can be + * unnecessary (and a waste of resources) if the underlying JMXConnector + * returned by the JMXConnectorFactory (client side) already uses the + * {@linkplain javax.management.event event service} to register for + * notifications with the server side. + *

      + * + *

      Name Spaces And Access Control

      + *

      + * Access to MBeans exposed through JMX namespaces is controlled by + * {@linkplain javax.management.namespace.JMXNamespacePermission + * jmx namespace permissions}. These permissions are checked by the + * MBeanServer in which the {@link + * javax.management.namespace.JMXNamespace JMXNamespace} MBean is registered. + * This is described in + * details in the {@link + * javax.management.namespace.JMXNamespace JMXNamespace} class. + *

      + *

      + * To implement a "firewall-like" access control in a JMX agent you + * can also place an {@link + * javax.management.remote.MBeanServerForwarder} in the JMX Connector + * Server which exposes the top-level MBeanServer of your application. + * This {@code MBeanServerForwarder} will be able to perform + * authorization checks for all MBeans, including those located in + * sub name spaces. + *

      + *

      + * For a tighter access control we recommend using a {@link + * java.lang.SecurityManager security manager}. + *

      + * @since 1.7 + *

      + **/ + +package javax.management.namespace; + diff --git a/jdk/src/share/classes/javax/management/openmbean/CompositeDataSupport.java b/jdk/src/share/classes/javax/management/openmbean/CompositeDataSupport.java index 172fa756161..4ef93b47611 100644 --- a/jdk/src/share/classes/javax/management/openmbean/CompositeDataSupport.java +++ b/jdk/src/share/classes/javax/management/openmbean/CompositeDataSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -355,6 +355,7 @@ public class CompositeDataSupport * @return true if the specified object is equal to this * CompositeDataSupport instance. */ + @Override public boolean equals(Object obj) { if (this == obj) { return true; @@ -419,6 +420,7 @@ public class CompositeDataSupport * * @return the hash code value for this CompositeDataSupport instance */ + @Override public int hashCode() { int hashcode = compositeType.hashCode(); @@ -457,16 +459,28 @@ public class CompositeDataSupport * * @return a string representation of this CompositeDataSupport instance */ + @Override public String toString() { - return new StringBuilder() .append(this.getClass().getName()) .append("(compositeType=") .append(compositeType.toString()) .append(",contents=") - .append(contents.toString()) + .append(contentString()) .append(")") .toString(); } + private String contentString() { + StringBuilder sb = new StringBuilder("{"); + String sep = ""; + for (Map.Entry entry : contents.entrySet()) { + sb.append(sep).append(entry.getKey()).append("="); + String s = Arrays.deepToString(new Object[] {entry.getValue()}); + sb.append(s.substring(1, s.length() - 1)); + sep = ", "; + } + sb.append("}"); + return sb.toString(); + } } diff --git a/jdk/src/share/classes/javax/management/openmbean/CompositeType.java b/jdk/src/share/classes/javax/management/openmbean/CompositeType.java index b513b0faa9a..b4c662ec9bc 100644 --- a/jdk/src/share/classes/javax/management/openmbean/CompositeType.java +++ b/jdk/src/share/classes/javax/management/openmbean/CompositeType.java @@ -89,7 +89,7 @@ public class CompositeType extends OpenType { *
        * @param itemNames The names of the items contained in the * composite data values described by this CompositeType instance; - * cannot be null and should contain at least one element; no element can be a null or empty string. + * cannot be null; no element can be null or an empty string. * Note that the order in which the item names are given is not important to differentiate a * CompositeType instance from another; * the item names are internally stored sorted in ascending alphanumeric order. @@ -97,7 +97,7 @@ public class CompositeType extends OpenType { * @param itemDescriptions The descriptions, in the same order as itemNames, of the items contained in the * composite data values described by this CompositeType instance; * should be of the same size as itemNames; - * no element can be a null or empty string. + * no element can be null or an empty string. *
        * @param itemTypes The open type instances, in the same order as itemNames, describing the items contained * in the composite data values described by this CompositeType instance; @@ -125,7 +125,7 @@ public class CompositeType extends OpenType { // super(CompositeData.class.getName(), typeName, description, false); - // Check the 3 arrays are not null or empty (ie length==0) and that there is no null element or empty string in them + // Check the 3 arrays are not null and that there is no null element or empty string in them // checkForNullElement(itemNames, "itemNames"); checkForNullElement(itemDescriptions, "itemDescriptions"); diff --git a/jdk/src/share/classes/javax/management/openmbean/MXBeanMapping.java b/jdk/src/share/classes/javax/management/openmbean/MXBeanMapping.java index 216912a4e31..339fbb21c09 100644 --- a/jdk/src/share/classes/javax/management/openmbean/MXBeanMapping.java +++ b/jdk/src/share/classes/javax/management/openmbean/MXBeanMapping.java @@ -108,6 +108,9 @@ import java.lang.reflect.Type; *

      If we are unable to modify the {@code MyLinkedList} class, * we can define an {@link MXBeanMappingFactory}. See the documentation * of that class for further details.

      + * + * @see MXBean specification, section + * "Custom MXBean type mappings" */ public abstract class MXBeanMapping { private final Type javaType; diff --git a/jdk/src/share/classes/javax/management/openmbean/MXBeanMappingFactory.java b/jdk/src/share/classes/javax/management/openmbean/MXBeanMappingFactory.java index 0820bf86a5d..f1dc6bcc080 100644 --- a/jdk/src/share/classes/javax/management/openmbean/MXBeanMappingFactory.java +++ b/jdk/src/share/classes/javax/management/openmbean/MXBeanMappingFactory.java @@ -48,7 +48,7 @@ import java.lang.reflect.Type; * effect by defining {@code MyLinkedListMappingFactory} as follows:

      * *
      - * public class MyLinkedListMappingFactory implements MXBeanMappingFactory {
      + * public class MyLinkedListMappingFactory extends MXBeanMappingFactory {
        *     public MyLinkedListMappingFactory() {}
        *
        *     public MXBeanMapping mappingForType(Type t, MXBeanMappingFactory f)
      @@ -82,6 +82,9 @@ import java.lang.reflect.Type;
        * appears in, or we can supply the factory to a {@link
        * javax.management.StandardMBean StandardMBean} constructor or MXBean
        * proxy.

      + * + * @see MXBean specification, section + * "Custom MXBean type mappings" */ public abstract class MXBeanMappingFactory { /** diff --git a/jdk/src/share/classes/javax/management/openmbean/TabularDataSupport.java b/jdk/src/share/classes/javax/management/openmbean/TabularDataSupport.java index f01b8e0a758..4e0c51cc9ba 100644 --- a/jdk/src/share/classes/javax/management/openmbean/TabularDataSupport.java +++ b/jdk/src/share/classes/javax/management/openmbean/TabularDataSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,15 +29,18 @@ package javax.management.openmbean; // java import // +import com.sun.jmx.mbeanserver.GetPropertyAction; import java.io.IOException; import java.io.ObjectInputStream; import java.io.Serializable; +import java.security.AccessController; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -79,12 +82,13 @@ public class TabularDataSupport /** * @serial This tabular data instance's contents: a {@link HashMap} */ + // field cannot be final because of clone method private Map dataMap; /** * @serial This tabular data instance's tabular type */ - private TabularType tabularType; + private final TabularType tabularType; /** * The array of item names that define the index used for rows (convenience field) @@ -109,7 +113,7 @@ public class TabularDataSupport */ public TabularDataSupport(TabularType tabularType) { - this(tabularType, 101, 0.75f); + this(tabularType, 16, 0.75f); } /** @@ -141,10 +145,18 @@ public class TabularDataSupport List tmpNames = tabularType.getIndexNames(); this.indexNamesArray = tmpNames.toArray(new String[tmpNames.size()]); + // Since LinkedHashMap was introduced in SE 1.4, it's conceivable even + // if very unlikely that we might be the server of a 1.3 client. In + // that case you'll need to set this property. See CR 6334663. + String useHashMapProp = AccessController.doPrivileged( + new GetPropertyAction("jmx.tabular.data.hash.map")); + boolean useHashMap = "true".equalsIgnoreCase(useHashMapProp); + // Construct the empty contents HashMap // - this.dataMap = - new HashMap(initialCapacity, loadFactor); + this.dataMap = useHashMap ? + new HashMap(initialCapacity, loadFactor) : + new LinkedHashMap(initialCapacity, loadFactor); } diff --git a/jdk/src/share/classes/javax/management/relation/RelationService.java b/jdk/src/share/classes/javax/management/relation/RelationService.java index 5950aafa573..98a4809ea41 100644 --- a/jdk/src/share/classes/javax/management/relation/RelationService.java +++ b/jdk/src/share/classes/javax/management/relation/RelationService.java @@ -108,7 +108,7 @@ public class RelationService extends NotificationBroadcasterSupport // the value HashMap mapping: // -> ArrayList of // to track where a given MBean is referenced. - private Map>> + private final Map>> myRefedMBeanObjName2RelIdsMap = new HashMap>>(); @@ -1492,7 +1492,7 @@ public class RelationService extends NotificationBroadcasterSupport // Clones the list of notifications to be able to still receive new // notifications while proceeding those ones List localUnregNtfList; - synchronized(myUnregNtfList) { + synchronized(myRefedMBeanObjName2RelIdsMap) { localUnregNtfList = new ArrayList(myUnregNtfList); // Resets list diff --git a/jdk/src/share/classes/javax/management/remote/IdentityMBeanServerForwarder.java b/jdk/src/share/classes/javax/management/remote/IdentityMBeanServerForwarder.java new file mode 100644 index 00000000000..0b1e996d747 --- /dev/null +++ b/jdk/src/share/classes/javax/management/remote/IdentityMBeanServerForwarder.java @@ -0,0 +1,303 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +package javax.management.remote; + +import java.io.ObjectInputStream; +import java.util.Set; +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.AttributeNotFoundException; +import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; +import javax.management.IntrospectionException; +import javax.management.InvalidAttributeValueException; +import javax.management.ListenerNotFoundException; +import javax.management.MBeanException; +import javax.management.MBeanInfo; +import javax.management.MBeanRegistrationException; +import javax.management.MBeanServer; +import javax.management.NotCompliantMBeanException; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.ObjectInstance; +import javax.management.ObjectName; +import javax.management.OperationsException; +import javax.management.QueryExp; +import javax.management.ReflectionException; +import javax.management.loading.ClassLoaderRepository; + +/** + * An {@link MBeanServerForwarder} that forwards all {@link MBeanServer} + * operations unchanged to the next {@code MBeanServer} in the chain. + * This class is typically subclassed to override some but not all methods. + */ +public class IdentityMBeanServerForwarder implements MBeanServerForwarder { + + private MBeanServer next; + + /** + *

      Construct a forwarder that has no next {@code MBeanServer}. + * The resulting object will be unusable until {@link #setMBeanServer + * setMBeanServer} is called to establish the next item in the chain.

      + */ + public IdentityMBeanServerForwarder() { + } + + /** + *

      Construct a forwarder that forwards to the given {@code MBeanServer}. + * It is not an error for {@code next} to be null, but the resulting object + * will be unusable until {@link #setMBeanServer setMBeanServer} is called + * to establish the next item in the chain.

      + */ + public IdentityMBeanServerForwarder(MBeanServer next) { + this.next = next; + } + + public synchronized MBeanServer getMBeanServer() { + return next; + } + + public synchronized void setMBeanServer(MBeanServer mbs) { + next = mbs; + } + + private synchronized MBeanServer next() { + return next; + } + + public void unregisterMBean(ObjectName name) + throws InstanceNotFoundException, MBeanRegistrationException { + next().unregisterMBean(name); + } + + public AttributeList setAttributes(ObjectName name, + AttributeList attributes) + throws InstanceNotFoundException, ReflectionException { + return next().setAttributes(name, attributes); + } + + public void setAttribute(ObjectName name, Attribute attribute) + throws InstanceNotFoundException, AttributeNotFoundException, + InvalidAttributeValueException, MBeanException, + ReflectionException { + next().setAttribute(name, attribute); + } + + public void removeNotificationListener(ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException, ListenerNotFoundException { + next().removeNotificationListener(name, listener, filter, handback); + } + + public void removeNotificationListener(ObjectName name, + NotificationListener listener) + throws InstanceNotFoundException, ListenerNotFoundException { + next().removeNotificationListener(name, listener); + } + + public void removeNotificationListener(ObjectName name, ObjectName listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException, ListenerNotFoundException { + next().removeNotificationListener(name, listener, filter, handback); + } + + public void removeNotificationListener(ObjectName name, ObjectName listener) + throws InstanceNotFoundException, ListenerNotFoundException { + next().removeNotificationListener(name, listener); + } + + public ObjectInstance registerMBean(Object object, ObjectName name) + throws InstanceAlreadyExistsException, MBeanRegistrationException, + NotCompliantMBeanException { + return next().registerMBean(object, name); + } + + public Set queryNames(ObjectName name, QueryExp query) { + return next().queryNames(name, query); + } + + public Set queryMBeans(ObjectName name, QueryExp query) { + return next().queryMBeans(name, query); + } + + public boolean isRegistered(ObjectName name) { + return next().isRegistered(name); + } + + public boolean isInstanceOf(ObjectName name, String className) + throws InstanceNotFoundException { + return next().isInstanceOf(name, className); + } + + public Object invoke(ObjectName name, String operationName, Object[] params, + String[] signature) + throws InstanceNotFoundException, MBeanException, + ReflectionException { + return next().invoke(name, operationName, params, signature); + } + + public Object instantiate(String className, ObjectName loaderName, + Object[] params, String[] signature) + throws ReflectionException, MBeanException, + InstanceNotFoundException { + return next().instantiate(className, loaderName, params, signature); + } + + public Object instantiate(String className, Object[] params, + String[] signature) + throws ReflectionException, MBeanException { + return next().instantiate(className, params, signature); + } + + public Object instantiate(String className, ObjectName loaderName) + throws ReflectionException, MBeanException, + InstanceNotFoundException { + return next().instantiate(className, loaderName); + } + + public Object instantiate(String className) + throws ReflectionException, MBeanException { + return next().instantiate(className); + } + + public ObjectInstance getObjectInstance(ObjectName name) + throws InstanceNotFoundException { + return next().getObjectInstance(name); + } + + public MBeanInfo getMBeanInfo(ObjectName name) + throws InstanceNotFoundException, IntrospectionException, + ReflectionException { + return next().getMBeanInfo(name); + } + + public Integer getMBeanCount() { + return next().getMBeanCount(); + } + + public String[] getDomains() { + return next().getDomains(); + } + + public String getDefaultDomain() { + return next().getDefaultDomain(); + } + + public ClassLoaderRepository getClassLoaderRepository() { + return next().getClassLoaderRepository(); + } + + public ClassLoader getClassLoaderFor(ObjectName mbeanName) + throws InstanceNotFoundException { + return next().getClassLoaderFor(mbeanName); + } + + public ClassLoader getClassLoader(ObjectName loaderName) + throws InstanceNotFoundException { + return next().getClassLoader(loaderName); + } + + public AttributeList getAttributes(ObjectName name, String[] attributes) + throws InstanceNotFoundException, ReflectionException { + return next().getAttributes(name, attributes); + } + + public Object getAttribute(ObjectName name, String attribute) + throws MBeanException, AttributeNotFoundException, + InstanceNotFoundException, ReflectionException { + return next().getAttribute(name, attribute); + } + + @Deprecated + public ObjectInputStream deserialize(String className, + ObjectName loaderName, + byte[] data) + throws InstanceNotFoundException, OperationsException, + ReflectionException { + return next().deserialize(className, loaderName, data); + } + + @Deprecated + public ObjectInputStream deserialize(String className, byte[] data) + throws OperationsException, ReflectionException { + return next().deserialize(className, data); + } + + @Deprecated + public ObjectInputStream deserialize(ObjectName name, byte[] data) + throws InstanceNotFoundException, OperationsException { + return next().deserialize(name, data); + } + + public ObjectInstance createMBean(String className, ObjectName name, + ObjectName loaderName, Object[] params, + String[] signature) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, InstanceNotFoundException { + return next().createMBean(className, name, loaderName, params, signature); + } + + public ObjectInstance createMBean(String className, ObjectName name, + Object[] params, String[] signature) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException { + return next().createMBean(className, name, params, signature); + } + + public ObjectInstance createMBean(String className, ObjectName name, + ObjectName loaderName) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, InstanceNotFoundException { + return next().createMBean(className, name, loaderName); + } + + public ObjectInstance createMBean(String className, ObjectName name) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException { + return next().createMBean(className, name); + } + + public void addNotificationListener(ObjectName name, ObjectName listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException { + next().addNotificationListener(name, listener, filter, handback); + } + + public void addNotificationListener(ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object handback) + throws InstanceNotFoundException { + next().addNotificationListener(name, listener, filter, handback); + } +} diff --git a/jdk/src/share/classes/javax/management/remote/JMXConnector.java b/jdk/src/share/classes/javax/management/remote/JMXConnector.java index 9ac3aa04304..1909a5afd3c 100644 --- a/jdk/src/share/classes/javax/management/remote/JMXConnector.java +++ b/jdk/src/share/classes/javax/management/remote/JMXConnector.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,6 +57,26 @@ public interface JMXConnector extends Closeable { public static final String CREDENTIALS = "jmx.remote.credentials"; + /** + *

      Name of the attribute that specifies whether to use the + * {@linkplain javax.management.event Event Service} to handle + * notifications for this connector. The value associated with + * this attribute, if any, is a String, which must be equal, + * ignoring case, to {@code "true"} or {@code "false"}.

      + * + *

      Not all connectors will understand this attribute, but the + * standard {@linkplain javax.management.remote.rmi.RMIConnector + * RMI Connector} does.

      + * + *

      If this attribute is not present, then the system property of the + * same name ({@value}) is consulted. If that is not set + * either, then the Event Service is not used.

      + * + * @since 1.7 + */ + public static final String USE_EVENT_SERVICE = + "jmx.remote.use.event.service"; + /** *

      Establishes the connection to the connector server. This * method is equivalent to {@link #connect(Map) diff --git a/jdk/src/share/classes/javax/management/remote/JMXConnectorFactory.java b/jdk/src/share/classes/javax/management/remote/JMXConnectorFactory.java index 23003f007c5..219865b603c 100644 --- a/jdk/src/share/classes/javax/management/remote/JMXConnectorFactory.java +++ b/jdk/src/share/classes/javax/management/remote/JMXConnectorFactory.java @@ -268,6 +268,14 @@ public class JMXConnectorFactory { return conn; } + private static Map newHashMap() { + return new HashMap(); + } + + private static Map newHashMap(Map map) { + return new HashMap(map); + } + /** *

      Creates a connector client for the connector server at the * given address. The resultant client is not connected until its @@ -300,16 +308,18 @@ public class JMXConnectorFactory { public static JMXConnector newJMXConnector(JMXServiceURL serviceURL, Map environment) throws IOException { - Map envcopy; + + final Map envcopy; if (environment == null) - envcopy = new HashMap(); + envcopy = newHashMap(); else { EnvHelp.checkAttributes(environment); - envcopy = new HashMap(environment); + envcopy = newHashMap(environment); } final ClassLoader loader = resolveClassLoader(envcopy); - final Class targetInterface = JMXConnectorProvider.class; + final Class targetInterface = + JMXConnectorProvider.class; final String protocol = serviceURL.getProtocol(); final String providerClassName = "ClientProvider"; @@ -351,9 +361,10 @@ public class JMXConnectorFactory { } } - envcopy = Collections.unmodifiableMap(envcopy); + final Map fixedenv = + Collections.unmodifiableMap(envcopy); - return provider.newJMXConnector(serviceURL, envcopy); + return provider.newJMXConnector(serviceURL, fixedenv); } private static String resolvePkgs(Map env) throws JMXProviderException { @@ -365,8 +376,8 @@ public class JMXConnectorFactory { if (pkgsObject == null) pkgsObject = - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public String run() { return System.getProperty(PROTOCOL_PROVIDER_PACKAGES); } }); @@ -423,8 +434,7 @@ public class JMXConnectorFactory { static Iterator getProviderIterator(final Class providerClass, final ClassLoader loader) { ServiceLoader serviceLoader = - ServiceLoader.load(providerClass, - loader); + ServiceLoader.load(providerClass, loader); return serviceLoader.iterator(); } @@ -528,8 +538,8 @@ public class JMXConnectorFactory { } if (loader == null) - loader = - AccessController.doPrivileged(new PrivilegedAction() { + loader = AccessController.doPrivileged( + new PrivilegedAction() { public ClassLoader run() { return Thread.currentThread().getContextClassLoader(); diff --git a/jdk/src/share/classes/javax/management/remote/JMXConnectorServer.java b/jdk/src/share/classes/javax/management/remote/JMXConnectorServer.java index 240bc3bdc0e..88348ff5de3 100644 --- a/jdk/src/share/classes/javax/management/remote/JMXConnectorServer.java +++ b/jdk/src/share/classes/javax/management/remote/JMXConnectorServer.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,17 +26,21 @@ package javax.management.remote; +import com.sun.jmx.remote.util.EnvHelp; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; +import javax.management.MBeanInfo; // for javadoc import javax.management.MBeanNotificationInfo; import javax.management.MBeanRegistration; import javax.management.MBeanServer; import javax.management.Notification; import javax.management.NotificationBroadcasterSupport; import javax.management.ObjectName; +import javax.management.event.EventClientDelegate; /** *

      Superclass of every connector server. A connector server is @@ -75,6 +79,48 @@ public abstract class JMXConnectorServer public static final String AUTHENTICATOR = "jmx.remote.authenticator"; + /** + *

      Name of the attribute that specifies whether this connector + * server can delegate notification handling to the + * {@linkplain javax.management.event Event Service}. + * The value associated with + * this attribute, if any, is a String, which must be equal, + * ignoring case, to {@code "true"} or {@code "false"}.

      + * + *

      Not all connector servers will understand this attribute, but the + * standard {@linkplain javax.management.remote.rmi.RMIConnectorServer + * RMI Connector Server} does.

      + * + *

      If this attribute is not present, then the system property of the + * same name ({@value}) is consulted. If that is not set + * either, then the Event Service is used if the connector server + * supports it.

      + * + * @since 1.7 + */ + public static final String DELEGATE_TO_EVENT_SERVICE = + "jmx.remote.delegate.event.service"; + + /** + *

      Name of the attribute that specifies whether this connector + * server simulates the existence of the {@link EventClientDelegate} + * MBean. The value associated with this attribute, if any, must + * be a string that is equal to {@code "true"} or {@code "false"}, + * ignoring case. If it is {@code "true"}, then the connector server + * will simulate an EventClientDelegate MBean, as described in {@link + * EventClientDelegate#newForwarder}. This MBean is needed for {@link + * javax.management.event.EventClient EventClient} to function correctly.

      + * + *

      Not all connector servers will understand this attribute, but the + * standard {@linkplain javax.management.remote.rmi.RMIConnectorServer + * RMI Connector Server} does. For a connector server that understands + * this attribute, the default value is {@code "true"}.

      + * + * @since 1.7 + */ + public static final String EVENT_CLIENT_DELEGATE_FORWARDER = + "jmx.remote.event.client.delegate.forwarder"; + /** *

      Constructs a connector server that will be registered as an * MBean in the MBean server it is attached to. This constructor @@ -89,34 +135,274 @@ public abstract class JMXConnectorServer /** *

      Constructs a connector server that is attached to the given * MBean server. A connector server that is created in this way - * can be registered in a different MBean server.

      + * can be registered in a different MBean server, or not registered + * in any MBean server.

      * * @param mbeanServer the MBean server that this connector server * is attached to. Null if this connector server will be attached * to an MBean server by being registered in it. */ public JMXConnectorServer(MBeanServer mbeanServer) { - this.mbeanServer = mbeanServer; + insertUserMBeanServer(mbeanServer); } /** *

      Returns the MBean server that this connector server is - * attached to.

      + * attached to, or the first in a chain of user-added + * {@link MBeanServerForwarder}s, if any.

      * * @return the MBean server that this connector server is attached * to, or null if it is not yet attached to an MBean server. + * + * @see #setMBeanServerForwarder + * @see #getSystemMBeanServer */ public synchronized MBeanServer getMBeanServer() { - return mbeanServer; + return userMBeanServer; } - public synchronized void setMBeanServerForwarder(MBeanServerForwarder mbsf) - { + public synchronized void setMBeanServerForwarder(MBeanServerForwarder mbsf) { if (mbsf == null) throw new IllegalArgumentException("Invalid null argument: mbsf"); - if (mbeanServer != null) mbsf.setMBeanServer(mbeanServer); - mbeanServer = mbsf; + if (userMBeanServer != null) + mbsf.setMBeanServer(userMBeanServer); + insertUserMBeanServer(mbsf); + } + + /** + *

      Remove a forwarder from the chain of forwarders. The forwarder can + * be in the system chain or the user chain. On successful return from + * this method, the first occurrence in the chain of an object that is + * {@linkplain Object#equals equal} to {@code mbsf} will have been + * removed.

      + * @param mbsf the forwarder to remove + * @throws NoSuchElementException if there is no occurrence of {@code mbsf} + * in the chain. + * @throws IllegalArgumentException if {@code mbsf} is null. + */ + public synchronized void removeMBeanServerForwarder(MBeanServerForwarder mbsf) { + if (mbsf == null) + throw new IllegalArgumentException("Invalid null argument: mbsf"); + + MBeanServerForwarder prev = null; + MBeanServer curr = systemMBeanServer; + while (curr instanceof MBeanServerForwarder && !mbsf.equals(curr)) { + prev = (MBeanServerForwarder) curr; + curr = prev.getMBeanServer(); + } + if (!(curr instanceof MBeanServerForwarder)) + throw new NoSuchElementException("MBeanServerForwarder not in chain"); + MBeanServerForwarder deleted = (MBeanServerForwarder) curr; + MBeanServer next = deleted.getMBeanServer(); + if (prev != null) + prev.setMBeanServer(next); + if (systemMBeanServer == deleted) + systemMBeanServer = next; + if (userMBeanServer == deleted) + userMBeanServer = next; + } + + /* + * Set userMBeanServer to mbs and arrange for the end of the chain of + * system MBeanServerForwarders to point to it. See the comment before + * the systemMBeanServer and userMBeanServer field declarations. + */ + private void insertUserMBeanServer(MBeanServer mbs) { + MBeanServerForwarder lastSystemMBSF = null; + for (MBeanServer mbsi = systemMBeanServer; + mbsi != userMBeanServer; + mbsi = lastSystemMBSF.getMBeanServer()) { + lastSystemMBSF = (MBeanServerForwarder) mbsi; + } + userMBeanServer = mbs; + if (lastSystemMBSF == null) + systemMBeanServer = mbs; + else + lastSystemMBSF.setMBeanServer(mbs); + } + + /** + *

      Returns the first item in the chain of system and then user + * forwarders. In the simplest case, a {@code JMXConnectorServer} + * is connected directly to an {@code MBeanServer}. But there can + * also be a chain of {@link MBeanServerForwarder}s between the two. + * This chain consists of two sub-chains: first the system chain + * and then the user chain. Incoming requests are given to the + * first forwarder in the system chain. Each forwarder can handle + * a request itself, or more usually forward it to the next forwarder, + * perhaps with some extra behavior such as logging or security + * checking before or after the forwarding. The last forwarder in + * the system chain is followed by the first forwarder in the user + * chain.

      + * + *

      The system chain is usually + * defined by a connector server based on the environment Map; + * see {@link JMXConnectorServerFactory#newJMXConnectorServer}. Allowing the + * connector server to define its forwarders in this way ensures that + * they are in the correct order - some forwarders need to be inserted + * before others for correct behavior. It is possible to modify the + * system chain, for example using {@link #setSystemMBeanServerForwarder} or + * {@link #removeMBeanServerForwarder}, but in that case the system + * chain is no longer guaranteed to be correct.

      + * + *

      The user chain is defined by calling {@link + * #setMBeanServerForwarder} to insert forwarders at the head of the user + * chain.

      + * + *

      If there are no forwarders in either chain, then both + * {@link #getMBeanServer()} and {@code getSystemMBeanServer()} will + * return the {@code MBeanServer} for this connector server. If there + * are forwarders in the user chain but not the system chain, then + * both methods will return the first forwarder in the user chain. + * If there are forwarders in the system chain but not the user chain, + * then {@code getSystemMBeanServer()} will return the first forwarder + * in the system chain, and {@code getMBeanServer()} will return the + * {@code MBeanServer} for this connector server. Finally, if there + * are forwarders in each chain then {@code getSystemMBeanServer()} + * will return the first forwarder in the system chain, and {@code + * getMBeanServer()} will return the first forwarder in the user chain.

      + * + *

      This code illustrates how the chains can be traversed:

      + * + *
      +     * JMXConnectorServer cs;
      +     * System.out.println("system chain:");
      +     * MBeanServer mbs = cs.getSystemMBeanServer();
      +     * while (true) {
      +     *     if (mbs == cs.getMBeanServer())
      +     *         System.out.println("user chain:");
      +     *     if (!(mbs instanceof MBeanServerForwarder))
      +     *         break;
      +     *     MBeanServerForwarder mbsf = (MBeanServerForwarder) mbs;
      +     *     System.out.println("--forwarder: " + mbsf);
      +     *     mbs = mbsf.getMBeanServer();
      +     * }
      +     * System.out.println("--MBean Server");
      +     * 
      + * + * @return the first item in the system chain of forwarders. + * + * @see #setSystemMBeanServerForwarder + */ + public synchronized MBeanServer getSystemMBeanServer() { + return systemMBeanServer; + } + + /** + *

      Inserts an object that intercepts requests for the MBean server + * that arrive through this connector server. This object will be + * supplied as the MBeanServer for any new connection + * created by this connector server. Existing connections are + * unaffected.

      + * + *

      This method can be called more than once with different + * {@link MBeanServerForwarder} objects. The result is a chain + * of forwarders. The last forwarder added is the first in the chain.

      + * + *

      This method modifies the system chain of {@link MBeanServerForwarder}s. + * Usually user code should change the user chain instead, via + * {@link #setMBeanServerForwarder}.

      + * + *

      Not all connector servers support a system chain of forwarders. + * Calling this method on a connector server that does not will produce an + * {@link UnsupportedOperationException}.

      + * + *

      Suppose {@code mbs} is the result of {@link #getSystemMBeanServer()} + * before calling this method. If {@code mbs} is not null, then + * {@code mbsf.setMBeanServer(mbs)} will be called. If doing so + * produces an exception, this method throws the same exception without + * any other effect. If {@code mbs} is null, or if the call to + * {@code mbsf.setMBeanServer(mbs)} succeeds, then this method will + * return normally and {@code getSystemMBeanServer()} will then return + * {@code mbsf}.

      + * + *

      The result of {@link #getMBeanServer()} is unchanged by this method.

      + * + * @param mbsf the new MBeanServerForwarder. + * + * @throws IllegalArgumentException if the call to {@link + * MBeanServerForwarder#setMBeanServer mbsf.setMBeanServer} fails + * with IllegalArgumentException, or if + * mbsf is null. + * + * @throws UnsupportedOperationException if + * {@link #supportsSystemMBeanServerForwarder} returns false. + * + * @see #getSystemMBeanServer() + */ + public synchronized void setSystemMBeanServerForwarder( + MBeanServerForwarder mbsf) { + if (mbsf == null) + throw new IllegalArgumentException("Invalid null argument: mbsf"); + mustSupportSystemMBSF(); + + if (systemMBeanServer != null) + mbsf.setMBeanServer(systemMBeanServer); + systemMBeanServer = mbsf; + } + + /** + *

      Returns true if this connector server supports a system chain of + * {@link MBeanServerForwarder}s. The default implementation of this + * method returns false. Connector servers that do support the system + * chain must override this method to return true. + * + * @return true if this connector server supports the system chain of + * forwarders. + */ + public boolean supportsSystemMBeanServerForwarder() { + return false; + } + + private void mustSupportSystemMBSF() { + if (!supportsSystemMBeanServerForwarder()) { + throw new UnsupportedOperationException( + "System MBeanServerForwarder not supported by this " + + "connector server"); + } + } + + /** + *

      Install {@link MBeanServerForwarder}s in the system chain + * based on the attributes in the given {@code Map}. A connector + * server that {@linkplain #supportsSystemMBeanServerForwarder supports} + * a system chain of {@code MBeanServerForwarder}s can call this method + * to add forwarders to that chain based on the contents of {@code env}. + * In order:

      + * + *
        + * + *
      • If {@link #EVENT_CLIENT_DELEGATE_FORWARDER} is absent, or is + * present with the value {@code "true"}, then a forwarder with the + * functionality of {@link EventClientDelegate#newForwarder} is inserted + * at the start of the system chain.
      • + * + *
      + * + *

      For {@code EVENT_CLIENT_DELEGATE_FORWARDER}, if the + * attribute is absent from the {@code Map} and a system property + * of the same name is defined, then the value of the system + * property is used as if it were in the {@code Map}. + * + *

      Attributes in {@code env} that are not listed above are ignored + * by this method.

      + * + * @throws UnsupportedOperationException if {@link + * #supportsSystemMBeanServerForwarder} is false. + */ + protected void installStandardForwarders(Map env) { + mustSupportSystemMBSF(); + + // Remember that forwarders must be added in reverse order! + + boolean ecd = EnvHelp.computeBooleanFromString( + env, EVENT_CLIENT_DELEGATE_FORWARDER, false, true); + + if (ecd) { + MBeanServerForwarder mbsf = EventClientDelegate.newForwarder(); + setSystemMBeanServerForwarder(mbsf); + } } public String[] getConnectionIds() { @@ -359,8 +645,8 @@ public abstract class JMXConnectorServer ObjectName name) { if (mbs == null || name == null) throw new NullPointerException("Null MBeanServer or ObjectName"); - if (mbeanServer == null) { - mbeanServer = mbs; + if (userMBeanServer == null) { + insertUserMBeanServer(mbs); myName = name; } return name; @@ -394,10 +680,53 @@ public abstract class JMXConnectorServer myName = null; } - /** - * The MBeanServer used by this server to execute a client request. + /* + * Fields describing the chains of forwarders (MBeanServerForwarders). + * In the general case, the forwarders look something like this: + * + * systemMBeanServer userMBeanServer + * | | + * v v + * mbsf1 -> mbsf2 -> mbsf3 -> mbsf4 -> mbsf5 -> mbs + * + * Here, each mbsfi is an MBeanServerForwarder, and the arrows + * illustrate its getMBeanServer() method. The last MBeanServerForwarder + * can point to an MBeanServer that is not instanceof MBeanServerForwarder, + * here mbs. + * + * Initially, the chain can be empty if this JMXConnectorServer was + * constructed without an MBeanServer. In this case, both systemMBS + * and userMBS will be null. If there is initially an MBeanServer, + * then both systemMBS and userMBS will point to it. + * + * Whenever userMBS is changed, the system chain must be updated. If there + * are forwarders in the system chain (between systemMBS and userMBS in the + * picture above), then the last one must point to the old value of userMBS + * (possibly null). It must be updated to point to the new value. If there + * are no forwarders in the system chain, then systemMBS must be updated to + * the new value of userMBS. The invariant is that starting from systemMBS + * and repeatedly calling MBSF.getMBeanServer() you will end up at + * userMBS. The implication is that you will not see any MBeanServer + * object on the way that is not also an MBeanServerForwarder. + * + * The method insertUserMBeanServer contains the logic to change userMBS + * and adjust the system chain appropriately. + * + * If userMBS is null and this JMXConnectorServer is registered in an + * MBeanServer, then userMBS becomes that MBeanServer, and the system + * chain must be updated as just described. + * + * When systemMBS is updated, there is no effect on userMBS. The system + * chain may contain forwarders even though the user chain is empty + * (there is no MBeanServer). In that case an attempt to forward an + * incoming request through the chain will fall off the end and fail with a + * NullPointerException. Usually a connector server will refuse to start() + * if it is not attached to an MBS, so this situation should not arise. */ - private MBeanServer mbeanServer = null; + + private MBeanServer userMBeanServer; + + private MBeanServer systemMBeanServer; /** * The name used to registered this server in an MBeanServer. diff --git a/jdk/src/share/classes/javax/management/remote/JMXConnectorServerFactory.java b/jdk/src/share/classes/javax/management/remote/JMXConnectorServerFactory.java index a641f3c98d9..4de8cbf5e26 100644 --- a/jdk/src/share/classes/javax/management/remote/JMXConnectorServerFactory.java +++ b/jdk/src/share/classes/javax/management/remote/JMXConnectorServerFactory.java @@ -35,10 +35,8 @@ import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; -import java.util.ServiceLoader; import javax.management.MBeanServer; -import javax.management.ObjectName; /** *

      Factory to create JMX API connector servers. There @@ -172,7 +170,8 @@ public class JMXConnectorServerFactory { * loader MBean name. This class loader is used to deserialize objects in * requests received from the client, possibly after consulting an * MBean-specific class loader. The value associated with this - * attribute is an instance of {@link ObjectName}.

      + * attribute is an instance of {@link javax.management.ObjectName + * ObjectName}.

      */ public static final String DEFAULT_CLASS_LOADER_NAME = "jmx.remote.default.class.loader.name"; diff --git a/jdk/src/share/classes/javax/management/remote/JMXConnectorServerMBean.java b/jdk/src/share/classes/javax/management/remote/JMXConnectorServerMBean.java index 048e5a92192..fb6f883a2b7 100644 --- a/jdk/src/share/classes/javax/management/remote/JMXConnectorServerMBean.java +++ b/jdk/src/share/classes/javax/management/remote/JMXConnectorServerMBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -105,23 +105,34 @@ public interface JMXConnectorServerMBean { public boolean isActive(); /** - *

      Adds an object that intercepts requests for the MBean server + *

      Inserts an object that intercepts requests for the MBean server * that arrive through this connector server. This object will be * supplied as the MBeanServer for any new connection * created by this connector server. Existing connections are * unaffected.

      * - *

      If this connector server is already associated with an + *

      This method can be called more than once with different + * {@link MBeanServerForwarder} objects. The result is a chain + * of forwarders. The last forwarder added is the first in the chain. + * In more detail:

      + * + *
        + *
      • If this connector server is already associated with an * MBeanServer object, then that object is given to * {@link MBeanServerForwarder#setMBeanServer * mbsf.setMBeanServer}. If doing so produces an exception, this * method throws the same exception without any other effect.

        * - *

        If this connector is not already associated with an + *

      • If this connector is not already associated with an * MBeanServer object, or if the * mbsf.setMBeanServer call just mentioned succeeds, * then mbsf becomes this connector server's * MBeanServer.

        + *
      + * + *

      A connector server may support two chains of forwarders, + * a system chain and a user chain. See {@link + * JMXConnectorServer#setSystemMBeanServerForwarder} for details.

      * * @param mbsf the new MBeanServerForwarder. * @@ -129,6 +140,8 @@ public interface JMXConnectorServerMBean { * MBeanServerForwarder#setMBeanServer mbsf.setMBeanServer} fails * with IllegalArgumentException. This includes the * case where mbsf is null. + * + * @see JMXConnectorServer#setSystemMBeanServerForwarder */ public void setMBeanServerForwarder(MBeanServerForwarder mbsf); diff --git a/jdk/src/share/classes/javax/management/remote/JMXServiceURL.java b/jdk/src/share/classes/javax/management/remote/JMXServiceURL.java index f2b19c5ef0b..06b3b92f91a 100644 --- a/jdk/src/share/classes/javax/management/remote/JMXServiceURL.java +++ b/jdk/src/share/classes/javax/management/remote/JMXServiceURL.java @@ -30,13 +30,14 @@ package javax.management.remote; import com.sun.jmx.remote.util.ClassLogger; import com.sun.jmx.remote.util.EnvHelp; -import java.beans.ConstructorProperties; import java.io.Serializable; import java.net.InetAddress; import java.net.MalformedURLException; import java.net.UnknownHostException; import java.util.BitSet; import java.util.StringTokenizer; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.InvalidKeyException; /** *

      The address of a JMX API connector server. Instances of this class @@ -273,7 +274,6 @@ public class JMXServiceURL implements Serializable { * is not possible to find the local host name, or if * port is negative. */ - @ConstructorProperties({"protocol", "host", "port", "URLPath"}) public JMXServiceURL(String protocol, String host, int port, String urlPath) throws MalformedURLException { @@ -338,6 +338,50 @@ public class JMXServiceURL implements Serializable { validate(); } + /** + *

      Construct a {@code JMXServiceURL} instance from the given + * {@code CompositeData}. The presence of this method means that + * {@code JMXServiceURL} is + * reconstructible in MXBeans.

      + * + *

      (The effect of this method could have been obtained more simply + * with a @{@link java.beans.ConstructorProperties ConstructorProperties} + * annotation on the four-parameter {@linkplain #JMXServiceURL( + * String, String, int, String) constructor}, but that would have meant + * that this API could not be implemented on versions of the Java platform + * that predated the introduction of that annotation.)

      + * + * @param cd a {@code CompositeData} object that must contain items called + * {@code protocol}, {@code host}, and {@code URLPath} of type {@code String} + * and {@code port} of type {@code Integer}. Such an object will be produced + * by the MXBean framework when mapping a {@code JMXServiceURL} + * instance to an Open Data value. + * + * @return a {@code JMXServiceURL} constructed with the protocol, host, + * port, and URL path extracted from the given {@code CompositeData}. + * + * @throws MalformedURLException if the given {@code CompositeData} does + * not contain all the required items with the required types or if the + * resultant URL is syntactically incorrect. + */ + public static JMXServiceURL from(CompositeData cd) + throws MalformedURLException { + try { + String proto = (String) cd.get("protocol"); + String host = (String) cd.get("host"); + int port = (Integer) cd.get("port"); + String urlPath = (String) cd.get("URLPath"); + return new JMXServiceURL(proto, host, port, urlPath); + } catch (RuntimeException e) { + // Could be InvalidKeyException if the item is missing, + // or ClassCastException if it is present but with the wrong type. + MalformedURLException x = new MalformedURLException(e.getMessage()); + x.initCause(e); + throw x; + } + } + private void validate() throws MalformedURLException { // Check protocol diff --git a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java index bff48451f9a..a87d146e94e 100644 --- a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java +++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,10 +25,12 @@ package javax.management.remote.rmi; +import com.sun.jmx.mbeanserver.Util; import static com.sun.jmx.mbeanserver.Util.cast; import com.sun.jmx.remote.internal.ServerCommunicatorAdmin; import com.sun.jmx.remote.internal.ServerNotifForwarder; import com.sun.jmx.remote.security.JMXSubjectDomainCombiner; +import com.sun.jmx.remote.security.NotificationAccessController; import com.sun.jmx.remote.security.SubjectDelegator; import com.sun.jmx.remote.util.ClassLoaderWithRepository; import com.sun.jmx.remote.util.ClassLogger; @@ -36,6 +38,7 @@ import com.sun.jmx.remote.util.EnvHelp; import com.sun.jmx.remote.util.OrderClassLoaders; import java.io.IOException; +import java.lang.reflect.UndeclaredThrowableException; import java.rmi.MarshalledObject; import java.rmi.UnmarshalException; import java.rmi.server.Unreferenced; @@ -56,19 +59,25 @@ import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.IntrospectionException; import javax.management.InvalidAttributeValueException; +import javax.management.JMX; import javax.management.ListenerNotFoundException; import javax.management.MBeanException; import javax.management.MBeanInfo; import javax.management.MBeanRegistrationException; import javax.management.MBeanServer; import javax.management.NotCompliantMBeanException; +import javax.management.Notification; import javax.management.NotificationFilter; import javax.management.ObjectInstance; import javax.management.ObjectName; import javax.management.QueryExp; import javax.management.ReflectionException; import javax.management.RuntimeOperationsException; -import javax.management.loading.ClassLoaderRepository; +import javax.management.event.EventClientDelegate; +import javax.management.event.EventClientDelegateMBean; +import javax.management.event.EventClientNotFoundException; +import javax.management.event.FetchingEventForwarder; +import javax.management.namespace.JMXNamespaces; import javax.management.remote.JMXServerErrorException; import javax.management.remote.NotificationResult; import javax.management.remote.TargetedNotification; @@ -149,28 +158,16 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { new PrivilegedAction() { public ClassLoaderWithRepository run() { return new ClassLoaderWithRepository( - getClassLoaderRepository(), - dcl); + mbeanServer.getClassLoaderRepository(), + dcl); } }); - serverCommunicatorAdmin = new RMIServerCommunicatorAdmin(EnvHelp.getServerConnectionTimeout(env)); this.env = env; } - private synchronized ServerNotifForwarder getServerNotifFwd() { - // Lazily created when first use. Mainly when - // addNotificationListener is first called. - if (serverNotifForwarder == null) - serverNotifForwarder = - new ServerNotifForwarder(mbeanServer, - env, - rmiServer.getNotifBuffer(), - connectionId); - return serverNotifForwarder; - } public String getConnectionId() throws IOException { // We should call reqIncomming() here... shouldn't we? @@ -181,6 +178,7 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { final boolean debug = logger.debugOn(); final String idstr = (debug?"["+this.toString()+"]":null); + final SubscriptionManager mgr; synchronized (this) { if (terminated) { if (debug) logger.debug("close",idstr + " already terminated."); @@ -195,11 +193,12 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { serverCommunicatorAdmin.terminate(); } - if (serverNotifForwarder != null) { - serverNotifForwarder.terminate(); - } + mgr = subscriptionManager; + subscriptionManager = null; } + if (mgr != null) mgr.terminate(); + rmiServer.clientClosed(this); if (debug) logger.debug("close",idstr + " closed."); @@ -955,8 +954,7 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { int i=0; ClassLoader targetCl; NotificationFilter[] filterValues = - new NotificationFilter[names.length]; - Object params[]; + new NotificationFilter[names.length]; Integer[] ids = new Integer[names.length]; final boolean debug=logger.debugOn(); @@ -991,8 +989,7 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { // remove all registered listeners for (int j=0; j action = - new PrivilegedAction() { - public NotificationResult run() { - return getServerNotifFwd().fetchNotifs(csn, t, mn); + + final PrivilegedExceptionAction action = + new PrivilegedExceptionAction() { + public NotificationResult run() throws IOException { + return doFetchNotifs(csn, t, mn); } }; - if (acc == null) - return action.run(); - else - return AccessController.doPrivileged(action, acc); + try { + if (acc == null) + return action.run(); + else + return AccessController.doPrivileged(action, acc); + } catch (IOException x) { + throw x; + } catch (RuntimeException x) { + throw x; + } catch (Exception x) { + // should not happen + throw new UndeclaredThrowableException(x); + } + } finally { serverCommunicatorAdmin.rspOutgoing(); } } + /** + * This is an abstraction class that let us use the legacy + * ServerNotifForwarder and the new EventClientDelegateMBean + * indifferently. + **/ + private static interface SubscriptionManager { + public void removeNotificationListener(ObjectName name, Integer id) + throws InstanceNotFoundException, ListenerNotFoundException, IOException; + public void removeNotificationListener(ObjectName name, Integer[] ids) + throws Exception; + public NotificationResult fetchNotifications(long csn, long timeout, int maxcount) + throws IOException; + public Integer addNotificationListener(ObjectName name, NotificationFilter filter) + throws InstanceNotFoundException, IOException; + public void terminate() + throws IOException; + } + + /** + * A SubscriptionManager that uses a ServerNotifForwarder. + **/ + private static class LegacySubscriptionManager implements SubscriptionManager { + private final ServerNotifForwarder forwarder; + LegacySubscriptionManager(ServerNotifForwarder forwarder) { + this.forwarder = forwarder; + } + + public void removeNotificationListener(ObjectName name, Integer id) + throws InstanceNotFoundException, ListenerNotFoundException, + IOException { + if (!JMXNamespaces.getContainingNamespace(name).equals("")) { + logger.debug("removeNotificationListener", + "This connector server is not configured to support " + + "forwarding of notification subscriptions to name spaces"); + throw new RuntimeOperationsException( + new UnsupportedOperationException( + "removeNotificationListener on name space MBeans. ")); + } + forwarder.removeNotificationListener(name,id); + } + + public void removeNotificationListener(ObjectName name, Integer[] ids) + throws Exception { + if (!JMXNamespaces.getContainingNamespace(name).equals("")) { + logger.debug("removeNotificationListener", + "This connector server is not configured to support " + + "forwarding of notification subscriptions to name spaces"); + throw new RuntimeOperationsException( + new UnsupportedOperationException( + "removeNotificationListener on name space MBeans. ")); + } + forwarder.removeNotificationListener(name,ids); + } + + public NotificationResult fetchNotifications(long csn, long timeout, int maxcount) { + return forwarder.fetchNotifs(csn,timeout,maxcount); + } + + public Integer addNotificationListener(ObjectName name, + NotificationFilter filter) + throws InstanceNotFoundException, IOException { + if (!JMXNamespaces.getContainingNamespace(name).equals("")) { + logger.debug("addNotificationListener", + "This connector server is not configured to support " + + "forwarding of notification subscriptions to name spaces"); + throw new RuntimeOperationsException( + new UnsupportedOperationException( + "addNotificationListener on name space MBeans. ")); + } + return forwarder.addNotificationListener(name,filter); + } + + public void terminate() { + forwarder.terminate(); + } + } + + /** + * A SubscriptionManager that uses an EventClientDelegateMBean. + **/ + private static class EventSubscriptionManager + implements SubscriptionManager { + private final MBeanServer mbeanServer; + private final EventClientDelegateMBean delegate; + private final NotificationAccessController notifAC; + private final boolean checkNotificationEmission; + private final String clientId; + private final String connectionId; + private volatile String mbeanServerName; + + EventSubscriptionManager( + MBeanServer mbeanServer, + EventClientDelegateMBean delegate, + Map env, + String clientId, + String connectionId) { + this.mbeanServer = mbeanServer; + this.delegate = delegate; + this.notifAC = EnvHelp.getNotificationAccessController(env); + this.checkNotificationEmission = + EnvHelp.computeBooleanFromString( + env, "jmx.remote.x.check.notification.emission", false); + this.clientId = clientId; + this.connectionId = connectionId; + } + + private String mbeanServerName() { + if (mbeanServerName != null) return mbeanServerName; + else return (mbeanServerName = getMBeanServerName(mbeanServer)); + } + + @SuppressWarnings("serial") // no serialVersionUID + private class AccessControlFilter implements NotificationFilter { + private final NotificationFilter wrapped; + private final ObjectName name; + + AccessControlFilter(ObjectName name, NotificationFilter wrapped) { + this.name = name; + this.wrapped = wrapped; + } + + public boolean isNotificationEnabled(Notification notification) { + try { + if (checkNotificationEmission) { + ServerNotifForwarder.checkMBeanPermission( + mbeanServerName(), mbeanServer, name, + "addNotificationListener"); + } + notifAC.fetchNotification( + connectionId, name, notification, getSubject()); + return (wrapped == null) ? true : + wrapped.isNotificationEnabled(notification); + } catch (InstanceNotFoundException e) { + return false; + } catch (SecurityException e) { + return false; + } + } + + } + + public Integer addNotificationListener( + ObjectName name, NotificationFilter filter) + throws InstanceNotFoundException, IOException { + if (notifAC != null) { + notifAC.addNotificationListener(connectionId, name, getSubject()); + filter = new AccessControlFilter(name, filter); + } + try { + return delegate.addListener(clientId,name,filter); + } catch (EventClientNotFoundException x) { + throw new IOException("Unknown clientId: "+clientId,x); + } + } + + public void removeNotificationListener(ObjectName name, Integer id) + throws InstanceNotFoundException, ListenerNotFoundException, + IOException { + if (notifAC != null) + notifAC.removeNotificationListener(connectionId, name, getSubject()); + try { + delegate.removeListenerOrSubscriber(clientId, id); + } catch (EventClientNotFoundException x) { + throw new IOException("Unknown clientId: "+clientId,x); + } + } + + public void removeNotificationListener(ObjectName name, Integer[] ids) + throws InstanceNotFoundException, ListenerNotFoundException, + IOException { + if (notifAC != null) + notifAC.removeNotificationListener(connectionId, name, getSubject()); + try { + for (Integer id : ids) + delegate.removeListenerOrSubscriber(clientId, id); + } catch (EventClientNotFoundException x) { + throw new IOException("Unknown clientId: "+clientId,x); + } + } + + public NotificationResult fetchNotifications(long csn, long timeout, + int maxcount) + throws IOException { + try { + // For some reason the delegate doesn't accept a negative + // sequence number. However legacy clients will always call + // fetchNotifications with a negative sequence number, when + // they call it for the first time. + // In that case, we will use 0 instead. + // + return delegate.fetchNotifications( + clientId, Math.max(csn, 0), maxcount, timeout); + } catch (EventClientNotFoundException x) { + throw new IOException("Unknown clientId: "+clientId,x); + } + } + + public void terminate() + throws IOException { + try { + delegate.removeClient(clientId); + } catch (EventClientNotFoundException x) { + throw new IOException("Unknown clientId: "+clientId,x); + } + } + + private static Subject getSubject() { + return Subject.getSubject(AccessController.getContext()); + } + } + + /** + * Creates a SubscriptionManager that uses either the legacy notifications + * mechanism (ServerNotifForwarder) or the new event service + * (EventClientDelegateMBean) depending on which option was passed in + * the connector's map. + **/ + private SubscriptionManager createSubscriptionManager() + throws IOException { + if (EnvHelp.delegateToEventService(env) && + mbeanServer.isRegistered(EventClientDelegate.OBJECT_NAME)) { + final EventClientDelegateMBean mbean = + JMX.newMBeanProxy(mbeanServer, + EventClientDelegate.OBJECT_NAME, + EventClientDelegateMBean.class); + String clientId; + try { + clientId = + mbean.addClient( + FetchingEventForwarder.class.getName(), + new Object[] {EnvHelp.getNotifBufferSize(env)}, + new String[] {int.class.getName()}); + } catch (Exception e) { + if (e instanceof IOException) + throw (IOException) e; + else + throw new IOException(e); + } + + // we're going to call remove client... + try { + mbean.lease(clientId, Long.MAX_VALUE); + } catch (EventClientNotFoundException x) { + throw new IOException("Unknown clientId: "+clientId,x); + } + return new EventSubscriptionManager(mbeanServer, mbean, env, + clientId, connectionId); + } else { + final ServerNotifForwarder serverNotifForwarder = + new ServerNotifForwarder(mbeanServer, + env, + rmiServer.getNotifBuffer(), + connectionId); + return new LegacySubscriptionManager(serverNotifForwarder); + } + } + + /** + * Lazy creation of a SubscriptionManager. + **/ + private synchronized SubscriptionManager getSubscriptionManager() + throws IOException { + // Lazily created when first use. Mainly when + // addNotificationListener is first called. + + if (subscriptionManager == null) { + subscriptionManager = createSubscriptionManager(); + } + return subscriptionManager; + } + + // calls SubscriptionManager. + private void doRemoveListener(ObjectName name, Integer id) + throws InstanceNotFoundException, ListenerNotFoundException, + IOException { + getSubscriptionManager().removeNotificationListener(name,id); + } + + // calls SubscriptionManager. + private void doRemoveListener(ObjectName name, Integer[] ids) + throws Exception { + getSubscriptionManager().removeNotificationListener(name,ids); + } + + // calls SubscriptionManager. + private NotificationResult doFetchNotifs(long csn, long timeout, int maxcount) + throws IOException { + return getSubscriptionManager().fetchNotifications(csn, timeout, maxcount); + } + + // calls SubscriptionManager. + private Integer doAddListener(ObjectName name, NotificationFilter filter) + throws InstanceNotFoundException, IOException { + return getSubscriptionManager().addNotificationListener(name,filter); + } + + /** *

      Returns a string representation of this object. In general, * the toString method returns a string that @@ -1313,16 +1618,6 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { // private methods //------------------------------------------------------------------------ - private ClassLoaderRepository getClassLoaderRepository() { - return - AccessController.doPrivileged( - new PrivilegedAction() { - public ClassLoaderRepository run() { - return mbeanServer.getClassLoaderRepository(); - } - }); - } - private ClassLoader getClassLoader(final ObjectName name) throws InstanceNotFoundException { try { @@ -1482,9 +1777,8 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { return null; case ADD_NOTIFICATION_LISTENERS: - return getServerNotifFwd().addNotificationListener( - (ObjectName)params[0], - (NotificationFilter)params[1]); + return doAddListener((ObjectName)params[0], + (NotificationFilter)params[1]); case ADD_NOTIFICATION_LISTENER_OBJECTNAME: mbeanServer.addNotificationListener((ObjectName)params[0], @@ -1494,9 +1788,7 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { return null; case REMOVE_NOTIFICATION_LISTENER: - getServerNotifFwd().removeNotificationListener( - (ObjectName)params[0], - (Integer[])params[1]); + doRemoveListener((ObjectName)params[0],(Integer[])params[1]); return null; case REMOVE_NOTIFICATION_LISTENER_OBJECTNAME: @@ -1607,6 +1899,15 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { return e; } + private static String getMBeanServerName(final MBeanServer server) { + final PrivilegedAction action = new PrivilegedAction() { + public String run() { + return Util.getMBeanServerSecurityName(server); + } + }; + return AccessController.doPrivileged(action); + } + private static final Object[] NO_OBJECTS = new Object[0]; private static final String[] NO_STRINGS = new String[0]; @@ -1709,23 +2010,21 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { private final static int REMOVE_NOTIFICATION_LISTENER = 19; private final static int - REMOVE_NOTIFICATION_LISTENER_FILTER_HANDBACK = 20; + REMOVE_NOTIFICATION_LISTENER_OBJECTNAME = 20; private final static int - REMOVE_NOTIFICATION_LISTENER_OBJECTNAME = 21; + REMOVE_NOTIFICATION_LISTENER_OBJECTNAME_FILTER_HANDBACK = 21; private final static int - REMOVE_NOTIFICATION_LISTENER_OBJECTNAME_FILTER_HANDBACK = 22; + SET_ATTRIBUTE = 22; private final static int - SET_ATTRIBUTE = 23; + SET_ATTRIBUTES = 23; private final static int - SET_ATTRIBUTES = 24; - private final static int - UNREGISTER_MBEAN = 25; + UNREGISTER_MBEAN = 24; // SERVER NOTIFICATION //-------------------- - private ServerNotifForwarder serverNotifForwarder; - private Map env; + private SubscriptionManager subscriptionManager; + private Map env; // TRACES & DEBUG //--------------- diff --git a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java index 2f5f234eac1..a620235ac13 100644 --- a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java +++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java @@ -25,6 +25,9 @@ package javax.management.remote.rmi; +import com.sun.jmx.event.DaemonThreadFactory; +import com.sun.jmx.event.EventConnection; +import com.sun.jmx.mbeanserver.PerThreadGroupPool; import com.sun.jmx.remote.internal.ClientCommunicatorAdmin; import com.sun.jmx.remote.internal.ClientListenerInfo; import com.sun.jmx.remote.internal.ClientNotifForwarder; @@ -68,6 +71,12 @@ import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.WeakHashMap; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.Executor; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; import javax.management.Attribute; import javax.management.AttributeList; import javax.management.AttributeNotFoundException; @@ -75,6 +84,7 @@ import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.IntrospectionException; import javax.management.InvalidAttributeValueException; +import javax.management.JMX; import javax.management.ListenerNotFoundException; import javax.management.MBeanException; import javax.management.MBeanInfo; @@ -92,6 +102,8 @@ import javax.management.ObjectInstance; import javax.management.ObjectName; import javax.management.QueryExp; import javax.management.ReflectionException; +import javax.management.event.EventClient; +import javax.management.event.EventClientDelegateMBean; import javax.management.remote.JMXConnectionNotification; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; @@ -280,8 +292,8 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable // client-side environment property is set to "true". // boolean checkStub = EnvHelp.computeBooleanFromString( - usemap, - "jmx.remote.x.check.stub"); + usemap, + "jmx.remote.x.check.stub",false); if (checkStub) checkStub(stub, rmiServerImplStubClass); // Connect IIOP Stub if needed. @@ -318,6 +330,8 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable // connectionId = getConnectionId(); + eventServiceEnabled = EnvHelp.eventServiceEnabled(env); + Notification connectedNotif = new JMXConnectionNotification(JMXConnectionNotification.OPENED, this, @@ -327,6 +341,8 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable null); sendNotification(connectedNotif); + // whether or not event service + if (tracing) logger.trace("connect",idstr + " done..."); } catch (IOException e) { if (tracing) @@ -378,13 +394,42 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable throw new IOException("Not connected"); } - MBeanServerConnection mbsc = rmbscMap.get(delegationSubject); - if (mbsc != null) - return mbsc; + MBeanServerConnection rmbsc = rmbscMap.get(delegationSubject); + if (rmbsc != null) { + return rmbsc; + } - mbsc = new RemoteMBeanServerConnection(delegationSubject); - rmbscMap.put(delegationSubject, mbsc); - return mbsc; + rmbsc = new RemoteMBeanServerConnection(delegationSubject); + if (eventServiceEnabled) { + EventClientDelegateMBean ecd = JMX.newMBeanProxy( + rmbsc, EventClientDelegateMBean.OBJECT_NAME, + EventClientDelegateMBean.class); + EventClient ec = new EventClient(ecd, null, defaultExecutor(), null, + EventClient.DEFAULT_LEASE_TIMEOUT); + + rmbsc = EventConnection.Factory.make(rmbsc, ec); + ec.addEventClientListener( + lostNotifListener, null, null); + } + rmbscMap.put(delegationSubject, rmbsc); + return rmbsc; + } + + private static Executor defaultExecutor() { + PerThreadGroupPool.Create create = + new PerThreadGroupPool.Create() { + public ThreadPoolExecutor createThreadPool(ThreadGroup group) { + ThreadFactory daemonThreadFactory = new DaemonThreadFactory( + "JMX RMIConnector listener dispatch %d"); + ThreadPoolExecutor exec = new ThreadPoolExecutor( + 1, 10, 1, TimeUnit.SECONDS, + new LinkedBlockingDeque(), + daemonThreadFactory); + exec.allowCoreThreadTimeOut(true); + return exec; + } + }; + return listenerDispatchThreadPool.getThreadPoolExecutor(create); } public void @@ -466,6 +511,17 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable communicatorAdmin.terminate(); } + // close all EventClient + for (MBeanServerConnection rmbsc : rmbscMap.values()) { + if (rmbsc instanceof EventConnection) { + try { + ((EventConnection)rmbsc).getEventClient().close(); + } catch (Exception e) { + // OK + } + } + } + if (rmiNotifClient != null) { try { rmiNotifClient.terminate(); @@ -592,18 +648,19 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable } if (debug) logger.debug("addListenersWithSubjects","registered " - + listenerIDs.length + " listener(s)"); + + ((listenerIDs==null)?0:listenerIDs.length) + + " listener(s)"); return listenerIDs; } //-------------------------------------------------------------------- // Implementation of MBeanServerConnection //-------------------------------------------------------------------- - private class RemoteMBeanServerConnection - implements MBeanServerConnection { - + private class RemoteMBeanServerConnection implements MBeanServerConnection { private Subject delegationSubject; + public EventClient eventClient = null; + public RemoteMBeanServerConnection() { this(null); } @@ -1205,6 +1262,7 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable IOException { final boolean debug = logger.debugOn(); + if (debug) logger.debug("addNotificationListener" + "(ObjectName,NotificationListener,"+ @@ -1226,8 +1284,9 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable public void removeNotificationListener(ObjectName name, NotificationListener listener) throws InstanceNotFoundException, - ListenerNotFoundException, - IOException { + ListenerNotFoundException, + IOException { + final boolean debug = logger.debugOn(); if (debug) logger.debug("removeNotificationListener"+ @@ -1804,6 +1863,26 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable terminated = false; connectionBroadcaster = new NotificationBroadcasterSupport(); + + lostNotifListener = + new NotificationListener() { + public void handleNotification(Notification n, Object hb) { + if (n != null && EventClient.NOTIFS_LOST.equals(n.getType())) { + Long lost = (Long)n.getUserData(); + final String msg = + "May have lost up to " + lost + + " notification" + (lost.longValue() == 1 ? "" : "s"); + sendNotification(new JMXConnectionNotification( + JMXConnectionNotification.NOTIFS_LOST, + RMIConnector.this, + connectionId, + clientNotifCounter++, + msg, + lost)); + + } + } + }; } //-------------------------------------------------------------------- @@ -2528,6 +2607,11 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable private transient ClientCommunicatorAdmin communicatorAdmin; + private boolean eventServiceEnabled; +// private transient EventRelay eventRelay; + + private transient NotificationListener lostNotifListener; + /** * A static WeakReference to an {@link org.omg.CORBA.ORB ORB} to * connect unconnected stubs. @@ -2546,4 +2630,7 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable private static String strings(final String[] strs) { return objects(strs); } + + private static final PerThreadGroupPool listenerDispatchThreadPool = + PerThreadGroupPool.make(); } diff --git a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectorServer.java b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectorServer.java index 28015461b2b..2cbe315bfdd 100644 --- a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectorServer.java +++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectorServer.java @@ -230,6 +230,8 @@ public class RMIConnectorServer extends JMXConnectorServer { this.address = url; this.rmiServerImpl = rmiServerImpl; + + installStandardForwarders(this.attributes); } /** @@ -380,8 +382,8 @@ public class RMIConnectorServer extends JMXConnectorServer { try { if (tracing) logger.trace("start", "setting default class loader"); - defaultClassLoader = - EnvHelp.resolveServerClassLoader(attributes, getMBeanServer()); + defaultClassLoader = EnvHelp.resolveServerClassLoader( + attributes, getSystemMBeanServer()); } catch (InstanceNotFoundException infc) { IllegalArgumentException x = new IllegalArgumentException("ClassLoader not found: "+infc); @@ -396,7 +398,7 @@ public class RMIConnectorServer extends JMXConnectorServer { else rmiServer = newServer(); - rmiServer.setMBeanServer(getMBeanServer()); + rmiServer.setMBeanServer(getSystemMBeanServer()); rmiServer.setDefaultClassLoader(defaultClassLoader); rmiServer.setRMIConnectorServer(this); rmiServer.export(); @@ -413,7 +415,7 @@ public class RMIConnectorServer extends JMXConnectorServer { final boolean rebind = EnvHelp.computeBooleanFromString( attributes, - JNDI_REBIND_ATTRIBUTE); + JNDI_REBIND_ATTRIBUTE,false); if (tracing) logger.trace("start", JNDI_REBIND_ATTRIBUTE + "=" + rebind); @@ -590,11 +592,39 @@ public class RMIConnectorServer extends JMXConnectorServer { return Collections.unmodifiableMap(map); } - public synchronized - void setMBeanServerForwarder(MBeanServerForwarder mbsf) { + @Override + public synchronized void setMBeanServerForwarder(MBeanServerForwarder mbsf) { + MBeanServer oldSMBS = getSystemMBeanServer(); super.setMBeanServerForwarder(mbsf); + if (oldSMBS != getSystemMBeanServer()) + updateMBeanServer(); + // If the system chain of MBeanServerForwarders is not empty, then + // there is no need to call rmiServerImpl.setMBeanServer, because + // it is pointing to the head of the system chain and that has not + // changed. (The *end* of the system chain will have been changed + // to point to mbsf.) + } + + private void updateMBeanServer() { if (rmiServerImpl != null) - rmiServerImpl.setMBeanServer(getMBeanServer()); + rmiServerImpl.setMBeanServer(getSystemMBeanServer()); + } + + @Override + public synchronized void setSystemMBeanServerForwarder( + MBeanServerForwarder mbsf) { + super.setSystemMBeanServerForwarder(mbsf); + updateMBeanServer(); + } + + /** + * {@inheritDoc} + * @return true, since this connector server does support a system chain + * of forwarders. + */ + @Override + public boolean supportsSystemMBeanServerForwarder() { + return true; } /* We repeat the definitions of connection{Opened,Closed,Failed} diff --git a/jdk/src/share/classes/javax/net/ssl/SSLServerSocket.java b/jdk/src/share/classes/javax/net/ssl/SSLServerSocket.java index cdeef2baf75..8232c1d5306 100644 --- a/jdk/src/share/classes/javax/net/ssl/SSLServerSocket.java +++ b/jdk/src/share/classes/javax/net/ssl/SSLServerSocket.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -108,9 +108,12 @@ public abstract class SSLServerSocket extends ServerSocket *

      * A port number of 0 creates a socket on any free port. *

      - * The backlog argument must be a positive - * value greater than 0. If the value passed if equal or less - * than 0, then the default value will be assumed. + * The backlog argument is the requested maximum number of + * pending connections on the socket. Its exact semantics are implementation + * specific. In particular, an implementation may impose a maximum length + * or may choose to ignore the parameter altogther. The value provided + * should be greater than 0. If it is less than or equal to + * 0, then an implementation specific default will be used. *

      * If there is a security manager, its checkListen * method is called with the port argument as its @@ -118,8 +121,8 @@ public abstract class SSLServerSocket extends ServerSocket * in a SecurityException. * * @param port the port on which to listen - * @param backlog how many connections may be pending before - * the system should start rejecting new requests + * @param backlog requested maximum length of the queue of incoming + * connections. * @throws IOException if an I/O error occurs when creating the socket * @throws SecurityException if a security manager exists and its * checkListen method doesn't allow the operation. @@ -150,16 +153,19 @@ public abstract class SSLServerSocket extends ServerSocket *

      * A port number of 0 creates a socket on any free port. *

      - *

      The backlog argument must be a positive - * value greater than 0. If the value passed if equal or less - * than 0, then the default value will be assumed. + * The backlog argument is the requested maximum number of + * pending connections on the socket. Its exact semantics are implementation + * specific. In particular, an implementation may impose a maximum length + * or may choose to ignore the parameter altogther. The value provided + * should be greater than 0. If it is less than or equal to + * 0, then an implementation specific default will be used. *

      * If address is null, it will default accepting connections * on any/all local addresses. * * @param port the port on which to listen - * @param backlog how many connections may be pending before - * the system should start rejecting new requests + * @param backlog requested maximum length of the queue of incoming + * connections. * @param address the address of the network interface through * which connections will be accepted * @throws IOException if an I/O error occurs when creating the socket diff --git a/jdk/src/share/classes/javax/swing/AbstractButton.java b/jdk/src/share/classes/javax/swing/AbstractButton.java index 4248a7144e0..d4810810128 100644 --- a/jdk/src/share/classes/javax/swing/AbstractButton.java +++ b/jdk/src/share/classes/javax/swing/AbstractButton.java @@ -1315,8 +1315,7 @@ public abstract class AbstractButton extends JComponent implements ItemSelectabl // Make sure the change actually took effect if (!selected && isSelected()) { if (getModel() instanceof DefaultButtonModel) { - ButtonGroup group = (ButtonGroup) - ((DefaultButtonModel)getModel()).getGroup(); + ButtonGroup group = ((DefaultButtonModel)getModel()).getGroup(); if (group != null) { group.clearSelection(); } @@ -1886,8 +1885,7 @@ public abstract class AbstractButton extends JComponent implements ItemSelectabl * @since 1.4 */ public ChangeListener[] getChangeListeners() { - return (ChangeListener[])(listenerList.getListeners( - ChangeListener.class)); + return listenerList.getListeners(ChangeListener.class); } /** @@ -1944,8 +1942,7 @@ public abstract class AbstractButton extends JComponent implements ItemSelectabl * @since 1.4 */ public ActionListener[] getActionListeners() { - return (ActionListener[])(listenerList.getListeners( - ActionListener.class)); + return listenerList.getListeners(ActionListener.class); } /** @@ -2137,7 +2134,7 @@ public abstract class AbstractButton extends JComponent implements ItemSelectabl * @since 1.4 */ public ItemListener[] getItemListeners() { - return (ItemListener[])listenerList.getListeners(ItemListener.class); + return listenerList.getListeners(ItemListener.class); } /** @@ -2981,7 +2978,7 @@ public abstract class AbstractButton extends JComponent implements ItemSelectabl paintViewR.height = AbstractButton.this.getHeight() - (paintViewInsets.top + paintViewInsets.bottom); String clippedText = SwingUtilities.layoutCompoundLabel( - (JComponent)AbstractButton.this, + AbstractButton.this, getFontMetrics(getFont()), text, icon, diff --git a/jdk/src/share/classes/javax/swing/AbstractCellEditor.java b/jdk/src/share/classes/javax/swing/AbstractCellEditor.java index 5ecdc439003..90b1c8d69b4 100644 --- a/jdk/src/share/classes/javax/swing/AbstractCellEditor.java +++ b/jdk/src/share/classes/javax/swing/AbstractCellEditor.java @@ -118,8 +118,7 @@ public abstract class AbstractCellEditor implements CellEditor, Serializable { * @since 1.4 */ public CellEditorListener[] getCellEditorListeners() { - return (CellEditorListener[])listenerList.getListeners( - CellEditorListener.class); + return listenerList.getListeners(CellEditorListener.class); } /** diff --git a/jdk/src/share/classes/javax/swing/AbstractListModel.java b/jdk/src/share/classes/javax/swing/AbstractListModel.java index 102218bdb7c..00c8841a533 100644 --- a/jdk/src/share/classes/javax/swing/AbstractListModel.java +++ b/jdk/src/share/classes/javax/swing/AbstractListModel.java @@ -85,8 +85,7 @@ public abstract class AbstractListModel implements ListModel, Serializable * @since 1.4 */ public ListDataListener[] getListDataListeners() { - return (ListDataListener[])listenerList.getListeners( - ListDataListener.class); + return listenerList.getListeners(ListDataListener.class); } diff --git a/jdk/src/share/classes/javax/swing/AbstractSpinnerModel.java b/jdk/src/share/classes/javax/swing/AbstractSpinnerModel.java index 2956339124c..9cf16c6db14 100644 --- a/jdk/src/share/classes/javax/swing/AbstractSpinnerModel.java +++ b/jdk/src/share/classes/javax/swing/AbstractSpinnerModel.java @@ -98,8 +98,7 @@ public abstract class AbstractSpinnerModel implements SpinnerModel, Serializable * @since 1.4 */ public ChangeListener[] getChangeListeners() { - return (ChangeListener[])listenerList.getListeners( - ChangeListener.class); + return listenerList.getListeners(ChangeListener.class); } diff --git a/jdk/src/share/classes/javax/swing/ActionMap.java b/jdk/src/share/classes/javax/swing/ActionMap.java index b1d4e4b20fb..3858eabe431 100644 --- a/jdk/src/share/classes/javax/swing/ActionMap.java +++ b/jdk/src/share/classes/javax/swing/ActionMap.java @@ -197,7 +197,7 @@ public class ActionMap implements Serializable { return pKeys; } - HashMap keyMap = new HashMap(); + HashMap keyMap = new HashMap(); int counter; for (counter = keys.length - 1; counter >= 0; counter--) { diff --git a/jdk/src/share/classes/javax/swing/AncestorNotifier.java b/jdk/src/share/classes/javax/swing/AncestorNotifier.java index 694bc5df08d..eb67ed15484 100644 --- a/jdk/src/share/classes/javax/swing/AncestorNotifier.java +++ b/jdk/src/share/classes/javax/swing/AncestorNotifier.java @@ -62,7 +62,7 @@ class AncestorNotifier implements ComponentListener, PropertyChangeListener, Ser } AncestorListener[] getAncestorListeners() { - return (AncestorListener[])listenerList.getListeners(AncestorListener.class); + return listenerList.getListeners(AncestorListener.class); } /** diff --git a/jdk/src/share/classes/javax/swing/ArrayTable.java b/jdk/src/share/classes/javax/swing/ArrayTable.java index b44fc436cdc..1ee5f07d88c 100644 --- a/jdk/src/share/classes/javax/swing/ArrayTable.java +++ b/jdk/src/share/classes/javax/swing/ArrayTable.java @@ -88,10 +88,10 @@ class ArrayTable implements Cloneable { // Write ou the Serializable key/value pairs. s.writeInt(validCount); if (validCount > 0) { - for (int counter = 0; counter < keys.length; counter++) { - if (keys[counter] != null) { - s.writeObject(keys[counter]); - s.writeObject(table.get(keys[counter])); + for (Object key : keys) { + if (key != null) { + s.writeObject(key); + s.writeObject(table.get(key)); if (--validCount == 0) { break; } @@ -315,7 +315,7 @@ class ArrayTable implements Cloneable { */ private void grow() { Object[] array = (Object[])table; - Hashtable tmp = new Hashtable(array.length/2); + Hashtable tmp = new Hashtable(array.length/2); for (int i = 0; i buttons = new Vector(); + protected Vector buttons = new Vector(); /** * The current selection. diff --git a/jdk/src/share/classes/javax/swing/DebugGraphicsInfo.java b/jdk/src/share/classes/javax/swing/DebugGraphicsInfo.java index f9e6c72a984..75be3e7f800 100644 --- a/jdk/src/share/classes/javax/swing/DebugGraphicsInfo.java +++ b/jdk/src/share/classes/javax/swing/DebugGraphicsInfo.java @@ -37,7 +37,7 @@ class DebugGraphicsInfo { Color flashColor = Color.red; int flashTime = 100; int flashCount = 2; - Hashtable componentToDebug; + Hashtable componentToDebug; JFrame debugFrame = null; java.io.PrintStream stream = System.out; @@ -46,7 +46,7 @@ class DebugGraphicsInfo { return; } if (componentToDebug == null) { - componentToDebug = new Hashtable(); + componentToDebug = new Hashtable(); } if (debug > 0) { componentToDebug.put(component, Integer.valueOf(debug)); @@ -59,7 +59,7 @@ class DebugGraphicsInfo { if (componentToDebug == null) { return 0; } else { - Integer integer = (Integer)componentToDebug.get(component); + Integer integer = componentToDebug.get(component); return integer == null ? 0 : integer.intValue(); } diff --git a/jdk/src/share/classes/javax/swing/DefaultBoundedRangeModel.java b/jdk/src/share/classes/javax/swing/DefaultBoundedRangeModel.java index d8e4f0f0454..c718ce6027f 100644 --- a/jdk/src/share/classes/javax/swing/DefaultBoundedRangeModel.java +++ b/jdk/src/share/classes/javax/swing/DefaultBoundedRangeModel.java @@ -343,8 +343,7 @@ public class DefaultBoundedRangeModel implements BoundedRangeModel, Serializable * @since 1.4 */ public ChangeListener[] getChangeListeners() { - return (ChangeListener[])listenerList.getListeners( - ChangeListener.class); + return listenerList.getListeners(ChangeListener.class); } diff --git a/jdk/src/share/classes/javax/swing/DefaultButtonModel.java b/jdk/src/share/classes/javax/swing/DefaultButtonModel.java index b9c94384426..8ad0acddb46 100644 --- a/jdk/src/share/classes/javax/swing/DefaultButtonModel.java +++ b/jdk/src/share/classes/javax/swing/DefaultButtonModel.java @@ -326,8 +326,7 @@ public class DefaultButtonModel implements ButtonModel, Serializable { * @since 1.4 */ public ChangeListener[] getChangeListeners() { - return (ChangeListener[])listenerList.getListeners( - ChangeListener.class); + return listenerList.getListeners(ChangeListener.class); } /** @@ -380,8 +379,7 @@ public class DefaultButtonModel implements ButtonModel, Serializable { * @since 1.4 */ public ActionListener[] getActionListeners() { - return (ActionListener[])listenerList.getListeners( - ActionListener.class); + return listenerList.getListeners(ActionListener.class); } /** @@ -434,7 +432,7 @@ public class DefaultButtonModel implements ButtonModel, Serializable { * @since 1.4 */ public ItemListener[] getItemListeners() { - return (ItemListener[])listenerList.getListeners(ItemListener.class); + return listenerList.getListeners(ItemListener.class); } /** diff --git a/jdk/src/share/classes/javax/swing/DefaultFocusManager.java b/jdk/src/share/classes/javax/swing/DefaultFocusManager.java index 417b625f95a..021867a5cca 100644 --- a/jdk/src/share/classes/javax/swing/DefaultFocusManager.java +++ b/jdk/src/share/classes/javax/swing/DefaultFocusManager.java @@ -156,18 +156,17 @@ final class LegacyLayoutFocusTraversalPolicy } } -final class CompareTabOrderComparator implements Comparator { +final class CompareTabOrderComparator implements Comparator { private final DefaultFocusManager defaultFocusManager; CompareTabOrderComparator(DefaultFocusManager defaultFocusManager) { this.defaultFocusManager = defaultFocusManager; } - public int compare(Object o1, Object o2) { + public int compare(Component o1, Component o2) { if (o1 == o2) { return 0; } - return (defaultFocusManager.compareTabOrder((Component)o1, - (Component)o2)) ? -1 : 1; + return (defaultFocusManager.compareTabOrder(o1, o2)) ? -1 : 1; } } diff --git a/jdk/src/share/classes/javax/swing/DefaultListSelectionModel.java b/jdk/src/share/classes/javax/swing/DefaultListSelectionModel.java index 329fa38b44a..2ba0e7b9d25 100644 --- a/jdk/src/share/classes/javax/swing/DefaultListSelectionModel.java +++ b/jdk/src/share/classes/javax/swing/DefaultListSelectionModel.java @@ -133,8 +133,7 @@ public class DefaultListSelectionModel implements ListSelectionModel, Cloneable, * @since 1.4 */ public ListSelectionListener[] getListSelectionListeners() { - return (ListSelectionListener[])listenerList.getListeners( - ListSelectionListener.class); + return listenerList.getListeners(ListSelectionListener.class); } /** diff --git a/jdk/src/share/classes/javax/swing/DefaultSingleSelectionModel.java b/jdk/src/share/classes/javax/swing/DefaultSingleSelectionModel.java index d0270f1c75e..c03b51f16dd 100644 --- a/jdk/src/share/classes/javax/swing/DefaultSingleSelectionModel.java +++ b/jdk/src/share/classes/javax/swing/DefaultSingleSelectionModel.java @@ -110,8 +110,7 @@ Serializable { * @since 1.4 */ public ChangeListener[] getChangeListeners() { - return (ChangeListener[])listenerList.getListeners( - ChangeListener.class); + return listenerList.getListeners(ChangeListener.class); } /** diff --git a/jdk/src/share/classes/javax/swing/GroupLayout.java b/jdk/src/share/classes/javax/swing/GroupLayout.java index fd1fd0c65cb..fb59d0c8564 100644 --- a/jdk/src/share/classes/javax/swing/GroupLayout.java +++ b/jdk/src/share/classes/javax/swing/GroupLayout.java @@ -1119,7 +1119,7 @@ public class GroupLayout implements LayoutManager2 { * creating one if necessary. */ private ComponentInfo getComponentInfo(Component component) { - ComponentInfo info = (ComponentInfo)componentInfos.get(component); + ComponentInfo info = componentInfos.get(component); if (info == null) { info = new ComponentInfo(component); componentInfos.put(component, info); @@ -1698,7 +1698,7 @@ public class GroupLayout implements LayoutManager2 { for (int counter = springs.size() - 1; counter >= 0; counter--) { Spring spring = springs.get(counter); if (spring instanceof AutoPreferredGapSpring) { - ((AutoPreferredGapSpring)spring).unset(); + spring.unset(); } else if (spring instanceof Group) { ((Group)spring).unsetAutopadding(); } diff --git a/jdk/src/share/classes/javax/swing/InputMap.java b/jdk/src/share/classes/javax/swing/InputMap.java index cba5a5d8bb3..0992b1188f8 100644 --- a/jdk/src/share/classes/javax/swing/InputMap.java +++ b/jdk/src/share/classes/javax/swing/InputMap.java @@ -200,7 +200,7 @@ public class InputMap implements Serializable { return pKeys; } - HashMap keyMap = new HashMap(); + HashMap keyMap = new HashMap(); int counter; for (counter = keys.length - 1; counter >= 0; counter--) { @@ -212,7 +212,7 @@ public class InputMap implements Serializable { KeyStroke[] allKeys = new KeyStroke[keyMap.size()]; - return (KeyStroke[])keyMap.keySet().toArray(allKeys); + return keyMap.keySet().toArray(allKeys); } private void writeObject(ObjectOutputStream s) throws IOException { diff --git a/jdk/src/share/classes/javax/swing/JApplet.java b/jdk/src/share/classes/javax/swing/JApplet.java index b9b5b2506b9..47f792a942d 100644 --- a/jdk/src/share/classes/javax/swing/JApplet.java +++ b/jdk/src/share/classes/javax/swing/JApplet.java @@ -131,10 +131,7 @@ public class JApplet extends Applet implements Accessible, // Check the timerQ and restart if necessary. TimerQueue q = TimerQueue.sharedInstance(); if(q != null) { - synchronized(q) { - if(!q.running) - q.start(); - } + q.startIfNeeded(); } /* Workaround for bug 4155072. The shared double buffer image diff --git a/jdk/src/share/classes/javax/swing/JComboBox.java b/jdk/src/share/classes/javax/swing/JComboBox.java index 2230147f4a9..42ef6466979 100644 --- a/jdk/src/share/classes/javax/swing/JComboBox.java +++ b/jdk/src/share/classes/javax/swing/JComboBox.java @@ -859,7 +859,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible { * @since 1.4 */ public ItemListener[] getItemListeners() { - return (ItemListener[])listenerList.getListeners(ItemListener.class); + return listenerList.getListeners(ItemListener.class); } /** @@ -897,8 +897,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible { * @since 1.4 */ public ActionListener[] getActionListeners() { - return (ActionListener[])listenerList.getListeners( - ActionListener.class); + return listenerList.getListeners(ActionListener.class); } /** @@ -937,8 +936,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible { * @since 1.4 */ public PopupMenuListener[] getPopupMenuListeners() { - return (PopupMenuListener[])listenerList.getListeners( - PopupMenuListener.class); + return listenerList.getListeners(PopupMenuListener.class); } /** @@ -1668,7 +1666,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible { if (editor != null) { Component comp = editor.getEditorComponent(); if (comp instanceof Accessible) { - AccessibleContext ac = ((Accessible)comp).getAccessibleContext(); + AccessibleContext ac = comp.getAccessibleContext(); if (ac != null) { // may be null ac.setAccessibleName(getAccessibleName()); ac.setAccessibleDescription(getAccessibleDescription()); @@ -1741,7 +1739,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible { // Fire a FOCUSED lost PropertyChangeEvent for the // previously selected list item. - PropertyChangeEvent pce = null; + PropertyChangeEvent pce; if (previousSelectedAccessible != null) { pce = new PropertyChangeEvent(previousSelectedAccessible, diff --git a/jdk/src/share/classes/javax/swing/JComponent.java b/jdk/src/share/classes/javax/swing/JComponent.java index 7d3881a1c05..831dc717a07 100644 --- a/jdk/src/share/classes/javax/swing/JComponent.java +++ b/jdk/src/share/classes/javax/swing/JComponent.java @@ -192,7 +192,8 @@ public abstract class JComponent extends Container implements Serializable, /** * @see #readObject */ - private static final Hashtable readObjectCallbacks = new Hashtable(1); + private static final Hashtable readObjectCallbacks = + new Hashtable(1); /** * Keys to use for forward focus traversal when the JComponent is @@ -356,7 +357,7 @@ public abstract class JComponent extends Container implements Serializable, /** * Temporary rectangles. */ - private static java.util.List tempRectangles = new java.util.ArrayList(11); + private static java.util.List tempRectangles = new java.util.ArrayList(11); /** Used for WHEN_FOCUSED bindings. */ private InputMap focusInputMap; @@ -451,7 +452,7 @@ public abstract class JComponent extends Container implements Serializable, Rectangle rect; int size = tempRectangles.size(); if (size > 0) { - rect = (Rectangle)tempRectangles.remove(size - 1); + rect = tempRectangles.remove(size - 1); } else { rect = new Rectangle(0, 0, 0, 0); @@ -806,7 +807,7 @@ public abstract class JComponent extends Container implements Serializable, // its index. if (paintingChild != null && (paintingChild instanceof JComponent) && - ((JComponent)paintingChild).isOpaque()) { + paintingChild.isOpaque()) { for (; i >= 0; i--) { if (getComponent(i) == paintingChild){ break; @@ -875,7 +876,7 @@ public abstract class JComponent extends Container implements Serializable, shouldSetFlagBack = true; } if(!printing) { - ((JComponent)comp).paint(cg); + comp.paint(cg); } else { if (!getFlag(IS_PRINTING_ALL)) { @@ -1098,7 +1099,7 @@ public abstract class JComponent extends Container implements Serializable, } private void adjustPaintFlags() { - JComponent jparent = null; + JComponent jparent; Container parent; for(parent = getParent() ; parent != null ; parent = parent.getParent()) { @@ -2096,7 +2097,7 @@ public abstract class JComponent extends Container implements Serializable, private void registerWithKeyboardManager(boolean onlyIfNew) { InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW, false); KeyStroke[] strokes; - Hashtable registered = (Hashtable)getClientProperty + Hashtable registered = (Hashtable)getClientProperty (WHEN_IN_FOCUSED_WINDOW_BINDINGS); if (inputMap != null) { @@ -2120,10 +2121,10 @@ public abstract class JComponent extends Container implements Serializable, } // Remove any old ones. if (registered != null && registered.size() > 0) { - Enumeration keys = registered.keys(); + Enumeration keys = registered.keys(); while (keys.hasMoreElements()) { - KeyStroke ks = (KeyStroke)keys.nextElement(); + KeyStroke ks = keys.nextElement(); unregisterWithKeyboardManager(ks); } registered.clear(); @@ -2131,7 +2132,7 @@ public abstract class JComponent extends Container implements Serializable, // Updated the registered Hashtable. if (strokes != null && strokes.length > 0) { if (registered == null) { - registered = new Hashtable(strokes.length); + registered = new Hashtable(strokes.length); putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, registered); } for (int counter = strokes.length - 1; counter >= 0; counter--) { @@ -2174,7 +2175,7 @@ public abstract class JComponent extends Container implements Serializable, InputMap km = getInputMap(WHEN_IN_FOCUSED_WINDOW, false); while (km != inputMap && km != null) { - km = (ComponentInputMap)km.getParent(); + km = km.getParent(); } if (km != null) { registerWithKeyboardManager(false); @@ -3673,7 +3674,7 @@ public abstract class JComponent extends Container implements Serializable, if (c != null && c instanceof Accessible) { AccessibleJComponent.this.firePropertyChange( AccessibleContext.ACCESSIBLE_CHILD_PROPERTY, - null, ((Accessible) c).getAccessibleContext()); + null, c.getAccessibleContext()); } } public void componentRemoved(ContainerEvent e) { @@ -3681,7 +3682,7 @@ public abstract class JComponent extends Container implements Serializable, if (c != null && c instanceof Accessible) { AccessibleJComponent.this.firePropertyChange( AccessibleContext.ACCESSIBLE_CHILD_PROPERTY, - ((Accessible) c).getAccessibleContext(), null); + c.getAccessibleContext(), null); } } } @@ -4377,7 +4378,7 @@ public abstract class JComponent extends Container implements Serializable, // System.out.println("A) checking opaque: " + ((JComponent)child).isOpaque() + " " + child); // System.out.print("B) "); // Thread.dumpStack(); - return ((JComponent)child).isOpaque(); + return child.isOpaque(); } else { /** Sometimes a heavy weight can have a bound larger than its peer size * so we should always draw under heavy weights @@ -4693,7 +4694,7 @@ public abstract class JComponent extends Container implements Serializable, result = (T[])getPropertyChangeListeners(); } else { - result = (T[])listenerList.getListeners(listenerType); + result = listenerList.getListeners(listenerType); } if (result.length == 0) { @@ -4904,7 +4905,7 @@ public abstract class JComponent extends Container implements Serializable, if(!isShowing()) { return; } - while(!((JComponent)c).isOpaque()) { + while(!c.isOpaque()) { parent = c.getParent(); if(parent != null) { x += c.getX(); @@ -5198,7 +5199,7 @@ public abstract class JComponent extends Container implements Serializable, Rectangle siblingRect; boolean opaque; if (sibling instanceof JComponent) { - opaque = ((JComponent)sibling).isOpaque(); + opaque = sibling.isOpaque(); if (!opaque) { if (retValue == PARTIALLY_OBSCURED) { continue; @@ -5345,7 +5346,7 @@ public abstract class JComponent extends Container implements Serializable, */ private class ReadObjectCallback implements ObjectInputValidation { - private final Vector roots = new Vector(1); + private final Vector roots = new Vector(1); private final ObjectInputStream inputStream; ReadObjectCallback(ObjectInputStream s) throws Exception { @@ -5361,8 +5362,7 @@ public abstract class JComponent extends Container implements Serializable, */ public void validateObject() throws InvalidObjectException { try { - for(int i = 0; i < roots.size(); i++) { - JComponent root = (JComponent)(roots.elementAt(i)); + for (JComponent root : roots) { SwingUtilities.updateComponentTreeUI(root); } } @@ -5382,8 +5382,7 @@ public abstract class JComponent extends Container implements Serializable, /* If the Component c is a descendant of one of the * existing roots (or it IS an existing root), we're done. */ - for(int i = 0; i < roots.size(); i++) { - JComponent root = (JComponent)roots.elementAt(i); + for (JComponent root : roots) { for(Component p = c; p != null; p = p.getParent()) { if (p == root) { return; @@ -5396,7 +5395,7 @@ public abstract class JComponent extends Container implements Serializable, * to the roots vector. */ for(int i = 0; i < roots.size(); i++) { - JComponent root = (JComponent)roots.elementAt(i); + JComponent root = roots.elementAt(i); for(Component p = root.getParent(); p != null; p = p.getParent()) { if (p == c) { roots.removeElementAt(i--); // !! @@ -5428,7 +5427,7 @@ public abstract class JComponent extends Container implements Serializable, * in the readObjectCallbacks table. Note that the ReadObjectCallback * constructor takes care of calling s.registerValidation(). */ - ReadObjectCallback cb = (ReadObjectCallback)(readObjectCallbacks.get(s)); + ReadObjectCallback cb = readObjectCallbacks.get(s); if (cb == null) { try { readObjectCallbacks.put(s, cb = new ReadObjectCallback(s)); diff --git a/jdk/src/share/classes/javax/swing/JDesktopPane.java b/jdk/src/share/classes/javax/swing/JDesktopPane.java index 2c0ab31202f..19cfefd65f9 100644 --- a/jdk/src/share/classes/javax/swing/JDesktopPane.java +++ b/jdk/src/share/classes/javax/swing/JDesktopPane.java @@ -133,8 +133,8 @@ public class JDesktopPane extends JLayeredPane implements Accessible public Component getDefaultComponent(Container c) { JInternalFrame jifArray[] = getAllFrames(); Component comp = null; - for (int i = 0; i < jifArray.length; i++) { - comp = jifArray[i].getFocusTraversalPolicy().getDefaultComponent(jifArray[i]); + for (JInternalFrame jif : jifArray) { + comp = jif.getFocusTraversalPolicy().getDefaultComponent(jif); if (comp != null) { break; } @@ -262,16 +262,15 @@ public class JDesktopPane extends JLayeredPane implements Accessible public JInternalFrame[] getAllFrames() { int i, count; JInternalFrame[] results; - Vector vResults = new Vector(10); - Object next, tmp; + Vector vResults = new Vector(10); count = getComponentCount(); for(i = 0; i < count; i++) { - next = getComponent(i); + Component next = getComponent(i); if(next instanceof JInternalFrame) - vResults.addElement(next); + vResults.addElement((JInternalFrame) next); else if(next instanceof JInternalFrame.JDesktopIcon) { - tmp = ((JInternalFrame.JDesktopIcon)next).getInternalFrame(); + JInternalFrame tmp = ((JInternalFrame.JDesktopIcon)next).getInternalFrame(); if(tmp != null) vResults.addElement(tmp); } @@ -324,18 +323,17 @@ public class JDesktopPane extends JLayeredPane implements Accessible public JInternalFrame[] getAllFramesInLayer(int layer) { int i, count; JInternalFrame[] results; - Vector vResults = new Vector(10); - Object next, tmp; + Vector vResults = new Vector(10); count = getComponentCount(); for(i = 0; i < count; i++) { - next = getComponent(i); + Component next = getComponent(i); if(next instanceof JInternalFrame) { if(((JInternalFrame)next).getLayer() == layer) - vResults.addElement(next); + vResults.addElement((JInternalFrame) next); } else if(next instanceof JInternalFrame.JDesktopIcon) { - tmp = ((JInternalFrame.JDesktopIcon)next).getInternalFrame(); - if(tmp != null && ((JInternalFrame)tmp).getLayer() == layer) + JInternalFrame tmp = ((JInternalFrame.JDesktopIcon)next).getInternalFrame(); + if(tmp != null && tmp.getLayer() == layer) vResults.addElement(tmp); } } diff --git a/jdk/src/share/classes/javax/swing/JDialog.java b/jdk/src/share/classes/javax/swing/JDialog.java index ac2a24ecc06..79640949084 100644 --- a/jdk/src/share/classes/javax/swing/JDialog.java +++ b/jdk/src/share/classes/javax/swing/JDialog.java @@ -277,7 +277,7 @@ public class JDialog extends Dialog implements WindowConstants, title, modal); if (owner == null) { WindowListener ownerShutdownListener = - (WindowListener)SwingUtilities.getSharedOwnerFrameShutdownListener(); + SwingUtilities.getSharedOwnerFrameShutdownListener(); addWindowListener(ownerShutdownListener); } dialogInit(); @@ -329,7 +329,7 @@ public class JDialog extends Dialog implements WindowConstants, title, modal, gc); if (owner == null) { WindowListener ownerShutdownListener = - (WindowListener)SwingUtilities.getSharedOwnerFrameShutdownListener(); + SwingUtilities.getSharedOwnerFrameShutdownListener(); addWindowListener(ownerShutdownListener); } dialogInit(); diff --git a/jdk/src/share/classes/javax/swing/JEditorPane.java b/jdk/src/share/classes/javax/swing/JEditorPane.java index 4d70cacb7b2..21528752fd5 100644 --- a/jdk/src/share/classes/javax/swing/JEditorPane.java +++ b/jdk/src/share/classes/javax/swing/JEditorPane.java @@ -319,8 +319,7 @@ public class JEditorPane extends JTextComponent { * @since 1.4 */ public synchronized HyperlinkListener[] getHyperlinkListeners() { - return (HyperlinkListener[])listenerList.getListeners( - HyperlinkListener.class); + return listenerList.getListeners(javax.swing.event.HyperlinkListener.class); } /** @@ -492,8 +491,8 @@ public class JEditorPane extends JTextComponent { if (pageProperties != null) { // transfer properties discovered in stream to the // document property collection. - for (Enumeration e = pageProperties.keys(); e.hasMoreElements() ;) { - Object key = e.nextElement(); + for (Enumeration e = pageProperties.keys(); e.hasMoreElements() ;) { + String key = e.nextElement(); doc.putProperty(key, pageProperties.get(key)); } pageProperties.clear(); @@ -775,7 +774,7 @@ public class JEditorPane extends JTextComponent { */ private void handleConnectionProperties(URLConnection conn) { if (pageProperties == null) { - pageProperties = new Hashtable(); + pageProperties = new Hashtable(); } String type = conn.getContentType(); if (type != null) { @@ -989,7 +988,7 @@ public class JEditorPane extends JTextComponent { * of the content type in the http header information. */ private void setCharsetFromContentTypeParameters(String paramlist) { - String charset = null; + String charset; try { // paramlist is handed to us with a leading ';', strip it. int semi = paramlist.indexOf(';'); @@ -1080,9 +1079,9 @@ public class JEditorPane extends JTextComponent { */ public EditorKit getEditorKitForContentType(String type) { if (typeHandlers == null) { - typeHandlers = new Hashtable(3); + typeHandlers = new Hashtable(3); } - EditorKit k = (EditorKit) typeHandlers.get(type); + EditorKit k = typeHandlers.get(type); if (k == null) { k = createEditorKitForContentType(type); if (k != null) { @@ -1106,7 +1105,7 @@ public class JEditorPane extends JTextComponent { */ public void setEditorKitForContentType(String type, EditorKit k) { if (typeHandlers == null) { - typeHandlers = new Hashtable(3); + typeHandlers = new Hashtable(3); } typeHandlers.put(type, k); } @@ -1176,13 +1175,12 @@ public class JEditorPane extends JTextComponent { * registered for the given type */ public static EditorKit createEditorKitForContentType(String type) { - EditorKit k = null; - Hashtable kitRegistry = getKitRegisty(); - k = (EditorKit) kitRegistry.get(type); + Hashtable kitRegistry = getKitRegisty(); + EditorKit k = kitRegistry.get(type); if (k == null) { // try to dynamically load the support - String classname = (String) getKitTypeRegistry().get(type); - ClassLoader loader = (ClassLoader) getKitLoaderRegistry().get(type); + String classname = getKitTypeRegistry().get(type); + ClassLoader loader = getKitLoaderRegistry().get(type); try { Class c; if (loader != null) { @@ -1252,20 +1250,20 @@ public class JEditorPane extends JTextComponent { * @since 1.3 */ public static String getEditorKitClassNameForContentType(String type) { - return (String)getKitTypeRegistry().get(type); + return getKitTypeRegistry().get(type); } - private static Hashtable getKitTypeRegistry() { + private static Hashtable getKitTypeRegistry() { loadDefaultKitsIfNecessary(); return (Hashtable)SwingUtilities.appContextGet(kitTypeRegistryKey); } - private static Hashtable getKitLoaderRegistry() { + private static Hashtable getKitLoaderRegistry() { loadDefaultKitsIfNecessary(); return (Hashtable)SwingUtilities.appContextGet(kitLoaderRegistryKey); } - private static Hashtable getKitRegisty() { + private static Hashtable getKitRegisty() { Hashtable ht = (Hashtable)SwingUtilities.appContextGet(kitRegistryKey); if (ht == null) { ht = new Hashtable(3); @@ -1512,7 +1510,7 @@ public class JEditorPane extends JTextComponent { private EditorKit kit; private boolean isUserSetEditorKit; - private Hashtable pageProperties; + private Hashtable pageProperties; /** Should be kept in sync with javax.swing.text.html.FormView counterpart. */ final static String PostDataProperty = "javax.swing.JEditorPane.postdata"; @@ -1520,7 +1518,7 @@ public class JEditorPane extends JTextComponent { /** * Table of registered type handlers for this editor. */ - private Hashtable typeHandlers; + private Hashtable typeHandlers; /* * Private AppContext keys for this class's static variables. @@ -1913,11 +1911,11 @@ public class JEditorPane extends JTextComponent { } } - private class LinkVector extends Vector { + private class LinkVector extends Vector { public int baseElementIndex(Element e) { HTMLLink l; for (int i = 0; i < elementCount; i++) { - l = (HTMLLink) elementAt(i); + l = elementAt(i); if (l.element == e) { return i; } @@ -2029,7 +2027,7 @@ public class JEditorPane extends JTextComponent { buildLinkTable(); } if (linkIndex >= 0 && linkIndex < hyperlinks.size()) { - return (AccessibleHyperlink) hyperlinks.elementAt(linkIndex); + return hyperlinks.elementAt(linkIndex); } else { return null; } diff --git a/jdk/src/share/classes/javax/swing/JFileChooser.java b/jdk/src/share/classes/javax/swing/JFileChooser.java index 4a213df6273..82c85fe9faa 100644 --- a/jdk/src/share/classes/javax/swing/JFileChooser.java +++ b/jdk/src/share/classes/javax/swing/JFileChooser.java @@ -248,7 +248,7 @@ public class JFileChooser extends JComponent implements Accessible { private String approveButtonToolTipText = null; private int approveButtonMnemonic = 0; - private Vector filters = new Vector(5); + private Vector filters = new Vector(5); private JDialog dialog = null; private int dialogType = OPEN_DIALOG; private int returnValue = ERROR_OPTION; @@ -503,7 +503,7 @@ public class JFileChooser extends JComponent implements Accessible { if(selectedFiles == null) { return new File[0]; } else { - return (File[]) selectedFiles.clone(); + return selectedFiles.clone(); } } @@ -1415,17 +1415,17 @@ public class JFileChooser extends JComponent implements Accessible { fileFilter = filter; if (filter != null) { if (isMultiSelectionEnabled() && selectedFiles != null && selectedFiles.length > 0) { - Vector fList = new Vector(); + Vector fList = new Vector(); boolean failed = false; - for (int i = 0; i < selectedFiles.length; i++) { - if (filter.accept(selectedFiles[i])) { - fList.add(selectedFiles[i]); + for (File file : selectedFiles) { + if (filter.accept(file)) { + fList.add(file); } else { failed = true; } } if (failed) { - setSelectedFiles((fList.size() == 0) ? null : (File[])fList.toArray(new File[fList.size()])); + setSelectedFiles((fList.size() == 0) ? null : fList.toArray(new File[fList.size()])); } } else if (selectedFile != null && !filter.accept(selectedFile)) { setSelectedFile(null); @@ -1702,8 +1702,7 @@ public class JFileChooser extends JComponent implements Accessible { * @since 1.4 */ public ActionListener[] getActionListeners() { - return (ActionListener[])listenerList.getListeners( - ActionListener.class); + return listenerList.getListeners(ActionListener.class); } /** @@ -1744,7 +1743,7 @@ public class JFileChooser extends JComponent implements Accessible { WeakReference jfcRef; public WeakPCL(JFileChooser jfc) { - jfcRef = new WeakReference(jfc); + jfcRef = new WeakReference(jfc); } public void propertyChange(PropertyChangeEvent ev) { assert ev.getPropertyName().equals(SHOW_HIDDEN_PROP); diff --git a/jdk/src/share/classes/javax/swing/JInternalFrame.java b/jdk/src/share/classes/javax/swing/JInternalFrame.java index c3e3cad1c11..837ffe49e4f 100644 --- a/jdk/src/share/classes/javax/swing/JInternalFrame.java +++ b/jdk/src/share/classes/javax/swing/JInternalFrame.java @@ -421,8 +421,8 @@ public class JInternalFrame extends JComponent implements invalidate(); Component[] children = getComponents(); if (children != null) { - for(int i = 0; i < children.length; i++) { - SwingUtilities.updateComponentTreeUI(children[i]); + for (Component child : children) { + SwingUtilities.updateComponentTreeUI(child); } } } @@ -1535,8 +1535,7 @@ public class JInternalFrame extends JComponent implements * @see #addInternalFrameListener */ public InternalFrameListener[] getInternalFrameListeners() { - return (InternalFrameListener[])listenerList.getListeners( - InternalFrameListener.class); + return listenerList.getListeners(InternalFrameListener.class); } // remind: name ok? all one method ok? need to be synchronized? @@ -2258,8 +2257,8 @@ public class JInternalFrame extends JComponent implements invalidate(); Component[] children = getComponents(); if (children != null) { - for(int i = 0; i < children.length; i++) { - SwingUtilities.updateComponentTreeUI(children[i]); + for (Component child : children) { + SwingUtilities.updateComponentTreeUI(child); } } } diff --git a/jdk/src/share/classes/javax/swing/JLayeredPane.java b/jdk/src/share/classes/javax/swing/JLayeredPane.java index b3cedb2d37e..e971fe1d8ef 100644 --- a/jdk/src/share/classes/javax/swing/JLayeredPane.java +++ b/jdk/src/share/classes/javax/swing/JLayeredPane.java @@ -191,7 +191,7 @@ public class JLayeredPane extends JComponent implements Accessible { private void validateOptimizedDrawing() { boolean layeredComponentFound = false; synchronized(getTreeLock()) { - Integer layer = null; + Integer layer; for (Component c : getComponents()) { layer = null; @@ -213,7 +213,7 @@ public class JLayeredPane extends JComponent implements Accessible { } protected void addImpl(Component comp, Object constraints, int index) { - int layer = DEFAULT_LAYER.intValue(); + int layer; int pos; if(constraints instanceof Integer) { @@ -364,7 +364,7 @@ public class JLayeredPane extends JComponent implements Accessible { if(c instanceof JComponent) ((JComponent)c).putClientProperty(LAYER_PROPERTY, layerObj); else - getComponentToLayer().put((Component)c, layerObj); + getComponentToLayer().put(c, layerObj); if(c.getParent() == null || c.getParent() != this) { repaint(c.getBounds()); @@ -388,7 +388,7 @@ public class JLayeredPane extends JComponent implements Accessible { if(c instanceof JComponent) i = (Integer)((JComponent)c).getClientProperty(LAYER_PROPERTY); else - i = (Integer)getComponentToLayer().get((Component)c); + i = getComponentToLayer().get(c); if(i == null) return DEFAULT_LAYER.intValue(); @@ -465,9 +465,9 @@ public class JLayeredPane extends JComponent implements Accessible { * @see #getComponentCountInLayer */ public int getPosition(Component c) { - int i, count, startLayer, curLayer, startLocation, pos = 0; + int i, startLayer, curLayer, startLocation, pos = 0; - count = getComponentCount(); + getComponentCount(); startLocation = getIndexOf(c); if(startLocation == -1) diff --git a/jdk/src/share/classes/javax/swing/JList.java b/jdk/src/share/classes/javax/swing/JList.java index a83a4c94e4c..772c7554056 100644 --- a/jdk/src/share/classes/javax/swing/JList.java +++ b/jdk/src/share/classes/javax/swing/JList.java @@ -1848,8 +1848,7 @@ public class JList extends JComponent implements Scrollable, Accessible * @since 1.4 */ public ListSelectionListener[] getListSelectionListeners() { - return (ListSelectionListener[])listenerList.getListeners( - ListSelectionListener.class); + return listenerList.getListeners(ListSelectionListener.class); } @@ -2220,9 +2219,9 @@ public class JList extends JComponent implements Scrollable, Accessible ListSelectionModel sm = getSelectionModel(); sm.clearSelection(); int size = getModel().getSize(); - for(int i = 0; i < indices.length; i++) { - if (indices[i] < size) { - sm.addSelectionInterval(indices[i], indices[i]); + for (int i : indices) { + if (i < size) { + sm.addSelectionInterval(i, i); } } } @@ -2724,7 +2723,7 @@ public class JList extends JComponent implements Scrollable, Accessible return true; } if (getParent() instanceof JViewport) { - return (((JViewport)getParent()).getWidth() > getPreferredSize().width); + return (getParent().getWidth() > getPreferredSize().width); } return false; } @@ -2749,7 +2748,7 @@ public class JList extends JComponent implements Scrollable, Accessible return true; } if (getParent() instanceof JViewport) { - return (((JViewport)getParent()).getHeight() > getPreferredSize().height); + return (getParent().getHeight() > getPreferredSize().height); } return false; } @@ -3161,7 +3160,7 @@ public class JList extends JComponent implements Scrollable, Accessible private AccessibleContext getCurrentAccessibleContext() { Component c = getComponentAtIndex(indexInParent); if (c instanceof Accessible) { - return ((Accessible) c).getAccessibleContext(); + return c.getAccessibleContext(); } else { return null; } diff --git a/jdk/src/share/classes/javax/swing/JMenu.java b/jdk/src/share/classes/javax/swing/JMenu.java index ed90cb73eec..cf069116c21 100644 --- a/jdk/src/share/classes/javax/swing/JMenu.java +++ b/jdk/src/share/classes/javax/swing/JMenu.java @@ -371,8 +371,8 @@ public class JMenu extends JMenuItem implements Accessible,MenuElement * @since 1.3 */ protected Point getPopupMenuOrigin() { - int x = 0; - int y = 0; + int x; + int y; JPopupMenu pm = getPopupMenu(); // Figure out the sizes needed to caclulate the menu position Dimension s = getSize(); @@ -900,10 +900,8 @@ public class JMenu extends JMenuItem implements Accessible,MenuElement * on another menu */ public boolean isTopLevelMenu() { - if (getParent() instanceof JMenuBar) - return true; + return getParent() instanceof JMenuBar; - return false; } /** @@ -1015,7 +1013,7 @@ public class JMenu extends JMenuItem implements Accessible,MenuElement * @since 1.4 */ public MenuListener[] getMenuListeners() { - return (MenuListener[])listenerList.getListeners(MenuListener.class); + return listenerList.getListeners(MenuListener.class); } /** @@ -1305,7 +1303,7 @@ public class JMenu extends JMenuItem implements Accessible,MenuElement * @return the array of menu items */ private MenuElement[] buildMenuElementArray(JMenu leaf) { - Vector elements = new Vector(); + Vector elements = new Vector(); Component current = leaf.getPopupMenu(); JPopupMenu pop; JMenu menu; @@ -1409,8 +1407,8 @@ public class JMenu extends JMenuItem implements Accessible,MenuElement public int getAccessibleChildrenCount() { Component[] children = getMenuComponents(); int count = 0; - for (int j = 0; j < children.length; j++) { - if (children[j] instanceof Accessible) { + for (Component child : children) { + if (child instanceof Accessible) { count++; } } @@ -1426,18 +1424,18 @@ public class JMenu extends JMenuItem implements Accessible,MenuElement public Accessible getAccessibleChild(int i) { Component[] children = getMenuComponents(); int count = 0; - for (int j = 0; j < children.length; j++) { - if (children[j] instanceof Accessible) { + for (Component child : children) { + if (child instanceof Accessible) { if (count == i) { - if (children[j] instanceof JComponent) { + if (child instanceof JComponent) { // FIXME: [[[WDW - probably should set this when // the component is added to the menu. I tried // to do this in most cases, but the separators // added by addSeparator are hard to get to.]]] - AccessibleContext ac = ((Accessible) children[j]).getAccessibleContext(); + AccessibleContext ac = child.getAccessibleContext(); ac.setAccessibleParent(JMenu.this); } - return (Accessible) children[j]; + return (Accessible) child; } else { count++; } @@ -1581,7 +1579,7 @@ public class JMenu extends JMenuItem implements Accessible,MenuElement } JMenuItem mi = getItem(i); if (mi != null && mi instanceof JMenu) { - if (((JMenu) mi).isSelected()) { + if (mi.isSelected()) { MenuElement old[] = MenuSelectionManager.defaultManager().getSelectedPath(); MenuElement me[] = new MenuElement[old.length-2]; diff --git a/jdk/src/share/classes/javax/swing/JMenuBar.java b/jdk/src/share/classes/javax/swing/JMenuBar.java index d6f04fbb427..724eba6b8ff 100644 --- a/jdk/src/share/classes/javax/swing/JMenuBar.java +++ b/jdk/src/share/classes/javax/swing/JMenuBar.java @@ -414,7 +414,7 @@ public class JMenuBar extends JComponent implements Accessible,MenuElement */ public MenuElement[] getSubElements() { MenuElement result[]; - Vector tmp = new Vector(); + Vector tmp = new Vector(); int c = getComponentCount(); int i; Component m; @@ -422,12 +422,12 @@ public class JMenuBar extends JComponent implements Accessible,MenuElement for(i=0 ; i < c ; i++) { m = getComponent(i); if(m instanceof MenuElement) - tmp.addElement(m); + tmp.addElement((MenuElement) m); } result = new MenuElement[tmp.size()]; for(i=0,c=tmp.size() ; i < c ; i++) - result[i] = (MenuElement) tmp.elementAt(i); + result[i] = tmp.elementAt(i); return result; } @@ -664,9 +664,9 @@ public class JMenuBar extends JComponent implements Accessible,MenuElement boolean retValue = super.processKeyBinding(ks, e, condition, pressed); if (!retValue) { MenuElement[] subElements = getSubElements(); - for (int i=0; i values = new Vector(); s.defaultWriteObject(); // Save the icon, if its Serializable. @@ -2342,7 +2339,7 @@ public class JOptionPane extends JComponent implements Accessible } // Save the treeModel, if its Serializable. if(options != null) { - Vector serOptions = new Vector(); + Vector serOptions = new Vector(); for(int counter = 0, maxCounter = options.length; counter < maxCounter; counter++) @@ -2510,16 +2507,16 @@ public class JOptionPane extends JComponent implements Accessible /** * Retrieves a method from the provided class and makes it accessible. */ - private static class ModalPrivilegedAction implements PrivilegedAction { - private Class clazz; + private static class ModalPrivilegedAction implements PrivilegedAction { + private Class clazz; private String methodName; - public ModalPrivilegedAction(Class clazz, String methodName) { + public ModalPrivilegedAction(Class clazz, String methodName) { this.clazz = clazz; this.methodName = methodName; } - public Object run() { + public Method run() { Method method = null; try { method = clazz.getDeclaredMethod(methodName, (Class[])null); diff --git a/jdk/src/share/classes/javax/swing/JPopupMenu.java b/jdk/src/share/classes/javax/swing/JPopupMenu.java index 83aec9a17b3..8f90a02a2a9 100644 --- a/jdk/src/share/classes/javax/swing/JPopupMenu.java +++ b/jdk/src/share/classes/javax/swing/JPopupMenu.java @@ -584,7 +584,7 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { int nitems = getComponentCount(); // PENDING(ges): Why not use an array? - Vector tempItems = new Vector(); + Vector tempItems = new Vector(); /* Remove the item at index, nitems-index times storing them in a temporary vector in the @@ -600,8 +600,8 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { /* Add the removed items back to the menu, they are already in the correct order in the temp vector. */ - for (int i = 0; i < tempItems.size() ; i++) { - add((Component)tempItems.elementAt(i)); + for (Component tempItem : tempItems) { + add(tempItem); } } @@ -632,8 +632,7 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { * @since 1.4 */ public PopupMenuListener[] getPopupMenuListeners() { - return (PopupMenuListener[])listenerList.getListeners( - PopupMenuListener.class); + return listenerList.getListeners(PopupMenuListener.class); } /** @@ -665,8 +664,7 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { * @since 1.5 */ public MenuKeyListener[] getMenuKeyListeners() { - return (MenuKeyListener[])listenerList.getListeners( - MenuKeyListener.class); + return listenerList.getListeners(MenuKeyListener.class); } /** @@ -781,7 +779,7 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { // set selection path before popping up! if (isPopupMenu()) { MenuElement me[] = new MenuElement[1]; - me[0] = (MenuElement) this; + me[0] = this; MenuSelectionManager.defaultManager().setSelectedPath(me); } } @@ -848,10 +846,7 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { * being displayed). */ public boolean isVisible() { - if(popup != null) - return true; - else - return false; + return popup != null; } /** @@ -1311,7 +1306,7 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { // Serialization support. //////////// private void writeObject(ObjectOutputStream s) throws IOException { - Vector values = new Vector(); + Vector values = new Vector(); s.defaultWriteObject(); // Save the invoker, if its Serializable. @@ -1494,7 +1489,7 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { */ public MenuElement[] getSubElements() { MenuElement result[]; - Vector tmp = new Vector(); + Vector tmp = new Vector(); int c = getComponentCount(); int i; Component m; @@ -1502,12 +1497,12 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { for(i=0 ; i < c ; i++) { m = getComponent(i); if(m instanceof MenuElement) - tmp.addElement(m); + tmp.addElement((MenuElement) m); } result = new MenuElement[tmp.size()]; for(i=0,c=tmp.size() ; i < c ; i++) - result[i] = (MenuElement) tmp.elementAt(i); + result[i] = tmp.elementAt(i); return result; } diff --git a/jdk/src/share/classes/javax/swing/JProgressBar.java b/jdk/src/share/classes/javax/swing/JProgressBar.java index b1d27c8cd02..9ba25d96cea 100644 --- a/jdk/src/share/classes/javax/swing/JProgressBar.java +++ b/jdk/src/share/classes/javax/swing/JProgressBar.java @@ -699,8 +699,7 @@ public class JProgressBar extends JComponent implements SwingConstants, Accessib * @since 1.4 */ public ChangeListener[] getChangeListeners() { - return (ChangeListener[])listenerList.getListeners( - ChangeListener.class); + return listenerList.getListeners(ChangeListener.class); } /** diff --git a/jdk/src/share/classes/javax/swing/JScrollBar.java b/jdk/src/share/classes/javax/swing/JScrollBar.java index 5897fd6fad8..90e2cc7595f 100644 --- a/jdk/src/share/classes/javax/swing/JScrollBar.java +++ b/jdk/src/share/classes/javax/swing/JScrollBar.java @@ -659,8 +659,7 @@ public class JScrollBar extends JComponent implements Adjustable, Accessible * @since 1.4 */ public AdjustmentListener[] getAdjustmentListeners() { - return (AdjustmentListener[])listenerList.getListeners( - AdjustmentListener.class); + return listenerList.getListeners(AdjustmentListener.class); } @@ -754,8 +753,8 @@ public class JScrollBar extends JComponent implements Adjustable, Accessible public void setEnabled(boolean x) { super.setEnabled(x); Component[] children = getComponents(); - for(int i = 0; i < children.length; i++) { - children[i].setEnabled(x); + for (Component child : children) { + child.setEnabled(x); } } diff --git a/jdk/src/share/classes/javax/swing/JSlider.java b/jdk/src/share/classes/javax/swing/JSlider.java index ea2b510be1d..c014f170b35 100644 --- a/jdk/src/share/classes/javax/swing/JSlider.java +++ b/jdk/src/share/classes/javax/swing/JSlider.java @@ -270,8 +270,7 @@ public class JSlider extends JComponent implements SwingConstants, Accessible { { checkOrientation(orientation); this.orientation = orientation; - sliderModel = new DefaultBoundedRangeModel(value, 0, min, max); - sliderModel.addChangeListener(changeListener); + setModel(new DefaultBoundedRangeModel(value, 0, min, max)); updateUI(); } @@ -284,7 +283,6 @@ public class JSlider extends JComponent implements SwingConstants, Accessible { { this.orientation = JSlider.HORIZONTAL; setModel(brm); - sliderModel.addChangeListener(changeListener); updateUI(); } @@ -476,15 +474,15 @@ public class JSlider extends JComponent implements SwingConstants, Accessible { if (newModel != null) { newModel.addChangeListener(changeListener); + } - if (accessibleContext != null) { - accessibleContext.firePropertyChange( - AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, - (oldModel == null - ? null : Integer.valueOf(oldModel.getValue())), - (newModel == null - ? null : Integer.valueOf(newModel.getValue()))); - } + if (accessibleContext != null) { + accessibleContext.firePropertyChange( + AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, + (oldModel == null + ? null : Integer.valueOf(oldModel.getValue())), + (newModel == null + ? null : Integer.valueOf(newModel.getValue()))); } firePropertyChange("model", oldModel, sliderModel); @@ -930,7 +928,7 @@ public class JSlider extends JComponent implements SwingConstants, Accessible { throw new IllegalArgumentException( "Label incremement must be > 0" ); } - class SmartHashtable extends Hashtable implements PropertyChangeListener { + class SmartHashtable extends Hashtable implements PropertyChangeListener { int increment = 0; int start = 0; boolean startAtMin = false; @@ -977,9 +975,8 @@ public class JSlider extends JComponent implements SwingConstants, Accessible { if ( e.getPropertyName().equals( "minimum" ) || e.getPropertyName().equals( "maximum" ) ) { - Dictionary labelTable = getLabelTable(); - Enumeration keys = labelTable.keys(); - Hashtable hashtable = new Hashtable(); + Enumeration keys = getLabelTable().keys(); + Hashtable hashtable = new Hashtable(); // Save the labels that were added by the developer while ( keys.hasMoreElements() ) { diff --git a/jdk/src/share/classes/javax/swing/JSpinner.java b/jdk/src/share/classes/javax/swing/JSpinner.java index dd573e10457..c5cebda03f7 100644 --- a/jdk/src/share/classes/javax/swing/JSpinner.java +++ b/jdk/src/share/classes/javax/swing/JSpinner.java @@ -433,8 +433,7 @@ public class JSpinner extends JComponent implements Accessible * @since 1.4 */ public ChangeListener[] getChangeListeners() { - return (ChangeListener[])listenerList.getListeners( - ChangeListener.class); + return listenerList.getListeners(ChangeListener.class); } @@ -1536,7 +1535,7 @@ public class JSpinner extends JComponent implements Accessible return textField.getAccessibleContext(); } } else if (editor instanceof Accessible) { - return ((Accessible)editor).getAccessibleContext(); + return editor.getAccessibleContext(); } return null; } @@ -1693,7 +1692,7 @@ public class JSpinner extends JComponent implements Accessible if (i < 0 || i > 1) { return false; } - Object o = null; + Object o; if (i == 0) { o = getNextValue(); // AccessibleAction.INCREMENT } else { diff --git a/jdk/src/share/classes/javax/swing/JTabbedPane.java b/jdk/src/share/classes/javax/swing/JTabbedPane.java index 9bcafb1ab32..2c74189fd33 100644 --- a/jdk/src/share/classes/javax/swing/JTabbedPane.java +++ b/jdk/src/share/classes/javax/swing/JTabbedPane.java @@ -313,8 +313,7 @@ public class JTabbedPane extends JComponent * @since 1.4 */ public ChangeListener[] getChangeListeners() { - return (ChangeListener[])listenerList.getListeners( - ChangeListener.class); + return listenerList.getListeners(ChangeListener.class); } /** @@ -2062,7 +2061,7 @@ public class JTabbedPane extends JComponent * Accessibility classes unnecessarily. */ AccessibleContext ac; - ac = ((Accessible) component).getAccessibleContext(); + ac = component.getAccessibleContext(); if (ac != null) { ac.setAccessibleParent(this); } diff --git a/jdk/src/share/classes/javax/swing/JTable.java b/jdk/src/share/classes/javax/swing/JTable.java index 976cb813093..1b770d89153 100644 --- a/jdk/src/share/classes/javax/swing/JTable.java +++ b/jdk/src/share/classes/javax/swing/JTable.java @@ -1677,16 +1677,16 @@ public class JTable extends JComponent implements TableModelListener, Scrollable if (!forDrop && state != null) { clearSelection(); - int[] rows = (int[])((int[][])state)[0]; - int[] cols = (int[])((int[][])state)[1]; - int[] anchleads = (int[])((int[][])state)[2]; + int[] rows = ((int[][])state)[0]; + int[] cols = ((int[][])state)[1]; + int[] anchleads = ((int[][])state)[2]; - for (int i = 0; i < rows.length; i++) { - addRowSelectionInterval(rows[i], rows[i]); + for (int row : rows) { + addRowSelectionInterval(row, row); } - for (int i = 0; i < cols.length; i++) { - addColumnSelectionInterval(cols[i], cols[i]); + for (int col : cols) { + addColumnSelectionInterval(col, col); } SwingUtilities2.setLeadAnchorWithoutSelection( @@ -1776,7 +1776,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable boolean oldValue = this.autoCreateRowSorter; this.autoCreateRowSorter = autoCreateRowSorter; if (autoCreateRowSorter) { - setRowSorter(new TableRowSorter(getModel())); + setRowSorter(new TableRowSorter(getModel())); } firePropertyChange("autoCreateRowSorter", oldValue, autoCreateRowSorter); @@ -3198,7 +3198,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable private void accommodateDelta(int resizingColumnIndex, int delta) { int columnCount = getColumnCount(); int from = resizingColumnIndex; - int to = columnCount; + int to; // Use the mode to determine how to absorb the changes. switch(autoResizeMode) { @@ -3237,8 +3237,6 @@ public class JTable extends JComponent implements TableModelListener, Scrollable } adjustSizes(totalWidth + delta, r, false); - - return; } private interface Resizable2 { @@ -3492,7 +3490,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable * @see #editingRow */ public boolean isEditing() { - return (cellEditor == null)? false : true; + return cellEditor != null; } /** @@ -3642,7 +3640,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable firePropertyChange("model", old, dataModel); if (getAutoCreateRowSorter()) { - setRowSorter(new TableRowSorter(dataModel)); + setRowSorter(new TableRowSorter(dataModel)); } } } @@ -5160,7 +5158,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable public boolean getScrollableTracksViewportHeight() { return getFillsViewportHeight() && getParent() instanceof JViewport - && (((JViewport)getParent()).getHeight() > getPreferredSize().height); + && (getParent().getHeight() > getPreferredSize().height); } /** @@ -5214,7 +5212,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable // by setting the client property JTable.autoStartsEdit to Boolean.FALSE. if (!retValue && condition == WHEN_ANCESTOR_OF_FOCUSED_COMPONENT && isFocusOwner() && - !Boolean.FALSE.equals((Boolean)getClientProperty("JTable.autoStartsEdit"))) { + !Boolean.FALSE.equals(getClientProperty("JTable.autoStartsEdit"))) { // We do not have a binding for the event. Component editorComponent = getEditorComponent(); if (editorComponent == null) { @@ -5436,7 +5434,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable this.value = null; ((JComponent)getComponent()).setBorder(new LineBorder(Color.black)); try { - Class type = table.getColumnClass(column); + Class type = table.getColumnClass(column); // Since our obligation is to produce a value which is // assignable for the required type it is OK to use the // String constructor for columns which are declared @@ -6627,10 +6625,10 @@ public class JTable extends JComponent implements TableModelListener, Scrollable } else if (name.compareTo("tableCellEditor") == 0) { if (oldValue != null && oldValue instanceof TableCellEditor) { - ((TableCellEditor) oldValue).removeCellEditorListener((CellEditorListener) this); + ((TableCellEditor) oldValue).removeCellEditorListener(this); } if (newValue != null && newValue instanceof TableCellEditor) { - ((TableCellEditor) newValue).addCellEditorListener((CellEditorListener) this); + ((TableCellEditor) newValue).addCellEditorListener(this); } } } @@ -7045,7 +7043,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable */ public Accessible getAccessibleSelection(int i) { if (i < 0 || i > getAccessibleSelectionCount()) { - return (Accessible) null; + return null; } int rowsSel = JTable.this.getSelectedRowCount(); @@ -7158,7 +7156,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable return getAccessibleChild((r * ttlCols) + c); } } - return (Accessible) null; + return null; } /** @@ -7906,7 +7904,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable JTable.this, getValueAt(row, column), false, false, row, column); if (component instanceof Accessible) { - return ((Accessible) component).getAccessibleContext(); + return component.getAccessibleContext(); } else { return null; } diff --git a/jdk/src/share/classes/javax/swing/JTextField.java b/jdk/src/share/classes/javax/swing/JTextField.java index b6d3b47f285..56ca320a746 100644 --- a/jdk/src/share/classes/javax/swing/JTextField.java +++ b/jdk/src/share/classes/javax/swing/JTextField.java @@ -475,8 +475,7 @@ public class JTextField extends JTextComponent implements SwingConstants { * @since 1.4 */ public synchronized ActionListener[] getActionListeners() { - return (ActionListener[])listenerList.getListeners( - ActionListener.class); + return listenerList.getListeners(ActionListener.class); } /** diff --git a/jdk/src/share/classes/javax/swing/JTree.java b/jdk/src/share/classes/javax/swing/JTree.java index e6aa08c054e..012db5063dc 100644 --- a/jdk/src/share/classes/javax/swing/JTree.java +++ b/jdk/src/share/classes/javax/swing/JTree.java @@ -187,7 +187,7 @@ public class JTree extends JComponent implements Scrollable, Accessible * information must be determined by visiting all the parent * paths and seeing if they are visible. */ - transient private Hashtable expandedState; + transient private Hashtable expandedState; /** @@ -281,7 +281,7 @@ public class JTree extends JComponent implements Scrollable, Accessible * Used when setExpandedState is invoked, * will be a Stack of Stacks. */ - transient private Stack expandedStack; + transient private Stack> expandedStack; /** * Lead selection path, may not be null. @@ -652,9 +652,9 @@ public class JTree extends JComponent implements Scrollable, Accessible @ConstructorProperties({"model"}) public JTree(TreeModel newModel) { super(); - expandedStack = new Stack(); + expandedStack = new Stack>(); toggleClickCount = 2; - expandedState = new Hashtable(); + expandedState = new Hashtable(); setLayout(null); rowHeight = 16; visibleRowCount = 20; @@ -691,7 +691,7 @@ public class JTree extends JComponent implements Scrollable, Accessible * description: The UI object that implements the Component's LookAndFeel. */ public void setUI(TreeUI ui) { - if ((TreeUI)this.ui != ui) { + if (this.ui != ui) { settingUI = true; uiTreeExpansionListener = null; try { @@ -1298,8 +1298,8 @@ public class JTree extends JComponent implements Scrollable, Accessible Object root = (model == null) ? null : model.getRoot(); TreePath rootPath = (root == null) ? null : new TreePath(root); - TreePath child = null; - TreePath parent = null; + TreePath child; + TreePath parent; boolean outside = row == -1 || p.y < bounds.y || p.y >= bounds.y + bounds.height; @@ -1940,14 +1940,14 @@ public class JTree extends JComponent implements Scrollable, Accessible if(!isExpanded(parent)) return null; - Enumeration toggledPaths = expandedState.keys(); - Vector elements = null; + Enumeration toggledPaths = expandedState.keys(); + Vector elements = null; TreePath path; Object value; if(toggledPaths != null) { while(toggledPaths.hasMoreElements()) { - path = (TreePath)toggledPaths.nextElement(); + path = toggledPaths.nextElement(); value = expandedState.get(path); // Add the path if it is expanded, a descendant of parent, // and it is visible (all parents expanded). This is rather @@ -1956,7 +1956,7 @@ public class JTree extends JComponent implements Scrollable, Accessible ((Boolean)value).booleanValue() && parent.isDescendant(path) && isVisible(path)) { if (elements == null) { - elements = new Vector(); + elements = new Vector(); } elements.addElement(path); } @@ -1990,9 +1990,9 @@ public class JTree extends JComponent implements Scrollable, Accessible return false; // Is this node expanded? - Object value = expandedState.get(path); + Boolean value = expandedState.get(path); - if(value == null || !((Boolean)value).booleanValue()) + if(value == null || !value.booleanValue()) return false; // It is, make sure its parent is also expanded. @@ -2018,7 +2018,7 @@ public class JTree extends JComponent implements Scrollable, Accessible TreePath path = tree.getPathForRow(this, row); if(path != null) { - Boolean value = (Boolean)expandedState.get(path); + Boolean value = expandedState.get(path); return (value != null && value.booleanValue()); } @@ -2704,8 +2704,7 @@ public class JTree extends JComponent implements Scrollable, Accessible * @since 1.4 */ public TreeExpansionListener[] getTreeExpansionListeners() { - return (TreeExpansionListener[])listenerList.getListeners( - TreeExpansionListener.class); + return listenerList.getListeners(TreeExpansionListener.class); } /** @@ -2737,8 +2736,7 @@ public class JTree extends JComponent implements Scrollable, Accessible * @since 1.4 */ public TreeWillExpandListener[] getTreeWillExpandListeners() { - return (TreeWillExpandListener[])listenerList.getListeners( - TreeWillExpandListener.class); + return listenerList.getListeners(TreeWillExpandListener.class); } /** @@ -2895,8 +2893,7 @@ public class JTree extends JComponent implements Scrollable, Accessible * @since 1.4 */ public TreeSelectionListener[] getTreeSelectionListeners() { - return (TreeSelectionListener[])listenerList.getListeners( - TreeSelectionListener.class); + return listenerList.getListeners(TreeSelectionListener.class); } /** @@ -3030,7 +3027,7 @@ public class JTree extends JComponent implements Scrollable, Accessible // Serialization support. private void writeObject(ObjectOutputStream s) throws IOException { - Vector values = new Vector(); + Vector values = new Vector(); s.defaultWriteObject(); // Save the cellRenderer, if its Serializable. @@ -3077,9 +3074,9 @@ public class JTree extends JComponent implements Scrollable, Accessible // Create an instance of expanded state. - expandedState = new Hashtable(); + expandedState = new Hashtable(); - expandedStack = new Stack(); + expandedStack = new Stack>(); Vector values = (Vector)s.readObject(); int indexCounter = 0; @@ -3132,13 +3129,13 @@ public class JTree extends JComponent implements Scrollable, Accessible TreeModel model = getModel(); if(model != null) { - Enumeration paths = expandedState.keys(); + Enumeration paths = expandedState.keys(); if(paths != null) { - Vector state = new Vector(); + Vector state = new Vector(); while(paths.hasMoreElements()) { - TreePath path = (TreePath)paths.nextElement(); + TreePath path = paths.nextElement(); Object archivePath; try { @@ -3502,7 +3499,7 @@ public class JTree extends JComponent implements Scrollable, Accessible */ public boolean getScrollableTracksViewportWidth() { if (getParent() instanceof JViewport) { - return (((JViewport)getParent()).getWidth() > getPreferredSize().width); + return getParent().getWidth() > getPreferredSize().width; } return false; } @@ -3518,7 +3515,7 @@ public class JTree extends JComponent implements Scrollable, Accessible */ public boolean getScrollableTracksViewportHeight() { if (getParent() instanceof JViewport) { - return (((JViewport)getParent()).getHeight() > getPreferredSize().height); + return getParent().getHeight() > getPreferredSize().height; } return false; } @@ -3535,14 +3532,14 @@ public class JTree extends JComponent implements Scrollable, Accessible protected void setExpandedState(TreePath path, boolean state) { if(path != null) { // Make sure all parents of path are expanded. - Stack stack; - TreePath parentPath = path.getParentPath(); + Stack stack; + TreePath parentPath = path.getParentPath(); if (expandedStack.size() == 0) { - stack = new Stack(); + stack = new Stack(); } else { - stack = (Stack)expandedStack.pop(); + stack = expandedStack.pop(); } try { @@ -3556,7 +3553,7 @@ public class JTree extends JComponent implements Scrollable, Accessible } } for(int counter = stack.size() - 1; counter >= 0; counter--) { - parentPath = (TreePath)stack.pop(); + parentPath = stack.pop(); if(!isExpanded(parentPath)) { try { fireTreeWillExpand(parentPath); @@ -3636,12 +3633,11 @@ public class JTree extends JComponent implements Scrollable, Accessible if(parent == null) return null; - Vector descendants = new Vector(); - Enumeration nodes = expandedState.keys(); - TreePath path; + Vector descendants = new Vector(); + Enumeration nodes = expandedState.keys(); while(nodes.hasMoreElements()) { - path = (TreePath)nodes.nextElement(); + TreePath path = nodes.nextElement(); if(parent.isDescendant(path)) descendants.addElement(path); } @@ -3664,8 +3660,8 @@ public class JTree extends JComponent implements Scrollable, Accessible { if(toRemove != null) { while(toRemove.hasMoreElements()) { - Enumeration descendants = getDescendantToggledPaths - ((TreePath)toRemove.nextElement()); + Enumeration descendants = getDescendantToggledPaths + (toRemove.nextElement()); if(descendants != null) { while(descendants.hasMoreElements()) { @@ -4250,7 +4246,7 @@ public class JTree extends JComponent implements Scrollable, Accessible private AccessibleContext getCurrentAccessibleContext() { Component c = getCurrentComponent(); if (c instanceof Accessible) { - return (((Accessible) c).getAccessibleContext()); + return c.getAccessibleContext(); } else { return null; } @@ -4573,7 +4569,7 @@ public class JTree extends JComponent implements Scrollable, Accessible private AccessibleContext getCurrentAccessibleContext() { Component c = getCurrentComponent(); if (c instanceof Accessible) { - return (((Accessible) c).getAccessibleContext()); + return c.getAccessibleContext(); } else { return null; } @@ -5117,12 +5113,8 @@ public class JTree extends JComponent implements Scrollable, Accessible public boolean isVisible() { Rectangle pathBounds = tree.getPathBounds(path); Rectangle parentBounds = tree.getVisibleRect(); - if (pathBounds != null && parentBounds != null && - parentBounds.intersects(pathBounds)) { - return true; - } else { - return false; - } + return pathBounds != null && parentBounds != null && + parentBounds.intersects(pathBounds); } public void setVisible(boolean b) { diff --git a/jdk/src/share/classes/javax/swing/JViewport.java b/jdk/src/share/classes/javax/swing/JViewport.java index f5a16bbd2c6..734e80a0557 100644 --- a/jdk/src/share/classes/javax/swing/JViewport.java +++ b/jdk/src/share/classes/javax/swing/JViewport.java @@ -389,7 +389,7 @@ public class JViewport extends JComponent implements Accessible // could be bigger than invalid size. validateView(); } - int dx = 0, dy = 0; + int dx, dy; dx = positionAdjustment(getWidth(), contentRect.width, contentRect.x); dy = positionAdjustment(getHeight(), contentRect.height, contentRect.y); @@ -682,10 +682,7 @@ public class JViewport extends JComponent implements Accessible * @see JComponent#isPaintingOrigin() */ boolean isPaintingOrigin() { - if (scrollMode == BACKINGSTORE_SCROLL_MODE) { - return true; - } - return false; + return scrollMode == BACKINGSTORE_SCROLL_MODE; } @@ -903,11 +900,7 @@ public class JViewport extends JComponent implements Accessible */ public void setScrollMode(int mode) { scrollMode = mode; - if (mode == BACKINGSTORE_SCROLL_MODE) { - backingStore = true; - } else { - backingStore = false; - } + backingStore = mode == BACKINGSTORE_SCROLL_MODE; } /** @@ -958,10 +951,10 @@ public class JViewport extends JComponent implements Accessible } } - private final boolean isBlitting() { + private boolean isBlitting() { Component view = getView(); return (scrollMode == BLIT_SCROLL_MODE) && - (view instanceof JComponent) && ((JComponent)view).isOpaque(); + (view instanceof JComponent) && view.isOpaque(); } @@ -1380,8 +1373,7 @@ public class JViewport extends JComponent implements Accessible * @since 1.4 */ public ChangeListener[] getChangeListeners() { - return (ChangeListener[])listenerList.getListeners( - ChangeListener.class); + return listenerList.getListeners(ChangeListener.class); } /** diff --git a/jdk/src/share/classes/javax/swing/JWindow.java b/jdk/src/share/classes/javax/swing/JWindow.java index c94803c4c4d..d805838b0e0 100644 --- a/jdk/src/share/classes/javax/swing/JWindow.java +++ b/jdk/src/share/classes/javax/swing/JWindow.java @@ -185,7 +185,7 @@ public class JWindow extends Window implements Accessible, super(owner == null? SwingUtilities.getSharedOwnerFrame() : owner); if (owner == null) { WindowListener ownerShutdownListener = - (WindowListener)SwingUtilities.getSharedOwnerFrameShutdownListener(); + SwingUtilities.getSharedOwnerFrameShutdownListener(); addWindowListener(ownerShutdownListener); } windowInit(); @@ -212,7 +212,7 @@ public class JWindow extends Window implements Accessible, owner); if (owner == null) { WindowListener ownerShutdownListener = - (WindowListener)SwingUtilities.getSharedOwnerFrameShutdownListener(); + SwingUtilities.getSharedOwnerFrameShutdownListener(); addWindowListener(ownerShutdownListener); } windowInit(); @@ -250,7 +250,7 @@ public class JWindow extends Window implements Accessible, owner, gc); if (owner == null) { WindowListener ownerShutdownListener = - (WindowListener)SwingUtilities.getSharedOwnerFrameShutdownListener(); + SwingUtilities.getSharedOwnerFrameShutdownListener(); addWindowListener(ownerShutdownListener); } windowInit(); diff --git a/jdk/src/share/classes/javax/swing/KeyboardManager.java b/jdk/src/share/classes/javax/swing/KeyboardManager.java index e27a72f3d32..d5ed58ba003 100644 --- a/jdk/src/share/classes/javax/swing/KeyboardManager.java +++ b/jdk/src/share/classes/javax/swing/KeyboardManager.java @@ -68,13 +68,13 @@ class KeyboardManager { /** * maps top-level containers to a sub-hashtable full of keystrokes */ - Hashtable containerMap = new Hashtable(); + Hashtable containerMap = new Hashtable(); /** * Maps component/keystroke pairs to a topLevel container * This is mainly used for fast unregister operations */ - Hashtable componentKeyStrokeMap = new Hashtable(); + Hashtable componentKeyStrokeMap = new Hashtable(); public static KeyboardManager getCurrentManager() { return currentManager; @@ -95,7 +95,7 @@ class KeyboardManager { if (topContainer == null) { return; } - Hashtable keyMap = (Hashtable)containerMap.get(topContainer); + Hashtable keyMap = containerMap.get(topContainer); if (keyMap == null) { // lazy evaluate one keyMap = registerNewTopContainer(topContainer); @@ -114,8 +114,8 @@ class KeyboardManager { // Then add the old compoennt and the new compoent to the vector // then insert the vector in the table if (tmp != c) { // this means this is already registered for this component, no need to dup - Vector v = new Vector(); - v.addElement(tmp); + Vector v = new Vector(); + v.addElement((JComponent) tmp); v.addElement(c); keyMap.put(k, v); } @@ -154,13 +154,13 @@ class KeyboardManager { ComponentKeyStrokePair ckp = new ComponentKeyStrokePair(c,ks); - Object topContainer = componentKeyStrokeMap.get(ckp); + Container topContainer = componentKeyStrokeMap.get(ckp); if (topContainer == null) { // never heard of this pairing, so bail return; } - Hashtable keyMap = (Hashtable)containerMap.get(topContainer); + Hashtable keyMap = containerMap.get(topContainer); if (keyMap == null) { // this should never happen, but I'm being safe Thread.dumpStack(); return; @@ -221,7 +221,7 @@ class KeyboardManager { ks=KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers(), !pressed); } - Hashtable keyMap = (Hashtable)containerMap.get(topAncestor); + Hashtable keyMap = containerMap.get(topAncestor); if (keyMap != null) { // this container isn't registered, so bail Object tmp = keyMap.get(ks); @@ -293,7 +293,7 @@ class KeyboardManager { if (top == null) { return; } - Hashtable keyMap = (Hashtable)containerMap.get(top); + Hashtable keyMap = containerMap.get(top); if (keyMap == null) { // lazy evaluate one keyMap = registerNewTopContainer(top); @@ -314,11 +314,11 @@ class KeyboardManager { public void unregisterMenuBar(JMenuBar mb) { - Object topContainer = getTopAncestor(mb); + Container topContainer = getTopAncestor(mb); if (topContainer == null) { return; } - Hashtable keyMap = (Hashtable)containerMap.get(topContainer); + Hashtable keyMap = containerMap.get(topContainer); if (keyMap!=null) { Vector v = (Vector)keyMap.get(JMenuBar.class); if (v != null) { diff --git a/jdk/src/share/classes/javax/swing/LayoutComparator.java b/jdk/src/share/classes/javax/swing/LayoutComparator.java index 42d85c70cb5..01ba6e54df0 100644 --- a/jdk/src/share/classes/javax/swing/LayoutComparator.java +++ b/jdk/src/share/classes/javax/swing/LayoutComparator.java @@ -39,7 +39,7 @@ import java.awt.Window; * * @author David Mendenhall */ -final class LayoutComparator implements Comparator, java.io.Serializable { +final class LayoutComparator implements Comparator, java.io.Serializable { private static final int ROW_TOLERANCE = 10; @@ -51,10 +51,7 @@ final class LayoutComparator implements Comparator, java.io.Serializable { leftToRight = orientation.isLeftToRight(); } - public int compare(Object o1, Object o2) { - Component a = (Component)o1; - Component b = (Component)o2; - + public int compare(Component a, Component b) { if (a == b) { return 0; } @@ -65,9 +62,9 @@ final class LayoutComparator implements Comparator, java.io.Serializable { // each Component and then search from the Window down until the // hierarchy branches. if (a.getParent() != b.getParent()) { - LinkedList aAncestory, bAncestory; + LinkedList aAncestory = new LinkedList(); - for(aAncestory = new LinkedList(); a != null; a = a.getParent()) { + for(; a != null; a = a.getParent()) { aAncestory.add(a); if (a instanceof Window) { break; @@ -78,7 +75,9 @@ final class LayoutComparator implements Comparator, java.io.Serializable { throw new ClassCastException(); } - for(bAncestory = new LinkedList(); b != null; b = b.getParent()) { + LinkedList bAncestory = new LinkedList(); + + for(; b != null; b = b.getParent()) { bAncestory.add(b); if (b instanceof Window) { break; @@ -89,18 +88,18 @@ final class LayoutComparator implements Comparator, java.io.Serializable { throw new ClassCastException(); } - for (ListIterator + for (ListIterator aIter = aAncestory.listIterator(aAncestory.size()), bIter = bAncestory.listIterator(bAncestory.size()); ;) { if (aIter.hasPrevious()) { - a = (Component)aIter.previous(); + a = aIter.previous(); } else { // a is an ancestor of b return -1; } if (bIter.hasPrevious()) { - b = (Component)bIter.previous(); + b = bIter.previous(); } else { // b is an ancestor of a return 1; diff --git a/jdk/src/share/classes/javax/swing/LayoutFocusTraversalPolicy.java b/jdk/src/share/classes/javax/swing/LayoutFocusTraversalPolicy.java index 7e200e02eaf..33d81a91a48 100644 --- a/jdk/src/share/classes/javax/swing/LayoutFocusTraversalPolicy.java +++ b/jdk/src/share/classes/javax/swing/LayoutFocusTraversalPolicy.java @@ -65,7 +65,7 @@ public class LayoutFocusTraversalPolicy extends SortingFocusTraversalPolicy * Constructs a LayoutFocusTraversalPolicy with the passed in * Comparator. */ - LayoutFocusTraversalPolicy(Comparator c) { + LayoutFocusTraversalPolicy(Comparator c) { super(c); } diff --git a/jdk/src/share/classes/javax/swing/LegacyGlueFocusTraversalPolicy.java b/jdk/src/share/classes/javax/swing/LegacyGlueFocusTraversalPolicy.java index f8a37fe7a2b..fe73a08957f 100644 --- a/jdk/src/share/classes/javax/swing/LegacyGlueFocusTraversalPolicy.java +++ b/jdk/src/share/classes/javax/swing/LegacyGlueFocusTraversalPolicy.java @@ -48,8 +48,8 @@ final class LegacyGlueFocusTraversalPolicy extends FocusTraversalPolicy private transient FocusTraversalPolicy delegatePolicy; private transient DefaultFocusManager delegateManager; - private HashMap forwardMap = new HashMap(), - backwardMap = new HashMap(); + private HashMap forwardMap = new HashMap(), + backwardMap = new HashMap(); LegacyGlueFocusTraversalPolicy(FocusTraversalPolicy delegatePolicy) { this.delegatePolicy = delegatePolicy; @@ -70,11 +70,11 @@ final class LegacyGlueFocusTraversalPolicy extends FocusTraversalPolicy public Component getComponentAfter(Container focusCycleRoot, Component aComponent) { Component hardCoded = aComponent, prevHardCoded; - HashSet sanity = new HashSet(); + HashSet sanity = new HashSet(); do { prevHardCoded = hardCoded; - hardCoded = (Component)forwardMap.get(hardCoded); + hardCoded = forwardMap.get(hardCoded); if (hardCoded == null) { if (delegatePolicy != null && prevHardCoded.isFocusCycleRoot(focusCycleRoot)) { @@ -99,11 +99,11 @@ final class LegacyGlueFocusTraversalPolicy extends FocusTraversalPolicy public Component getComponentBefore(Container focusCycleRoot, Component aComponent) { Component hardCoded = aComponent, prevHardCoded; - HashSet sanity = new HashSet(); + HashSet sanity = new HashSet(); do { prevHardCoded = hardCoded; - hardCoded = (Component)backwardMap.get(hardCoded); + hardCoded = backwardMap.get(hardCoded); if (hardCoded == null) { if (delegatePolicy != null && prevHardCoded.isFocusCycleRoot(focusCycleRoot)) { diff --git a/jdk/src/share/classes/javax/swing/MenuSelectionManager.java b/jdk/src/share/classes/javax/swing/MenuSelectionManager.java index 8e1f36a3aa0..e1234c69aa6 100644 --- a/jdk/src/share/classes/javax/swing/MenuSelectionManager.java +++ b/jdk/src/share/classes/javax/swing/MenuSelectionManager.java @@ -37,7 +37,7 @@ import sun.awt.AppContext; * @author Arnaud Weber */ public class MenuSelectionManager { - private Vector selection = new Vector(); + private Vector selection = new Vector(); /* diagnostic aids -- should be false for production builds. */ private static final boolean TRACE = false; // trace creates and disposes @@ -100,14 +100,14 @@ public class MenuSelectionManager { } for(i=0,c=path.length;i= firstDifference ; i--) { - MenuElement me = (MenuElement)selection.elementAt(i); + MenuElement me = selection.elementAt(i); selection.removeElementAt(i); me.menuSelectionChanged(false); } @@ -131,7 +131,7 @@ public class MenuSelectionManager { MenuElement res[] = new MenuElement[selection.size()]; int i,c; for(i=0,c=selection.size();i 0) { - MenuElement me = (MenuElement)selection.elementAt(0); + MenuElement me = selection.elementAt(0); return isComponentPartOfCurrentMenu(me,c); } else return false; diff --git a/jdk/src/share/classes/javax/swing/MultiUIDefaults.java b/jdk/src/share/classes/javax/swing/MultiUIDefaults.java index 30867e22804..d7d435ef15f 100644 --- a/jdk/src/share/classes/javax/swing/MultiUIDefaults.java +++ b/jdk/src/share/classes/javax/swing/MultiUIDefaults.java @@ -56,8 +56,7 @@ class MultiUIDefaults extends UIDefaults return value; } - for(int i = 0; i < tables.length; i++) { - UIDefaults table = tables[i]; + for (UIDefaults table : tables) { value = (table != null) ? table.get(key) : null; if (value != null) { return value; @@ -75,8 +74,7 @@ class MultiUIDefaults extends UIDefaults return value; } - for(int i = 0; i < tables.length; i++) { - UIDefaults table = tables[i]; + for (UIDefaults table : tables) { value = (table != null) ? table.get(key,l) : null; if (value != null) { return value; @@ -89,8 +87,7 @@ class MultiUIDefaults extends UIDefaults public int size() { int n = super.size(); - for(int i = 0; i < tables.length; i++) { - UIDefaults table = tables[i]; + for (UIDefaults table : tables) { n += (table != null) ? table.size() : 0; } return n; @@ -102,7 +99,7 @@ class MultiUIDefaults extends UIDefaults } - public Enumeration keys() + public Enumeration keys() { Enumeration[] enums = new Enumeration[1 + tables.length]; enums[0] = super.keys(); @@ -116,7 +113,7 @@ class MultiUIDefaults extends UIDefaults } - public Enumeration elements() + public Enumeration elements() { Enumeration[] enums = new Enumeration[1 + tables.length]; enums[0] = super.elements(); @@ -137,7 +134,7 @@ class MultiUIDefaults extends UIDefaults } } - private static class MultiUIDefaultsEnumerator implements Enumeration + private static class MultiUIDefaultsEnumerator implements Enumeration { Enumeration[] enums; int n = 0; @@ -175,8 +172,7 @@ class MultiUIDefaults extends UIDefaults return value; } - for(int i = 0; i < tables.length; i++) { - UIDefaults table = tables[i]; + for (UIDefaults table : tables) { value = (table != null) ? table.remove(key) : null; if (value != null) { return value; @@ -189,8 +185,7 @@ class MultiUIDefaults extends UIDefaults public void clear() { super.clear(); - for(int i = 0; i < tables.length; i++) { - UIDefaults table = tables[i]; + for (UIDefaults table : tables) { if (table != null) { table.clear(); } diff --git a/jdk/src/share/classes/javax/swing/PopupFactory.java b/jdk/src/share/classes/javax/swing/PopupFactory.java index f9c3c0dd5d7..753959cea1f 100644 --- a/jdk/src/share/classes/javax/swing/PopupFactory.java +++ b/jdk/src/share/classes/javax/swing/PopupFactory.java @@ -313,9 +313,9 @@ public class PopupFactory { if(contents instanceof JPopupMenu) { JPopupMenu jpm = (JPopupMenu) contents; Component popComps[] = jpm.getComponents(); - for(int i=0;i cache; + Map> heavyPopupCache = getHeavyWeightPopupCache(); if (heavyPopupCache.containsKey(w)) { - cache = (List)heavyPopupCache.get(w); + cache = heavyPopupCache.get(w); } else { return null; } - int c; - if ((c = cache.size()) > 0) { - HeavyWeightPopup r = (HeavyWeightPopup)cache.get(0); + if (cache.size() > 0) { + HeavyWeightPopup r = cache.get(0); cache.remove(0); return r; } @@ -380,13 +379,13 @@ public class PopupFactory { * Window to a List of * HeavyWeightPopups. */ - private static Map getHeavyWeightPopupCache() { + private static Map> getHeavyWeightPopupCache() { synchronized (HeavyWeightPopup.class) { - Map cache = (Map)SwingUtilities.appContextGet( + Map> cache = (Map>)SwingUtilities.appContextGet( heavyWeightPopupCacheKey); if (cache == null) { - cache = new HashMap(2); + cache = new HashMap>(2); SwingUtilities.appContextPut(heavyWeightPopupCacheKey, cache); } @@ -399,13 +398,13 @@ public class PopupFactory { */ private static void recycleHeavyWeightPopup(HeavyWeightPopup popup) { synchronized (HeavyWeightPopup.class) { - List cache; - Object window = SwingUtilities.getWindowAncestor( + List cache; + Window window = SwingUtilities.getWindowAncestor( popup.getComponent()); - Map heavyPopupCache = getHeavyWeightPopupCache(); + Map> heavyPopupCache = getHeavyWeightPopupCache(); if (window instanceof Popup.DefaultFrame || - !((Window)window).isVisible()) { + !window.isVisible()) { // If the Window isn't visible, we don't cache it as we // likely won't ever get a windowClosed event to clean up. // We also don't cache DefaultFrames as this indicates @@ -414,28 +413,27 @@ public class PopupFactory { popup._dispose(); return; } else if (heavyPopupCache.containsKey(window)) { - cache = (List)heavyPopupCache.get(window); + cache = heavyPopupCache.get(window); } else { - cache = new ArrayList(); + cache = new ArrayList(); heavyPopupCache.put(window, cache); // Clean up if the Window is closed - final Window w = (Window)window; + final Window w = window; w.addWindowListener(new WindowAdapter() { public void windowClosed(WindowEvent e) { - List popups; + List popups; synchronized(HeavyWeightPopup.class) { - Map heavyPopupCache2 = + Map> heavyPopupCache2 = getHeavyWeightPopupCache(); - popups = (List)heavyPopupCache2.remove(w); + popups = heavyPopupCache2.remove(w); } if (popups != null) { for (int counter = popups.size() - 1; counter >= 0; counter--) { - ((HeavyWeightPopup)popups.get(counter)). - _dispose(); + popups.get(counter)._dispose(); } } } @@ -534,10 +532,9 @@ public class PopupFactory { Window[] ownedWindows = w.getOwnedWindows(); if(ownedWindows != null) { Rectangle bnd = component.getBounds(); - for(int i=0; i getLightWeightPopupCache() { + List cache = (List)SwingUtilities.appContextGet( lightWeightPopupCacheKey); if (cache == null) { - cache = new ArrayList(); + cache = new ArrayList(); SwingUtilities.appContextPut(lightWeightPopupCacheKey, cache); } return cache; @@ -682,7 +679,7 @@ public class PopupFactory { */ private static void recycleLightWeightPopup(LightWeightPopup popup) { synchronized (LightWeightPopup.class) { - List lightPopupCache = getLightWeightPopupCache(); + List lightPopupCache = getLightWeightPopupCache(); if (lightPopupCache.size() < MAX_CACHE_SIZE) { lightPopupCache.add(popup); } @@ -695,11 +692,9 @@ public class PopupFactory { */ private static LightWeightPopup getRecycledLightWeightPopup() { synchronized (LightWeightPopup.class) { - List lightPopupCache = getLightWeightPopupCache(); - int c; - if((c = lightPopupCache.size()) > 0) { - LightWeightPopup r = (LightWeightPopup)lightPopupCache. - get(0); + List lightPopupCache = getLightWeightPopupCache(); + if (lightPopupCache.size() > 0) { + LightWeightPopup r = lightPopupCache.get(0); lightPopupCache.remove(0); return r; } @@ -755,8 +750,7 @@ public class PopupFactory { component.setLocation(p.x, p.y); if (parent instanceof JLayeredPane) { - ((JLayeredPane)parent).add(component, - JLayeredPane.POPUP_LAYER, 0); + parent.add(component, JLayeredPane.POPUP_LAYER, 0); } else { parent.add(component); } @@ -826,12 +820,12 @@ public class PopupFactory { /** * Returns the cache to use for medium weight popups. */ - private static List getMediumWeightPopupCache() { - List cache = (List)SwingUtilities.appContextGet( + private static List getMediumWeightPopupCache() { + List cache = (List)SwingUtilities.appContextGet( mediumWeightPopupCacheKey); if (cache == null) { - cache = new ArrayList(); + cache = new ArrayList(); SwingUtilities.appContextPut(mediumWeightPopupCacheKey, cache); } return cache; @@ -842,7 +836,7 @@ public class PopupFactory { */ private static void recycleMediumWeightPopup(MediumWeightPopup popup) { synchronized (MediumWeightPopup.class) { - List mediumPopupCache = getMediumWeightPopupCache(); + List mediumPopupCache = getMediumWeightPopupCache(); if (mediumPopupCache.size() < MAX_CACHE_SIZE) { mediumPopupCache.add(popup); } @@ -855,12 +849,9 @@ public class PopupFactory { */ private static MediumWeightPopup getRecycledMediumWeightPopup() { synchronized (MediumWeightPopup.class) { - java.util.List mediumPopupCache = - getMediumWeightPopupCache(); - int c; - if ((c=mediumPopupCache.size()) > 0) { - MediumWeightPopup r = (MediumWeightPopup)mediumPopupCache. - get(0); + List mediumPopupCache = getMediumWeightPopupCache(); + if (mediumPopupCache.size() > 0) { + MediumWeightPopup r = mediumPopupCache.get(0); mediumPopupCache.remove(0); return r; } @@ -904,7 +895,7 @@ public class PopupFactory { x, y); component.setVisible(false); component.setLocation(p.x, p.y); - ((JLayeredPane)parent).add(component, JLayeredPane.POPUP_LAYER, + parent.add(component, JLayeredPane.POPUP_LAYER, 0); } else { Point p = SwingUtilities.convertScreenLocationToParent(parent, diff --git a/jdk/src/share/classes/javax/swing/RepaintManager.java b/jdk/src/share/classes/javax/swing/RepaintManager.java index 91034dbf8f2..b0e6c048f62 100644 --- a/jdk/src/share/classes/javax/swing/RepaintManager.java +++ b/jdk/src/share/classes/javax/swing/RepaintManager.java @@ -40,6 +40,8 @@ import sun.awt.SunToolkit; import sun.java2d.SunGraphicsEnvironment; import sun.security.action.GetPropertyAction; +import com.sun.java.swing.SwingUtilities3; + /** * This class manages repaint requests, allowing the number @@ -303,6 +305,11 @@ public class RepaintManager */ public synchronized void addInvalidComponent(JComponent invalidComponent) { + RepaintManager delegate = getDelegate(invalidComponent); + if (delegate != null) { + delegate.addInvalidComponent(invalidComponent); + return; + } Component validateRoot = null; /* Find the first JComponent ancestor of this component whose @@ -373,6 +380,11 @@ public class RepaintManager * @see #addInvalidComponent */ public synchronized void removeInvalidComponent(JComponent component) { + RepaintManager delegate = getDelegate(component); + if (delegate != null) { + delegate.removeInvalidComponent(component); + return; + } if(invalidComponents != null) { int index = invalidComponents.indexOf(component); if(index != -1) { @@ -464,6 +476,11 @@ public class RepaintManager */ public void addDirtyRegion(JComponent c, int x, int y, int w, int h) { + RepaintManager delegate = getDelegate(c); + if (delegate != null) { + delegate.addDirtyRegion(c, x, y, w, h); + return; + } addDirtyRegion0(c, x, y, w, h); } @@ -572,7 +589,7 @@ public class RepaintManager */ private synchronized boolean extendDirtyRegion( Component c, int x, int y, int w, int h) { - Rectangle r = (Rectangle)dirtyComponents.get(c); + Rectangle r = dirtyComponents.get(c); if (r != null) { // A non-null r implies c is already marked as dirty, // and that the parent is valid. Therefore we can @@ -588,9 +605,13 @@ public class RepaintManager * dirty. */ public Rectangle getDirtyRegion(JComponent aComponent) { - Rectangle r = null; + RepaintManager delegate = getDelegate(aComponent); + if (delegate != null) { + return delegate.getDirtyRegion(aComponent); + } + Rectangle r; synchronized(this) { - r = (Rectangle)dirtyComponents.get(aComponent); + r = dirtyComponents.get(aComponent); } if(r == null) return new Rectangle(0,0,0,0); @@ -603,6 +624,11 @@ public class RepaintManager * completely painted during the next paintDirtyRegions() call. */ public void markCompletelyDirty(JComponent aComponent) { + RepaintManager delegate = getDelegate(aComponent); + if (delegate != null) { + delegate.markCompletelyDirty(aComponent); + return; + } addDirtyRegion(aComponent,0,0,Integer.MAX_VALUE,Integer.MAX_VALUE); } @@ -611,6 +637,11 @@ public class RepaintManager * get painted during the next paintDirtyRegions() call. */ public void markCompletelyClean(JComponent aComponent) { + RepaintManager delegate = getDelegate(aComponent); + if (delegate != null) { + delegate.markCompletelyClean(aComponent); + return; + } synchronized(this) { dirtyComponents.remove(aComponent); } @@ -623,6 +654,10 @@ public class RepaintManager * if it return true. */ public boolean isCompletelyDirty(JComponent aComponent) { + RepaintManager delegate = getDelegate(aComponent); + if (delegate != null) { + return delegate.isCompletelyDirty(aComponent); + } Rectangle r; r = getDirtyRegion(aComponent); @@ -710,8 +745,8 @@ public class RepaintManager Rectangle rect; int localBoundsX = 0; int localBoundsY = 0; - int localBoundsH = 0; - int localBoundsW = 0; + int localBoundsH; + int localBoundsW; Enumeration keys; roots = new ArrayList(count); @@ -818,7 +853,7 @@ public class RepaintManager dx = rootDx = 0; dy = rootDy = 0; - tmp.setBounds((Rectangle) dirtyComponents.get(dirtyComponent)); + tmp.setBounds(dirtyComponents.get(dirtyComponent)); // System.out.println("Collect dirty component for bound " + tmp + // "component bounds is " + cBounds);; @@ -865,7 +900,7 @@ public class RepaintManager Rectangle r; tmp.setLocation(tmp.x + rootDx - dx, tmp.y + rootDy - dy); - r = (Rectangle)dirtyComponents.get(rootDirtyComponent); + r = dirtyComponents.get(rootDirtyComponent); SwingUtilities.computeUnion(tmp.x,tmp.y,tmp.width,tmp.height,r); } @@ -900,6 +935,10 @@ public class RepaintManager * repaint manager. */ public Image getOffscreenBuffer(Component c,int proposedWidth,int proposedHeight) { + RepaintManager delegate = getDelegate(c); + if (delegate != null) { + return delegate.getOffscreenBuffer(c, proposedWidth, proposedHeight); + } return _getOffscreenBuffer(c, proposedWidth, proposedHeight); } @@ -917,6 +956,11 @@ public class RepaintManager */ public Image getVolatileOffscreenBuffer(Component c, int proposedWidth,int proposedHeight) { + RepaintManager delegate = getDelegate(c); + if (delegate != null) { + return delegate.getVolatileOffscreenBuffer(c, proposedWidth, + proposedHeight); + } GraphicsConfiguration config = c.getGraphicsConfiguration(); if (config == null) { config = GraphicsEnvironment.getLocalGraphicsEnvironment(). @@ -941,7 +985,7 @@ public class RepaintManager private Image _getOffscreenBuffer(Component c, int proposedWidth, int proposedHeight) { Dimension maxSize = getDoubleBufferMaximumSize(); - DoubleBufferInfo doubleBuffer = null; + DoubleBufferInfo doubleBuffer; int width, height; if (standardDoubleBuffer == null) { @@ -1010,7 +1054,7 @@ public class RepaintManager Iterator gcs = volatileMap.keySet().iterator(); while (gcs.hasNext()) { GraphicsConfiguration gc = (GraphicsConfiguration)gcs.next(); - VolatileImage image = (VolatileImage)volatileMap.get(gc); + VolatileImage image = volatileMap.get(gc); if (image.getWidth() > width || image.getHeight() > height) { image.flush(); gcs.remove(); @@ -1178,7 +1222,7 @@ public class RepaintManager */ void beginPaint() { boolean multiThreadedPaint = false; - int paintDepth = 0; + int paintDepth; Thread currentThread = Thread.currentThread(); synchronized(this) { paintDepth = this.paintDepth; @@ -1550,4 +1594,11 @@ public class RepaintManager prePaintDirtyRegions(); } } + private RepaintManager getDelegate(Component c) { + RepaintManager delegate = SwingUtilities3.getDelegateRepaintManager(c); + if (this == delegate) { + delegate = null; + } + return delegate; + } } diff --git a/jdk/src/share/classes/javax/swing/SortingFocusTraversalPolicy.java b/jdk/src/share/classes/javax/swing/SortingFocusTraversalPolicy.java index e920acccba2..85a2bb96a25 100644 --- a/jdk/src/share/classes/javax/swing/SortingFocusTraversalPolicy.java +++ b/jdk/src/share/classes/javax/swing/SortingFocusTraversalPolicy.java @@ -79,7 +79,7 @@ public class SortingFocusTraversalPolicy * sorted list should be reused if possible. */ transient private Container cachedRoot; - transient private List cachedCycle; + transient private List cachedCycle; // Delegate our fitness test to ContainerOrder so that we only have to // code the algorithm once. @@ -111,7 +111,7 @@ public class SortingFocusTraversalPolicy return cycle; } private int getComponentIndex(List cycle, Component aComponent) { - int index = 0; + int index; try { index = Collections.binarySearch(cycle, aComponent, comparator); } catch (ClassCastException e) { @@ -130,14 +130,14 @@ public class SortingFocusTraversalPolicy return index; } - private void enumerateAndSortCycle(Container focusCycleRoot, List cycle) { + private void enumerateAndSortCycle(Container focusCycleRoot, List cycle) { if (focusCycleRoot.isShowing()) { enumerateCycle(focusCycleRoot, cycle); Collections.sort(cycle, comparator); } } - private void enumerateCycle(Container container, List cycle) { + private void enumerateCycle(Container container, List cycle) { if (!(container.isVisible() && container.isDisplayable())) { return; } @@ -145,8 +145,7 @@ public class SortingFocusTraversalPolicy cycle.add(container); Component[] components = container.getComponents(); - for (int i = 0; i < components.length; i++) { - Component comp = components[i]; + for (Component comp : components) { if (comp instanceof Container) { Container cont = (Container)comp; @@ -385,8 +384,8 @@ public class SortingFocusTraversalPolicy return getLastComponent(aContainer); } - Component comp = null; - Component tryComp = null; + Component comp; + Component tryComp; for (index--; index>=0; index--) { comp = cycle.get(index); @@ -442,8 +441,7 @@ public class SortingFocusTraversalPolicy } if (log.isLoggable(Level.FINE)) log.fine("### Cycle is " + cycle); - for (int i = 0; i < cycle.size(); i++) { - Component comp = cycle.get(i); + for (Component comp : cycle) { if (accept(comp)) { return comp; } else if (comp instanceof Container && comp != aContainer) { diff --git a/jdk/src/share/classes/javax/swing/SpringLayout.java b/jdk/src/share/classes/javax/swing/SpringLayout.java index 34847944219..e825f4c6104 100644 --- a/jdk/src/share/classes/javax/swing/SpringLayout.java +++ b/jdk/src/share/classes/javax/swing/SpringLayout.java @@ -185,11 +185,11 @@ import java.util.*; * @since 1.4 */ public class SpringLayout implements LayoutManager2 { - private Map componentConstraints = new HashMap(); + private Map componentConstraints = new HashMap(); private Spring cyclicReference = Spring.constant(Spring.UNSET); - private Set cyclicSprings; - private Set acyclicSprings; + private Set cyclicSprings; + private Set acyclicSprings; /** @@ -415,8 +415,7 @@ public class SpringLayout implements LayoutManager2 { } if (!valid) { String[] all = horizontal ? ALL_HORIZONTAL : ALL_VERTICAL; - for (int i = 0; i < all.length; i++) { - String s = all[i]; + for (String s : all) { if (!history.contains(s)) { setConstraint(s, null); } @@ -822,8 +821,7 @@ public class SpringLayout implements LayoutManager2 { /*pp*/ void reset() { Spring[] allSprings = {x, y, width, height, east, south, horizontalCenter, verticalCenter, baseline}; - for (int i = 0; i < allSprings.length; i++) { - Spring s = allSprings[i]; + for (Spring s : allSprings) { if (s != null) { s.setValue(Spring.UNSET); } @@ -881,8 +879,8 @@ public class SpringLayout implements LayoutManager2 { public SpringLayout() {} private void resetCyclicStatuses() { - cyclicSprings = new HashSet(); - acyclicSprings = new HashSet(); + cyclicSprings = new HashSet(); + acyclicSprings = new HashSet(); } private void setParent(Container p) { @@ -1145,7 +1143,7 @@ public class SpringLayout implements LayoutManager2 { * @return the constraints for the specified component */ public Constraints getConstraints(Component c) { - Constraints result = (Constraints)componentConstraints.get(c); + Constraints result = componentConstraints.get(c); if (result == null) { if (c instanceof javax.swing.JComponent) { Object cp = ((javax.swing.JComponent)c).getClientProperty(SpringLayout.class); diff --git a/jdk/src/share/classes/javax/swing/SwingUtilities.java b/jdk/src/share/classes/javax/swing/SwingUtilities.java index d8f29e5288c..0493510a7bb 100644 --- a/jdk/src/share/classes/javax/swing/SwingUtilities.java +++ b/jdk/src/share/classes/javax/swing/SwingUtilities.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -108,11 +108,8 @@ public class SwingUtilities implements SwingConstants * Return true if a contains b */ public static final boolean isRectangleContainingRectangle(Rectangle a,Rectangle b) { - if (b.x >= a.x && (b.x + b.width) <= (a.x + a.width) && - b.y >= a.y && (b.y + b.height) <= (a.y + a.height)) { - return true; - } - return false; + return b.x >= a.x && (b.x + b.width) <= (a.x + a.width) && + b.y >= a.y && (b.y + b.height) <= (a.y + a.height); } /** @@ -272,8 +269,7 @@ public class SwingUtilities implements SwingConstants } if (parent instanceof Container) { Component components[] = ((Container)parent).getComponents(); - for (int i = 0 ; i < components.length ; i++) { - Component comp = components[i]; + for (Component comp : components) { if (comp != null && comp.isVisible()) { Point loc = comp.getLocation(); if (comp instanceof Container) { @@ -376,8 +372,8 @@ public class SwingUtilities implements SwingConstants do { if(c instanceof JComponent) { - x = ((JComponent)c).getX(); - y = ((JComponent)c).getY(); + x = c.getX(); + y = c.getY(); } else if(c instanceof java.applet.Applet || c instanceof java.awt.Window) { try { @@ -415,8 +411,8 @@ public class SwingUtilities implements SwingConstants do { if(c instanceof JComponent) { - x = ((JComponent)c).getX(); - y = ((JComponent)c).getY(); + x = c.getX(); + y = c.getY(); } else if(c instanceof java.applet.Applet || c instanceof java.awt.Window) { try { @@ -974,12 +970,13 @@ public class SwingUtilities implements SwingConstants boolean textIsEmpty = (text == null) || text.equals(""); int lsb = 0; + int rsb = 0; /* Unless both text and icon are non-null, we effectively ignore * the value of textIconGap. */ int gap; - View v = null; + View v; if (textIsEmpty) { textR.width = textR.height = 0; text = ""; @@ -1015,7 +1012,7 @@ public class SwingUtilities implements SwingConstants if (lsb < 0) { textR.width -= lsb; } - int rsb = SwingUtilities2.getRightSideBearing(c, fm, text); + rsb = SwingUtilities2.getRightSideBearing(c, fm, text); if (rsb > 0) { textR.width += rsb; } @@ -1118,6 +1115,11 @@ public class SwingUtilities implements SwingConstants // lsb is negative. Shift the x location so that the text is // visually drawn at the right location. textR.x -= lsb; + + textR.width += lsb; + } + if (rsb > 0) { + textR.width -= rsb; } return text; @@ -1242,8 +1244,8 @@ public class SwingUtilities implements SwingConstants children = ((Container)c).getComponents(); } if (children != null) { - for(int i = 0; i < children.length; i++) { - updateComponentTreeUI0(children[i]); + for (Component child : children) { + updateComponentTreeUI0(child); } } } @@ -1696,7 +1698,7 @@ public class SwingUtilities implements SwingConstants */ public static void replaceUIActionMap(JComponent component, ActionMap uiActionMap) { - ActionMap map = component.getActionMap((uiActionMap != null));; + ActionMap map = component.getActionMap((uiActionMap != null)); while (map != null) { ActionMap parent = map.getParent(); @@ -1764,8 +1766,7 @@ public class SwingUtilities implements SwingConstants */ void installListeners() { Window[] windows = getOwnedWindows(); - for (int ind = 0; ind < windows.length; ind++){ - Window window = windows[ind]; + for (Window window : windows) { if (window != null) { window.removeWindowListener(this); window.addWindowListener(this); @@ -1780,8 +1781,7 @@ public class SwingUtilities implements SwingConstants public void windowClosed(WindowEvent e) { synchronized(getTreeLock()) { Window[] windows = getOwnedWindows(); - for (int ind = 0; ind < windows.length; ind++) { - Window window = windows[ind]; + for (Window window : windows) { if (window != null) { if (window.isDisplayable()) { return; @@ -1869,7 +1869,7 @@ public class SwingUtilities implements SwingConstants } - static Class loadSystemClass(String className) throws ClassNotFoundException { + static Class loadSystemClass(String className) throws ClassNotFoundException { return Class.forName(className, true, Thread.currentThread(). getContextClassLoader()); } diff --git a/jdk/src/share/classes/javax/swing/Timer.java b/jdk/src/share/classes/javax/swing/Timer.java index a96d2ce8dc9..4f339158efc 100644 --- a/jdk/src/share/classes/javax/swing/Timer.java +++ b/jdk/src/share/classes/javax/swing/Timer.java @@ -270,8 +270,7 @@ public class Timer implements Serializable * @since 1.4 */ public ActionListener[] getActionListeners() { - return (ActionListener[])listenerList.getListeners( - ActionListener.class); + return listenerList.getListeners(ActionListener.class); } diff --git a/jdk/src/share/classes/javax/swing/TimerQueue.java b/jdk/src/share/classes/javax/swing/TimerQueue.java index 2121939011f..f68f4e99688 100644 --- a/jdk/src/share/classes/javax/swing/TimerQueue.java +++ b/jdk/src/share/classes/javax/swing/TimerQueue.java @@ -31,6 +31,7 @@ package javax.swing; import java.util.*; import java.util.concurrent.*; +import java.util.concurrent.locks.*; import java.util.concurrent.atomic.AtomicLong; import sun.awt.AppContext; @@ -52,7 +53,8 @@ class TimerQueue implements Runnable new StringBuffer("TimerQueue.expiredTimersKey"); private final DelayQueue queue; - volatile boolean running; + private volatile boolean running; + private final Lock runningLock; /* Lock object used in place of class object for synchronization. * (4187686) @@ -69,7 +71,8 @@ class TimerQueue implements Runnable super(); queue = new DelayQueue(); // Now start the TimerQueue thread. - start(); + runningLock = new ReentrantLock(); + startIfNeeded(); } @@ -87,33 +90,30 @@ class TimerQueue implements Runnable } - synchronized void start() { - if (running) { - throw new RuntimeException("Can't start a TimerQueue " + - "that is already running"); - } - else { - final ThreadGroup threadGroup = - AppContext.getAppContext().getThreadGroup(); - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - Thread timerThread = new Thread(threadGroup, TimerQueue.this, - "TimerQueue"); - timerThread.setDaemon(true); - timerThread.setPriority(Thread.NORM_PRIORITY); - timerThread.start(); - return null; - } - }); - running = true; + void startIfNeeded() { + if (! running) { + runningLock.lock(); + try { + final ThreadGroup threadGroup = + AppContext.getAppContext().getThreadGroup(); + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Object run() { + Thread timerThread = new Thread(threadGroup, TimerQueue.this, + "TimerQueue"); + timerThread.setDaemon(true); + timerThread.setPriority(Thread.NORM_PRIORITY); + timerThread.start(); + return null; + } + }); + running = true; + } finally { + runningLock.unlock(); + } } } - synchronized void stop() { - running = false; - } - void addTimer(Timer timer, long delayMillis) { timer.getLock().lock(); try { @@ -164,6 +164,7 @@ class TimerQueue implements Runnable public void run() { + runningLock.lock(); try { while (running) { try { @@ -195,14 +196,14 @@ class TimerQueue implements Runnable } } catch (ThreadDeath td) { - synchronized (this) { - running = false; - // Mark all the timers we contain as not being queued. - for (DelayedTimer delayedTimer : queue) { - delayedTimer.getTimer().cancelEvent(); - } - throw td; + // Mark all the timers we contain as not being queued. + for (DelayedTimer delayedTimer : queue) { + delayedTimer.getTimer().cancelEvent(); } + throw td; + } finally { + running = false; + runningLock.unlock(); } } @@ -225,7 +226,7 @@ class TimerQueue implements Runnable /** * Returns nanosecond time offset by origin */ - private final static long now() { + private static long now() { return System.nanoTime() - NANO_ORIGIN; } diff --git a/jdk/src/share/classes/javax/swing/UIDefaults.java b/jdk/src/share/classes/javax/swing/UIDefaults.java index 302dc00b0dd..7a372e79753 100644 --- a/jdk/src/share/classes/javax/swing/UIDefaults.java +++ b/jdk/src/share/classes/javax/swing/UIDefaults.java @@ -72,11 +72,11 @@ import sun.util.CoreResourceBundleControl; */ public class UIDefaults extends Hashtable { - private static final Object PENDING = new String("Pending"); + private static final Object PENDING = "Pending"; private SwingPropertyChangeSupport changeSupport; - private Vector resourceBundles; + private Vector resourceBundles; private Locale defaultLocale = Locale.getDefault(); @@ -86,7 +86,7 @@ public class UIDefaults extends Hashtable * Access to this should be done while holding a lock on the * UIDefaults, eg synchronized(this). */ - private Map resourceCache; + private Map> resourceCache; /** * Creates an empty defaults table. @@ -106,7 +106,7 @@ public class UIDefaults extends Hashtable */ public UIDefaults(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor); - resourceCache = new HashMap(); + resourceCache = new HashMap>(); } @@ -281,24 +281,24 @@ public class UIDefaults extends Hashtable if( defaultLocale == null ) return null; else - l = (Locale)defaultLocale; + l = defaultLocale; } synchronized(this) { - return getResourceCache(l).get((String)key); + return getResourceCache(l).get(key); } } /** * Returns a Map of the known resources for the given locale. */ - private Map getResourceCache(Locale l) { - Map values = (Map)resourceCache.get(l); + private Map getResourceCache(Locale l) { + Map values = resourceCache.get(l); if (values == null) { - values = new HashMap(); + values = new HashMap(); for (int i=resourceBundles.size()-1; i >= 0; i--) { - String bundleName = (String)resourceBundles.get(i); + String bundleName = resourceBundles.get(i); try { Control c = CoreResourceBundleControl.getRBControlInstance(bundleName); ResourceBundle b; @@ -751,7 +751,7 @@ public class UIDefaults extends Hashtable Object cl = get("ClassLoader"); ClassLoader uiClassLoader = (cl != null) ? (ClassLoader)cl : target.getClass().getClassLoader(); - Class uiClass = getUIClass(target.getUIClassID(), uiClassLoader); + Class uiClass = getUIClass(target.getUIClassID(), uiClassLoader); Object uiObject = null; if (uiClass == null) { @@ -761,8 +761,7 @@ public class UIDefaults extends Hashtable try { Method m = (Method)get(uiClass); if (m == null) { - Class acClass = javax.swing.JComponent.class; - m = uiClass.getMethod("createUI", new Class[]{acClass}); + m = uiClass.getMethod("createUI", new Class[]{JComponent.class}); put(uiClass, m); } uiObject = MethodUtil.invoke(m, null, new Object[]{target}); @@ -862,7 +861,7 @@ public class UIDefaults extends Hashtable return; } if( resourceBundles == null ) { - resourceBundles = new Vector(5); + resourceBundles = new Vector(5); } if (!resourceBundles.contains(bundleName)) { resourceBundles.add( bundleName ); @@ -1064,7 +1063,7 @@ public class UIDefaults extends Hashtable className = c; methodName = m; if (o != null) { - args = (Object[])o.clone(); + args = o.clone(); } } @@ -1079,10 +1078,10 @@ public class UIDefaults extends Hashtable // In order to pick up the security policy in effect at the // time of creation we use a doPrivileged with the // AccessControlContext that was in place when this was created. - return AccessController.doPrivileged(new PrivilegedAction() { + return AccessController.doPrivileged(new PrivilegedAction() { public Object run() { try { - Class c; + Class c; Object cl; // See if we should use a separate ClassLoader if (table == null || !((cl = table.get("ClassLoader")) diff --git a/jdk/src/share/classes/javax/swing/UIManager.java b/jdk/src/share/classes/javax/swing/UIManager.java index 6fb543d3374..a4a62f0096c 100644 --- a/jdk/src/share/classes/javax/swing/UIManager.java +++ b/jdk/src/share/classes/javax/swing/UIManager.java @@ -191,7 +191,7 @@ public class UIManager implements Serializable MultiUIDefaults multiUIDefaults = new MultiUIDefaults(tables); LookAndFeel lookAndFeel; LookAndFeel multiLookAndFeel = null; - Vector auxLookAndFeels = null; + Vector auxLookAndFeels = null; SwingPropertyChangeSupport changeSupport; UIDefaults getLookAndFeelDefaults() { return tables[0]; } @@ -378,7 +378,7 @@ public class UIManager implements Serializable private static LookAndFeelInfo[] installedLAFs; static { - ArrayList iLAFs = new ArrayList(4); + ArrayList iLAFs = new ArrayList(4); iLAFs.add(new LookAndFeelInfo( "Metal", "javax.swing.plaf.metal.MetalLookAndFeel")); iLAFs.add(new LookAndFeelInfo("CDE/Motif", @@ -400,8 +400,7 @@ public class UIManager implements Serializable iLAFs.add(new LookAndFeelInfo("GTK+", "com.sun.java.swing.plaf.gtk.GTKLookAndFeel")); } - installedLAFs = (LookAndFeelInfo[])iLAFs.toArray( - new LookAndFeelInfo[iLAFs.size()]); + installedLAFs = iLAFs.toArray(new LookAndFeelInfo[iLAFs.size()]); } @@ -640,7 +639,7 @@ public class UIManager implements Serializable * @see #getSystemLookAndFeelClassName */ public static String getCrossPlatformLookAndFeelClassName() { - String laf = (String)AccessController.doPrivileged( + String laf = AccessController.doPrivileged( new GetPropertyAction("swing.crossplatformlaf")); if (laf != null) { return laf; @@ -1079,9 +1078,9 @@ public class UIManager implements Serializable // for that. return; } - Vector v = getLAFState().auxLookAndFeels; + Vector v = getLAFState().auxLookAndFeels; if (v == null) { - v = new Vector(); + v = new Vector(); } if (!v.contains(laf)) { @@ -1115,7 +1114,7 @@ public class UIManager implements Serializable boolean result; - Vector v = getLAFState().auxLookAndFeels; + Vector v = getLAFState().auxLookAndFeels; if ((v == null) || (v.size() == 0)) { return false; } @@ -1151,14 +1150,14 @@ public class UIManager implements Serializable static public LookAndFeel[] getAuxiliaryLookAndFeels() { maybeInitialize(); - Vector v = getLAFState().auxLookAndFeels; + Vector v = getLAFState().auxLookAndFeels; if ((v == null) || (v.size() == 0)) { return null; } else { LookAndFeel[] rv = new LookAndFeel[v.size()]; for (int i = 0; i < rv.length; i++) { - rv[i] = (LookAndFeel)v.elementAt(i); + rv[i] = v.elementAt(i); } return rv; } @@ -1225,7 +1224,7 @@ public class UIManager implements Serializable final Properties props = new Properties(); java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new java.security.PrivilegedAction() { public Object run() { try { File file = new File(makeSwingPropertiesFilename()); @@ -1284,7 +1283,7 @@ public class UIManager implements Serializable * property. For example given "swing.installedlafs=motif,windows" * lafs = {"motif", "windows"}. */ - Vector lafs = new Vector(); + Vector lafs = new Vector(); StringTokenizer st = new StringTokenizer(ilafsString, ",", false); while (st.hasMoreTokens()) { lafs.addElement(st.nextToken()); @@ -1294,9 +1293,8 @@ public class UIManager implements Serializable * list. If they both exist then add a LookAndFeelInfo to * the installedLafs array. */ - Vector ilafs = new Vector(lafs.size()); - for(int i = 0; i < lafs.size(); i++) { - String laf = (String)lafs.elementAt(i); + Vector ilafs = new Vector(lafs.size()); + for (String laf : lafs) { String name = swingProps.getProperty(makeInstalledLAFKey(laf, "name"), laf); String cls = swingProps.getProperty(makeInstalledLAFKey(laf, "class")); if (cls != null) { @@ -1306,7 +1304,7 @@ public class UIManager implements Serializable installedLAFs = new LookAndFeelInfo[ilafs.size()]; for(int i = 0; i < ilafs.size(); i++) { - installedLAFs[i] = (LookAndFeelInfo)(ilafs.elementAt(i)); + installedLAFs[i] = ilafs.elementAt(i); } } @@ -1350,7 +1348,7 @@ public class UIManager implements Serializable return; } - Vector auxLookAndFeels = new Vector(); + Vector auxLookAndFeels = new Vector(); StringTokenizer p = new StringTokenizer(auxLookAndFeelNames,","); String factoryName; @@ -1451,7 +1449,7 @@ public class UIManager implements Serializable Component c = e.getComponent(); if ((!(c instanceof JComponent) || - (c != null && !((JComponent)c).isEnabled())) && + (c != null && !c.isEnabled())) && JComponent.KeyboardState.shouldProcess(e) && SwingUtilities.processKeyBindings(e)) { e.consume(); diff --git a/jdk/src/share/classes/javax/swing/border/CompoundBorder.java b/jdk/src/share/classes/javax/swing/border/CompoundBorder.java index f736cf90278..46ac44e50c0 100644 --- a/jdk/src/share/classes/javax/swing/border/CompoundBorder.java +++ b/jdk/src/share/classes/javax/swing/border/CompoundBorder.java @@ -79,10 +79,13 @@ public class CompoundBorder extends AbstractBorder { } /** - * Returns whether or not this compound border is opaque. - * Returns true if both the inside and outside borders are - * non-null and opaque; returns false otherwise. + * Returns whether or not the compound border is opaque. + * + * @return {@code true} if the inside and outside borders + * are each either {@code null} or opaque; + * or {@code false} otherwise */ + @Override public boolean isBorderOpaque() { return (outsideBorder == null || outsideBorder.isBorderOpaque()) && (insideBorder == null || insideBorder.isBorderOpaque()); diff --git a/jdk/src/share/classes/javax/swing/colorchooser/AbstractColorChooserPanel.java b/jdk/src/share/classes/javax/swing/colorchooser/AbstractColorChooserPanel.java index 9fa819ba935..c9ea9d77494 100644 --- a/jdk/src/share/classes/javax/swing/colorchooser/AbstractColorChooserPanel.java +++ b/jdk/src/share/classes/javax/swing/colorchooser/AbstractColorChooserPanel.java @@ -160,7 +160,9 @@ public abstract class AbstractColorChooserPanel extends JPanel { * is editing */ public ColorSelectionModel getColorSelectionModel() { - return chooser.getSelectionModel(); + return (this.chooser != null) + ? this.chooser.getSelectionModel() + : null; } /** @@ -168,7 +170,17 @@ public abstract class AbstractColorChooserPanel extends JPanel { * @return the Color that is selected */ protected Color getColorFromModel() { - return getColorSelectionModel().getSelectedColor(); + ColorSelectionModel model = getColorSelectionModel(); + return (model != null) + ? model.getSelectedColor() + : null; + } + + void setSelectedColor(Color color) { + ColorSelectionModel model = getColorSelectionModel(); + if (model != null) { + model.setSelectedColor(color); + } } /** diff --git a/jdk/src/share/classes/javax/swing/colorchooser/ColorChooserComponentFactory.java b/jdk/src/share/classes/javax/swing/colorchooser/ColorChooserComponentFactory.java index b36c6524d8a..0ee01e6cb5a 100644 --- a/jdk/src/share/classes/javax/swing/colorchooser/ColorChooserComponentFactory.java +++ b/jdk/src/share/classes/javax/swing/colorchooser/ColorChooserComponentFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-2001 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,9 +25,7 @@ package javax.swing.colorchooser; -import javax.swing.*; - - +import javax.swing.JComponent; /** * A class designed to produce preconfigured "accessory" objects to @@ -49,16 +47,17 @@ public class ColorChooserComponentFactory { private ColorChooserComponentFactory() { } // can't instantiate - public static AbstractColorChooserPanel[] getDefaultChooserPanels() { - AbstractColorChooserPanel[] choosers = { new DefaultSwatchChooserPanel(), - new DefaultHSBChooserPanel(), - new DefaultRGBChooserPanel() }; - return choosers; + return new AbstractColorChooserPanel[] { + new DefaultSwatchChooserPanel(), + new ColorChooserPanel(new ColorModelHSV()), + new ColorChooserPanel(new ColorModelHSL()), + new ColorChooserPanel(new ColorModel()), + new ColorChooserPanel(new ColorModelCMYK()), + }; } public static JComponent getPreviewPanel() { return new DefaultPreviewPanel(); } - } diff --git a/jdk/src/share/classes/javax/swing/colorchooser/ColorChooserPanel.java b/jdk/src/share/classes/javax/swing/colorchooser/ColorChooserPanel.java new file mode 100644 index 00000000000..acd6cdcc3fc --- /dev/null +++ b/jdk/src/share/classes/javax/swing/colorchooser/ColorChooserPanel.java @@ -0,0 +1,187 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.swing.colorchooser; + +import java.awt.Color; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.Icon; +import javax.swing.JComponent; +import javax.swing.JFormattedTextField; +import javax.swing.JLabel; +import javax.swing.SwingConstants; + +final class ColorChooserPanel extends AbstractColorChooserPanel implements PropertyChangeListener { + + private static final int MASK = 0xFF000000; + private final ColorModel model; + private final ColorPanel panel; + private final DiagramComponent slider; + private final DiagramComponent diagram; + private final JFormattedTextField text; + private final JLabel label; + + ColorChooserPanel(ColorModel model) { + this.model = model; + this.panel = new ColorPanel(this.model); + this.slider = new DiagramComponent(this.panel, false); + this.diagram = new DiagramComponent(this.panel, true); + this.text = new JFormattedTextField(); + this.label = new JLabel(null, null, SwingConstants.RIGHT); + ValueFormatter.init(6, true, this.text); + } + + @Override + public void updateChooser() { + Color color = getColorFromModel(); + if (color != null) { + this.panel.setColor(color); + this.text.setValue(Integer.valueOf(color.getRGB())); + this.slider.repaint(); + this.diagram.repaint(); + } + } + + @Override + protected void buildChooser() { + if (0 == getComponentCount()) { + setLayout(new GridBagLayout()); + + GridBagConstraints gbc = new GridBagConstraints(); + + gbc.gridx = 3; + gbc.gridwidth = 2; + gbc.weighty = 1.0; + gbc.anchor = GridBagConstraints.NORTH; + gbc.fill = GridBagConstraints.HORIZONTAL; + gbc.insets.top = 10; + gbc.insets.right = 10; + add(this.panel, gbc); + + gbc.gridwidth = 1; + gbc.weightx = 1.0; + gbc.weighty = 0.0; + gbc.anchor = GridBagConstraints.CENTER; + gbc.insets.right = 5; + gbc.insets.bottom = 10; + add(this.label, gbc); + + gbc.gridx = 4; + gbc.weightx = 0.0; + gbc.insets.right = 10; + add(this.text, gbc); + + gbc.gridx = 2; + gbc.gridheight = 2; + gbc.anchor = GridBagConstraints.NORTH; + gbc.ipadx = this.text.getPreferredSize().height; + gbc.ipady = getPreferredSize().height; + add(this.slider, gbc); + + gbc.gridx = 1; + gbc.insets.left = 10; + gbc.ipadx = gbc.ipady; + add(this.diagram, gbc); + + this.label.setLabelFor(this.text); + this.text.addPropertyChangeListener("value", this); // NON-NLS: the property name + this.slider.setBorder(this.text.getBorder()); + this.diagram.setBorder(this.text.getBorder()); + + setInheritsPopupMenu(this, true); // CR:4966112 + } + String label = this.model.getText(this, "HexCode"); // NON-NLS: suffix + boolean visible = label != null; + this.text.setVisible(visible); + this.label.setVisible(visible); + if (visible) { + this.label.setText(label); + int mnemonic = this.model.getInteger(this, "HexCodeMnemonic"); // NON-NLS: suffix + if (mnemonic > 0) { + this.label.setDisplayedMnemonic(mnemonic); + mnemonic = this.model.getInteger(this, "HexCodeMnemonicIndex"); // NON-NLS: suffix + if (mnemonic >= 0) { + this.label.setDisplayedMnemonicIndex(mnemonic); + } + } + } + this.panel.buildPanel(); + } + + @Override + public String getDisplayName() { + return this.model.getText(this, "Name"); // NON-NLS: suffix + } + + @Override + public int getMnemonic() { + return this.model.getInteger(this, "Mnemonic"); // NON-NLS: suffix + } + + @Override + public int getDisplayedMnemonicIndex() { + return this.model.getInteger(this, "DisplayedMnemonicIndex"); // NON-NLS: suffix + } + + @Override + public Icon getSmallDisplayIcon() { + return null; + } + + @Override + public Icon getLargeDisplayIcon() { + return null; + } + + public void propertyChange(PropertyChangeEvent event) { + ColorSelectionModel model = getColorSelectionModel(); + if (model != null) { + Object object = event.getNewValue(); + if (object instanceof Integer) { + int value = MASK & model.getSelectedColor().getRGB() | (Integer) object; + model.setSelectedColor(new Color(value, true)); + } + } + this.text.selectAll(); + } + + /** + * Allows to show context popup for all components recursively. + * + * @param component the root component of the tree + * @param value whether or not the popup menu is inherited + */ + private static void setInheritsPopupMenu(JComponent component, boolean value) { + component.setInheritsPopupMenu(value); + for (Object object : component.getComponents()) { + if (object instanceof JComponent) { + setInheritsPopupMenu((JComponent) object, value); + } + } + } +} diff --git a/jdk/src/share/classes/javax/swing/colorchooser/ColorModel.java b/jdk/src/share/classes/javax/swing/colorchooser/ColorModel.java new file mode 100644 index 00000000000..955ed162663 --- /dev/null +++ b/jdk/src/share/classes/javax/swing/colorchooser/ColorModel.java @@ -0,0 +1,102 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.swing.colorchooser; + +import java.awt.Component; +import javax.swing.UIManager; + +class ColorModel { + + private final String prefix; + private final String[] labels; + + ColorModel(String name, String... labels) { + this.prefix = "ColorChooser." + name; // NON-NLS: default prefix + this.labels = labels; + } + + ColorModel() { + this("rgb", "Red", "Green", "Blue", "Alpha"); // NON-NLS: components + } + + void setColor(int color, float[] model) { + model[0] = normalize(color >> 16); + model[1] = normalize(color >> 8); + model[2] = normalize(color); + model[3] = normalize(color >> 24); + } + + int getColor(float[] model) { + return to8bit(model[2]) | (to8bit(model[1]) << 8) | (to8bit(model[0]) << 16) | (to8bit(model[3]) << 24); + } + + int getCount() { + return this.labels.length; + } + + int getMinimum(int index) { + return 0; + } + + int getMaximum(int index) { + return 255; + } + + float getDefault(int index) { + return 0.0f; + } + + final String getLabel(Component component, int index) { + return getText(component, this.labels[index]); + } + + private static float normalize(int value) { + return (float) (value & 0xFF) / 255.0f; + } + + private static int to8bit(float value) { + return (int) (255.0f * value); + } + + final String getText(Component component, String suffix) { + return UIManager.getString(this.prefix + suffix + "Text", component.getLocale()); // NON-NLS: default postfix + } + + final int getInteger(Component component, String suffix) { + Object value = UIManager.get(this.prefix + suffix, component.getLocale()); + if (value instanceof Integer) { + return (Integer) value; + } + if (value instanceof String) { + try { + return Integer.parseInt((String) value); + } + catch (NumberFormatException exception) { + } + } + return -1; + } +} diff --git a/jdk/src/share/classes/javax/swing/colorchooser/ColorModelCMYK.java b/jdk/src/share/classes/javax/swing/colorchooser/ColorModelCMYK.java new file mode 100644 index 00000000000..77a7ca55594 --- /dev/null +++ b/jdk/src/share/classes/javax/swing/colorchooser/ColorModelCMYK.java @@ -0,0 +1,94 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.swing.colorchooser; + +final class ColorModelCMYK extends ColorModel { + + ColorModelCMYK() { + super("cmyk", "Cyan", "Magenta", "Yellow", "Black", "Alpha"); // NON-NLS: components + } + + @Override + void setColor(int color, float[] space) { + super.setColor(color, space); + space[4] = space[3]; + RGBtoCMYK(space, space); + } + + @Override + int getColor(float[] space) { + CMYKtoRGB(space, space); + space[3] = space[4]; + return super.getColor(space); + } + + /** + * Converts CMYK components of a color to a set of RGB components. + * + * @param cmyk a float array with length equal to + * the number of CMYK components + * @param rgb a float array with length of at least 3 + * that contains RGB components of a color + * @return a float array that contains RGB components + */ + private static float[] CMYKtoRGB(float[] cmyk, float[] rgb) { + if (rgb == null) { + rgb = new float[3]; + } + rgb[0] = 1.0f + cmyk[0] * cmyk[3] - cmyk[3] - cmyk[0]; + rgb[1] = 1.0f + cmyk[1] * cmyk[3] - cmyk[3] - cmyk[1]; + rgb[2] = 1.0f + cmyk[2] * cmyk[3] - cmyk[3] - cmyk[2]; + return rgb; + } + + /** + * Converts RGB components of a color to a set of CMYK components. + * + * @param rgb a float array with length of at least 3 + * that contains RGB components of a color + * @param cmyk a float array with length equal to + * the number of CMYK components + * @return a float array that contains CMYK components + */ + private static float[] RGBtoCMYK(float[] rgb, float[] cmyk) { + if (cmyk == null) { + cmyk = new float[4]; + } + float max = ColorModelHSL.max(rgb[0], rgb[1], rgb[2]); + if (max > 0.0f) { + cmyk[0] = 1.0f - rgb[0] / max; + cmyk[1] = 1.0f - rgb[1] / max; + cmyk[2] = 1.0f - rgb[2] / max; + } + else { + cmyk[0] = 0.0f; + cmyk[1] = 0.0f; + cmyk[2] = 0.0f; + } + cmyk[3] = 1.0f - max; + return cmyk; + } +} diff --git a/jdk/src/share/classes/javax/swing/colorchooser/ColorModelHSL.java b/jdk/src/share/classes/javax/swing/colorchooser/ColorModelHSL.java new file mode 100644 index 00000000000..85b0c8e5da4 --- /dev/null +++ b/jdk/src/share/classes/javax/swing/colorchooser/ColorModelHSL.java @@ -0,0 +1,188 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.swing.colorchooser; + +final class ColorModelHSL extends ColorModel { + + ColorModelHSL() { + super("hsl", "Hue", "Saturation", "Lightness", "Transparency"); // NON-NLS: components + } + + @Override + void setColor(int color, float[] space) { + super.setColor(color, space); + RGBtoHSL(space, space); + space[3] = 1.0f - space[3]; + } + + @Override + int getColor(float[] space) { + space[3] = 1.0f - space[3]; + HSLtoRGB(space, space); + return super.getColor(space); + } + + @Override + int getMaximum(int index) { + return (index == 0) ? 360 : 100; + } + + @Override + float getDefault(int index) { + return (index == 0) ? -1.0f : (index == 2) ? 0.5f : 1.0f; + } + + /** + * Converts HSL components of a color to a set of RGB components. + * + * @param hsl a float array with length equal to + * the number of HSL components + * @param rgb a float array with length of at least 3 + * that contains RGB components of a color + * @return a float array that contains RGB components + */ + private static float[] HSLtoRGB(float[] hsl, float[] rgb) { + if (rgb == null) { + rgb = new float[3]; + } + float hue = hsl[0]; + float saturation = hsl[1]; + float lightness = hsl[2]; + + if (saturation > 0.0f) { + hue = (hue < 1.0f) ? hue * 6.0f : 0.0f; + float q = lightness + saturation * ((lightness > 0.5f) ? 1.0f - lightness : lightness); + float p = 2.0f * lightness - q; + rgb[0]= normalize(q, p, (hue < 4.0f) ? (hue + 2.0f) : (hue - 4.0f)); + rgb[1]= normalize(q, p, hue); + rgb[2]= normalize(q, p, (hue < 2.0f) ? (hue + 4.0f) : (hue - 2.0f)); + } + else { + rgb[0] = lightness; + rgb[1] = lightness; + rgb[2] = lightness; + } + return rgb; + } + + /** + * Converts RGB components of a color to a set of HSL components. + * + * @param rgb a float array with length of at least 3 + * that contains RGB components of a color + * @param hsl a float array with length equal to + * the number of HSL components + * @return a float array that contains HSL components + */ + private static float[] RGBtoHSL(float[] rgb, float[] hsl) { + if (hsl == null) { + hsl = new float[3]; + } + float max = max(rgb[0], rgb[1], rgb[2]); + float min = min(rgb[0], rgb[1], rgb[2]); + + float summa = max + min; + float saturation = max - min; + if (saturation > 0.0f) { + saturation /= (summa > 1.0f) + ? 2.0f - summa + : summa; + } + hsl[0] = getHue(rgb[0], rgb[1], rgb[2], max, min); + hsl[1] = saturation; + hsl[2] = summa / 2.0f; + return hsl; + } + + /** + * Returns the smaller of three color components. + * + * @param red the red component of the color + * @param green the green component of the color + * @param blue the blue component of the color + * @return the smaller of {@code red}, {@code green} and {@code blue} + */ + static float min(float red, float green, float blue) { + float min = (red < green) ? red : green; + return (min < blue) ? min : blue; + } + + /** + * Returns the larger of three color components. + * + * @param red the red component of the color + * @param green the green component of the color + * @param blue the blue component of the color + * @return the larger of {@code red}, {@code green} and {@code blue} + */ + static float max(float red, float green, float blue) { + float max = (red > green) ? red : green; + return (max > blue) ? max : blue; + } + + /** + * Calculates the hue component for HSL and HSV color spaces. + * + * @param red the red component of the color + * @param green the green component of the color + * @param blue the blue component of the color + * @param max the larger of {@code red}, {@code green} and {@code blue} + * @param min the smaller of {@code red}, {@code green} and {@code blue} + * @return the hue component + */ + static float getHue(float red, float green, float blue, float max, float min) { + float hue = max - min; + if (hue > 0.0f) { + if (max == red) { + hue = (green - blue) / hue; + if (hue < 0.0f) { + hue += 6.0f; + } + } + else if (max == green) { + hue = 2.0f + (blue - red) / hue; + } + else /*max == blue*/ { + hue = 4.0f + (red - green) / hue; + } + hue /= 6.0f; + } + return hue; + } + + private static float normalize(float q, float p, float color) { + if (color < 1.0f) { + return p + (q - p) * color; + } + if (color < 3.0f) { + return q; + } + if (color < 4.0f) { + return p + (q - p) * (4.0f - color); + } + return p; + } +} diff --git a/jdk/src/share/classes/javax/swing/colorchooser/ColorModelHSV.java b/jdk/src/share/classes/javax/swing/colorchooser/ColorModelHSV.java new file mode 100644 index 00000000000..e33eef77dfe --- /dev/null +++ b/jdk/src/share/classes/javax/swing/colorchooser/ColorModelHSV.java @@ -0,0 +1,138 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.swing.colorchooser; + +final class ColorModelHSV extends ColorModel { + + ColorModelHSV() { + super("hsv", "Hue", "Saturation", "Value", "Transparency"); // NON-NLS: components + } + + @Override + void setColor(int color, float[] space) { + super.setColor(color, space); + RGBtoHSV(space, space); + space[3] = 1.0f - space[3]; + } + + @Override + int getColor(float[] space) { + space[3] = 1.0f - space[3]; + HSVtoRGB(space, space); + return super.getColor(space); + } + + @Override + int getMaximum(int index) { + return (index == 0) ? 360 : 100; + } + + @Override + float getDefault(int index) { + return (index == 0) ? -1.0f : 1.0f; + } + + /** + * Converts HSV components of a color to a set of RGB components. + * + * @param hsv a float array with length equal to + * the number of HSV components + * @param rgb a float array with length of at least 3 + * that contains RGB components of a color + * @return a float array that contains RGB components + */ + private static float[] HSVtoRGB(float[] hsv, float[] rgb) { + if (rgb == null) { + rgb = new float[3]; + } + float hue = hsv[0]; + float saturation = hsv[1]; + float value = hsv[2]; + + rgb[0] = value; + rgb[1] = value; + rgb[2] = value; + + if (saturation > 0.0f) { + hue = (hue < 1.0f) ? hue * 6.0f : 0.0f; + int integer = (int) hue; + float f = hue - (float) integer; + switch (integer) { + case 0: + rgb[1] *= 1.0f - saturation * (1.0f - f); + rgb[2] *= 1.0f - saturation; + break; + case 1: + rgb[0] *= 1.0f - saturation * f; + rgb[2] *= 1.0f - saturation; + break; + case 2: + rgb[0] *= 1.0f - saturation; + rgb[2] *= 1.0f - saturation * (1.0f - f); + break; + case 3: + rgb[0] *= 1.0f - saturation; + rgb[1] *= 1.0f - saturation * f; + break; + case 4: + rgb[0] *= 1.0f - saturation * (1.0f - f); + rgb[1] *= 1.0f - saturation; + break; + case 5: + rgb[1] *= 1.0f - saturation; + rgb[2] *= 1.0f - saturation * f; + break; + } + } + return rgb; + } + + /** + * Converts RGB components of a color to a set of HSV components. + * + * @param rgb a float array with length of at least 3 + * that contains RGB components of a color + * @param hsv a float array with length equal to + * the number of HSV components + * @return a float array that contains HSV components + */ + private static float[] RGBtoHSV(float[] rgb, float[] hsv) { + if (hsv == null) { + hsv = new float[3]; + } + float max = ColorModelHSL.max(rgb[0], rgb[1], rgb[2]); + float min = ColorModelHSL.min(rgb[0], rgb[1], rgb[2]); + + float saturation = max - min; + if (saturation > 0.0f) { + saturation /= max; + } + hsv[0] = ColorModelHSL.getHue(rgb[0], rgb[1], rgb[2], max, min); + hsv[1] = saturation; + hsv[2] = max; + return hsv; + } +} diff --git a/jdk/src/share/classes/javax/swing/colorchooser/ColorPanel.java b/jdk/src/share/classes/javax/swing/colorchooser/ColorPanel.java new file mode 100644 index 00000000000..7cccca63089 --- /dev/null +++ b/jdk/src/share/classes/javax/swing/colorchooser/ColorPanel.java @@ -0,0 +1,210 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.swing.colorchooser; + +import java.awt.Color; +import java.awt.ContainerOrderFocusTraversalPolicy; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.ButtonGroup; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.border.EmptyBorder; + +final class ColorPanel extends JPanel implements ActionListener { + + private final SlidingSpinner[] spinners = new SlidingSpinner[5]; + private final float[] values = new float[this.spinners.length]; + + private final ColorModel model; + private Color color; + private int x = 1; + private int y = 2; + private int z; + + ColorPanel(ColorModel model) { + super(new GridBagLayout()); + + GridBagConstraints gbc = new GridBagConstraints(); + gbc.fill = GridBagConstraints.HORIZONTAL; + + gbc.gridx = 1; + ButtonGroup group = new ButtonGroup(); + EmptyBorder border = null; + for (int i = 0; i < this.spinners.length; i++) { + if (i < 3) { + JRadioButton button = new JRadioButton(); + if (i == 0) { + Insets insets = button.getInsets(); + insets.left = button.getPreferredSize().width; + border = new EmptyBorder(insets); + button.setSelected(true); + gbc.insets.top = 5; + } + add(button, gbc); + group.add(button); + button.setActionCommand(Integer.toString(i)); + button.addActionListener(this); + this.spinners[i] = new SlidingSpinner(this, button); + } + else { + JLabel label = new JLabel(); + add(label, gbc); + label.setBorder(border); + label.setFocusable(false); + this.spinners[i] = new SlidingSpinner(this, label); + } + } + gbc.gridx = 2; + gbc.weightx = 1.0; + gbc.insets.top = 0; + gbc.insets.left = 5; + for (SlidingSpinner spinner : this.spinners) { + add(spinner.getSlider(), gbc); + gbc.insets.top = 5; + } + gbc.gridx = 3; + gbc.weightx = 0.0; + gbc.insets.top = 0; + for (SlidingSpinner spinner : this.spinners) { + add(spinner.getSpinner(), gbc); + gbc.insets.top = 5; + } + setFocusTraversalPolicy(new ContainerOrderFocusTraversalPolicy()); + setFocusTraversalPolicyProvider(true); + setFocusable(false); + + this.model = model; + } + + public void actionPerformed(ActionEvent event) { + try { + this.z = Integer.parseInt(event.getActionCommand()); + this.y = (this.z != 2) ? 2 : 1; + this.x = (this.z != 0) ? 0 : 1; + getParent().repaint(); + } + catch (NumberFormatException exception) { + } + } + + void buildPanel() { + int count = this.model.getCount(); + this.spinners[4].setVisible(count > 4); + for (int i = 0; i < count; i++) { + Object object = this.spinners[i].getLabel(); + if (object instanceof JRadioButton) { + JRadioButton button = (JRadioButton) object; + button.setText(this.model.getLabel(this, i)); + } + else if (object instanceof JLabel) { + JLabel label = (JLabel) object; + label.setText(this.model.getLabel(this, i)); + } + this.spinners[i].setRange(this.model.getMinimum(i), this.model.getMaximum(i)); + this.spinners[i].setValue(this.values[i]); + } + } + + void colorChanged() { + this.color = new Color(getColor(0), true); + Object parent = getParent(); + if (parent instanceof ColorChooserPanel) { + ColorChooserPanel chooser = (ColorChooserPanel) parent; + chooser.setSelectedColor(this.color); + chooser.repaint(); + } + } + + float getValueX() { + return this.spinners[this.x].getValue(); + } + + float getValueY() { + return 1.0f - this.spinners[this.y].getValue(); + } + + float getValueZ() { + return 1.0f - this.spinners[this.z].getValue(); + } + + void setValue(float z) { + this.spinners[this.z].setValue(1.0f - z); + colorChanged(); + } + + void setValue(float x, float y) { + this.spinners[this.x].setValue(x); + this.spinners[this.y].setValue(1.0f - y); + colorChanged(); + } + + int getColor(float z) { + setDefaultValue(this.x); + setDefaultValue(this.y); + this.values[this.z] = 1.0f - z; + return getColor(3); + } + + int getColor(float x, float y) { + this.values[this.x] = x; + this.values[this.y] = 1.0f - y; + setValue(this.z); + return getColor(3); + } + + void setColor(Color color) { + if (!color.equals(this.color)) { + this.color = color; + this.model.setColor(color.getRGB(), this.values); + for (int i = 0; i < this.model.getCount(); i++) { + this.spinners[i].setValue(this.values[i]); + } + } + } + + private int getColor(int index) { + while (index < this.model.getCount()) { + setValue(index++); + } + return this.model.getColor(this.values); + } + + private void setValue(int index) { + this.values[index] = this.spinners[index].getValue(); + } + + private void setDefaultValue(int index) { + float value = this.model.getDefault(index); + this.values[index] = (value < 0.0f) + ? this.spinners[index].getValue() + : value; + } +} diff --git a/jdk/src/share/classes/javax/swing/colorchooser/DefaultHSBChooserPanel.java b/jdk/src/share/classes/javax/swing/colorchooser/DefaultHSBChooserPanel.java deleted file mode 100644 index 89759e247a4..00000000000 --- a/jdk/src/share/classes/javax/swing/colorchooser/DefaultHSBChooserPanel.java +++ /dev/null @@ -1,801 +0,0 @@ -/* - * Copyright 1998-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package javax.swing.colorchooser; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import javax.swing.event.*; -import javax.swing.border.*; -import java.awt.image.*; -import java.util.Locale; - -/** - * Implements the default HSB Color chooser - * - * @author Tom Santos - * @author Steve Wilson - * @author Mark Davidson - * @author Shannon Hickey - */ -class DefaultHSBChooserPanel extends AbstractColorChooserPanel implements ChangeListener, HierarchyListener { - - private transient HSBImage palette; - private transient HSBImage sliderPalette; - - private transient Image paletteImage; - private transient Image sliderPaletteImage; - - private JSlider slider; - private JSpinner hField; - private JSpinner sField; - private JSpinner bField; - - private JTextField redField; - private JTextField greenField; - private JTextField blueField; - - private boolean isAdjusting = false; // Flag which indicates that values are set internally - private Point paletteSelection = new Point(); - private JLabel paletteLabel; - private JLabel sliderPaletteLabel; - - private JRadioButton hRadio; - private JRadioButton sRadio; - private JRadioButton bRadio; - - private static final int PALETTE_DIMENSION = 200; - private static final int MAX_HUE_VALUE = 359; - private static final int MAX_SATURATION_VALUE = 100; - private static final int MAX_BRIGHTNESS_VALUE = 100; - - private int currentMode = HUE_MODE; - - private static final int HUE_MODE = 0; - private static final int SATURATION_MODE = 1; - private static final int BRIGHTNESS_MODE = 2; - - public DefaultHSBChooserPanel() { - } - - private void addPaletteListeners() { - paletteLabel.addMouseListener(new MouseAdapter() { - public void mousePressed(MouseEvent e ) { - float[] hsb = new float[3]; - palette.getHSBForLocation( e.getX(), e.getY(), hsb ); - updateHSB( hsb[0], hsb[1], hsb[2] ); - } - }); - - paletteLabel.addMouseMotionListener(new MouseMotionAdapter() { - public void mouseDragged( MouseEvent e ){ - int labelWidth = paletteLabel.getWidth(); - - int labelHeight = paletteLabel.getHeight(); - int x = e.getX(); - int y = e.getY(); - - if ( x >= labelWidth ) { - x = labelWidth - 1; - } - - if ( y >= labelHeight ) { - y = labelHeight - 1; - } - - if ( x < 0 ) { - x = 0; - } - - if ( y < 0 ) { - y = 0; - } - - float[] hsb = new float[3]; - palette.getHSBForLocation( x, y, hsb ); - updateHSB( hsb[0], hsb[1], hsb[2] ); - } - }); - } - - private void updatePalette( float h, float s, float b ) { - int x = 0; - int y = 0; - - switch ( currentMode ) { - case HUE_MODE: - if ( h != palette.getHue() ) { - palette.setHue( h ); - palette.nextFrame(); - } - x = PALETTE_DIMENSION - (int)(s * PALETTE_DIMENSION); - y = PALETTE_DIMENSION - (int)(b * PALETTE_DIMENSION); - break; - case SATURATION_MODE: - if ( s != palette.getSaturation() ) { - palette.setSaturation( s ); - palette.nextFrame(); - } - x = (int)(h * PALETTE_DIMENSION); - y = PALETTE_DIMENSION - (int)(b * PALETTE_DIMENSION); - break; - case BRIGHTNESS_MODE: - if ( b != palette.getBrightness() ) { - palette.setBrightness( b ); - palette.nextFrame(); - } - x = (int)(h * PALETTE_DIMENSION); - y = PALETTE_DIMENSION - (int)(s * PALETTE_DIMENSION); - break; - } - - paletteSelection.setLocation( x, y ); - paletteLabel.repaint(); - } - - private void updateSlider( float h, float s, float b ) { - // Update the slider palette if necessary. - // When the slider is the hue slider or the hue hasn't changed, - // the hue of the palette will not need to be updated. - if (currentMode != HUE_MODE && h != sliderPalette.getHue() ) { - sliderPalette.setHue( h ); - sliderPalette.nextFrame(); - } - - float value = 0f; - - switch ( currentMode ) { - case HUE_MODE: - value = h; - break; - case SATURATION_MODE: - value = s; - break; - case BRIGHTNESS_MODE: - value = b; - break; - } - - slider.setValue( Math.round(value * (slider.getMaximum())) ); - } - - private void updateHSBTextFields( float hue, float saturation, float brightness ) { - int h = Math.round(hue * 359); - int s = Math.round(saturation * 100); - int b = Math.round(brightness * 100); - - if (((Integer)hField.getValue()).intValue() != h) { - hField.setValue(new Integer(h)); - } - if (((Integer)sField.getValue()).intValue() != s) { - sField.setValue(new Integer(s)); - } - if (((Integer)bField.getValue()).intValue() != b) { - bField.setValue(new Integer(b)); - } - } - - /** - * Updates the values of the RGB fields to reflect the new color change - */ - private void updateRGBTextFields( Color color ) { - redField.setText(String.valueOf(color.getRed())); - greenField.setText(String.valueOf(color.getGreen())); - blueField.setText(String.valueOf(color.getBlue())); - } - - /** - * Main internal method of updating the ui controls and the color model. - */ - private void updateHSB( float h, float s, float b ) { - if ( !isAdjusting ) { - isAdjusting = true; - - updatePalette( h, s, b ); - updateSlider( h, s, b ); - updateHSBTextFields( h, s, b ); - - Color color = Color.getHSBColor(h, s, b); - updateRGBTextFields( color ); - - getColorSelectionModel().setSelectedColor( color ); - - isAdjusting = false; - } - } - - /** - * Invoked automatically when the model's state changes. - * It is also called by installChooserPanel to allow - * you to set up the initial state of your chooser. - * Override this method to update your ChooserPanel. - */ - public void updateChooser() { - if ( !isAdjusting ) { - float[] hsb = getHSBColorFromModel(); - updateHSB( hsb[0], hsb[1], hsb[2] ); - } - } - - public void installChooserPanel(JColorChooser enclosingChooser) { - super.installChooserPanel(enclosingChooser); - setInheritsPopupMenu(true); - addHierarchyListener(this); - } - - /** - * Invoked when the panel is removed from the chooser. - */ - public void uninstallChooserPanel(JColorChooser enclosingChooser) { - super.uninstallChooserPanel(enclosingChooser); - cleanupPalettesIfNecessary(); - removeAll(); - removeHierarchyListener(this); - } - - /** - * Returns an float array containing the HSB values of the selected color from - * the ColorSelectionModel - */ - private float[] getHSBColorFromModel() { - Color color = getColorFromModel(); - float[] hsb = new float[3]; - Color.RGBtoHSB( color.getRed(), color.getGreen(), color.getBlue(), hsb ); - - return hsb; - } - - /** - * Builds a new chooser panel. - */ - protected void buildChooser() { - setLayout(new BorderLayout()); - JComponent spp = buildSliderPalettePanel(); - spp.setInheritsPopupMenu(true); - add(spp, BorderLayout.BEFORE_LINE_BEGINS); - - JPanel controlHolder = new JPanel(new SmartGridLayout(1,3)); - JComponent hsbControls = buildHSBControls(); - hsbControls.setInheritsPopupMenu(true); - controlHolder.add(hsbControls); - - controlHolder.add(new JLabel(" ")); // spacer - - JComponent rgbControls = buildRGBControls(); - rgbControls.setInheritsPopupMenu(true); - controlHolder.add(rgbControls); - controlHolder.setInheritsPopupMenu(true); - - controlHolder.setBorder(new EmptyBorder( 10, 5, 10, 5)); - add( controlHolder, BorderLayout.CENTER); - } - - /** - * Creates the panel with the uneditable RGB field - */ - private JComponent buildRGBControls() { - JPanel panel = new JPanel(new SmartGridLayout(2,3)); - panel.setInheritsPopupMenu(true); - - Color color = getColorFromModel(); - redField = new JTextField( String.valueOf(color.getRed()), 3 ); - redField.setEditable(false); - redField.setHorizontalAlignment( JTextField.RIGHT ); - redField.setInheritsPopupMenu(true); - - greenField = new JTextField(String.valueOf(color.getGreen()), 3 ); - greenField.setEditable(false); - greenField.setHorizontalAlignment( JTextField.RIGHT ); - greenField.setInheritsPopupMenu(true); - - blueField = new JTextField( String.valueOf(color.getBlue()), 3 ); - blueField.setEditable(false); - blueField.setHorizontalAlignment( JTextField.RIGHT ); - blueField.setInheritsPopupMenu(true); - - Locale locale = getLocale(); - String redString = UIManager.getString("ColorChooser.hsbRedText", locale); - String greenString = UIManager.getString("ColorChooser.hsbGreenText", locale); - String blueString = UIManager.getString("ColorChooser.hsbBlueText", locale); - - panel.add( new JLabel(redString) ); - panel.add( redField ); - panel.add( new JLabel(greenString) ); - panel.add( greenField ); - panel.add( new JLabel(blueString) ); - panel.add( blueField ); - - return panel; - } - - /** - * Creates the panel with the editable HSB fields and the radio buttons. - */ - private JComponent buildHSBControls() { - - Locale locale = getLocale(); - String hueString = UIManager.getString("ColorChooser.hsbHueText", locale); - String saturationString = UIManager.getString("ColorChooser.hsbSaturationText", locale); - String brightnessString = UIManager.getString("ColorChooser.hsbBrightnessText", locale); - - RadioButtonHandler handler = new RadioButtonHandler(); - - hRadio = new JRadioButton(hueString); - hRadio.addActionListener(handler); - hRadio.setSelected(true); - hRadio.setInheritsPopupMenu(true); - - sRadio = new JRadioButton(saturationString); - sRadio.addActionListener(handler); - sRadio.setInheritsPopupMenu(true); - - bRadio = new JRadioButton(brightnessString); - bRadio.addActionListener(handler); - bRadio.setInheritsPopupMenu(true); - - ButtonGroup group = new ButtonGroup(); - group.add(hRadio); - group.add(sRadio); - group.add(bRadio); - - float[] hsb = getHSBColorFromModel(); - - hField = new JSpinner(new SpinnerNumberModel((int)(hsb[0] * 359), 0, 359, 1)); - sField = new JSpinner(new SpinnerNumberModel((int)(hsb[1] * 100), 0, 100, 1)); - bField = new JSpinner(new SpinnerNumberModel((int)(hsb[2] * 100), 0, 100, 1)); - - hField.addChangeListener(this); - sField.addChangeListener(this); - bField.addChangeListener(this); - - hField.setInheritsPopupMenu(true); - sField.setInheritsPopupMenu(true); - bField.setInheritsPopupMenu(true); - - JPanel panel = new JPanel( new SmartGridLayout(2, 3) ); - - panel.add(hRadio); - panel.add(hField); - panel.add(sRadio); - panel.add(sField); - panel.add(bRadio); - panel.add(bField); - panel.setInheritsPopupMenu(true); - - return panel; - } - - /** - * Handler for the radio button classes. - */ - private class RadioButtonHandler implements ActionListener { - public void actionPerformed(ActionEvent evt) { - Object obj = evt.getSource(); - - if (obj instanceof JRadioButton) { - JRadioButton button = (JRadioButton)obj; - if (button == hRadio) { - setMode(HUE_MODE); - } else if (button == sRadio) { - setMode(SATURATION_MODE); - } else if (button == bRadio) { - setMode(BRIGHTNESS_MODE); - } - } - } - } - - private void setMode(int mode) { - if (currentMode == mode) { - return; - } - - isAdjusting = true; // Ensure no events propagate from changing slider value. - currentMode = mode; - - float[] hsb = getHSBColorFromModel(); - - switch (currentMode) { - case HUE_MODE: - slider.setInverted(true); - slider.setMaximum(MAX_HUE_VALUE); - palette.setValues(HSBImage.HSQUARE, hsb[0], 1.0f, 1.0f); - sliderPalette.setValues(HSBImage.HSLIDER, 0f, 1.0f, 1.0f); - break; - case SATURATION_MODE: - slider.setInverted(false); - slider.setMaximum(MAX_SATURATION_VALUE); - palette.setValues(HSBImage.SSQUARE, hsb[0], hsb[1], 1.0f); - sliderPalette.setValues(HSBImage.SSLIDER, hsb[0], 1.0f, 1.0f); - break; - case BRIGHTNESS_MODE: - slider.setInverted(false); - slider.setMaximum(MAX_BRIGHTNESS_VALUE); - palette.setValues(HSBImage.BSQUARE, hsb[0], 1.0f, hsb[2]); - sliderPalette.setValues(HSBImage.BSLIDER, hsb[0], 1.0f, 1.0f); - break; - } - - isAdjusting = false; - - palette.nextFrame(); - sliderPalette.nextFrame(); - - updateChooser(); - } - - protected JComponent buildSliderPalettePanel() { - - // This slider has to have a minimum of 0. A lot of math in this file is simplified due to this. - slider = new JSlider(JSlider.VERTICAL, 0, MAX_HUE_VALUE, 0); - slider.setInverted(true); - slider.setPaintTrack(false); - slider.setPreferredSize(new Dimension(slider.getPreferredSize().width, PALETTE_DIMENSION + 15)); - slider.addChangeListener(this); - slider.setInheritsPopupMenu(true); - // We're not painting ticks, but need to ask UI classes to - // paint arrow shape anyway, if possible. - slider.putClientProperty("Slider.paintThumbArrowShape", Boolean.TRUE); - paletteLabel = createPaletteLabel(); - addPaletteListeners(); - sliderPaletteLabel = new JLabel(); - - JPanel panel = new JPanel(); - panel.add( paletteLabel ); - panel.add( slider ); - panel.add( sliderPaletteLabel ); - - initializePalettesIfNecessary(); - - return panel; - } - - private void initializePalettesIfNecessary() { - if (palette != null) { - return; - } - - float[] hsb = getHSBColorFromModel(); - - switch(currentMode){ - case HUE_MODE: - palette = new HSBImage(HSBImage.HSQUARE, PALETTE_DIMENSION, PALETTE_DIMENSION, hsb[0], 1.0f, 1.0f); - sliderPalette = new HSBImage(HSBImage.HSLIDER, 16, PALETTE_DIMENSION, 0f, 1.0f, 1.0f); - break; - case SATURATION_MODE: - palette = new HSBImage(HSBImage.SSQUARE, PALETTE_DIMENSION, PALETTE_DIMENSION, 1.0f, hsb[1], 1.0f); - sliderPalette = new HSBImage(HSBImage.SSLIDER, 16, PALETTE_DIMENSION, 1.0f, 0f, 1.0f); - break; - case BRIGHTNESS_MODE: - palette = new HSBImage(HSBImage.BSQUARE, PALETTE_DIMENSION, PALETTE_DIMENSION, 1.0f, 1.0f, hsb[2]); - sliderPalette = new HSBImage(HSBImage.BSLIDER, 16, PALETTE_DIMENSION, 1.0f, 1.0f, 0f); - break; - } - paletteImage = Toolkit.getDefaultToolkit().createImage(palette); - sliderPaletteImage = Toolkit.getDefaultToolkit().createImage(sliderPalette); - - paletteLabel.setIcon(new ImageIcon(paletteImage)); - sliderPaletteLabel.setIcon(new ImageIcon(sliderPaletteImage)); - } - - private void cleanupPalettesIfNecessary() { - if (palette == null) { - return; - } - - palette.aborted = true; - sliderPalette.aborted = true; - - palette.nextFrame(); - sliderPalette.nextFrame(); - - palette = null; - sliderPalette = null; - - paletteImage = null; - sliderPaletteImage = null; - - paletteLabel.setIcon(null); - sliderPaletteLabel.setIcon(null); - } - - protected JLabel createPaletteLabel() { - return new JLabel() { - protected void paintComponent( Graphics g ) { - super.paintComponent( g ); - g.setColor( Color.white ); - g.drawOval( paletteSelection.x - 4, paletteSelection.y - 4, 8, 8 ); - } - }; - } - - public String getDisplayName() { - return UIManager.getString("ColorChooser.hsbNameText", getLocale()); - } - - /** - * Provides a hint to the look and feel as to the - * KeyEvent.VK constant that can be used as a mnemonic to - * access the panel. A return value <= 0 indicates there is no mnemonic. - *

      - * The return value here is a hint, it is ultimately up to the look - * and feel to honor the return value in some meaningful way. - *

      - * This implementation looks up the value from the default - * ColorChooser.hsbMnemonic, or if it - * isn't available (or not an Integer) returns -1. - * The lookup for the default is done through the UIManager: - * UIManager.get("ColorChooser.rgbMnemonic");. - * - * @return KeyEvent.VK constant identifying the mnemonic; <= 0 for no - * mnemonic - * @see #getDisplayedMnemonicIndex - * @since 1.4 - */ - public int getMnemonic() { - return getInt("ColorChooser.hsbMnemonic", -1); - } - - /** - * Provides a hint to the look and feel as to the index of the character in - * getDisplayName that should be visually identified as the - * mnemonic. The look and feel should only use this if - * getMnemonic returns a value > 0. - *

      - * The return value here is a hint, it is ultimately up to the look - * and feel to honor the return value in some meaningful way. For example, - * a look and feel may wish to render each - * AbstractColorChooserPanel in a JTabbedPane, - * and further use this return value to underline a character in - * the getDisplayName. - *

      - * This implementation looks up the value from the default - * ColorChooser.rgbDisplayedMnemonicIndex, or if it - * isn't available (or not an Integer) returns -1. - * The lookup for the default is done through the UIManager: - * UIManager.get("ColorChooser.hsbDisplayedMnemonicIndex");. - * - * @return Character index to render mnemonic for; -1 to provide no - * visual identifier for this panel. - * @see #getMnemonic - * @since 1.4 - */ - public int getDisplayedMnemonicIndex() { - return getInt("ColorChooser.hsbDisplayedMnemonicIndex", -1); - } - - public Icon getSmallDisplayIcon() { - return null; - } - - public Icon getLargeDisplayIcon() { - return null; - } - - /** - * Class for the slider and palette images. - */ - class HSBImage extends SyntheticImage { - protected float h = .0f; - protected float s = .0f; - protected float b = .0f; - protected float[] hsb = new float[3]; - - protected boolean isDirty = true; - protected int cachedY; - protected int cachedColor; - protected int type; - - private static final int HSQUARE = 0; - private static final int SSQUARE = 1; - private static final int BSQUARE = 2; - private static final int HSLIDER = 3; - private static final int SSLIDER = 4; - private static final int BSLIDER = 5; - - protected HSBImage(int type, int width, int height, float h, float s, float b) { - super(width, height); - setValues(type, h, s, b); - } - - public void setValues(int type, float h, float s, float b) { - this.type = type; - cachedY = -1; - cachedColor = 0; - setHue( h ); - setSaturation( s ); - setBrightness( b ); - } - - public final void setHue( float hue ) { - h = hue; - } - - public final void setSaturation( float saturation ) { - s = saturation; - } - - public final void setBrightness( float brightness ) { - b = brightness; - } - - public final float getHue() { - return h; - } - - public final float getSaturation() { - return s; - } - - public final float getBrightness() { - return b; - } - - protected boolean isStatic() { - return false; - } - - public synchronized void nextFrame() { - isDirty = true; - notifyAll(); - } - - public synchronized void addConsumer(ImageConsumer ic) { - isDirty = true; - super.addConsumer(ic); - } - - private int getRGBForLocation( int x, int y ) { - if (type >= HSLIDER && y == cachedY) { - return cachedColor; - } - - getHSBForLocation( x, y, hsb ); - cachedY = y; - cachedColor = Color.HSBtoRGB( hsb[0], hsb[1], hsb[2] ); - - return cachedColor; - } - - public void getHSBForLocation( int x, int y, float[] hsbArray ) { - switch (type) { - case HSQUARE: { - float saturationStep = ((float)x) / width; - float brightnessStep = ((float)y) / height; - hsbArray[0] = h; - hsbArray[1] = s - saturationStep; - hsbArray[2] = b - brightnessStep; - break; - } - case SSQUARE: { - float brightnessStep = ((float)y) / height; - float step = 1.0f / ((float)width); - hsbArray[0] = x * step; - hsbArray[1] = s; - hsbArray[2] = 1.0f - brightnessStep; - break; - } - case BSQUARE: { - float saturationStep = ((float)y) / height; - float step = 1.0f / ((float)width); - hsbArray[0] = x * step; - hsbArray[1] = 1.0f - saturationStep; - hsbArray[2] = b; - break; - } - case HSLIDER: { - float step = 1.0f / ((float)height); - hsbArray[0] = y * step; - hsbArray[1] = s; - hsbArray[2] = b; - break; - } - case SSLIDER: { - float saturationStep = ((float)y) / height; - hsbArray[0] = h; - hsbArray[1] = s - saturationStep; - hsbArray[2] = b; - break; - } - case BSLIDER: { - float brightnessStep = ((float)y) / height; - hsbArray[0] = h; - hsbArray[1] = s; - hsbArray[2] = b - brightnessStep; - break; - } - } - } - - /** - * Overriden method from SyntheticImage - */ - protected void computeRow( int y, int[] row ) { - if ( y == 0 ) { - synchronized ( this ) { - try { - while ( !isDirty ) { - wait(); - } - } catch (InterruptedException ie) { - } - isDirty = false; - } - } - - if (aborted) { - return; - } - - for ( int i = 0; i < row.length; ++i ) { - row[i] = getRGBForLocation( i, y ); - } - } - } - - public void stateChanged(ChangeEvent e) { - if (e.getSource() == slider) { - boolean modelIsAdjusting = slider.getModel().getValueIsAdjusting(); - - if (!modelIsAdjusting && !isAdjusting) { - int sliderValue = slider.getValue(); - int sliderRange = slider.getMaximum(); - float value = (float)sliderValue / (float)sliderRange; - - float[] hsb = getHSBColorFromModel(); - - switch ( currentMode ){ - case HUE_MODE: - updateHSB(value, hsb[1], hsb[2]); - break; - case SATURATION_MODE: - updateHSB(hsb[0], value, hsb[2]); - break; - case BRIGHTNESS_MODE: - updateHSB(hsb[0], hsb[1], value); - break; - } - } - } else if (e.getSource() instanceof JSpinner) { - float hue = ((Integer)hField.getValue()).floatValue() / 359f; - float saturation = ((Integer)sField.getValue()).floatValue() / 100f; - float brightness = ((Integer)bField.getValue()).floatValue() / 100f; - - updateHSB(hue, saturation, brightness); - } - } - - public void hierarchyChanged(HierarchyEvent he) { - if ((he.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) { - if (isDisplayable()) { - initializePalettesIfNecessary(); - } else { - cleanupPalettesIfNecessary(); - } - } - } - -} diff --git a/jdk/src/share/classes/javax/swing/colorchooser/DefaultRGBChooserPanel.java b/jdk/src/share/classes/javax/swing/colorchooser/DefaultRGBChooserPanel.java deleted file mode 100644 index 28850dffaac..00000000000 --- a/jdk/src/share/classes/javax/swing/colorchooser/DefaultRGBChooserPanel.java +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright 1998-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package javax.swing.colorchooser; - -import javax.swing.*; -import javax.swing.event.*; -import java.awt.*; -import java.util.Locale; - -/** - * The standard RGB chooser. - *

      - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is - * appropriate for short term storage or RMI between applications running - * the same version of Swing. As of 1.4, support for long term storage - * of all JavaBeansTM - * has been added to the java.beans package. - * Please see {@link java.beans.XMLEncoder}. - * - * @author Steve Wilson - * @author Mark Davidson - * @see JColorChooser - * @see AbstractColorChooserPanel - */ -class DefaultRGBChooserPanel extends AbstractColorChooserPanel implements ChangeListener { - - protected JSlider redSlider; - protected JSlider greenSlider; - protected JSlider blueSlider; - protected JSpinner redField; - protected JSpinner blueField; - protected JSpinner greenField; - - private final int minValue = 0; - private final int maxValue = 255; - - private boolean isAdjusting = false; // indicates the fields are being set internally - - public DefaultRGBChooserPanel() { - super(); - setInheritsPopupMenu(true); - } - - /** - * Sets the values of the controls to reflect the color - */ - private void setColor( Color newColor ) { - int red = newColor.getRed(); - int blue = newColor.getBlue(); - int green = newColor.getGreen(); - - if (redSlider.getValue() != red) { - redSlider.setValue(red); - } - if (greenSlider.getValue() != green) { - greenSlider.setValue(green); - } - if (blueSlider.getValue() != blue) { - blueSlider.setValue(blue); - } - - if (((Integer)redField.getValue()).intValue() != red) - redField.setValue(new Integer(red)); - if (((Integer)greenField.getValue()).intValue() != green) - greenField.setValue(new Integer(green)); - if (((Integer)blueField.getValue()).intValue() != blue ) - blueField.setValue(new Integer(blue)); - } - - public String getDisplayName() { - return UIManager.getString("ColorChooser.rgbNameText", getLocale()); - } - - /** - * Provides a hint to the look and feel as to the - * KeyEvent.VK constant that can be used as a mnemonic to - * access the panel. A return value <= 0 indicates there is no mnemonic. - *

      - * The return value here is a hint, it is ultimately up to the look - * and feel to honor the return value in some meaningful way. - *

      - * This implementation looks up the value from the default - * ColorChooser.rgbMnemonic, or if it - * isn't available (or not an Integer) returns -1. - * The lookup for the default is done through the UIManager: - * UIManager.get("ColorChooser.rgbMnemonic");. - * - * @return KeyEvent.VK constant identifying the mnemonic; <= 0 for no - * mnemonic - * @see #getDisplayedMnemonicIndex - * @since 1.4 - */ - public int getMnemonic() { - return getInt("ColorChooser.rgbMnemonic", -1); - } - - /** - * Provides a hint to the look and feel as to the index of the character in - * getDisplayName that should be visually identified as the - * mnemonic. The look and feel should only use this if - * getMnemonic returns a value > 0. - *

      - * The return value here is a hint, it is ultimately up to the look - * and feel to honor the return value in some meaningful way. For example, - * a look and feel may wish to render each - * AbstractColorChooserPanel in a JTabbedPane, - * and further use this return value to underline a character in - * the getDisplayName. - *

      - * This implementation looks up the value from the default - * ColorChooser.rgbDisplayedMnemonicIndex, or if it - * isn't available (or not an Integer) returns -1. - * The lookup for the default is done through the UIManager: - * UIManager.get("ColorChooser.rgbDisplayedMnemonicIndex");. - * - * @return Character index to render mnemonic for; -1 to provide no - * visual identifier for this panel. - * @see #getMnemonic - * @since 1.4 - */ - public int getDisplayedMnemonicIndex() { - return getInt("ColorChooser.rgbDisplayedMnemonicIndex", -1); - } - - public Icon getSmallDisplayIcon() { - return null; - } - - public Icon getLargeDisplayIcon() { - return null; - } - - /** - * The background color, foreground color, and font are already set to the - * defaults from the defaults table before this method is called. - */ - public void installChooserPanel(JColorChooser enclosingChooser) { - super.installChooserPanel(enclosingChooser); - } - - protected void buildChooser() { - - Locale locale = getLocale(); - String redString = UIManager.getString("ColorChooser.rgbRedText", locale); - String greenString = UIManager.getString("ColorChooser.rgbGreenText", locale); - String blueString = UIManager.getString("ColorChooser.rgbBlueText", locale); - - setLayout( new BorderLayout() ); - Color color = getColorFromModel(); - - - JPanel enclosure = new JPanel(); - enclosure.setLayout( new SmartGridLayout( 3, 3 ) ); - enclosure.setInheritsPopupMenu(true); - - // The panel that holds the sliders - - add( enclosure, BorderLayout.CENTER ); - // sliderPanel.setBorder(new LineBorder(Color.black)); - - // The row for the red value - JLabel l = new JLabel(redString); - l.setDisplayedMnemonic(getInt("ColorChooser.rgbRedMnemonic", -1)); - enclosure.add(l); - redSlider = new JSlider(JSlider.HORIZONTAL, 0, 255, color.getRed()); - redSlider.setMajorTickSpacing( 85 ); - redSlider.setMinorTickSpacing( 17 ); - redSlider.setPaintTicks( true ); - redSlider.setPaintLabels( true ); - redSlider.setInheritsPopupMenu(true); - enclosure.add( redSlider ); - redField = new JSpinner( - new SpinnerNumberModel(color.getRed(), minValue, maxValue, 1)); - l.setLabelFor(redSlider); - redField.setInheritsPopupMenu(true); - JPanel redFieldHolder = new JPanel(new CenterLayout()); - redFieldHolder.setInheritsPopupMenu(true); - redField.addChangeListener(this); - redFieldHolder.add(redField); - enclosure.add(redFieldHolder); - - - // The row for the green value - l = new JLabel(greenString); - l.setDisplayedMnemonic(getInt("ColorChooser.rgbGreenMnemonic", -1)); - enclosure.add(l); - greenSlider = new JSlider(JSlider.HORIZONTAL, 0, 255, color.getGreen()); - greenSlider.setMajorTickSpacing( 85 ); - greenSlider.setMinorTickSpacing( 17 ); - greenSlider.setPaintTicks( true ); - greenSlider.setPaintLabels( true ); - greenSlider.setInheritsPopupMenu(true); - enclosure.add(greenSlider); - greenField = new JSpinner( - new SpinnerNumberModel(color.getGreen(), minValue, maxValue, 1)); - l.setLabelFor(greenSlider); - greenField.setInheritsPopupMenu(true); - JPanel greenFieldHolder = new JPanel(new CenterLayout()); - greenFieldHolder.add(greenField); - greenFieldHolder.setInheritsPopupMenu(true); - greenField.addChangeListener(this); - enclosure.add(greenFieldHolder); - - // The slider for the blue value - l = new JLabel(blueString); - l.setDisplayedMnemonic(getInt("ColorChooser.rgbBlueMnemonic", -1)); - enclosure.add(l); - blueSlider = new JSlider(JSlider.HORIZONTAL, 0, 255, color.getBlue()); - blueSlider.setMajorTickSpacing( 85 ); - blueSlider.setMinorTickSpacing( 17 ); - blueSlider.setPaintTicks( true ); - blueSlider.setPaintLabels( true ); - blueSlider.setInheritsPopupMenu(true); - enclosure.add(blueSlider); - blueField = new JSpinner( - new SpinnerNumberModel(color.getBlue(), minValue, maxValue, 1)); - l.setLabelFor(blueSlider); - blueField.setInheritsPopupMenu(true); - JPanel blueFieldHolder = new JPanel(new CenterLayout()); - blueFieldHolder.add(blueField); - blueField.addChangeListener(this); - blueFieldHolder.setInheritsPopupMenu(true); - enclosure.add(blueFieldHolder); - - redSlider.addChangeListener( this ); - greenSlider.addChangeListener( this ); - blueSlider.addChangeListener( this ); - - redSlider.putClientProperty("JSlider.isFilled", Boolean.TRUE); - greenSlider.putClientProperty("JSlider.isFilled", Boolean.TRUE); - blueSlider.putClientProperty("JSlider.isFilled", Boolean.TRUE); - } - - public void uninstallChooserPanel(JColorChooser enclosingChooser) { - super.uninstallChooserPanel(enclosingChooser); - removeAll(); - } - - public void updateChooser() { - if (!isAdjusting) { - isAdjusting = true; - - setColor(getColorFromModel()); - - isAdjusting = false; - } - } - - public void stateChanged( ChangeEvent e ) { - if ( e.getSource() instanceof JSlider && !isAdjusting) { - - int red = redSlider.getValue(); - int green = greenSlider.getValue(); - int blue = blueSlider.getValue() ; - Color color = new Color (red, green, blue); - - getColorSelectionModel().setSelectedColor(color); - } else if (e.getSource() instanceof JSpinner && !isAdjusting) { - - int red = ((Integer)redField.getValue()).intValue(); - int green = ((Integer)greenField.getValue()).intValue(); - int blue = ((Integer)blueField.getValue()).intValue(); - Color color = new Color (red, green, blue); - - getColorSelectionModel().setSelectedColor(color); - } - } - -} diff --git a/jdk/src/share/classes/javax/swing/colorchooser/DefaultSwatchChooserPanel.java b/jdk/src/share/classes/javax/swing/colorchooser/DefaultSwatchChooserPanel.java index 779b664a280..3cbd0df3b85 100644 --- a/jdk/src/share/classes/javax/swing/colorchooser/DefaultSwatchChooserPanel.java +++ b/jdk/src/share/classes/javax/swing/colorchooser/DefaultSwatchChooserPanel.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -213,17 +213,15 @@ class DefaultSwatchChooserPanel extends AbstractColorChooserPanel { class RecentSwatchListener extends MouseAdapter implements Serializable { public void mousePressed(MouseEvent e) { Color color = recentSwatchPanel.getColorForLocation(e.getX(), e.getY()); - getColorSelectionModel().setSelectedColor(color); - + setSelectedColor(color); } } class MainSwatchListener extends MouseAdapter implements Serializable { public void mousePressed(MouseEvent e) { Color color = swatchPanel.getColorForLocation(e.getX(), e.getY()); - getColorSelectionModel().setSelectedColor(color); + setSelectedColor(color); recentSwatchPanel.setMostRecentColor(color); - } } diff --git a/jdk/src/share/classes/javax/swing/colorchooser/DiagramComponent.java b/jdk/src/share/classes/javax/swing/colorchooser/DiagramComponent.java new file mode 100644 index 00000000000..04905589e99 --- /dev/null +++ b/jdk/src/share/classes/javax/swing/colorchooser/DiagramComponent.java @@ -0,0 +1,160 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.swing.colorchooser; + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.image.BufferedImage; +import javax.swing.JComponent; + +final class DiagramComponent extends JComponent implements MouseListener, MouseMotionListener { + + private final ColorPanel panel; + private final boolean diagram; + + private final Insets insets = new Insets(0, 0, 0, 0); + + private int width; + private int height; + + private int[] array; + private BufferedImage image; + + DiagramComponent(ColorPanel panel, boolean diagram) { + this.panel = panel; + this.diagram = diagram; + addMouseListener(this); + addMouseMotionListener(this); + } + + @Override + protected void paintComponent(Graphics g) { + getInsets(this.insets); + this.width = getWidth() - this.insets.left - this.insets.right; + this.height = getHeight() - this.insets.top - this.insets.bottom; + + boolean update = (this.image == null) + || (this.width != this.image.getWidth()) + || (this.height != this.image.getHeight()); + if (update) { + int size = this.width * this.height; + if ((this.array == null) || (this.array.length < size)) { + this.array = new int[size]; + } + this.image = new BufferedImage(this.width, this.height, BufferedImage.TYPE_INT_RGB); + } + { + float dx = 1.0f / (float) (this.width - 1); + float dy = 1.0f / (float) (this.height - 1); + + int offset = 0; + float y = 0.0f; + for (int h = 0; h < this.height; h++, y += dy) { + if (this.diagram) { + float x = 0.0f; + for (int w = 0; w < this.width; w++, x += dx, offset++) { + this.array[offset] = this.panel.getColor(x, y); + } + } + else { + int color = this.panel.getColor(y); + for (int w = 0; w < this.width; w++, offset++) { + this.array[offset] = color; + } + } + } + } + this.image.setRGB(0, 0, this.width, this.height, this.array, 0, this.width); + g.drawImage(this.image, this.insets.left, this.insets.top, this.width, this.height, this); + if (isEnabled()) { + this.width--; + this.height--; + g.setXORMode(Color.WHITE); + g.setColor(Color.BLACK); + if (this.diagram) { + int x = getValue(this.panel.getValueX(), this.insets.left, this.width); + int y = getValue(this.panel.getValueY(), this.insets.top, this.height); + g.drawLine(x - 8, y, x + 8, y); + g.drawLine(x, y - 8, x, y + 8); + } + else { + int z = getValue(this.panel.getValueZ(), this.insets.top, this.height); + g.drawLine(this.insets.left, z, this.insets.left + this.width, z); + } + g.setPaintMode(); + } + } + + public void mousePressed(MouseEvent event) { + mouseDragged(event); + } + + public void mouseReleased(MouseEvent event) { + } + + public void mouseClicked(MouseEvent event) { + } + + public void mouseEntered(MouseEvent event) { + } + + public void mouseExited(MouseEvent event) { + } + + public void mouseMoved(MouseEvent event) { + } + + public void mouseDragged(MouseEvent event) { + if (isEnabled()) { + float y = getValue(event.getY(), this.insets.top, this.height); + if (this.diagram) { + float x = getValue(event.getX(), this.insets.left, this.width); + this.panel.setValue(x, y); + } + else { + this.panel.setValue(y); + } + } + } + + private static int getValue(float value, int min, int max) { + return min + (int) (value * (float) (max)); + } + + private static float getValue(int value, int min, int max) { + if (min < value) { + value -= min; + return (value < max) + ? (float) value / (float) max + : 1.0f; + } + return 0.0f; + } +} diff --git a/jdk/src/share/classes/javax/swing/colorchooser/SlidingSpinner.java b/jdk/src/share/classes/javax/swing/colorchooser/SlidingSpinner.java new file mode 100644 index 00000000000..99e9bf29858 --- /dev/null +++ b/jdk/src/share/classes/javax/swing/colorchooser/SlidingSpinner.java @@ -0,0 +1,118 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.swing.colorchooser; + +import javax.swing.JComponent; +import javax.swing.JSlider; +import javax.swing.JSpinner; +import javax.swing.JSpinner.DefaultEditor; +import javax.swing.SpinnerNumberModel; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +final class SlidingSpinner implements ChangeListener { + + private final ColorPanel panel; + private final JComponent label; + private final SpinnerNumberModel model = new SpinnerNumberModel(); + private final JSlider slider = new JSlider(); + private final JSpinner spinner = new JSpinner(this.model); + private float value; + private boolean internal; + + SlidingSpinner(ColorPanel panel, JComponent label) { + this.panel = panel; + this.label = label; + this.slider.addChangeListener(this); + this.spinner.addChangeListener(this); + DefaultEditor editor = (DefaultEditor) this.spinner.getEditor(); + ValueFormatter.init(3, false, editor.getTextField()); + editor.setFocusable(false); + this.spinner.setFocusable(false); + } + + JComponent getLabel() { + return this.label; + } + + JSlider getSlider() { + return this.slider; + } + + JSpinner getSpinner() { + return this.spinner; + } + + float getValue() { + return this.value; + } + + void setValue(float value) { + int min = this.slider.getMinimum(); + int max = this.slider.getMaximum(); + this.internal = true; + this.slider.setValue(min + (int) (value * (float) (max - min))); + this.spinner.setValue(Integer.valueOf(this.slider.getValue())); + this.internal = false; + this.value = value; + } + + void setRange(int min, int max) { + this.internal = true; + this.slider.setMinimum(min); + this.slider.setMaximum(max); + this.model.setMinimum(Integer.valueOf(min)); + this.model.setMaximum(Integer.valueOf(max)); + this.internal = false; + } + + void setVisible(boolean visible) { + this.label.setVisible(visible); + this.slider.setVisible(visible); + this.spinner.setVisible(visible); + } + + public void stateChanged(ChangeEvent event) { + if (!this.internal) { + if (this.spinner == event.getSource()) { + Object value = this.spinner.getValue(); + if (value instanceof Integer) { + this.internal = true; + this.slider.setValue((Integer) value); + this.internal = false; + } + } + int value = this.slider.getValue(); + this.internal = true; + this.spinner.setValue(Integer.valueOf(value)); + this.internal = false; + int min = this.slider.getMinimum(); + int max = this.slider.getMaximum(); + this.value = (float) (value - min) / (float) (max - min); + this.panel.colorChanged(); + } + } +} diff --git a/jdk/src/share/classes/javax/swing/colorchooser/SyntheticImage.java b/jdk/src/share/classes/javax/swing/colorchooser/SyntheticImage.java deleted file mode 100644 index cec69e9c39d..00000000000 --- a/jdk/src/share/classes/javax/swing/colorchooser/SyntheticImage.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package javax.swing.colorchooser; - -import java.awt.*; -import java.awt.image.*; - -/** A helper class to make computing synthetic images a little easier. - * All you need to do is define a subclass that overrides computeRow - * to compute a row of the image. It is passed the y coordinate of the - * row and an array into which to put the pixels in - * - * standard ARGB format. - *

      Normal usage looks something like this: - *

       Image i = createImage(new SyntheticImage(200, 100) {
      - *       protected void computeRow(int y, int[] row) {
      - *         for(int i = width; --i>=0; ) {
      - *             int grey = i*255/(width-1);
      - *             row[i] = (255<<24)|(grey<<16)|(grey<<8)|grey;
      - *         }
      - *       }
      - *   }
      - *  
      This creates a image 200 pixels wide and 100 pixels high - * that is a horizontal grey ramp, going from black on the left to - * white on the right. - *

      - * If the image is to be a movie, override isStatic to return false, - * y cycling back to 0 is computeRow's signal that the next - * frame has started. It is acceptable (expected?) for computeRow(0,r) - * to pause until the appropriate time to start the next frame. - * - * @author James Gosling - */ -abstract class SyntheticImage implements ImageProducer { - private SyntheticImageGenerator root; - protected int width=10, height=100; - static final ColorModel cm = ColorModel.getRGBdefault(); - public static final int pixMask = 0xFF; - private Thread runner; - protected SyntheticImage() { } - protected SyntheticImage(int w, int h) { width = w; height = h; } - protected void computeRow(int y, int[] row) { - int p = 255-255*y/(height-1); - p = (pixMask<<24)|(p<<16)|(p<<8)|p; - for (int i = row.length; --i>=0; ) row[i] = p; - } - public synchronized void addConsumer(ImageConsumer ic){ - for (SyntheticImageGenerator ics = root; ics != null; ics = ics.next) - if (ics.ic == ic) return; - root = new SyntheticImageGenerator(ic, root, this); - } - public synchronized boolean isConsumer(ImageConsumer ic){ - for (SyntheticImageGenerator ics = root; ics != null; ics = ics.next) - if (ics.ic == ic) return true; - return false; - } - public synchronized void removeConsumer(ImageConsumer ic) { - SyntheticImageGenerator prev = null; - for (SyntheticImageGenerator ics = root; ics != null; ics = ics.next) { - if (ics.ic == ic) { - ics.useful = false; - if (prev!=null) prev.next = ics.next; - else root = ics.next; - return; - } - prev = ics; - } - } - public synchronized void startProduction(ImageConsumer ic) { - addConsumer(ic); - for (SyntheticImageGenerator ics = root; ics != null; ics = ics.next) - if (ics.useful && !ics.isAlive()) - ics.start(); - } - protected boolean isStatic() { return true; } - public void nextFrame(int param) {}//Override if !isStatic - public void requestTopDownLeftRightResend(ImageConsumer ic){} - - protected volatile boolean aborted = false; -} - -class SyntheticImageGenerator extends Thread { - ImageConsumer ic; - boolean useful; - SyntheticImageGenerator next; - SyntheticImage parent; - SyntheticImageGenerator(ImageConsumer ic, SyntheticImageGenerator next, - SyntheticImage parent) { - super("SyntheticImageGenerator"); - this.ic = ic; - this.next = next; - this.parent = parent; - useful = true; - setDaemon(true); - } - public void run() { - ImageConsumer ic = this.ic; - int w = parent.width; - int h = parent.height; - int hints = ic.SINGLEPASS|ic.COMPLETESCANLINES|ic.TOPDOWNLEFTRIGHT; - if (parent.isStatic()) - hints |= ic.SINGLEFRAME; - ic.setHints(hints); - ic.setDimensions(w, h); - ic.setProperties(null); - ic.setColorModel(parent.cm); - - if (useful) { - int[] row=new int[w]; - doPrivileged( new Runnable() { - public void run() { - Thread.currentThread().setPriority(Thread.MIN_PRIORITY); - } - }); - - do { - for (int y = 0; y>= 4; + } + return new String(array).toUpperCase(ENGLISH); + } + throw new ParseException("illegal object", 0); + } + + @Override + protected DocumentFilter getDocumentFilter() { + return this.filter; + } + + public void focusGained(FocusEvent event) { + Object source = event.getSource(); + if (source instanceof JFormattedTextField) { + this.text = (JFormattedTextField) source; + SwingUtilities.invokeLater(this); + } + } + + public void focusLost(FocusEvent event) { + } + + public void run() { + if (this.text != null) { + this.text.selectAll(); + } + } + + private boolean isValid(int length) { + return (0 <= length) && (length <= this.length); + } + + private boolean isValid(String text) { + int length = text.length(); + for (int i = 0; i < length; i++) { + char ch = text.charAt(i); + if (Character.digit(ch, this.radix) < 0) { + return false; + } + } + return true; + } +} diff --git a/jdk/src/share/classes/javax/swing/filechooser/FileSystemView.java b/jdk/src/share/classes/javax/swing/filechooser/FileSystemView.java index 855a357575e..c2ff7bb8df8 100644 --- a/jdk/src/share/classes/javax/swing/filechooser/FileSystemView.java +++ b/jdk/src/share/classes/javax/swing/filechooser/FileSystemView.java @@ -136,8 +136,8 @@ public abstract class FileSystemView { } File[] roots = getRoots(); - for (int i = 0; i < roots.length; i++) { - if (roots[i].equals(f)) { + for (File root : roots) { + if (root.equals(f)) { return true; } } @@ -252,8 +252,8 @@ public abstract class FileSystemView { return true; } File[] children = getFiles(folder, false); - for (int i = 0; i < children.length; i++) { - if (file.equals(children[i])) { + for (File child : children) { + if (file.equals(child)) { return true; } } @@ -276,9 +276,9 @@ public abstract class FileSystemView { public File getChild(File parent, String fileName) { if (parent instanceof ShellFolder) { File[] children = getFiles(parent, false); - for (int i = 0; i < children.length; i++) { - if (children[i].getName().equals(fileName)) { - return children[i]; + for (File child : children) { + if (child.getName().equals(fileName)) { + return child; } } } @@ -444,7 +444,7 @@ public abstract class FileSystemView { * Gets the list of shown (i.e. not hidden) files. */ public File[] getFiles(File dir, boolean useFileHiding) { - Vector files = new Vector(); + Vector files = new Vector(); // add all files in dir @@ -483,7 +483,7 @@ public abstract class FileSystemView { } } - return (File[])files.toArray(new File[files.size()]); + return files.toArray(new File[files.size()]); } @@ -590,7 +590,7 @@ class UnixFileSystemView extends FileSystemView { if(containingDir == null) { throw new IOException("Containing directory is null:"); } - File newFolder = null; + File newFolder; // Unix - using OpenWindows' default folder name. Can't find one for Motif/CDE. newFolder = createFileObject(containingDir, newFolderString); int i = 1; @@ -614,11 +614,7 @@ class UnixFileSystemView extends FileSystemView { } public boolean isDrive(File dir) { - if (isFloppyDrive(dir)) { - return true; - } else { - return false; - } + return isFloppyDrive(dir); } public boolean isFloppyDrive(File dir) { @@ -700,9 +696,8 @@ class WindowsFileSystemView extends FileSystemView { if(containingDir == null) { throw new IOException("Containing directory is null:"); } - File newFolder = null; // Using NT's default folder name - newFolder = createFileObject(containingDir, newFolderString); + File newFolder = createFileObject(containingDir, newFolderString); int i = 2; while (newFolder.exists() && (i < 100)) { newFolder = createFileObject(containingDir, MessageFormat.format( @@ -770,9 +765,8 @@ class GenericFileSystemView extends FileSystemView { if(containingDir == null) { throw new IOException("Containing directory is null:"); } - File newFolder = null; // Using NT's default folder name - newFolder = createFileObject(containingDir, newFolderString); + File newFolder = createFileObject(containingDir, newFolderString); if(newFolder.exists()) { throw new IOException("Directory already exists:" + newFolder.getAbsolutePath()); diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicButtonListener.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicButtonListener.java index 05e35cc72ec..c366217b73d 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicButtonListener.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicButtonListener.java @@ -165,7 +165,7 @@ public class BasicButtonListener implements MouseListener, MouseMotionListener, JRootPane root = b.getRootPane(); if (root != null) { BasicButtonUI ui = (BasicButtonUI)BasicLookAndFeel.getUIOfType( - ((AbstractButton)b).getUI(), BasicButtonUI.class); + b.getUI(), BasicButtonUI.class); if (ui != null && DefaultLookup.getBoolean(b, ui, ui.getPropertyPrefix() + "defaultButtonFollowsFocus", true)) { @@ -185,7 +185,7 @@ public class BasicButtonListener implements MouseListener, MouseMotionListener, JButton initialDefault = (JButton)root.getClientProperty("initialDefaultButton"); if (b != initialDefault) { BasicButtonUI ui = (BasicButtonUI)BasicLookAndFeel.getUIOfType( - ((AbstractButton)b).getUI(), BasicButtonUI.class); + b.getUI(), BasicButtonUI.class); if (ui != null && DefaultLookup.getBoolean(b, ui, ui.getPropertyPrefix() + "defaultButtonFollowsFocus", true)) { @@ -239,7 +239,7 @@ public class BasicButtonListener implements MouseListener, MouseMotionListener, } } } - }; + } public void mouseReleased(MouseEvent e) { if (SwingUtilities.isLeftMouseButton(e)) { @@ -253,7 +253,7 @@ public class BasicButtonListener implements MouseListener, MouseMotionListener, model.setPressed(false); model.setArmed(false); } - }; + } public void mouseEntered(MouseEvent e) { AbstractButton b = (AbstractButton) e.getSource(); @@ -263,7 +263,7 @@ public class BasicButtonListener implements MouseListener, MouseMotionListener, } if (model.isPressed()) model.setArmed(true); - }; + } public void mouseExited(MouseEvent e) { AbstractButton b = (AbstractButton) e.getSource(); @@ -272,7 +272,7 @@ public class BasicButtonListener implements MouseListener, MouseMotionListener, model.setRollover(false); } model.setArmed(false); - }; + } /** diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicButtonUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicButtonUI.java index 6802c9d81bf..5dc98f2c17e 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicButtonUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicButtonUI.java @@ -237,7 +237,7 @@ public class BasicButtonUI extends ButtonUI{ /* the fallback icon should be based on the selected state */ if (model.isSelected()) { - selectedIcon = (Icon) b.getSelectedIcon(); + selectedIcon = b.getSelectedIcon(); if (selectedIcon != null) { icon = selectedIcon; } @@ -245,31 +245,31 @@ public class BasicButtonUI extends ButtonUI{ if(!model.isEnabled()) { if(model.isSelected()) { - tmpIcon = (Icon) b.getDisabledSelectedIcon(); + tmpIcon = b.getDisabledSelectedIcon(); if (tmpIcon == null) { tmpIcon = selectedIcon; } } if (tmpIcon == null) { - tmpIcon = (Icon) b.getDisabledIcon(); + tmpIcon = b.getDisabledIcon(); } } else if(model.isPressed() && model.isArmed()) { - tmpIcon = (Icon) b.getPressedIcon(); + tmpIcon = b.getPressedIcon(); if(tmpIcon != null) { // revert back to 0 offset clearTextShiftOffset(); } } else if(b.isRolloverEnabled() && model.isRollover()) { if(model.isSelected()) { - tmpIcon = (Icon) b.getRolloverSelectedIcon(); + tmpIcon = b.getRolloverSelectedIcon(); if (tmpIcon == null) { tmpIcon = selectedIcon; } } if (tmpIcon == null) { - tmpIcon = (Icon) b.getRolloverIcon(); + tmpIcon = b.getRolloverIcon(); } } @@ -451,9 +451,9 @@ public class BasicButtonUI extends ButtonUI{ MouseMotionListener[] listeners = b.getMouseMotionListeners(); if (listeners != null) { - for (int counter = 0; counter < listeners.length; counter++) { - if (listeners[counter] instanceof BasicButtonListener) { - return (BasicButtonListener)listeners[counter]; + for (MouseMotionListener listener : listeners) { + if (listener instanceof BasicButtonListener) { + return (BasicButtonListener) listener; } } } diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicColorChooserUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicColorChooserUI.java index fd63e7fcbb6..09f9372b9c3 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicColorChooserUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicColorChooserUI.java @@ -299,8 +299,10 @@ public class BasicColorChooserUI extends ColorChooserUI tabbedPane.addTab(name, centerWrapper); if (mnemonic > 0) { tabbedPane.setMnemonicAt(i, mnemonic); - tabbedPane.setDisplayedMnemonicIndexAt( - i, newPanels[i].getDisplayedMnemonicIndex()); + int index = newPanels[i].getDisplayedMnemonicIndex(); + if (index >= 0) { + tabbedPane.setDisplayedMnemonicIndexAt(i, index); + } } } } diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxEditor.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxEditor.java index bc41bfb0821..c7ec981845c 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxEditor.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxEditor.java @@ -92,7 +92,7 @@ public class BasicComboBoxEditor implements ComboBoxEditor,FocusListener { return oldValue; } else { // Must take the value from the editor and get the value and cast it to the new type. - Class cls = oldValue.getClass(); + Class cls = oldValue.getClass(); try { Method method = cls.getMethod("valueOf", new Class[]{String.class}); newValue = method.invoke(oldValue, new Object[] { editor.getText()}); diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java index f073eeda816..c49387fd91f 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java @@ -1509,15 +1509,21 @@ public class BasicComboBoxUI extends ComboBoxUI { || ui.isTableCellEditor) { Object listItem = ui.popup.getList().getSelectedValue(); if (listItem != null) { - comboBox.getModel().setSelectedItem(listItem); - // Ensure that JComboBox.actionPerformed() - // doesn't set editor value as selected item + // Use the selected value from popup + // to set the selected item in combo box, + // but ensure before that JComboBox.actionPerformed() + // won't use editor's value to set the selected item comboBox.getEditor().setItem(listItem); + comboBox.setSelectedItem(listItem); } } comboBox.setPopupVisible(false); } else { + // Hide combo box if it is a table cell editor + if (ui.isTableCellEditor && !comboBox.isEditable()) { + comboBox.setSelectedItem(comboBox.getSelectedItem()); + } // Call the default button binding. // This is a pretty messy way of passing an event through // to the root pane. diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicDesktopIconUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicDesktopIconUI.java index 9aab4dbe17d..5ebb6289440 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicDesktopIconUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicDesktopIconUI.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,7 @@ public class BasicDesktopIconUI extends DesktopIconUI { protected JInternalFrame.JDesktopIcon desktopIcon; protected JInternalFrame frame; + private DesktopIconMover desktopIconMover; /** * The title pane component used in the desktop icon. @@ -127,12 +128,21 @@ public class BasicDesktopIconUI extends DesktopIconUI { mouseInputListener = createMouseInputListener(); desktopIcon.addMouseMotionListener(mouseInputListener); desktopIcon.addMouseListener(mouseInputListener); + getDesktopIconMover().installListeners(); } protected void uninstallListeners() { desktopIcon.removeMouseMotionListener(mouseInputListener); desktopIcon.removeMouseListener(mouseInputListener); mouseInputListener = null; + getDesktopIconMover().uninstallListeners(); + } + + private DesktopIconMover getDesktopIconMover() { + if (desktopIconMover == null) { + desktopIconMover = new DesktopIconMover(desktopIcon); + } + return desktopIconMover; } protected void installDefaults() { diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java index 52877839218..8cff0a3e7cb 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java @@ -43,10 +43,10 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh private JFileChooser filechooser = null; // PENDING(jeff) pick the size more sensibly - private Vector fileCache = new Vector(50); + private Vector fileCache = new Vector(50); private LoadFilesThread loadThread = null; - private Vector files = null; - private Vector directories = null; + private Vector files = null; + private Vector directories = null; private int fetchID = 0; private PropertyChangeSupport changeSupport; @@ -106,14 +106,14 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh if (files != null) { return files; } - files = new Vector(); - directories = new Vector(); + files = new Vector(); + directories = new Vector(); directories.addElement(filechooser.getFileSystemView().createFileObject( filechooser.getCurrentDirectory(), "..") ); for (int i = 0; i < getSize(); i++) { - File f = (File)fileCache.get(i); + File f = fileCache.get(i); if (filechooser.isTraversable(f)) { directories.add(f); } else { @@ -215,7 +215,7 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh class LoadFilesThread extends Thread { File currentDirectory = null; int fid; - Vector runnables = new Vector(10); + Vector runnables = new Vector(10); public LoadFilesThread(File currentDirectory, int fid) { super("Basic L&F File Loading Thread"); @@ -223,7 +223,7 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh this.fid = fid; } - private void invokeLater(Runnable runnable) { + private void invokeLater(DoChangeContents runnable) { runnables.addElement(runnable); SwingUtilities.invokeLater(runnable); } @@ -245,9 +245,9 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh } // run through the file list, add directories and selectable files to fileCache - for (int i = 0; i < list.length; i++) { - if(filechooser.accept(list[i])) { - acceptsList.addElement(list[i]); + for (File file : list) { + if (filechooser.accept(file)) { + acceptsList.addElement(file); } } @@ -258,11 +258,11 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh // First sort alphabetically by filename sort(acceptsList); - Vector newDirectories = new Vector(50); - Vector newFiles = new Vector(); + Vector newDirectories = new Vector(50); + Vector newFiles = new Vector(); // run through list grabbing directories in chunks of ten for(int i = 0; i < acceptsList.size(); i++) { - File f = (File) acceptsList.elementAt(i); + File f = acceptsList.elementAt(i); boolean isTraversable = filechooser.isTraversable(f); if (isTraversable) { newDirectories.addElement(f); @@ -274,7 +274,7 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh } } - Vector newFileCache = new Vector(newDirectories); + Vector newFileCache = new Vector(newDirectories); newFileCache.addAll(newFiles); int newSize = newFileCache.size(); @@ -320,7 +320,7 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh if(isInterrupted()) { return; } - invokeLater(new DoChangeContents(null, 0, new Vector(fileCache.subList(start, end)), + invokeLater(new DoChangeContents(null, 0, new Vector(fileCache.subList(start, end)), start, fid)); newFileCache = null; } @@ -334,9 +334,9 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh } - public void cancelRunnables(Vector runnables) { - for(int i = 0; i < runnables.size(); i++) { - ((DoChangeContents)runnables.elementAt(i)).cancel(); + public void cancelRunnables(Vector runnables) { + for (DoChangeContents runnable : runnables) { + runnable.cancel(); } } @@ -449,15 +449,14 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh class DoChangeContents implements Runnable { - private List addFiles; - private List remFiles; + private List addFiles; + private List remFiles; private boolean doFire = true; private int fid; private int addStart = 0; private int remStart = 0; - private int change; - public DoChangeContents(List addFiles, int addStart, List remFiles, int remStart, int fid) { + public DoChangeContents(List addFiles, int addStart, List remFiles, int remStart, int fid) { this.addFiles = addFiles; this.addStart = addStart; this.remFiles = remFiles; diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java index 467db5a1bb7..13d13cdcefe 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java @@ -36,6 +36,7 @@ import java.awt.datatransfer.*; import java.beans.*; import java.io.*; import java.util.*; +import java.util.List; import java.util.regex.*; import sun.awt.shell.ShellFolder; import sun.swing.*; @@ -159,9 +160,9 @@ public class BasicFileChooserUI extends FileChooserUI { } public void uninstallUI(JComponent c) { - uninstallListeners((JFileChooser) filechooser); - uninstallComponents((JFileChooser) filechooser); - uninstallDefaults((JFileChooser) filechooser); + uninstallListeners(filechooser); + uninstallComponents(filechooser); + uninstallDefaults(filechooser); if(accessoryPanel != null) { accessoryPanel.removeAll(); @@ -506,9 +507,9 @@ public class BasicFileChooserUI extends FileChooserUI { setDirectorySelected(true); setDirectory(((File)objects[0])); } else { - ArrayList fList = new ArrayList(objects.length); - for (int i = 0; i < objects.length; i++) { - File f = (File)objects[i]; + ArrayList fList = new ArrayList(objects.length); + for (Object object : objects) { + File f = (File) object; boolean isDir = f.isDirectory(); if ((chooser.isFileSelectionEnabled() && !isDir) || (chooser.isDirectorySelectionEnabled() @@ -518,7 +519,7 @@ public class BasicFileChooserUI extends FileChooserUI { } } if (fList.size() > 0) { - files = (File[])fList.toArray(new File[fList.size()]); + files = fList.toArray(new File[fList.size()]); } setDirectorySelected(false); } @@ -829,11 +830,17 @@ public class BasicFileChooserUI extends FileChooserUI { File dir = chooser.getCurrentDirectory(); if (filename != null) { - // Remove whitespace from beginning and end of filename - filename = filename.trim(); + // Remove whitespaces from end of filename + int i = filename.length() - 1; + + while (i >=0 && filename.charAt(i) <= ' ') { + i--; + } + + filename = filename.substring(0, i + 1); } - if (filename == null || filename.equals("")) { + if (filename == null || filename.length() == 0) { // no file selected, multiple selection off, therefore cancel the approve action resetGlobFilter(); return; @@ -842,100 +849,93 @@ public class BasicFileChooserUI extends FileChooserUI { File selectedFile = null; File[] selectedFiles = null; - if (filename != null && !filename.equals("")) { - // Unix: Resolve '~' to user's home directory - if (File.separatorChar == '/') { - if (filename.startsWith("~/")) { - filename = System.getProperty("user.home") + filename.substring(1); - } else if (filename.equals("~")) { - filename = System.getProperty("user.home"); - } - } - - if (chooser.isMultiSelectionEnabled() && filename.startsWith("\"")) { - ArrayList fList = new ArrayList(); - - filename = filename.substring(1); - if (filename.endsWith("\"")) { - filename = filename.substring(0, filename.length()-1); - } - File[] children = null; - int childIndex = 0; - do { - String str; - int i = filename.indexOf("\" \""); - if (i > 0) { - str = filename.substring(0, i); - filename = filename.substring(i+3); - } else { - str = filename; - filename = ""; - } - File file = fs.createFileObject(str); - if (!file.isAbsolute()) { - if (children == null) { - children = fs.getFiles(dir, false); - Arrays.sort(children); - } - for (int k = 0; k < children.length; k++) { - int l = (childIndex + k) % children.length; - if (children[l].getName().equals(str)) { - file = children[l]; - childIndex = l + 1; - break; - } - } - } - fList.add(file); - } while (filename.length() > 0); - if (fList.size() > 0) { - selectedFiles = (File[])fList.toArray(new File[fList.size()]); - } - resetGlobFilter(); - } else { - selectedFile = fs.createFileObject(filename); - if(!selectedFile.isAbsolute()) { - selectedFile = fs.getChild(dir, filename); - } - // check for wildcard pattern - FileFilter currentFilter = chooser.getFileFilter(); - if (!selectedFile.exists() && isGlobPattern(filename)) { - changeDirectory(selectedFile.getParentFile()); - if (globFilter == null) { - globFilter = new GlobFilter(); - } - try { - globFilter.setPattern(selectedFile.getName()); - if (!(currentFilter instanceof GlobFilter)) { - actualFileFilter = currentFilter; - } - chooser.setFileFilter(null); - chooser.setFileFilter(globFilter); - return; - } catch (PatternSyntaxException pse) { - // Not a valid glob pattern. Abandon filter. - } - } - - resetGlobFilter(); - - // Check for directory change action - boolean isDir = (selectedFile != null && selectedFile.isDirectory()); - boolean isTrav = (selectedFile != null && chooser.isTraversable(selectedFile)); - boolean isDirSelEnabled = chooser.isDirectorySelectionEnabled(); - boolean isFileSelEnabled = chooser.isFileSelectionEnabled(); - boolean isCtrl = (e != null && (e.getModifiers() & ActionEvent.CTRL_MASK) != 0); - - if (isDir && isTrav && (isCtrl || !isDirSelEnabled)) { - changeDirectory(selectedFile); - return; - } else if ((isDir || !isFileSelEnabled) - && (!isDir || !isDirSelEnabled) - && (!isDirSelEnabled || selectedFile.exists())) { - selectedFile = null; - } + // Unix: Resolve '~' to user's home directory + if (File.separatorChar == '/') { + if (filename.startsWith("~/")) { + filename = System.getProperty("user.home") + filename.substring(1); + } else if (filename.equals("~")) { + filename = System.getProperty("user.home"); } } + + if (chooser.isMultiSelectionEnabled() && filename.length() > 1 && + filename.charAt(0) == '"' && filename.charAt(filename.length() - 1) == '"') { + List fList = new ArrayList(); + + String[] files = filename.substring(1, filename.length() - 1).split("\" \""); + // Optimize searching files by names in "children" array + Arrays.sort(files); + + File[] children = null; + int childIndex = 0; + + for (String str : files) { + File file = fs.createFileObject(str); + if (!file.isAbsolute()) { + if (children == null) { + children = fs.getFiles(dir, false); + Arrays.sort(children); + } + for (int k = 0; k < children.length; k++) { + int l = (childIndex + k) % children.length; + if (children[l].getName().equals(str)) { + file = children[l]; + childIndex = l + 1; + break; + } + } + } + fList.add(file); + } + + if (!fList.isEmpty()) { + selectedFiles = fList.toArray(new File[fList.size()]); + } + resetGlobFilter(); + } else { + selectedFile = fs.createFileObject(filename); + if (!selectedFile.isAbsolute()) { + selectedFile = fs.getChild(dir, filename); + } + // check for wildcard pattern + FileFilter currentFilter = chooser.getFileFilter(); + if (!selectedFile.exists() && isGlobPattern(filename)) { + changeDirectory(selectedFile.getParentFile()); + if (globFilter == null) { + globFilter = new GlobFilter(); + } + try { + globFilter.setPattern(selectedFile.getName()); + if (!(currentFilter instanceof GlobFilter)) { + actualFileFilter = currentFilter; + } + chooser.setFileFilter(null); + chooser.setFileFilter(globFilter); + return; + } catch (PatternSyntaxException pse) { + // Not a valid glob pattern. Abandon filter. + } + } + + resetGlobFilter(); + + // Check for directory change action + boolean isDir = (selectedFile != null && selectedFile.isDirectory()); + boolean isTrav = (selectedFile != null && chooser.isTraversable(selectedFile)); + boolean isDirSelEnabled = chooser.isDirectorySelectionEnabled(); + boolean isFileSelEnabled = chooser.isFileSelectionEnabled(); + boolean isCtrl = (e != null && (e.getModifiers() & ActionEvent.CTRL_MASK) != 0); + + if (isDir && isTrav && (isCtrl || !isDirSelEnabled)) { + changeDirectory(selectedFile); + return; + } else if ((isDir || !isFileSelEnabled) + && (!isDir || !isDirSelEnabled) + && (!isDirSelEnabled || selectedFile.exists())) { + selectedFile = null; + } + } + if (selectedFiles != null || selectedFile != null) { if (selectedFiles != null || chooser.isMultiSelectionEnabled()) { if (selectedFiles == null) { @@ -1213,7 +1213,7 @@ public class BasicFileChooserUI extends FileChooserUI { } public Icon getCachedIcon(File f) { - return (Icon) iconCache.get(f); + return iconCache.get(f); } public void cacheIcon(File f, Icon i) { @@ -1296,8 +1296,7 @@ public class BasicFileChooserUI extends FileChooserUI { htmlBuf.append("\n\n

        \n"); - for (int i = 0; i < values.length; i++) { - Object obj = values[i]; + for (Object obj : values) { String val = ((obj == null) ? "" : obj.toString()); plainBuf.append(val + "\n"); htmlBuf.append("
      • " + val + "\n"); @@ -1337,9 +1336,9 @@ public class BasicFileChooserUI extends FileChooserUI { */ protected Object getRicherData(DataFlavor flavor) { if (DataFlavor.javaFileListFlavor.equals(flavor)) { - ArrayList files = new ArrayList(); - for (int i = 0; i < fileData.length; i++) { - files.add(fileData[i]); + ArrayList files = new ArrayList(); + for (Object file : this.fileData) { + files.add(file); } return files; } diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicGraphicsUtils.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicGraphicsUtils.java index ecb8f0dccc0..3cf822cfec2 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicGraphicsUtils.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicGraphicsUtils.java @@ -266,7 +266,7 @@ public class BasicGraphicsUtils return null; } - Icon icon = (Icon) b.getIcon(); + Icon icon = b.getIcon(); String text = b.getText(); Font font = b.getFont(); @@ -277,7 +277,7 @@ public class BasicGraphicsUtils Rectangle viewR = new Rectangle(Short.MAX_VALUE, Short.MAX_VALUE); SwingUtilities.layoutCompoundLabel( - (JComponent) b, fm, text, icon, + b, fm, text, icon, b.getVerticalAlignment(), b.getHorizontalAlignment(), b.getVerticalTextPosition(), b.getHorizontalTextPosition(), viewR, iconR, textR, (text == null ? 0 : textIconGap) diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java index 344a4b2b512..b131824f441 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java @@ -86,6 +86,7 @@ public class BasicInternalFrameTitlePane extends JComponent protected Action moveAction; protected Action sizeAction; + // These constants are not used in JDK code protected static final String CLOSE_CMD = UIManager.getString("InternalFrameTitlePane.closeButtonText"); protected static final String ICONIFY_CMD = @@ -268,18 +269,18 @@ public class BasicInternalFrameTitlePane extends JComponent } protected void addSystemMenuItems(JMenu systemMenu) { - JMenuItem mi = (JMenuItem)systemMenu.add(restoreAction); + JMenuItem mi = systemMenu.add(restoreAction); mi.setMnemonic('R'); - mi = (JMenuItem)systemMenu.add(moveAction); + mi = systemMenu.add(moveAction); mi.setMnemonic('M'); - mi = (JMenuItem)systemMenu.add(sizeAction); + mi = systemMenu.add(sizeAction); mi.setMnemonic('S'); - mi = (JMenuItem)systemMenu.add(iconifyAction); + mi = systemMenu.add(iconifyAction); mi.setMnemonic('n'); - mi = (JMenuItem)systemMenu.add(maximizeAction); + mi = systemMenu.add(maximizeAction); mi.setMnemonic('x'); systemMenu.add(new JSeparator()); - mi = (JMenuItem)systemMenu.add(closeAction); + mi = systemMenu.add(closeAction); mi.setMnemonic('C'); } @@ -413,7 +414,7 @@ public class BasicInternalFrameTitlePane extends JComponent // PropertyChangeListener // public void propertyChange(PropertyChangeEvent evt) { - String prop = (String)evt.getPropertyName(); + String prop = evt.getPropertyName(); if (prop == JInternalFrame.IS_SELECTED_PROPERTY) { repaint(); @@ -428,19 +429,19 @@ public class BasicInternalFrameTitlePane extends JComponent } if ("closable" == prop) { - if ((Boolean)evt.getNewValue() == Boolean.TRUE) { + if (evt.getNewValue() == Boolean.TRUE) { add(closeButton); } else { remove(closeButton); } } else if ("maximizable" == prop) { - if ((Boolean)evt.getNewValue() == Boolean.TRUE) { + if (evt.getNewValue() == Boolean.TRUE) { add(maxButton); } else { remove(maxButton); } } else if ("iconable" == prop) { - if ((Boolean)evt.getNewValue() == Boolean.TRUE) { + if (evt.getNewValue() == Boolean.TRUE) { add(iconButton); } else { remove(iconButton); @@ -600,7 +601,8 @@ public class BasicInternalFrameTitlePane extends JComponent */ public class CloseAction extends AbstractAction { public CloseAction() { - super(CLOSE_CMD); + super(UIManager.getString( + "InternalFrameTitlePane.closeButtonText")); } public void actionPerformed(ActionEvent e) { @@ -616,7 +618,8 @@ public class BasicInternalFrameTitlePane extends JComponent */ public class MaximizeAction extends AbstractAction { public MaximizeAction() { - super(MAXIMIZE_CMD); + super(UIManager.getString( + "InternalFrameTitlePane.maximizeButtonText")); } public void actionPerformed(ActionEvent evt) { @@ -644,7 +647,8 @@ public class BasicInternalFrameTitlePane extends JComponent */ public class IconifyAction extends AbstractAction { public IconifyAction() { - super(ICONIFY_CMD); + super(UIManager.getString( + "InternalFrameTitlePane.minimizeButtonText")); } public void actionPerformed(ActionEvent e) { @@ -664,7 +668,8 @@ public class BasicInternalFrameTitlePane extends JComponent */ public class RestoreAction extends AbstractAction { public RestoreAction() { - super(RESTORE_CMD); + super(UIManager.getString( + "InternalFrameTitlePane.restoreButtonText")); } public void actionPerformed(ActionEvent evt) { @@ -690,7 +695,8 @@ public class BasicInternalFrameTitlePane extends JComponent */ public class MoveAction extends AbstractAction { public MoveAction() { - super(MOVE_CMD); + super(UIManager.getString( + "InternalFrameTitlePane.moveButtonText")); } public void actionPerformed(ActionEvent e) { @@ -723,7 +729,8 @@ public class BasicInternalFrameTitlePane extends JComponent */ public class SizeAction extends AbstractAction { public SizeAction() { - super(SIZE_CMD); + super(UIManager.getString( + "InternalFrameTitlePane.sizeButtonText")); } public void actionPerformed(ActionEvent e) { @@ -774,7 +781,7 @@ public class BasicInternalFrameTitlePane extends JComponent } } public boolean isFocusTraversable() { return false; } - public void requestFocus() {}; + public void requestFocus() {} public AccessibleContext getAccessibleContext() { AccessibleContext ac = super.getAccessibleContext(); if (uiKey != null) { @@ -783,6 +790,6 @@ public class BasicInternalFrameTitlePane extends JComponent } return ac; } - }; // end NoFocusButton + } // end NoFocusButton } // End Title Pane Class diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java index 83b0fd73bd9..46eefa26c14 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,7 +55,6 @@ public class BasicInternalFrameUI extends InternalFrameUI protected MouseInputAdapter borderListener; protected PropertyChangeListener propertyChangeListener; protected LayoutManager internalFrameLayout; - protected ComponentListener componentListener; protected MouseInputListener glassPaneDispatcher; private InternalFrameListener internalFrameListener; @@ -67,9 +66,9 @@ public class BasicInternalFrameUI extends InternalFrameUI protected BasicInternalFrameTitlePane titlePane; // access needs this private static DesktopManager sharedDesktopManager; - private boolean componentListenerAdded = false; private Rectangle parentBounds; + private DesktopIconMover desktopIconMover; private boolean dragging = false; private boolean resizing = false; @@ -210,14 +209,17 @@ public class BasicInternalFrameUI extends InternalFrameUI frame.getGlassPane().addMouseListener(glassPaneDispatcher); frame.getGlassPane().addMouseMotionListener(glassPaneDispatcher); } - componentListener = createComponentListener(); if (frame.getParent() != null) { parentBounds = frame.getParent().getBounds(); } - if ((frame.getParent() != null) && !componentListenerAdded) { - frame.getParent().addComponentListener(componentListener); - componentListenerAdded = true; + getDesktopIconMover().installListeners(); + } + + private DesktopIconMover getDesktopIconMover() { + if (desktopIconMover == null) { + desktopIconMover = new DesktopIconMover(frame); } + return desktopIconMover; } // Provide a FocusListener to listen for a WINDOW_LOST_FOCUS event, @@ -288,11 +290,7 @@ public class BasicInternalFrameUI extends InternalFrameUI * @since 1.3 */ protected void uninstallListeners() { - if ((frame.getParent() != null) && componentListenerAdded) { - frame.getParent().removeComponentListener(componentListener); - componentListenerAdded = false; - } - componentListener = null; + getDesktopIconMover().uninstallListeners(); if (glassPaneDispatcher != null) { frame.getGlassPane().removeMouseListener(glassPaneDispatcher); frame.getGlassPane().removeMouseMotionListener(glassPaneDispatcher); @@ -320,7 +318,7 @@ public class BasicInternalFrameUI extends InternalFrameUI if (resizing) { return; } - Cursor s = (Cursor)frame.getLastCursor(); + Cursor s = frame.getLastCursor(); if (s == null) { s = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR); } @@ -338,13 +336,13 @@ public class BasicInternalFrameUI extends InternalFrameUI public Dimension getPreferredSize(JComponent x) { - if((JComponent)frame == x) + if(frame == x) return frame.getLayout().preferredLayoutSize(x); return new Dimension(100, 100); } public Dimension getMinimumSize(JComponent x) { - if((JComponent)frame == x) { + if(frame == x) { return frame.getLayout().minimumLayoutSize(x); } return new Dimension(0, 0); @@ -1095,7 +1093,7 @@ public class BasicInternalFrameUI extends InternalFrameUI updateFrameCursor(); } - }; /// End BorderListener Class + } /// End BorderListener Class protected class ComponentHandler implements ComponentListener { // NOTE: This class exists only for backward compatability. All @@ -1198,7 +1196,6 @@ public class BasicInternalFrameUI extends InternalFrameUI } } - private static boolean isDragging = false; private class Handler implements ComponentListener, InternalFrameListener, LayoutManager, MouseInputListener, PropertyChangeListener, WindowFocusListener, SwingConstants { @@ -1230,15 +1227,6 @@ public class BasicInternalFrameUI extends InternalFrameUI } } - // Relocate the icon base on the new parent bounds. - if (icon != null) { - Rectangle iconBounds = icon.getBounds(); - int y = iconBounds.y + - (parentNewBounds.height - parentBounds.height); - icon.setBounds(iconBounds.x, y, - iconBounds.width, iconBounds.height); - } - // Update the new parent bounds for next resize. if (!parentBounds.equals(parentNewBounds)) { parentBounds = parentNewBounds; @@ -1384,9 +1372,6 @@ public class BasicInternalFrameUI extends InternalFrameUI // MouseInputListener - private Component mouseEventTarget = null; - private Component dragSource = null; - public void mousePressed(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } @@ -1403,7 +1388,7 @@ public class BasicInternalFrameUI extends InternalFrameUI // PropertyChangeListener public void propertyChange(PropertyChangeEvent evt) { - String prop = (String)evt.getPropertyName(); + String prop = evt.getPropertyName(); JInternalFrame f = (JInternalFrame)evt.getSource(); Object newValue = evt.getNewValue(); Object oldValue = evt.getOldValue(); @@ -1413,10 +1398,6 @@ public class BasicInternalFrameUI extends InternalFrameUI // Cancel a resize in progress if the internal frame // gets a setClosed(true) or dispose(). cancelResize(); - if ((frame.getParent() != null) && componentListenerAdded) { - frame.getParent().removeComponentListener( - componentListener); - } closeFrame(f); } } else if (JInternalFrame.IS_MAXIMUM_PROPERTY == prop) { @@ -1449,16 +1430,6 @@ public class BasicInternalFrameUI extends InternalFrameUI } else { parentBounds = null; } - if ((frame.getParent() != null) && !componentListenerAdded) { - f.getParent().addComponentListener(componentListener); - componentListenerAdded = true; - } else if ((newValue == null) && componentListenerAdded) { - if (f.getParent() != null) { - f.getParent().removeComponentListener( - componentListener); - } - componentListenerAdded = false; - } } else if (JInternalFrame.TITLE_PROPERTY == prop || prop == "closable" || prop == "iconable" || prop == "maximizable") { diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicLabelUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicLabelUI.java index af51ecc7c50..c1f65d2aa23 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicLabelUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicLabelUI.java @@ -65,6 +65,9 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener protected static BasicLabelUI labelUI = new BasicLabelUI(); private final static BasicLabelUI SAFE_BASIC_LABEL_UI = new BasicLabelUI(); + private Rectangle paintIconR = new Rectangle(); + private Rectangle paintTextR = new Rectangle(); + static void loadActionMap(LazyActionMap map) { map.put(new Actions(Actions.PRESS)); map.put(new Actions(Actions.RELEASE)); @@ -135,17 +138,6 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener textX, textY); } - - /* These rectangles/insets are allocated once for this shared LabelUI - * implementation. Re-using rectangles rather than allocating - * them in each paint call halved the time it took paint to run. - */ - private static Rectangle paintIconR = new Rectangle(); - private static Rectangle paintTextR = new Rectangle(); - private static Rectangle paintViewR = new Rectangle(); - private static Insets paintViewInsets = new Insets(0, 0, 0, 0); - - /** * Paint the label text in the foreground color, if the label * is opaque then paint the entire background with the background @@ -194,10 +186,11 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener private String layout(JLabel label, FontMetrics fm, int width, int height) { - Insets insets = label.getInsets(paintViewInsets); + Insets insets = label.getInsets(null); String text = label.getText(); Icon icon = (label.isEnabled()) ? label.getIcon() : label.getDisabledIcon(); + Rectangle paintViewR = new Rectangle(); paintViewR.x = insets.left; paintViewR.y = insets.top; paintViewR.width = width - (insets.left + insets.right); @@ -208,24 +201,13 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener paintTextR); } - - /* These rectangles/insets are allocated once for this shared LabelUI - * implementation. Re-using rectangles rather than allocating - * them in each getPreferredSize call sped up the method substantially. - */ - private static Rectangle iconR = new Rectangle(); - private static Rectangle textR = new Rectangle(); - private static Rectangle viewR = new Rectangle(); - private static Insets viewInsets = new Insets(0, 0, 0, 0); - - public Dimension getPreferredSize(JComponent c) { JLabel label = (JLabel)c; String text = label.getText(); Icon icon = (label.isEnabled()) ? label.getIcon() : label.getDisabledIcon(); - Insets insets = label.getInsets(viewInsets); + Insets insets = label.getInsets(null); Font font = label.getFont(); int dx = insets.left + insets.right; @@ -242,6 +224,9 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener } else { FontMetrics fm = label.getFontMetrics(font); + Rectangle iconR = new Rectangle(); + Rectangle textR = new Rectangle(); + Rectangle viewR = new Rectangle(); iconR.x = iconR.y = iconR.width = iconR.height = 0; textR.x = textR.y = textR.width = textR.height = 0; diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java index e0d139f48ef..68bba5774b7 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java @@ -2102,8 +2102,6 @@ public abstract class BasicLookAndFeel extends LookAndFeel implements Serializab * soundFile passed into this method, it will * return null. * - * @param baseClass used as the root class/location to get the - * soundFile from * @param soundFile the name of the audio file to be retrieved * from disk * @return A byte[] with audio data or null @@ -2120,9 +2118,9 @@ public abstract class BasicLookAndFeel extends LookAndFeel implements Serializab * Class.getResourceAsStream just returns raw * bytes, which we can convert to a sound. */ - byte[] buffer = (byte[])AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + byte[] buffer = AccessController.doPrivileged( + new PrivilegedAction() { + public byte[] run() { try { InputStream resource = BasicLookAndFeel.this. getClass().getResourceAsStream(soundFile); @@ -2184,9 +2182,9 @@ public abstract class BasicLookAndFeel extends LookAndFeel implements Serializab UIManager.get("AuditoryCues.playList"); if (audioStrings != null) { // create a HashSet to help us decide to play or not - HashSet audioCues = new HashSet(); - for (int i = 0; i < audioStrings.length; i++) { - audioCues.add(audioStrings[i]); + HashSet audioCues = new HashSet(); + for (Object audioString : audioStrings) { + audioCues.add(audioString); } // get the name of the Action String actionName = (String)audioAction.getValue(Action.NAME); @@ -2237,7 +2235,7 @@ public abstract class BasicLookAndFeel extends LookAndFeel implements Serializab * This class contains listener that watches for all the mouse * events that can possibly invoke popup on the component */ - class AWTEventHelper implements AWTEventListener,PrivilegedAction { + class AWTEventHelper implements AWTEventListener,PrivilegedAction { AWTEventHelper() { super(); AccessController.doPrivileged(this); diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java index 85f56a52cd9..a58cc467c5f 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java @@ -25,9 +25,6 @@ package javax.swing.plaf.basic; -import sun.swing.MenuItemCheckIconFactory; -import sun.swing.SwingUtilities2; -import static sun.swing.SwingUtilities2.BASICMENUITEMUI_MAX_TEXT_OFFSET; import java.awt.*; import java.awt.event.*; import java.beans.PropertyChangeEvent; @@ -39,8 +36,7 @@ import javax.swing.border.*; import javax.swing.plaf.*; import javax.swing.text.View; -import sun.swing.UIAction; -import sun.swing.StringUIClientPropertyKey; +import sun.swing.*; /** * BasicMenuItem implementation @@ -91,24 +87,6 @@ public class BasicMenuItemUI extends MenuItemUI private static final boolean VERBOSE = false; // show reuse hits/misses private static final boolean DEBUG = false; // show bad params, misc. - // Allows to reuse layoutInfo object. - // Shouldn't be used directly. Use getLayoutInfo() instead. - private final transient LayoutInfo layoutInfo = new LayoutInfo(); - - /* Client Property keys for calculation of maximal widths */ - static final StringUIClientPropertyKey MAX_ARROW_WIDTH = - new StringUIClientPropertyKey("maxArrowWidth"); - static final StringUIClientPropertyKey MAX_CHECK_WIDTH = - new StringUIClientPropertyKey("maxCheckWidth"); - static final StringUIClientPropertyKey MAX_ICON_WIDTH = - new StringUIClientPropertyKey("maxIconWidth"); - static final StringUIClientPropertyKey MAX_TEXT_WIDTH = - new StringUIClientPropertyKey("maxTextWidth"); - static final StringUIClientPropertyKey MAX_ACC_WIDTH = - new StringUIClientPropertyKey("maxAccWidth"); - static final StringUIClientPropertyKey MAX_LABEL_WIDTH = - new StringUIClientPropertyKey("maxLabelWidth"); - static void loadActionMap(LazyActionMap map) { // NOTE: BasicMenuUI also calls into this method. map.put(new Actions(Actions.CLICK)); @@ -199,13 +177,14 @@ public class BasicMenuItemUI extends MenuItemUI //In case of column layout, .checkIconFactory is defined for this UI, //the icon is compatible with it and useCheckAndArrow() is true, //then the icon is handled by the checkIcon. - boolean isColumnLayout = LayoutInfo.isColumnLayout( + boolean isColumnLayout = MenuItemLayoutHelper.isColumnLayout( BasicGraphicsUtils.isLeftToRight(menuItem), menuItem); if (isColumnLayout) { MenuItemCheckIconFactory iconFactory = (MenuItemCheckIconFactory) UIManager.get(prefix + ".checkIconFactory"); - if (iconFactory != null && useCheckAndArrow() + if (iconFactory != null + && MenuItemLayoutHelper.useCheckAndArrow(menuItem) && iconFactory.isCompatible(checkIcon, prefix)) { checkIcon = iconFactory.getIcon(menuItem); } @@ -256,20 +235,7 @@ public class BasicMenuItemUI extends MenuItemUI uninstallComponents(menuItem); uninstallListeners(); uninstallKeyboardActions(); - - - // Remove values from the parent's Client Properties. - JComponent p = getMenuItemParent(menuItem); - if(p != null) { - p.putClientProperty(BasicMenuItemUI.MAX_ARROW_WIDTH, null ); - p.putClientProperty(BasicMenuItemUI.MAX_CHECK_WIDTH, null ); - p.putClientProperty(BasicMenuItemUI.MAX_ACC_WIDTH, null ); - p.putClientProperty(BasicMenuItemUI.MAX_TEXT_WIDTH, null ); - p.putClientProperty(BasicMenuItemUI.MAX_ICON_WIDTH, null ); - p.putClientProperty(BasicMenuItemUI.MAX_LABEL_WIDTH, null ); - p.putClientProperty(BASICMENUITEMUI_MAX_TEXT_OFFSET, null ); - } - + MenuItemLayoutHelper.clearUsedParentClientProperties(menuItem); menuItem = null; } @@ -405,19 +371,6 @@ public class BasicMenuItemUI extends MenuItemUI return d; } - // Returns parent of this component if it is not a top-level menu - // Otherwise returns null - private static JComponent getMenuItemParent(JMenuItem mi) { - Container parent = mi.getParent(); - if ((parent instanceof JComponent) && - (!(mi instanceof JMenu) || - !((JMenu)mi).isTopLevelMenu())) { - return (JComponent) parent; - } else { - return null; - } - } - protected Dimension getPreferredMenuItemSize(JComponent c, Icon checkIcon, Icon arrowIcon, @@ -447,32 +400,36 @@ public class BasicMenuItemUI extends MenuItemUI // the icon and text when user points a menu item by mouse. JMenuItem mi = (JMenuItem) c; - LayoutInfo li = getLayoutInfo(mi, checkIcon, arrowIcon, - createMaxViewRect(), defaultTextIconGap, acceleratorDelimiter, - BasicGraphicsUtils.isLeftToRight(mi), acceleratorFont, - useCheckAndArrow(), getPropertyPrefix()); + MenuItemLayoutHelper lh = new MenuItemLayoutHelper(mi, checkIcon, + arrowIcon, MenuItemLayoutHelper.createMaxRect(), defaultTextIconGap, + acceleratorDelimiter, BasicGraphicsUtils.isLeftToRight(mi), + mi.getFont(), acceleratorFont, + MenuItemLayoutHelper.useCheckAndArrow(menuItem), + getPropertyPrefix()); Dimension result = new Dimension(); // Calculate the result width - result.width = li.leadingGap; - addWidth(li.maxCheckWidth, li.afterCheckIconGap, result); + result.width = lh.getLeadingGap(); + MenuItemLayoutHelper.addMaxWidth(lh.getCheckSize(), + lh.getAfterCheckIconGap(), result); // Take into account mimimal text offset. - if ((!li.isTopLevelMenu) - && (li.minTextOffset > 0) - && (result.width < li.minTextOffset)) { - result.width = li.minTextOffset; + if ((!lh.isTopLevelMenu()) + && (lh.getMinTextOffset() > 0) + && (result.width < lh.getMinTextOffset())) { + result.width = lh.getMinTextOffset(); } - addWidth(li.maxLabelWidth, li.gap, result); - addWidth(li.maxAccWidth, li.gap, result); - addWidth(li.maxArrowWidth, li.gap, result); + MenuItemLayoutHelper.addMaxWidth(lh.getLabelSize(), lh.getGap(), result); + MenuItemLayoutHelper.addMaxWidth(lh.getAccSize(), lh.getGap(), result); + MenuItemLayoutHelper.addMaxWidth(lh.getArrowSize(), lh.getGap(), result); // Calculate the result height - result.height = max(li.checkRect.height, li.labelRect.height, - li.accRect.height, li.arrowRect.height); + result.height = MenuItemLayoutHelper.max(lh.getCheckSize().getHeight(), + lh.getLabelSize().getHeight(), lh.getAccSize().getHeight(), + lh.getArrowSize().getHeight()); // Take into account menu item insets - Insets insets = li.mi.getInsets(); + Insets insets = lh.getMenuItem().getInsets(); if(insets != null) { result.width += insets.left + insets.right; result.height += insets.top + insets.bottom; @@ -492,500 +449,9 @@ public class BasicMenuItemUI extends MenuItemUI result.height++; } - li.clear(); return result; } - private Rectangle createMaxViewRect() { - return new Rectangle(0,0,Short.MAX_VALUE, Short.MAX_VALUE); - } - - private void addWidth(int width, int gap, Dimension result) { - if (width > 0) { - result.width += width + gap; - } - } - - private static int max(int... values) { - int maxValue = Integer.MIN_VALUE; - for (int i : values) { - if (i > maxValue) { - maxValue = i; - } - } - return maxValue; - } - - // LayoutInfo helps to calculate preferred size and to paint a menu item - private static class LayoutInfo { - JMenuItem mi; - JComponent miParent; - - FontMetrics fm; - FontMetrics accFm; - - Icon icon; - Icon checkIcon; - Icon arrowIcon; - String text; - String accText; - - boolean isColumnLayout; - boolean useCheckAndArrow; - boolean isLeftToRight; - boolean isTopLevelMenu; - View htmlView; - - int verticalAlignment; - int horizontalAlignment; - int verticalTextPosition; - int horizontalTextPosition; - int gap; - int leadingGap; - int afterCheckIconGap; - int minTextOffset; - - Rectangle viewRect; - Rectangle iconRect; - Rectangle textRect; - Rectangle accRect; - Rectangle checkRect; - Rectangle arrowRect; - Rectangle labelRect; - - int origIconWidth; - int origTextWidth; - int origAccWidth; - int origCheckWidth; - int origArrowWidth; - - int maxIconWidth; - int maxTextWidth; - int maxAccWidth; - int maxCheckWidth; - int maxArrowWidth; - int maxLabelWidth; - - // Empty constructor helps to create "final" LayoutInfo object - public LayoutInfo() { - } - - public LayoutInfo(JMenuItem mi, Icon checkIcon, Icon arrowIcon, - Rectangle viewRect, int gap, String accDelimiter, - boolean isLeftToRight, Font acceleratorFont, - boolean useCheckAndArrow, String propertyPrefix) { - reset(mi, checkIcon, arrowIcon, viewRect, gap, accDelimiter, - isLeftToRight, acceleratorFont, useCheckAndArrow, - propertyPrefix); - } - - // Allows to reuse a LayoutInfo object - public void reset(JMenuItem mi, Icon checkIcon, Icon arrowIcon, - Rectangle viewRect, int gap, String accDelimiter, - boolean isLeftToRight, Font acceleratorFont, - boolean useCheckAndArrow, String propertyPrefix) { - this.mi = mi; - this.miParent = getMenuItemParent(mi); - this.accText = getAccText(accDelimiter); - this.verticalAlignment = mi.getVerticalAlignment(); - this.horizontalAlignment = mi.getHorizontalAlignment(); - this.verticalTextPosition = mi.getVerticalTextPosition(); - this.horizontalTextPosition = mi.getHorizontalTextPosition(); - this.useCheckAndArrow = useCheckAndArrow; - this.fm = mi.getFontMetrics(mi.getFont()); - this.accFm = mi.getFontMetrics(acceleratorFont); - this.isLeftToRight = isLeftToRight; - this.isColumnLayout = isColumnLayout(); - this.isTopLevelMenu = (this.miParent == null)? true : false; - this.checkIcon = checkIcon; - this.icon = getIcon(propertyPrefix); - this.arrowIcon = arrowIcon; - this.text = mi.getText(); - this.gap = gap; - this.afterCheckIconGap = getAfterCheckIconGap(propertyPrefix); - this.minTextOffset = getMinTextOffset(propertyPrefix); - this.htmlView = (View) mi.getClientProperty(BasicHTML.propertyKey); - - this.viewRect = viewRect; - this.iconRect = new Rectangle(); - this.textRect = new Rectangle(); - this.accRect = new Rectangle(); - this.checkRect = new Rectangle(); - this.arrowRect = new Rectangle(); - this.labelRect = new Rectangle(); - - calcWidthsAndHeights(); - this.origIconWidth = iconRect.width; - this.origTextWidth = textRect.width; - this.origAccWidth = accRect.width; - this.origCheckWidth = checkRect.width; - this.origArrowWidth = arrowRect.width; - - calcMaxWidths(); - this.leadingGap = getLeadingGap(propertyPrefix); - calcMaxTextOffset(); - } - - // Clears fields to remove all links to other objects - // to prevent memory leaks - public void clear() { - mi = null; - miParent = null; - fm = null; - accFm = null; - icon = null; - checkIcon = null; - arrowIcon = null; - text = null; - accText = null; - htmlView = null; - viewRect = null; - iconRect = null; - textRect = null; - accRect = null; - checkRect = null; - arrowRect = null; - labelRect = null; - } - - private String getAccText(String acceleratorDelimiter) { - String accText = ""; - KeyStroke accelerator = mi.getAccelerator(); - if (accelerator != null) { - int modifiers = accelerator.getModifiers(); - if (modifiers > 0) { - accText = KeyEvent.getKeyModifiersText(modifiers); - accText += acceleratorDelimiter; - } - int keyCode = accelerator.getKeyCode(); - if (keyCode != 0) { - accText += KeyEvent.getKeyText(keyCode); - } else { - accText += accelerator.getKeyChar(); - } - } - return accText; - } - - // In case of column layout, .checkIconFactory is defined for this UI, - // the icon is compatible with it and useCheckAndArrow() is true, - // then the icon is handled by the checkIcon. - private Icon getIcon(String propertyPrefix) { - Icon icon = null; - MenuItemCheckIconFactory iconFactory = - (MenuItemCheckIconFactory) UIManager.get(propertyPrefix - + ".checkIconFactory"); - if (!isColumnLayout || !useCheckAndArrow || iconFactory == null - || !iconFactory.isCompatible(checkIcon, propertyPrefix)) { - icon = mi.getIcon(); - } - return icon; - } - - private int getMinTextOffset(String propertyPrefix) { - int minimumTextOffset = 0; - Object minimumTextOffsetObject = - UIManager.get(propertyPrefix + ".minimumTextOffset"); - if (minimumTextOffsetObject instanceof Integer) { - minimumTextOffset = (Integer) minimumTextOffsetObject; - } - return minimumTextOffset; - } - - private int getAfterCheckIconGap(String propertyPrefix) { - int afterCheckIconGap = gap; - Object afterCheckIconGapObject = - UIManager.get(propertyPrefix + ".afterCheckIconGap"); - if (afterCheckIconGapObject instanceof Integer) { - afterCheckIconGap = (Integer) afterCheckIconGapObject; - } - return afterCheckIconGap; - } - - private int getLeadingGap(String propertyPrefix) { - if (maxCheckWidth > 0) { - return getCheckOffset(propertyPrefix); - } else { - return gap; // There is no any check icon - } - } - - private int getCheckOffset(String propertyPrefix) { - int checkIconOffset = gap; - Object checkIconOffsetObject = - UIManager.get(propertyPrefix + ".checkIconOffset"); - if (checkIconOffsetObject instanceof Integer) { - checkIconOffset = (Integer) checkIconOffsetObject; - } - return checkIconOffset; - } - - private void calcWidthsAndHeights() - { - // iconRect - if (icon != null) { - iconRect.width = icon.getIconWidth(); - iconRect.height = icon.getIconHeight(); - } - - // accRect - if (!accText.equals("")) { - accRect.width = SwingUtilities2.stringWidth( - mi, accFm, accText); - accRect.height = accFm.getHeight(); - } - - // textRect - if (text == null) { - text = ""; - } else if (!text.equals("")) { - if (htmlView != null) { - // Text is HTML - textRect.width = - (int) htmlView.getPreferredSpan(View.X_AXIS); - textRect.height = - (int) htmlView.getPreferredSpan(View.Y_AXIS); - } else { - // Text isn't HTML - textRect.width = - SwingUtilities2.stringWidth(mi, fm, text); - textRect.height = fm.getHeight(); - } - } - - if (useCheckAndArrow) { - // checkIcon - if (checkIcon != null) { - checkRect.width = checkIcon.getIconWidth(); - checkRect.height = checkIcon.getIconHeight(); - } - // arrowRect - if (arrowIcon != null) { - arrowRect.width = arrowIcon.getIconWidth(); - arrowRect.height = arrowIcon.getIconHeight(); - } - } - - // labelRect - if (isColumnLayout) { - labelRect.width = iconRect.width + textRect.width + gap; - labelRect.height = max(checkRect.height, iconRect.height, - textRect.height, accRect.height, arrowRect.height); - } else { - textRect = new Rectangle(); - iconRect = new Rectangle(); - SwingUtilities.layoutCompoundLabel(mi, fm, text, icon, - verticalAlignment, horizontalAlignment, - verticalTextPosition, horizontalTextPosition, - viewRect, iconRect, textRect, gap); - labelRect = iconRect.union(textRect); - } - } - - private void calcMaxWidths() { - maxCheckWidth = calcMaxValue(BasicMenuItemUI.MAX_CHECK_WIDTH, - checkRect.width); - maxArrowWidth = calcMaxValue(BasicMenuItemUI.MAX_ARROW_WIDTH, - arrowRect.width); - maxAccWidth = calcMaxValue(BasicMenuItemUI.MAX_ACC_WIDTH, - accRect.width); - - if (isColumnLayout) { - maxIconWidth = calcMaxValue(BasicMenuItemUI.MAX_ICON_WIDTH, - iconRect.width); - maxTextWidth = calcMaxValue(BasicMenuItemUI.MAX_TEXT_WIDTH, - textRect.width); - int curGap = gap; - if ((maxIconWidth == 0) || (maxTextWidth == 0)) { - curGap = 0; - } - maxLabelWidth = - calcMaxValue(BasicMenuItemUI.MAX_LABEL_WIDTH, - maxIconWidth + maxTextWidth + curGap); - } else { - // We shouldn't use current icon and text widths - // in maximal widths calculation for complex layout. - maxIconWidth = getParentIntProperty(BasicMenuItemUI.MAX_ICON_WIDTH); - maxLabelWidth = calcMaxValue(BasicMenuItemUI.MAX_LABEL_WIDTH, - labelRect.width); - // If maxLabelWidth is wider - // than the widest icon + the widest text + gap, - // we should update the maximal text witdh - int candidateTextWidth = maxLabelWidth - maxIconWidth; - if (maxIconWidth > 0) { - candidateTextWidth -= gap; - } - maxTextWidth = calcMaxValue(BasicMenuItemUI.MAX_TEXT_WIDTH, - candidateTextWidth); - } - } - - // Calculates and returns maximal value - // through specified parent component client property. - private int calcMaxValue(Object propertyName, int value) { - // Get maximal value from parent client property - int maxValue = getParentIntProperty(propertyName); - // Store new maximal width in parent client property - if (value > maxValue) { - if (miParent != null) { - miParent.putClientProperty(propertyName, value); - } - return value; - } else { - return maxValue; - } - } - - // Returns parent client property as int - private int getParentIntProperty(Object propertyName) { - Object value = null; - if (miParent != null) { - value = miParent.getClientProperty(propertyName); - } - if ((value == null) || !(value instanceof Integer)){ - value = 0; - } - return (Integer)value; - } - - private boolean isColumnLayout() { - return isColumnLayout(isLeftToRight, horizontalAlignment, - horizontalTextPosition, verticalTextPosition); - } - - public static boolean isColumnLayout(boolean isLeftToRight, - JMenuItem mi) { - assert(mi != null); - return isColumnLayout(isLeftToRight, mi.getHorizontalAlignment(), - mi.getHorizontalTextPosition(), mi.getVerticalTextPosition()); - } - - // Answers should we do column layout for a menu item or not. - // We do it when a user doesn't set any alignments - // and text positions manually, except the vertical alignment. - public static boolean isColumnLayout( boolean isLeftToRight, - int horizontalAlignment, int horizontalTextPosition, - int verticalTextPosition) { - if (verticalTextPosition != SwingConstants.CENTER) { - return false; - } - if (isLeftToRight) { - if (horizontalAlignment != SwingConstants.LEADING - && horizontalAlignment != SwingConstants.LEFT) { - return false; - } - if (horizontalTextPosition != SwingConstants.TRAILING - && horizontalTextPosition != SwingConstants.RIGHT) { - return false; - } - } else { - if (horizontalAlignment != SwingConstants.LEADING - && horizontalAlignment != SwingConstants.RIGHT) { - return false; - } - if (horizontalTextPosition != SwingConstants.TRAILING - && horizontalTextPosition != SwingConstants.LEFT) { - return false; - } - } - return true; - } - - // Calculates maximal text offset. - // It is required for some L&Fs (ex: Vista L&F). - // The offset is meaningful only for L2R column layout. - private void calcMaxTextOffset() { - if (!isColumnLayout || !isLeftToRight) { - return; - } - - // Calculate the current text offset - int offset = viewRect.x + leadingGap + maxCheckWidth - + afterCheckIconGap + maxIconWidth + gap; - if (maxCheckWidth == 0) { - offset -= afterCheckIconGap; - } - if (maxIconWidth == 0) { - offset -= gap; - } - - // maximal text offset shouldn't be less than minimal text offset; - if (offset < minTextOffset) { - offset = minTextOffset; - } - - // Calculate and store the maximal text offset - calcMaxValue(BASICMENUITEMUI_MAX_TEXT_OFFSET, offset); - } - - public String toString() { - StringBuilder result = new StringBuilder(); - result.append(super.toString()).append("\n"); - result.append("accFm = ").append(accFm).append("\n"); - result.append("accRect = ").append(accRect).append("\n"); - result.append("accText = ").append(accText).append("\n"); - result.append("afterCheckIconGap = ").append(afterCheckIconGap) - .append("\n"); - result.append("arrowIcon = ").append(arrowIcon).append("\n"); - result.append("arrowRect = ").append(arrowRect).append("\n"); - result.append("checkIcon = ").append(checkIcon).append("\n"); - result.append("checkRect = ").append(checkRect).append("\n"); - result.append("fm = ").append(fm).append("\n"); - result.append("gap = ").append(gap).append("\n"); - result.append("horizontalAlignment = ").append(horizontalAlignment) - .append("\n"); - result.append("horizontalTextPosition = ") - .append(horizontalTextPosition).append("\n"); - result.append("htmlView = ").append(htmlView).append("\n"); - result.append("icon = ").append(icon).append("\n"); - result.append("iconRect = ").append(iconRect).append("\n"); - result.append("isColumnLayout = ").append(isColumnLayout).append("\n"); - result.append("isLeftToRight = ").append(isLeftToRight).append("\n"); - result.append("isTopLevelMenu = ").append(isTopLevelMenu).append("\n"); - result.append("labelRect = ").append(labelRect).append("\n"); - result.append("leadingGap = ").append(leadingGap).append("\n"); - result.append("maxAccWidth = ").append(maxAccWidth).append("\n"); - result.append("maxArrowWidth = ").append(maxArrowWidth).append("\n"); - result.append("maxCheckWidth = ").append(maxCheckWidth).append("\n"); - result.append("maxIconWidth = ").append(maxIconWidth).append("\n"); - result.append("maxLabelWidth = ").append(maxLabelWidth).append("\n"); - result.append("maxTextWidth = ").append(maxTextWidth).append("\n"); - result.append("maxTextOffset = ") - .append(getParentIntProperty(BASICMENUITEMUI_MAX_TEXT_OFFSET)) - .append("\n"); - result.append("mi = ").append(mi).append("\n"); - result.append("minTextOffset = ").append(minTextOffset).append("\n"); - result.append("miParent = ").append(miParent).append("\n"); - result.append("origAccWidth = ").append(origAccWidth).append("\n"); - result.append("origArrowWidth = ").append(origArrowWidth).append("\n"); - result.append("origCheckWidth = ").append(origCheckWidth).append("\n"); - result.append("origIconWidth = ").append(origIconWidth).append("\n"); - result.append("origTextWidth = ").append(origTextWidth).append("\n"); - result.append("text = ").append(text).append("\n"); - result.append("textRect = ").append(textRect).append("\n"); - result.append("useCheckAndArrow = ").append(useCheckAndArrow) - .append("\n"); - result.append("verticalAlignment = ").append(verticalAlignment) - .append("\n"); - result.append("verticalTextPosition = ") - .append(verticalTextPosition).append("\n"); - result.append("viewRect = ").append(viewRect).append("\n"); - return result.toString(); - } - } // End of LayoutInfo - - // Reuses layoutInfo object to reduce the amount of produced garbage - private LayoutInfo getLayoutInfo(JMenuItem mi, Icon checkIcon, Icon arrowIcon, - Rectangle viewRect, int gap, String accDelimiter, - boolean isLeftToRight, Font acceleratorFont, - boolean useCheckAndArrow, String propertyPrefix) { - // layoutInfo is final and always not null - layoutInfo.reset(mi, checkIcon, arrowIcon, viewRect, - gap, accDelimiter, isLeftToRight, acceleratorFont, - useCheckAndArrow, propertyPrefix); - return layoutInfo; - } - /** * We draw the background in paintMenuItem() * so override update (which fills the background of opaque @@ -1016,122 +482,132 @@ public class BasicMenuItemUI extends MenuItemUI Rectangle viewRect = new Rectangle(0, 0, mi.getWidth(), mi.getHeight()); applyInsets(viewRect, mi.getInsets()); - LayoutInfo li = getLayoutInfo(mi, checkIcon, arrowIcon, - viewRect, defaultTextIconGap, acceleratorDelimiter, - BasicGraphicsUtils.isLeftToRight(mi), acceleratorFont, - useCheckAndArrow(), getPropertyPrefix()); - layoutMenuItem(li); + MenuItemLayoutHelper lh = new MenuItemLayoutHelper(mi, checkIcon, + arrowIcon, viewRect, defaultTextIconGap, acceleratorDelimiter, + BasicGraphicsUtils.isLeftToRight(mi), mi.getFont(), + acceleratorFont, MenuItemLayoutHelper.useCheckAndArrow(menuItem), + getPropertyPrefix()); + MenuItemLayoutHelper.LayoutResult lr = lh.layoutMenuItem(); paintBackground(g, mi, background); - paintCheckIcon(g, li, holdc, foreground); - paintIcon(g, li, holdc); - paintText(g, li); - paintAccText(g, li); - paintArrowIcon(g, li, foreground); + paintCheckIcon(g, lh, lr, holdc, foreground); + paintIcon(g, lh, lr, holdc); + paintText(g, lh, lr); + paintAccText(g, lh, lr); + paintArrowIcon(g, lh, lr, foreground); // Restore original graphics font and color g.setColor(holdc); g.setFont(holdf); - - li.clear(); } - private void paintIcon(Graphics g, LayoutInfo li, Color holdc) { - if (li.icon != null) { + private void paintIcon(Graphics g, MenuItemLayoutHelper lh, + MenuItemLayoutHelper.LayoutResult lr, Color holdc) { + if (lh.getIcon() != null) { Icon icon; - ButtonModel model = li.mi.getModel(); + ButtonModel model = lh.getMenuItem().getModel(); if (!model.isEnabled()) { - icon = (Icon) li.mi.getDisabledIcon(); + icon = lh.getMenuItem().getDisabledIcon(); } else if (model.isPressed() && model.isArmed()) { - icon = (Icon) li.mi.getPressedIcon(); + icon = lh.getMenuItem().getPressedIcon(); if (icon == null) { // Use default icon - icon = (Icon) li.mi.getIcon(); + icon = lh.getMenuItem().getIcon(); } } else { - icon = (Icon) li.mi.getIcon(); + icon = lh.getMenuItem().getIcon(); } if (icon != null) { - icon.paintIcon(li.mi, g, li.iconRect.x, li.iconRect.y); + icon.paintIcon(lh.getMenuItem(), g, lr.getIconRect().x, + lr.getIconRect().y); g.setColor(holdc); } } } - private void paintCheckIcon(Graphics g, LayoutInfo li, + private void paintCheckIcon(Graphics g, MenuItemLayoutHelper lh, + MenuItemLayoutHelper.LayoutResult lr, Color holdc, Color foreground) { - if (li.checkIcon != null) { - ButtonModel model = li.mi.getModel(); - if (model.isArmed() - || (li.mi instanceof JMenu && model.isSelected())) { + if (lh.getCheckIcon() != null) { + ButtonModel model = lh.getMenuItem().getModel(); + if (model.isArmed() || (lh.getMenuItem() instanceof JMenu + && model.isSelected())) { g.setColor(foreground); } else { g.setColor(holdc); } - if (li.useCheckAndArrow) { - li.checkIcon.paintIcon(li.mi, g, li.checkRect.x, - li.checkRect.y); + if (lh.useCheckAndArrow()) { + lh.getCheckIcon().paintIcon(lh.getMenuItem(), g, + lr.getCheckRect().x, lr.getCheckRect().y); } g.setColor(holdc); } } - private void paintAccText(Graphics g, LayoutInfo li) { - if (!li.accText.equals("")) { - ButtonModel model = li.mi.getModel(); - g.setFont(acceleratorFont); + private void paintAccText(Graphics g, MenuItemLayoutHelper lh, + MenuItemLayoutHelper.LayoutResult lr) { + if (!lh.getAccText().equals("")) { + ButtonModel model = lh.getMenuItem().getModel(); + g.setFont(lh.getAccFontMetrics().getFont()); if (!model.isEnabled()) { // *** paint the accText disabled if (disabledForeground != null) { g.setColor(disabledForeground); - SwingUtilities2.drawString(li.mi, g, li.accText, - li.accRect.x, - li.accRect.y + li.accFm.getAscent()); + SwingUtilities2.drawString(lh.getMenuItem(), g, + lh.getAccText(), lr.getAccRect().x, + lr.getAccRect().y + lh.getAccFontMetrics().getAscent()); } else { - g.setColor(li.mi.getBackground().brighter()); - SwingUtilities2.drawString(li.mi, g, li.accText, li.accRect.x, - li.accRect.y + li.accFm.getAscent()); - g.setColor(li.mi.getBackground().darker()); - SwingUtilities2.drawString(li.mi, g, li.accText, - li.accRect.x - 1, - li.accRect.y + li.accFm.getAscent() - 1); + g.setColor(lh.getMenuItem().getBackground().brighter()); + SwingUtilities2.drawString(lh.getMenuItem(), g, + lh.getAccText(), lr.getAccRect().x, + lr.getAccRect().y + lh.getAccFontMetrics().getAscent()); + g.setColor(lh.getMenuItem().getBackground().darker()); + SwingUtilities2.drawString(lh.getMenuItem(), g, + lh.getAccText(), lr.getAccRect().x - 1, + lr.getAccRect().y + lh.getFontMetrics().getAscent() - 1); } } else { // *** paint the accText normally - if (model.isArmed() || - (li.mi instanceof JMenu && model.isSelected())) { + if (model.isArmed() + || (lh.getMenuItem() instanceof JMenu + && model.isSelected())) { g.setColor(acceleratorSelectionForeground); } else { g.setColor(acceleratorForeground); } - SwingUtilities2.drawString(li.mi, g, li.accText, li.accRect.x, - li.accRect.y + li.accFm.getAscent()); + SwingUtilities2.drawString(lh.getMenuItem(), g, lh.getAccText(), + lr.getAccRect().x, lr.getAccRect().y + + lh.getAccFontMetrics().getAscent()); } } } - private void paintText(Graphics g, LayoutInfo li) { - if (!li.text.equals("")) { - if (li.htmlView != null) { + private void paintText(Graphics g, MenuItemLayoutHelper lh, + MenuItemLayoutHelper.LayoutResult lr) { + if (!lh.getText().equals("")) { + if (lh.getHtmlView() != null) { // Text is HTML - li.htmlView.paint(g, li.textRect); + lh.getHtmlView().paint(g, lr.getTextRect()); } else { // Text isn't HTML - paintText(g, li.mi, li.textRect, li.text); + paintText(g, lh.getMenuItem(), lr.getTextRect(), lh.getText()); } } } - private void paintArrowIcon(Graphics g, LayoutInfo li, Color foreground) { - if (li.arrowIcon != null) { - ButtonModel model = li.mi.getModel(); - if (model.isArmed() - || (li.mi instanceof JMenu && model.isSelected())) { + private void paintArrowIcon(Graphics g, MenuItemLayoutHelper lh, + MenuItemLayoutHelper.LayoutResult lr, + Color foreground) { + if (lh.getArrowIcon() != null) { + ButtonModel model = lh.getMenuItem().getModel(); + if (model.isArmed() || (lh.getMenuItem() instanceof JMenu + && model.isSelected())) { g.setColor(foreground); } - if (li.useCheckAndArrow) { - li.arrowIcon.paintIcon(li.mi, g, li.arrowRect.x, li.arrowRect.y); + if (lh.useCheckAndArrow()) { + lh.getArrowIcon().paintIcon(lh.getMenuItem(), g, + lr.getArrowRect().x, lr.getArrowRect().y); } } } @@ -1216,346 +692,6 @@ public class BasicMenuItemUI extends MenuItemUI } } - - /** - * Layout icon, text, check icon, accelerator text and arrow icon - * in the viewRect and return their positions. - * - * If horizontalAlignment, verticalTextPosition and horizontalTextPosition - * are default (user doesn't set any manually) the layouting algorithm is: - * Elements are layouted in the five columns: - * check icon + icon + text + accelerator text + arrow icon - * - * In the other case elements are layouted in the four columns: - * check icon + label + accelerator text + arrow icon - * Label is icon and text rectangles union. - * - * The order of columns can be reversed. - * It depends on the menu item orientation. - */ - private void layoutMenuItem(LayoutInfo li) - { - li.checkRect.width = li.maxCheckWidth; - li.accRect.width = li.maxAccWidth; - li.arrowRect.width = li.maxArrowWidth; - - if (li.isColumnLayout) { - if (li.isLeftToRight) { - doLTRColumnLayout(li); - } else { - doRTLColumnLayout(li); - } - } else { - if (li.isLeftToRight) { - doLTRComplexLayout(li); - } else { - doRTLComplexLayout(li); - } - } - - alignAccCheckAndArrowVertically(li); - } - - // Aligns the accelertor text and the check and arrow icons vertically - // with the center of the label rect. - private void alignAccCheckAndArrowVertically(LayoutInfo li) { - li.accRect.y = (int)(li.labelRect.y + (float)li.labelRect.height/2 - - (float)li.accRect.height/2); - fixVerticalAlignment(li, li.accRect); - if (li.useCheckAndArrow) { - li.arrowRect.y = (int)(li.labelRect.y + (float)li.labelRect.height/2 - - (float)li.arrowRect.height/2); - li.checkRect.y = (int)(li.labelRect.y + (float)li.labelRect.height/2 - - (float)li.checkRect.height/2); - fixVerticalAlignment(li, li.arrowRect); - fixVerticalAlignment(li, li.checkRect); - } - } - - // Fixes vertical alignment of all menu item elements if a rect.y - // or (rect.y + rect.height) is out of viewRect bounds - private void fixVerticalAlignment(LayoutInfo li, Rectangle r) { - int delta = 0; - if (r.y < li.viewRect.y) { - delta = li.viewRect.y - r.y; - } else if (r.y + r.height > li.viewRect.y + li.viewRect.height) { - delta = li.viewRect.y + li.viewRect.height - r.y - r.height; - } - if (delta != 0) { - li.checkRect.y += delta; - li.iconRect.y += delta; - li.textRect.y += delta; - li.accRect.y += delta; - li.arrowRect.y += delta; - } - } - - private void doLTRColumnLayout(LayoutInfo li) { - // Set maximal width for all the five basic rects - // (three other ones are already maximal) - li.iconRect.width = li.maxIconWidth; - li.textRect.width = li.maxTextWidth; - - // Set X coordinates - // All rects will be aligned at the left side - calcXPositionsL2R(li.viewRect.x, li.leadingGap, li.gap, li.checkRect, - li.iconRect, li.textRect); - - // Tune afterCheckIconGap - if (li.checkRect.width > 0) { // there is the afterCheckIconGap - li.iconRect.x += li.afterCheckIconGap - li.gap; - li.textRect.x += li.afterCheckIconGap - li.gap; - } - - calcXPositionsR2L(li.viewRect.x + li.viewRect.width, li.gap, - li.arrowRect, li.accRect); - - // Take into account minimal text offset - int textOffset = li.textRect.x - li.viewRect.x; - if (!li.isTopLevelMenu && (textOffset < li.minTextOffset)) { - li.textRect.x += li.minTextOffset - textOffset; - } - - // Take into account the left side bearings for text and accelerator text. - fixTextRects(li); - - // Set Y coordinate for text and icon. - // Y coordinates for other rects - // will be calculated later in layoutMenuItem. - calcTextAndIconYPositions(li); - - // Calculate valid X and Y coordinates for labelRect - li.labelRect = li.textRect.union(li.iconRect); - } - - private void doLTRComplexLayout(LayoutInfo li) { - li.labelRect.width = li.maxLabelWidth; - - // Set X coordinates - calcXPositionsL2R(li.viewRect.x, li.leadingGap, li.gap, li.checkRect, - li.labelRect); - - // Tune afterCheckIconGap - if (li.checkRect.width > 0) { // there is the afterCheckIconGap - li.labelRect.x += li.afterCheckIconGap - li.gap; - } - - calcXPositionsR2L(li.viewRect.x + li.viewRect.width, li.gap, - li.arrowRect, li.accRect); - - // Take into account minimal text offset - int labelOffset = li.labelRect.x - li.viewRect.x; - if (!li.isTopLevelMenu && (labelOffset < li.minTextOffset)) { - li.labelRect.x += li.minTextOffset - labelOffset; - } - - // Take into account the left side bearing for accelerator text. - // The LSB for text is taken into account in layoutCompoundLabel() below. - fixAccTextRect(li); - - // Layout icon and text with SwingUtilities.layoutCompoundLabel() - // within the labelRect - li.textRect = new Rectangle(); - li.iconRect = new Rectangle(); - SwingUtilities.layoutCompoundLabel( - li.mi, li.fm, li.text, li.icon, li.verticalAlignment, - li.horizontalAlignment, li.verticalTextPosition, - li.horizontalTextPosition, li.labelRect, - li.iconRect, li.textRect, li.gap); - } - - private void doRTLColumnLayout(LayoutInfo li) { - // Set maximal width for all the five basic rects - // (three other ones are already maximal) - li.iconRect.width = li.maxIconWidth; - li.textRect.width = li.maxTextWidth; - - // Set X coordinates - calcXPositionsR2L(li.viewRect.x + li.viewRect.width, li.leadingGap, - li.gap, li.checkRect, li.iconRect, li.textRect); - - // Tune the gap after check icon - if (li.checkRect.width > 0) { // there is the gap after check icon - li.iconRect.x -= li.afterCheckIconGap - li.gap; - li.textRect.x -= li.afterCheckIconGap - li.gap; - } - - calcXPositionsL2R(li.viewRect.x, li.gap, li.arrowRect, - li.accRect); - - // Take into account minimal text offset - int textOffset = (li.viewRect.x + li.viewRect.width) - - (li.textRect.x + li.textRect.width); - if (!li.isTopLevelMenu && (textOffset < li.minTextOffset)) { - li.textRect.x -= li.minTextOffset - textOffset; - } - - // Align icon, text, accelerator text, check icon and arrow icon - // at the right side - rightAlignAllRects(li); - - // Take into account the left side bearings for text and accelerator text. - fixTextRects(li); - - // Set Y coordinates for text and icon. - // Y coordinates for other rects - // will be calculated later in layoutMenuItem. - calcTextAndIconYPositions(li); - - // Calculate valid X and Y coordinate for labelRect - li.labelRect = li.textRect.union(li.iconRect); - } - - private void doRTLComplexLayout(LayoutInfo li) { - li.labelRect.width = li.maxLabelWidth; - - // Set X coordinates - calcXPositionsR2L(li.viewRect.x + li.viewRect.width, li.leadingGap, - li.gap, li.checkRect, li.labelRect); - - // Tune the gap after check icon - if (li.checkRect.width > 0) { // there is the gap after check icon - li.labelRect.x -= li.afterCheckIconGap - li.gap; - } - - calcXPositionsL2R(li.viewRect.x, li.gap, li.arrowRect, - li.accRect); - - // Take into account minimal text offset - int labelOffset = (li.viewRect.x + li.viewRect.width) - - (li.labelRect.x + li.labelRect.width); - if (!li.isTopLevelMenu && (labelOffset < li.minTextOffset)) { - li.labelRect.x -= li.minTextOffset - labelOffset; - } - - // Align icon, text, accelerator text, check icon and arrow icon - // at the right side - rightAlignAllRects(li); - - // Take into account the left side bearing for accelerator text. - // The LSB for text is taken into account in layoutCompoundLabel() below. - fixAccTextRect(li); - - // Layout icon and text with SwingUtilities.layoutCompoundLabel() - // within the labelRect - li.textRect = new Rectangle(); - li.iconRect = new Rectangle(); - SwingUtilities.layoutCompoundLabel( - menuItem, li.fm, li.text, li.icon, li.verticalAlignment, - li.horizontalAlignment, li.verticalTextPosition, - li.horizontalTextPosition, li.labelRect, - li.iconRect, li.textRect, li.gap); - } - - private void calcXPositionsL2R(int startXPos, int leadingGap, - int gap, Rectangle... rects) { - int curXPos = startXPos + leadingGap; - for (Rectangle rect : rects) { - rect.x = curXPos; - if (rect.width > 0) { - curXPos += rect.width + gap; - } - } - } - - private void calcXPositionsL2R(int startXPos, int gap, Rectangle... rects) { - calcXPositionsL2R(startXPos, gap, gap, rects); - } - - private void calcXPositionsR2L(int startXPos, int leadingGap, - int gap, Rectangle... rects) { - int curXPos = startXPos - leadingGap; - for (Rectangle rect : rects) { - rect.x = curXPos - rect.width; - if (rect.width > 0) { - curXPos -= rect.width + gap; - } - } - } - - private void calcXPositionsR2L(int startXPos, int gap, Rectangle... rects) { - calcXPositionsR2L(startXPos, gap, gap, rects); - } - - // Takes into account the left side bearings for text and accelerator text - private void fixTextRects(LayoutInfo li) { - if (li.htmlView == null) { // The text isn't a HTML - int lsb = SwingUtilities2.getLeftSideBearing(li.mi, li.fm, li.text); - if (lsb < 0) { - li.textRect.x -= lsb; - } - } - fixAccTextRect(li); - } - - // Takes into account the left side bearing for accelerator text - private void fixAccTextRect(LayoutInfo li) { - int lsb = SwingUtilities2 - .getLeftSideBearing(li.mi, li.accFm, li.accText); - if (lsb < 0) { - li.accRect.x -= lsb; - } - } - - // Sets Y coordinates of text and icon - // taking into account the vertical alignment - private void calcTextAndIconYPositions(LayoutInfo li) { - if (li.verticalAlignment == SwingUtilities.TOP) { - li.textRect.y = (int)(li.viewRect.y - + (float)li.labelRect.height/2 - - (float)li.textRect.height/2); - li.iconRect.y = (int)(li.viewRect.y - + (float)li.labelRect.height/2 - - (float)li.iconRect.height/2); - } else if (li.verticalAlignment == SwingUtilities.CENTER) { - li.textRect.y = (int)(li.viewRect.y - + (float)li.viewRect.height/2 - - (float)li.textRect.height/2); - li.iconRect.y = (int)(li.viewRect.y - + (float)li.viewRect.height/2 - - (float)li.iconRect.height/2); - } - else if (li.verticalAlignment == SwingUtilities.BOTTOM) { - li.textRect.y = (int)(li.viewRect.y + li.viewRect.height - - (float)li.labelRect.height/2 - - (float)li.textRect.height/2); - li.iconRect.y = (int)(li.viewRect.y + li.viewRect.height - - (float)li.labelRect.height/2 - - (float)li.iconRect.height/2); - } - } - - // Aligns icon, text, accelerator text, check icon and arrow icon - // at the right side - private void rightAlignAllRects(LayoutInfo li) { - li.iconRect.x = li.iconRect.x + li.iconRect.width - li.origIconWidth; - li.iconRect.width = li.origIconWidth; - li.textRect.x = li.textRect.x + li.textRect.width - li.origTextWidth; - li.textRect.width = li.origTextWidth; - li.accRect.x = li.accRect.x + li.accRect.width - - li.origAccWidth; - li.accRect.width = li.origAccWidth; - li.checkRect.x = li.checkRect.x + li.checkRect.width - - li.origCheckWidth; - li.checkRect.width = li.origCheckWidth; - li.arrowRect.x = li.arrowRect.x + li.arrowRect.width - - li.origArrowWidth; - li.arrowRect.width = li.origArrowWidth; - } - - /* - * Returns false if the component is a JMenu and it is a top - * level menu (on the menubar). - */ - private boolean useCheckAndArrow(){ - boolean b = true; - if((menuItem instanceof JMenu) && - (((JMenu)menuItem).isTopLevelMenu())) { - b = false; - } - return b; - } - public MenuElement[] getPath() { MenuSelectionManager m = MenuSelectionManager.defaultManager(); MenuElement oldPath[] = m.getSelectedPath(); @@ -1601,7 +737,7 @@ public class BasicMenuItemUI extends MenuItemUI for(i=0,j=path.length; i 0) { me = new MenuElement[4]; me[0] = (MenuElement) cnt; - me[1] = (MenuElement) menu; - me[2] = (MenuElement) menu.getPopupMenu(); + me[1] = menu; + me[2] = menu.getPopupMenu(); me[3] = subElements[0]; } else { me = new MenuElement[3]; me[0] = (MenuElement)cnt; me[1] = menu; - me[2] = (MenuElement) menu.getPopupMenu(); + me[2] = menu.getPopupMenu(); } defaultManager.setSelectedPath(me); } @@ -606,7 +605,7 @@ public class BasicMenuUI extends BasicMenuItemUI MenuSelectionManager manager = e.getMenuSelectionManager(); if (key == Character.toLowerCase(e.getKeyChar())) { JPopupMenu popupMenu = ((JMenu)menuItem).getPopupMenu(); - ArrayList newList = new ArrayList(Arrays.asList(path)); + ArrayList newList = new ArrayList(Arrays.asList(path)); newList.add(popupMenu); MenuElement subs[] = popupMenu.getSubElements(); MenuElement sub = @@ -614,8 +613,8 @@ public class BasicMenuUI extends BasicMenuItemUI if(sub != null) { newList.add(sub); } - MenuElement newPath[] = new MenuElement[0];; - newPath = (MenuElement[]) newList.toArray(newPath); + MenuElement newPath[] = new MenuElement[0]; + newPath = newList.toArray(newPath); manager.setSelectedPath(newPath); e.consume(); } else if (((JMenu)menuItem).isTopLevelMenu() diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java index 4a226a282e9..5f0610fa14e 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java @@ -109,7 +109,7 @@ public class BasicOptionPaneUI extends OptionPaneUI { static { - newline = (String)java.security.AccessController.doPrivileged( + newline = java.security.AccessController.doPrivileged( new GetPropertyAction("line.separator")); if (newline == null) { newline = "\n"; @@ -262,7 +262,7 @@ public class BasicOptionPaneUI extends OptionPaneUI { * getMinimumOptionPaneSize. */ public Dimension getPreferredSize(JComponent c) { - if ((JOptionPane)c == optionPane) { + if (c == optionPane) { Dimension ourMin = getMinimumOptionPaneSize(); LayoutManager lm = c.getLayout(); @@ -366,8 +366,8 @@ public class BasicOptionPaneUI extends OptionPaneUI { } else if (msg instanceof Object[]) { Object [] msgs = (Object[]) msg; - for (int i = 0; i < msgs.length; i++) { - addMessageComponents(container, cons, msgs[i], maxll, false); + for (Object o : msgs) { + addMessageComponents(container, cons, o, maxll, false); } } else if (msg instanceof Icon) { @@ -381,7 +381,7 @@ public class BasicOptionPaneUI extends OptionPaneUI { if (len <= 0) { return; } - int nl = -1; + int nl; int nll = 0; if ((nl = s.indexOf(newline)) >= 0) { @@ -1320,7 +1320,7 @@ public class BasicOptionPaneUI extends OptionPaneUI { else if (changeName == "componentOrientation") { ComponentOrientation o = (ComponentOrientation)e.getNewValue(); JOptionPane op = (JOptionPane)e.getSource(); - if (o != (ComponentOrientation)e.getOldValue()) { + if (o != e.getOldValue()) { op.applyComponentOrientation(o); } } @@ -1418,7 +1418,7 @@ public class BasicOptionPaneUI extends OptionPaneUI { } JButton createButton() { - JButton button = null; + JButton button; if (minimumWidth > 0) { button = new ConstrainedButton(text, minimumWidth); diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicPopupMenuUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicPopupMenuUI.java index d2d3a0197b7..8fbb79fffae 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicPopupMenuUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicPopupMenuUI.java @@ -225,14 +225,14 @@ public class BasicPopupMenuUI extends PopupMenuUI { return popup; } - static List getPopups() { + static List getPopups() { MenuSelectionManager msm = MenuSelectionManager.defaultManager(); MenuElement[] p = msm.getSelectedPath(); - List list = new ArrayList(p.length); - for(int i = 0; i < p.length; i++) { - if (p[i] instanceof JPopupMenu) { - list.add((JPopupMenu)p[i]); + List list = new ArrayList(p.length); + for (MenuElement element : p) { + if (element instanceof JPopupMenu) { + list.add((JPopupMenu) element); } } return list; @@ -290,14 +290,14 @@ public class BasicPopupMenuUI extends PopupMenuUI { MenuElement subitem = findEnabledChild( subpopup.getSubElements(), -1, true); - ArrayList lst = new ArrayList(Arrays.asList(e.getPath())); + ArrayList lst = new ArrayList(Arrays.asList(e.getPath())); lst.add(menuToOpen); lst.add(subpopup); if (subitem != null) { lst.add(subitem); } - MenuElement newPath[] = new MenuElement[0];; - newPath = (MenuElement[])lst.toArray(newPath); + MenuElement newPath[] = new MenuElement[0]; + newPath = lst.toArray(newPath); MenuSelectionManager.defaultManager().setSelectedPath(newPath); e.consume(); } @@ -345,7 +345,7 @@ public class BasicPopupMenuUI extends PopupMenuUI { } if (matches == 0) { - ; // no op + // no op } else if (matches == 1) { // Invoke the menu action JMenuItem item = (JMenuItem)items[firstMatch]; @@ -362,7 +362,7 @@ public class BasicPopupMenuUI extends PopupMenuUI { // Select the menu item with the matching mnemonic. If // the same mnemonic has been invoked then select the next // menu item in the cycle. - MenuElement newItem = null; + MenuElement newItem; newItem = items[indexes[(currentIndex + 1) % matches]]; @@ -372,7 +372,6 @@ public class BasicPopupMenuUI extends PopupMenuUI { manager.setSelectedPath(newPath); e.consume(); } - return; } public void menuKeyReleased(MenuKeyEvent e) { @@ -625,7 +624,7 @@ public class BasicPopupMenuUI extends PopupMenuUI { // 4234793: This action should call JPopupMenu.firePopupMenuCanceled but it's // a protected method. The real solution could be to make // firePopupMenuCanceled public and call it directly. - JPopupMenu lastPopup = (JPopupMenu)getLastPopup(); + JPopupMenu lastPopup = getLastPopup(); if (lastPopup != null) { lastPopup.putClientProperty("JPopupMenu.firePopupMenuCanceled", Boolean.TRUE); } @@ -703,7 +702,7 @@ public class BasicPopupMenuUI extends PopupMenuUI { static MenuElement findEnabledChild(MenuElement e[], int fromIndex, boolean forward) { - MenuElement result = null; + MenuElement result; if (forward) { result = nextEnabledChild(e, fromIndex+1, e.length-1); if (result == null) result = nextEnabledChild(e, 0, fromIndex-1); @@ -752,7 +751,7 @@ public class BasicPopupMenuUI extends PopupMenuUI { // A grab needs to be added final Toolkit tk = Toolkit.getDefaultToolkit(); java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new java.security.PrivilegedAction() { public Object run() { tk.addAWTEventListener(MouseGrabber.this, AWTEvent.MOUSE_EVENT_MASK | @@ -785,7 +784,7 @@ public class BasicPopupMenuUI extends PopupMenuUI { final Toolkit tk = Toolkit.getDefaultToolkit(); // The grab should be removed java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new java.security.PrivilegedAction() { public Object run() { tk.removeAWTEventListener(MouseGrabber.this); return null; @@ -911,10 +910,8 @@ public class BasicPopupMenuUI extends PopupMenuUI { // 4234793: This action should call firePopupMenuCanceled but it's // a protected method. The real solution could be to make // firePopupMenuCanceled public and call it directly. - List popups = getPopups(); - Iterator iter = popups.iterator(); - while (iter.hasNext()) { - JPopupMenu popup = (JPopupMenu) iter.next(); + List popups = getPopups(); + for (JPopupMenu popup : popups) { popup.putClientProperty("JPopupMenu.firePopupMenuCanceled", Boolean.TRUE); } MenuSelectionManager.defaultManager().clearSelectedPath(); diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java index 567f4e79446..d1ddab9934a 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java @@ -150,15 +150,15 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI } } else if(model.isSelected()) { if(b.isRolloverEnabled() && model.isRollover()) { - altIcon = (Icon) b.getRolloverSelectedIcon(); + altIcon = b.getRolloverSelectedIcon(); if (altIcon == null) { - altIcon = (Icon) b.getSelectedIcon(); + altIcon = b.getSelectedIcon(); } } else { - altIcon = (Icon) b.getSelectedIcon(); + altIcon = b.getSelectedIcon(); } } else if(b.isRolloverEnabled() && model.isRollover()) { - altIcon = (Icon) b.getRolloverIcon(); + altIcon = b.getRolloverIcon(); } if(altIcon == null) { @@ -214,7 +214,7 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI String text = b.getText(); - Icon buttonIcon = (Icon) b.getIcon(); + Icon buttonIcon = b.getIcon(); if(buttonIcon == null) { buttonIcon = getDefaultIcon(); } diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java index 28427f7b3b0..0c7e995f053 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java @@ -106,13 +106,13 @@ public class BasicSplitPaneUI extends SplitPaneUI * Keys to use for forward focus traversal when the JComponent is * managing focus. */ - private static Set managingFocusForwardTraversalKeys; + private static Set managingFocusForwardTraversalKeys; /** * Keys to use for backward focus traversal when the JComponent is * managing focus. */ - private static Set managingFocusBackwardTraversalKeys; + private static Set managingFocusBackwardTraversalKeys; /** @@ -370,7 +370,7 @@ public class BasicSplitPaneUI extends SplitPaneUI // focus forward traversal key if (managingFocusForwardTraversalKeys==null) { - managingFocusForwardTraversalKeys = new HashSet(); + managingFocusForwardTraversalKeys = new HashSet(); managingFocusForwardTraversalKeys.add( KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0)); } @@ -378,7 +378,7 @@ public class BasicSplitPaneUI extends SplitPaneUI managingFocusForwardTraversalKeys); // focus backward traversal key if (managingFocusBackwardTraversalKeys==null) { - managingFocusBackwardTraversalKeys = new HashSet(); + managingFocusBackwardTraversalKeys = new HashSet(); managingFocusBackwardTraversalKeys.add( KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK)); } @@ -2170,7 +2170,7 @@ public class BasicSplitPaneUI extends SplitPaneUI Component focusOn = (direction > 0) ? policy.getComponentAfter(rootAncestor, splitPane) : policy.getComponentBefore(rootAncestor, splitPane); - HashSet focusFrom = new HashSet(); + HashSet focusFrom = new HashSet(); if (splitPane.isAncestorOf(focusOn)) { do { focusFrom.add(focusOn); @@ -2212,7 +2212,7 @@ public class BasicSplitPaneUI extends SplitPaneUI private Component getNextSide(JSplitPane splitPane, Component focus) { Component left = splitPane.getLeftComponent(); Component right = splitPane.getRightComponent(); - Component next = null; + Component next; if (focus!=null && SwingUtilities.isDescendingFrom(focus, left) && right!=null) { next = getFirstAvailableComponent(right); diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java index 29919d50475..a266b77141e 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java @@ -142,9 +142,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { private Component visibleComponent; // PENDING(api): See comment for ContainerHandler - private Vector htmlViews; + private Vector htmlViews; - private Hashtable mnemonicToIndexMap; + private Hashtable mnemonicToIndexMap; /** * InputMap used for mnemonics. Only non-null if the JTabbedPane has @@ -546,7 +546,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { * Installs the state needed for mnemonics. */ private void initMnemonics() { - mnemonicToIndexMap = new Hashtable(); + mnemonicToIndexMap = new Hashtable(); mnemonicInputMap = new ComponentInputMapUIResource(tabPane); mnemonicInputMap.setParent(SwingUtilities.getUIInputMap(tabPane, JComponent.WHEN_IN_FOCUSED_WINDOW)); @@ -909,10 +909,10 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { private static final int CROP_SEGMENT = 12; private static Polygon createCroppedTabShape(int tabPlacement, Rectangle tabRect, int cropline) { - int rlen = 0; - int start = 0; - int end = 0; - int ostart = 0; + int rlen; + int start; + int end; + int ostart; switch(tabPlacement) { case LEFT: @@ -1014,7 +1014,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { tabPane.putClientProperty("html", v); } - SwingUtilities.layoutCompoundLabel((JComponent) tabPane, + SwingUtilities.layoutCompoundLabel(tabPane, metrics, title, icon, SwingUtilities.CENTER, SwingUtilities.CENTER, @@ -1694,7 +1694,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { */ protected View getTextViewForTab(int tabIndex) { if (htmlViews != null) { - return (View)htmlViews.elementAt(tabIndex); + return htmlViews.elementAt(tabIndex); } return null; } @@ -2230,8 +2230,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { if (mnemonic >= 'a' && mnemonic <='z') { mnemonic -= ('a' - 'A'); } - Integer index = (Integer)ui.mnemonicToIndexMap. - get(Integer.valueOf(mnemonic)); + Integer index = ui.mnemonicToIndexMap.get(Integer.valueOf(mnemonic)); if (index != null && pane.isEnabledAt(index.intValue())) { pane.setSelectedIndex(index.intValue()); } @@ -2292,8 +2291,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { for (int i = 0; i < tabPane.getTabCount(); i++) { Component component = tabPane.getComponentAt(i); if (component != null) { - Dimension size = zeroSize; - size = minimum? component.getMinimumSize() : + Dimension size = minimum ? component.getMinimumSize() : component.getPreferredSize(); if (size != null) { @@ -2305,7 +2303,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { // Add content border insets to minimum size width += cWidth; height += cHeight; - int tabExtent = 0; + int tabExtent; // Calculate how much space the tabs will need, based on the // minimum size required to display largest child + content border @@ -3143,7 +3141,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { Insets tabAreaInsets = getTabAreaInsets(tabPlacement); int fontHeight = metrics.getHeight(); int selectedIndex = tabPane.getSelectedIndex(); - int i, j; + int i; boolean verticalTabRuns = (tabPlacement == LEFT || tabPlacement == RIGHT); boolean leftToRight = BasicGraphicsUtils.isLeftToRight(tabPane); int x = tabAreaInsets.left; @@ -3433,10 +3431,10 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } public String toString() { - return new String("viewport.viewSize="+viewport.getViewSize()+"\n"+ + return "viewport.viewSize=" + viewport.getViewSize() + "\n" + "viewport.viewRectangle="+viewport.getViewRect()+"\n"+ "leadingTabIndex="+leadingTabIndex+"\n"+ - "tabViewPosition="+tabViewPosition); + "tabViewPosition=" + tabViewPosition; } } @@ -3788,8 +3786,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } } - private Vector createHTMLVector() { - Vector htmlViews = new Vector(); + private Vector createHTMLVector() { + Vector htmlViews = new Vector(); int count = tabPane.getTabCount(); if (count>0) { for (int i=0 ; i storedForwardTraversalKeys = editor. getFocusTraversalKeys(KeyboardFocusManager. FORWARD_TRAVERSAL_KEYS); - Set storedBackwardTraversalKeys = editor. + Set storedBackwardTraversalKeys = editor. getFocusTraversalKeys(KeyboardFocusManager. BACKWARD_TRAVERSAL_KEYS); - Set forwardTraversalKeys = - new HashSet(storedForwardTraversalKeys); - Set backwardTraversalKeys = - new HashSet(storedBackwardTraversalKeys); + Set forwardTraversalKeys = + new HashSet(storedForwardTraversalKeys); + Set backwardTraversalKeys = + new HashSet(storedBackwardTraversalKeys); if (editor.isEditable()) { forwardTraversalKeys. remove(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0)); @@ -1888,7 +1888,7 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory { * * @param e The change notification from the currently associated * document. - * @see DocumentListener#changeUpdate + * @see DocumentListener#changedUpdate(DocumentEvent) */ public final void changedUpdate(DocumentEvent e) { Rectangle alloc = (painted) ? getVisibleEditorRect() : null; @@ -1964,9 +1964,9 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory { } try { rootView.setSize(alloc.width, alloc.height); - Enumeration components = constraints.keys(); + Enumeration components = constraints.keys(); while (components.hasMoreElements()) { - Component comp = (Component) components.nextElement(); + Component comp = components.nextElement(); View v = (View) constraints.get(comp); Shape ca = calculateViewPosition(alloc, v); if (ca != null) { @@ -2009,7 +2009,7 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory { public void addLayoutComponent(Component comp, Object constraint) { if (constraint instanceof View) { if (constraints == null) { - constraints = new Hashtable(7); + constraints = new Hashtable(7); } constraints.put(comp, constraint); } @@ -2060,7 +2060,7 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory { * These are View objects for those components that are represented * by a View in the View tree. */ - private Hashtable constraints; + private Hashtable constraints; private boolean i18nView = false; } @@ -2457,8 +2457,7 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory { JTextComponent c = (JTextComponent)comp; int pos = modeBetween - ? ((JTextComponent.DropLocation)c.getDropLocation()).getIndex() - : c.getCaretPosition(); + ? c.getDropLocation().getIndex() : c.getCaretPosition(); // if we are importing to the same component that we exported from // then don't actually do anything if the drop location is inside diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicToggleButtonUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicToggleButtonUI.java index 60802d6cc70..18daffa5999 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicToggleButtonUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicToggleButtonUI.java @@ -125,31 +125,31 @@ public class BasicToggleButtonUI extends BasicButtonUI { if(!model.isEnabled()) { if(model.isSelected()) { - icon = (Icon) b.getDisabledSelectedIcon(); + icon = b.getDisabledSelectedIcon(); } else { - icon = (Icon) b.getDisabledIcon(); + icon = b.getDisabledIcon(); } } else if(model.isPressed() && model.isArmed()) { - icon = (Icon) b.getPressedIcon(); + icon = b.getPressedIcon(); if(icon == null) { // Use selected icon - icon = (Icon) b.getSelectedIcon(); + icon = b.getSelectedIcon(); } } else if(model.isSelected()) { if(b.isRolloverEnabled() && model.isRollover()) { - icon = (Icon) b.getRolloverSelectedIcon(); + icon = b.getRolloverSelectedIcon(); if (icon == null) { - icon = (Icon) b.getSelectedIcon(); + icon = b.getSelectedIcon(); } } else { - icon = (Icon) b.getSelectedIcon(); + icon = b.getSelectedIcon(); } } else if(b.isRolloverEnabled() && model.isRollover()) { - icon = (Icon) b.getRolloverIcon(); + icon = b.getRolloverIcon(); } if(icon == null) { - icon = (Icon) b.getIcon(); + icon = b.getIcon(); } icon.paintIcon(b, g, iconRect.x, iconRect.y); diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicToolBarUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicToolBarUI.java index 061dd31b4ed..0eafa7e3b6b 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicToolBarUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicToolBarUI.java @@ -83,8 +83,8 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants private static Border nonRolloverToggleBorder; private boolean rolloverBorders = false; - private HashMap borderTable = new HashMap(); - private Hashtable rolloverTable = new Hashtable(); + private HashMap borderTable = new HashMap(); + private Hashtable rolloverTable = new Hashtable(); /** @@ -171,7 +171,7 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants uninstallKeyboardActions(); // Clear instance vars - if (isFloating() == true) + if (isFloating()) setFloating(false, null); floatingToolBar = null; @@ -273,9 +273,8 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants // Put focus listener on all components in toolbar Component[] components = toolBar.getComponents(); - for ( int i = 0; i < components.length; ++i ) - { - components[ i ].addFocusListener( toolBarFocusListener ); + for (Component component : components) { + component.addFocusListener(toolBarFocusListener); } } } @@ -307,9 +306,8 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants // Remove focus listener from all components in toolbar Component[] components = toolBar.getComponents(); - for ( int i = 0; i < components.length; ++i ) - { - components[ i ].removeFocusListener( toolBarFocusListener ); + for (Component component : components) { + component.removeFocusListener(toolBarFocusListener); } toolBarFocusListener = null; @@ -616,10 +614,10 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants // Put rollover borders on buttons Component[] components = c.getComponents(); - for ( int i = 0; i < components.length; ++i ) { - if ( components[ i ] instanceof JComponent ) { - ( (JComponent)components[ i ] ).updateUI(); - setBorderToRollover( components[ i ] ); + for (Component component : components) { + if (component instanceof JComponent) { + ((JComponent) component).updateUI(); + setBorderToRollover(component); } } } @@ -640,10 +638,10 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants // Put non-rollover borders on buttons. These borders reduce the margin. Component[] components = c.getComponents(); - for ( int i = 0; i < components.length; ++i ) { - if ( components[ i ] instanceof JComponent ) { - ( (JComponent)components[ i ] ).updateUI(); - setBorderToNonRollover( components[ i ] ); + for (Component component : components) { + if (component instanceof JComponent) { + ((JComponent) component).updateUI(); + setBorderToNonRollover(component); } } } @@ -664,8 +662,8 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants // Put back the normal borders on buttons Component[] components = c.getComponents(); - for ( int i = 0; i < components.length; ++i ) { - setBorderToNormal( components[ i ] ); + for (Component component : components) { + setBorderToNormal(component); } } @@ -681,7 +679,7 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants if (c instanceof AbstractButton) { AbstractButton b = (AbstractButton)c; - Border border = (Border)borderTable.get(b); + Border border = borderTable.get(b); if (border == null || border instanceof UIResource) { borderTable.put(b, b.getBorder()); } @@ -721,7 +719,7 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants if (c instanceof AbstractButton) { AbstractButton b = (AbstractButton)c; - Border border = (Border)borderTable.get(b); + Border border = borderTable.get(b); if (border == null || border instanceof UIResource) { borderTable.put(b, b.getBorder()); } @@ -765,10 +763,10 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants if (c instanceof AbstractButton) { AbstractButton b = (AbstractButton)c; - Border border = (Border)borderTable.remove(b); + Border border = borderTable.remove(b); b.setBorder(border); - Boolean value = (Boolean)rolloverTable.remove(b); + Boolean value = rolloverTable.remove(b); if (value != null) { b.setRolloverEnabled(value.booleanValue()); } @@ -785,7 +783,7 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants } public void setFloating(boolean b, Point p) { - if (toolBar.isFloatable() == true) { + if (toolBar.isFloatable()) { boolean visible = false; Window ancestor = SwingUtilities.getWindowAncestor(toolBar); if (ancestor != null) { @@ -953,7 +951,7 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants protected void dragTo(Point position, Point origin) { - if (toolBar.isFloatable() == true) + if (toolBar.isFloatable()) { try { @@ -1003,7 +1001,7 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants protected void floatAt(Point position, Point origin) { - if(toolBar.isFloatable() == true) + if(toolBar.isFloatable()) { try { @@ -1174,7 +1172,7 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants if (!tb.isEnabled()) { return; } - if (isDragging == true) { + if (isDragging) { Point position = evt.getPoint(); if (origin == null) origin = evt.getComponent().getLocationOnScreen(); @@ -1242,7 +1240,7 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants protected class FrameListener extends WindowAdapter { public void windowClosing(WindowEvent w) { - if (toolBar.isFloatable() == true) { + if (toolBar.isFloatable()) { if (dragWindow != null) dragWindow.setVisible(false); floating = false; diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java index 56b16ba7cce..eee08821e05 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java @@ -1263,7 +1263,7 @@ public class BasicTreeUI extends TreeUI } private Rectangle getDropLineRect(JTree.DropLocation loc) { - Rectangle rect = null; + Rectangle rect; TreePath path = loc.getPath(); int index = loc.getChildIndex(); boolean ltr = leftToRight; @@ -2138,7 +2138,7 @@ public class BasicTreeUI extends TreeUI compositeRequestFocus(editingComponent); boolean selectAll = true; - if(event != null && event instanceof MouseEvent) { + if(event != null) { /* Find the component that will get forwarded all the mouse events until mouseReleased. */ Point componentPoint = SwingUtilities.convertPoint @@ -3125,7 +3125,7 @@ public class BasicTreeUI extends TreeUI private static final TransferHandler defaultTransferHandler = new TreeTransferHandler(); - static class TreeTransferHandler extends TransferHandler implements UIResource, Comparator { + static class TreeTransferHandler extends TransferHandler implements UIResource, Comparator { private JTree tree; @@ -3156,9 +3156,7 @@ public class BasicTreeUI extends TreeUI TreePath lastPath = null; TreePath[] displayPaths = getDisplayOrderPaths(paths); - for (int i = 0; i < displayPaths.length; i++) { - TreePath path = displayPaths[i]; - + for (TreePath path : displayPaths) { Object node = path.getLastPathComponent(); boolean leaf = model.isLeaf(node); String label = getDisplayString(path, true, leaf); @@ -3179,9 +3177,9 @@ public class BasicTreeUI extends TreeUI return null; } - public int compare(Object o1, Object o2) { - int row1 = tree.getRowForPath((TreePath)o1); - int row2 = tree.getRowForPath((TreePath)o2); + public int compare(TreePath o1, TreePath o2) { + int row1 = tree.getRowForPath(o1); + int row2 = tree.getRowForPath(o2); return row1 - row2; } @@ -3200,15 +3198,15 @@ public class BasicTreeUI extends TreeUI */ TreePath[] getDisplayOrderPaths(TreePath[] paths) { // sort the paths to display order rather than selection order - ArrayList selOrder = new ArrayList(); - for (int i = 0; i < paths.length; i++) { - selOrder.add(paths[i]); + ArrayList selOrder = new ArrayList(); + for (TreePath path : paths) { + selOrder.add(path); } Collections.sort(selOrder, this); int n = selOrder.size(); TreePath[] displayPaths = new TreePath[n]; for (int i = 0; i < n; i++) { - displayPaths[i] = (TreePath) selOrder.get(i); + displayPaths[i] = selOrder.get(i); } return displayPaths; } @@ -3321,10 +3319,7 @@ public class BasicTreeUI extends TreeUI InputMap inputMap = tree.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); KeyStroke key = KeyStroke.getKeyStrokeForEvent(event); - if (inputMap != null && inputMap.get(key) != null) { - return true; - } - return false; + return inputMap != null && inputMap.get(key) != null; } diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/DefaultMenuLayout.java b/jdk/src/share/classes/javax/swing/plaf/basic/DefaultMenuLayout.java index b29cfaf7aa6..5acae97eded 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/DefaultMenuLayout.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/DefaultMenuLayout.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,6 @@ import javax.swing.plaf.UIResource; import java.awt.Container; import java.awt.Dimension; -import static sun.swing.SwingUtilities2.BASICMENUITEMUI_MAX_TEXT_OFFSET; /** * The default layout manager for Popup menus and menubars. This @@ -49,18 +48,7 @@ public class DefaultMenuLayout extends BoxLayout implements UIResource { public Dimension preferredLayoutSize(Container target) { if (target instanceof JPopupMenu) { JPopupMenu popupMenu = (JPopupMenu) target; - - // Before the calculation of menu preferred size - // clear the previously calculated maximal widths and offsets - // in menu's Client Properties - popupMenu.putClientProperty(BasicMenuItemUI.MAX_ACC_WIDTH, null); - popupMenu.putClientProperty(BasicMenuItemUI.MAX_ARROW_WIDTH, null); - popupMenu.putClientProperty(BasicMenuItemUI.MAX_CHECK_WIDTH, null); - popupMenu.putClientProperty(BasicMenuItemUI.MAX_ICON_WIDTH, null); - popupMenu.putClientProperty(BasicMenuItemUI.MAX_LABEL_WIDTH, null); - popupMenu.putClientProperty(BasicMenuItemUI.MAX_TEXT_WIDTH, null); - popupMenu.putClientProperty(BASICMENUITEMUI_MAX_TEXT_OFFSET, null); - + sun.swing.MenuItemLayoutHelper.clearUsedClientProperties(popupMenu); if (popupMenu.getComponentCount() == 0) { return new Dimension(0, 0); } diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/DesktopIconMover.java b/jdk/src/share/classes/javax/swing/plaf/basic/DesktopIconMover.java new file mode 100644 index 00000000000..deff4f27a5f --- /dev/null +++ b/jdk/src/share/classes/javax/swing/plaf/basic/DesktopIconMover.java @@ -0,0 +1,168 @@ +/* + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.swing.plaf.basic; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.beans.*; + +/** + * DesktopIconMover is intended to move desktop icon + * when parent window is resized. + */ +class DesktopIconMover implements ComponentListener, PropertyChangeListener { + private Component parent; + private JInternalFrame frame; // if not null, DesktopIconMover(frame) + // constructor was used + private JInternalFrame.JDesktopIcon icon; + private Rectangle parentBounds; + private boolean componentListenerAdded = false; + + public DesktopIconMover(JInternalFrame frame) { + if (frame == null) { + throw new NullPointerException("Frame cannot be null"); + } + this.frame = frame; + this.icon = frame.getDesktopIcon(); + if (icon == null) { + throw new NullPointerException( + "frame.getDesktopIcon() cannot be null"); + } + this.parent = frame.getParent(); + if (this.parent != null) { + parentBounds = this.parent.getBounds(); + } + } + + public DesktopIconMover(JInternalFrame.JDesktopIcon icon) { + if (icon == null) { + throw new NullPointerException("Icon cannot be null"); + } + this.icon = icon; + this.parent = icon.getParent(); + if (this.parent != null) { + parentBounds = this.parent.getBounds(); + } + } + + public void installListeners() { + if (frame != null) { + frame.addPropertyChangeListener(this); + } else { + icon.addPropertyChangeListener(this); + } + addComponentListener(); + } + + public void uninstallListeners() { + if (frame != null) { + frame.removePropertyChangeListener(this); + } else { + icon.removePropertyChangeListener(this); + } + removeComponentListener(); + } + + public void propertyChange(PropertyChangeEvent evt) { + String propName = evt.getPropertyName(); + if ("ancestor".equals(propName)) { + Component newAncestor = (Component) evt.getNewValue(); + + // Remove component listener if parent is changing + Component probablyNewParent = getCurrentParent(); + if ((probablyNewParent != null) && + (!probablyNewParent.equals(parent))) { + removeComponentListener(); + parent = probablyNewParent; + } + + if (newAncestor == null) { + removeComponentListener(); + } else { + addComponentListener(); + } + + // Update parentBounds + if (parent != null) { + parentBounds = parent.getBounds(); + } else { + parentBounds = null; + } + } else if (JInternalFrame.IS_CLOSED_PROPERTY.equals(propName)) { + removeComponentListener(); + } + } + + private void addComponentListener() { + if (!componentListenerAdded && (parent != null)) { + parent.addComponentListener(this); + componentListenerAdded = true; + } + } + + private void removeComponentListener() { + if ((parent != null) && componentListenerAdded) { + parent.removeComponentListener(this); + componentListenerAdded = false; + } + } + + private Component getCurrentParent() { + if (frame != null) { + return frame.getParent(); + } else { + return icon.getParent(); + } + } + + public void componentResized(ComponentEvent e) { + if ((parent == null) || (parentBounds == null)) { + return; + } + + Rectangle parentNewBounds = parent.getBounds(); + if ((parentNewBounds == null) || parentNewBounds.equals(parentBounds)) { + return; + } + + // Move desktop icon only in up-down direction + int newIconY = icon.getLocation().y + + (parentNewBounds.height - parentBounds.height); + icon.setLocation(icon.getLocation().x, newIconY); + + parentBounds = parentNewBounds; + } + + public void componentMoved(ComponentEvent e) { + } + + public void componentShown(ComponentEvent e) { + } + + public void componentHidden(ComponentEvent e) { + } +} diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/DragRecognitionSupport.java b/jdk/src/share/classes/javax/swing/plaf/basic/DragRecognitionSupport.java index 060019810e4..be457ccb258 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/DragRecognitionSupport.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/DragRecognitionSupport.java @@ -73,8 +73,7 @@ class DragRecognitionSupport { * Returns whether or not the event is potentially part of a drag sequence. */ public static boolean mousePressed(MouseEvent me) { - return ((DragRecognitionSupport)getDragRecognitionSupport()). - mousePressedImpl(me); + return getDragRecognitionSupport().mousePressedImpl(me); } /** @@ -82,16 +81,14 @@ class DragRecognitionSupport { * that started the recognition. Otherwise, return null. */ public static MouseEvent mouseReleased(MouseEvent me) { - return ((DragRecognitionSupport)getDragRecognitionSupport()). - mouseReleasedImpl(me); + return getDragRecognitionSupport().mouseReleasedImpl(me); } /** * Returns whether or not a drag gesture recognition is ongoing. */ public static boolean mouseDragged(MouseEvent me, BeforeDrag bd) { - return ((DragRecognitionSupport)getDragRecognitionSupport()). - mouseDraggedImpl(me, bd); + return getDragRecognitionSupport().mouseDraggedImpl(me, bd); } private void clearState() { diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/LazyActionMap.java b/jdk/src/share/classes/javax/swing/plaf/basic/LazyActionMap.java index f148707a769..e57ff78d23d 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/LazyActionMap.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/LazyActionMap.java @@ -142,7 +142,7 @@ class LazyActionMap extends ActionMapUIResource { Object loader = _loader; _loader = null; - Class klass = (Class)loader; + Class klass = (Class)loader; try { Method method = klass.getDeclaredMethod("loadActionMap", new Class[] { LazyActionMap.class }); diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/DefaultMetalTheme.java b/jdk/src/share/classes/javax/swing/plaf/metal/DefaultMetalTheme.java index dbb9b346a4d..96b944d0db2 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/DefaultMetalTheme.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/DefaultMetalTheme.java @@ -387,9 +387,9 @@ public class DefaultMetalTheme extends MetalTheme { * that it is wrapped inside a doPrivileged call. */ protected Font getPrivilegedFont(final int key) { - return (Font)java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + return java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Font run() { return Font.getFont(getDefaultPropertyName(key)); } } diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalBumps.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalBumps.java index ec6f0300c8a..47e379a48ff 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalBumps.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalBumps.java @@ -49,7 +49,7 @@ class MetalBumps implements Icon { protected Color shadowColor; protected Color backColor; - protected static Vector buffers = new Vector(); + protected static Vector buffers = new Vector(); protected BumpBuffer buffer; public MetalBumps( Dimension bumpArea ) { @@ -81,10 +81,7 @@ class MetalBumps implements Icon { } BumpBuffer result = null; - Enumeration elements = buffers.elements(); - - while ( elements.hasMoreElements() ) { - BumpBuffer aBuffer = (BumpBuffer)elements.nextElement(); + for (BumpBuffer aBuffer : buffers) { if ( aBuffer.hasSameConfiguration(gc, aTopColor, aShadowColor, aBackColor)) { result = aBuffer; @@ -120,8 +117,7 @@ class MetalBumps implements Icon { public void paintIcon( Component c, Graphics g, int x, int y ) { GraphicsConfiguration gc = (g instanceof Graphics2D) ? - (GraphicsConfiguration)((Graphics2D)g). - getDeviceConfiguration() : null; + ((Graphics2D) g).getDeviceConfiguration() : null; buffer = getBuffer(gc, topColor, shadowColor, backColor); diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java index 3489cd3e4ea..fd837b9abf2 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java @@ -782,7 +782,7 @@ public class MetalFileChooserUI extends BasicFileChooserUI { } else if (s.equals("componentOrientation")) { ComponentOrientation o = (ComponentOrientation)e.getNewValue(); JFileChooser cc = (JFileChooser)e.getSource(); - if (o != (ComponentOrientation)e.getOldValue()) { + if (o != e.getOldValue()) { cc.applyComponentOrientation(o); } } else if (s == "FileChooser.useShellFolder") { @@ -927,7 +927,7 @@ public class MetalFileChooserUI extends BasicFileChooserUI { * Data model for a type-face selection combo-box. */ protected class DirectoryComboBoxModel extends AbstractListModel implements ComboBoxModel { - Vector directories = new Vector(); + Vector directories = new Vector(); int[] depths = null; File selectedDirectory = null; JFileChooser chooser = getFileChooser(); @@ -966,7 +966,7 @@ public class MetalFileChooserUI extends BasicFileChooserUI { // Get the canonical (full) path. This has the side // benefit of removing extraneous chars from the path, // for example /foo/bar/ becomes /foo/bar - File canonical = null; + File canonical; try { canonical = ShellFolder.getNormalizedFile(directory); } catch (IOException e) { @@ -979,7 +979,7 @@ public class MetalFileChooserUI extends BasicFileChooserUI { File sf = useShellFolder ? ShellFolder.getShellFolder(canonical) : canonical; File f = sf; - Vector path = new Vector(10); + Vector path = new Vector(10); do { path.addElement(f); } while ((f = f.getParentFile()) != null); @@ -987,7 +987,7 @@ public class MetalFileChooserUI extends BasicFileChooserUI { int pathCount = path.size(); // Insert chain at appropriate place in vector for (int i = 0; i < pathCount; i++) { - f = (File)path.get(i); + f = path.get(i); if (directories.contains(f)) { int topIndex = directories.indexOf(f); for (int j = i-1; j >= 0; j--) { @@ -1006,12 +1006,12 @@ public class MetalFileChooserUI extends BasicFileChooserUI { private void calculateDepths() { depths = new int[directories.size()]; for (int i = 0; i < depths.length; i++) { - File dir = (File)directories.get(i); + File dir = directories.get(i); File parent = dir.getParentFile(); depths[i] = 0; if (parent != null) { for (int j = i-1; j >= 0; j--) { - if (parent.equals((File)directories.get(j))) { + if (parent.equals(directories.get(j))) { depths[i] = depths[j] + 1; break; } @@ -1110,8 +1110,8 @@ public class MetalFileChooserUI extends BasicFileChooserUI { FileFilter currentFilter = getFileChooser().getFileFilter(); boolean found = false; if(currentFilter != null) { - for(int i=0; i < filters.length; i++) { - if(filters[i] == currentFilter) { + for (FileFilter filter : filters) { + if (filter == currentFilter) { found = true; } } diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalIconFactory.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalIconFactory.java index c7da086d466..212961e5174 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalIconFactory.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalIconFactory.java @@ -598,7 +598,7 @@ public class MetalIconFactory implements Serializable { } // Some calculations that are needed more than once later on. - int oneHalf = (int)(iconSize / 2); // 16 -> 8 + int oneHalf = iconSize / 2; // 16 -> 8 g.translate(x, y); @@ -1502,7 +1502,7 @@ public class MetalIconFactory implements Serializable { // PENDING: Replace this class with CachedPainter. - Vector images = new Vector(1, 1); + Vector images = new Vector(1, 1); ImageGcPair currentImageGcPair; class ImageGcPair { @@ -1514,12 +1514,8 @@ public class MetalIconFactory implements Serializable { } boolean hasSameConfiguration(GraphicsConfiguration newGC) { - if (((newGC != null) && (newGC.equals(gc))) || - ((newGC == null) && (gc == null))) - { - return true; - } - return false; + return ((newGC != null) && (newGC.equals(gc))) || + ((newGC == null) && (gc == null)); } } @@ -1528,9 +1524,7 @@ public class MetalIconFactory implements Serializable { if ((currentImageGcPair == null) || !(currentImageGcPair.hasSameConfiguration(newGC))) { - Enumeration elements = images.elements(); - while (elements.hasMoreElements()) { - ImageGcPair imgGcPair = (ImageGcPair)elements.nextElement(); + for (ImageGcPair imgGcPair : images) { if (imgGcPair.hasSameConfiguration(newGC)) { currentImageGcPair = imgGcPair; return imgGcPair.image; diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalInternalFrameTitlePane.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalInternalFrameTitlePane.java index a0b8ada118f..6de655d586e 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalInternalFrameTitlePane.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalInternalFrameTitlePane.java @@ -191,7 +191,7 @@ public class MetalInternalFrameTitlePane extends BasicInternalFrameTitlePane { extends BasicInternalFrameTitlePane.PropertyChangeHandler { public void propertyChange(PropertyChangeEvent evt) { - String prop = (String)evt.getPropertyName(); + String prop = evt.getPropertyName(); if( prop.equals(JInternalFrame.IS_SELECTED_PROPERTY) ) { Boolean b = (Boolean)evt.getNewValue(); iconButton.putClientProperty("paintActive", b); @@ -242,7 +242,7 @@ public class MetalInternalFrameTitlePane extends BasicInternalFrameTitlePane { } // Compute height. - int height = 0; + int height; if (isPalette) { height = paletteTitleHeight; } else { @@ -410,7 +410,7 @@ public class MetalInternalFrameTitlePane extends BasicInternalFrameTitlePane { g.drawLine ( width - 1, 0 , width -1, 0); - int titleLength = 0; + int titleLength; int xOffset = leftToRight ? 5 : width - 5; String frameTitle = frame.getTitle(); diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java index f0084d9f162..07432841961 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java @@ -2208,9 +2208,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel if (methodName == null) { return c.newInstance(); } - Method method = (Method)AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + Method method = AccessController.doPrivileged( + new PrivilegedAction() { + public Method run() { Method[] methods = c.getDeclaredMethods(); for (int counter = methods.length - 1; counter >= 0; counter--) { @@ -2273,7 +2273,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel } } - static ReferenceQueue queue = new ReferenceQueue(); + static ReferenceQueue queue = new ReferenceQueue(); static void flushUnreferenced() { AATextListener aatl; @@ -2283,7 +2283,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel } static class AATextListener - extends WeakReference implements PropertyChangeListener { + extends WeakReference implements PropertyChangeListener { private String key = SunToolkit.DESKTOPFONTHINTS; @@ -2294,7 +2294,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel } public void propertyChange(PropertyChangeEvent pce) { - LookAndFeel laf = (LookAndFeel)get(); + LookAndFeel laf = get(); if (laf == null || laf != UIManager.getLookAndFeel()) { dispose(); return; @@ -2318,8 +2318,8 @@ public class MetalLookAndFeel extends BasicLookAndFeel private static void updateWindowUI(Window window) { SwingUtilities.updateComponentTreeUI(window); Window ownedWins[] = window.getOwnedWindows(); - for (int i=0; i < ownedWins.length; i++) { - updateWindowUI(ownedWins[i]); + for (Window w : ownedWins) { + updateWindowUI(w); } } @@ -2328,8 +2328,8 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ private static void updateAllUIs() { Frame appFrames[] = Frame.getFrames(); - for (int j=0; j < appFrames.length; j++) { - updateWindowUI(appFrames[j]); + for (Frame frame : appFrames) { + updateWindowUI(frame); } } diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalRadioButtonUI.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalRadioButtonUI.java index 1d6882455c1..ba96b21e6ee 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalRadioButtonUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalRadioButtonUI.java @@ -164,15 +164,15 @@ public class MetalRadioButtonUI extends BasicRadioButtonUI { } } else if(model.isSelected()) { if(b.isRolloverEnabled() && model.isRollover()) { - altIcon = (Icon) b.getRolloverSelectedIcon(); + altIcon = b.getRolloverSelectedIcon(); if (altIcon == null) { - altIcon = (Icon) b.getSelectedIcon(); + altIcon = b.getSelectedIcon(); } } else { - altIcon = (Icon) b.getSelectedIcon(); + altIcon = b.getSelectedIcon(); } } else if(b.isRolloverEnabled() && model.isRollover()) { - altIcon = (Icon) b.getRolloverIcon(); + altIcon = b.getRolloverIcon(); } if(altIcon == null) { diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalSliderUI.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalSliderUI.java index 13563b80ecc..7a26c46b225 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalSliderUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalSliderUI.java @@ -27,23 +27,13 @@ package javax.swing.plaf.metal; import javax.swing.plaf.basic.BasicSliderUI; -import java.awt.Component; -import java.awt.Container; import java.awt.Graphics; import java.awt.Dimension; import java.awt.Rectangle; -import java.awt.Point; -import java.awt.Insets; import java.awt.Color; -import java.io.Serializable; -import java.awt.IllegalComponentStateException; -import java.awt.Polygon; import java.beans.*; -import javax.swing.border.AbstractBorder; - import javax.swing.*; -import javax.swing.event.*; import javax.swing.plaf.*; /** @@ -131,10 +121,7 @@ public class MetalSliderUI extends BasicSliderUI { scrollListener.setScrollByBlock( false ); - Object sliderFillProp = c.getClientProperty( SLIDER_FILL ); - if ( sliderFillProp != null ) { - filledSlider = ((Boolean)sliderFillProp).booleanValue(); - } + prepareFilledSliderField(); } protected PropertyChangeListener createPropertyChangeListener( JSlider slider ) { @@ -145,18 +132,23 @@ public class MetalSliderUI extends BasicSliderUI { public void propertyChange( PropertyChangeEvent e ) { // listen for slider fill super.propertyChange( e ); - String name = e.getPropertyName(); - if ( name.equals( SLIDER_FILL ) ) { - if ( e.getNewValue() != null ) { - filledSlider = ((Boolean)e.getNewValue()).booleanValue(); - } - else { - filledSlider = false; - } + if (e.getPropertyName().equals(SLIDER_FILL)) { + prepareFilledSliderField(); } } } + private void prepareFilledSliderField() { + // Use true for Ocean theme + filledSlider = MetalLookAndFeel.usingOcean(); + + Object sliderFillProp = slider.getClientProperty(SLIDER_FILL); + + if (sliderFillProp != null) { + filledSlider = ((Boolean) sliderFillProp).booleanValue(); + } + } + public void paintThumb(Graphics g) { Rectangle knobBounds = thumbRect; @@ -172,22 +164,11 @@ public class MetalSliderUI extends BasicSliderUI { g.translate( -knobBounds.x, -knobBounds.y ); } - /** - * If chooseFirstis true, c1 is returned, - * otherwise c2. - */ - private Color chooseColor(boolean chooseFirst, Color c1, Color c2) { - if (chooseFirst) { - return c2; - } - return c1; - } - /** * Returns a rectangle enclosing the track that will be painted. */ private Rectangle getPaintTrackRect() { - int trackLeft = 0, trackRight = 0, trackTop = 0, trackBottom = 0; + int trackLeft = 0, trackRight, trackTop = 0, trackBottom; if (slider.getOrientation() == JSlider.HORIZONTAL) { trackBottom = (trackRect.height - 1) - getThumbOverhang(); trackTop = trackBottom - (getTrackWidth() - 1); @@ -223,8 +204,8 @@ public class MetalSliderUI extends BasicSliderUI { int trackLeft = 0; int trackTop = 0; - int trackRight = 0; - int trackBottom = 0; + int trackRight; + int trackBottom; // Draw the track if ( slider.getOrientation() == JSlider.HORIZONTAL ) { @@ -266,11 +247,11 @@ public class MetalSliderUI extends BasicSliderUI { // Draw the fill if ( filledSlider ) { - int middleOfThumb = 0; - int fillTop = 0; - int fillLeft = 0; - int fillBottom = 0; - int fillRight = 0; + int middleOfThumb; + int fillTop; + int fillLeft; + int fillBottom; + int fillRight; if ( slider.getOrientation() == JSlider.HORIZONTAL ) { middleOfThumb = thumbRect.x + (thumbRect.width / 2); @@ -314,8 +295,7 @@ public class MetalSliderUI extends BasicSliderUI { } else { g.setColor( MetalLookAndFeel.getControlShadow() ); - g.fillRect( fillLeft, fillTop, - fillRight - fillLeft, trackBottom - trackTop ); + g.fillRect(fillLeft, fillTop, fillRight - fillLeft, fillBottom - fillTop); } } @@ -336,105 +316,137 @@ public class MetalSliderUI extends BasicSliderUI { int w = paintRect.width; int h = paintRect.height; - if (!slider.isEnabled()) { - g.setColor(MetalLookAndFeel.getControlShadow()); - g.drawRect(0, 0, w - 1, h - 1); - } - else if (slider.getOrientation() == JSlider.HORIZONTAL) { - int middleOfThumb = thumbRect.x + (thumbRect.width / 2) - - paintRect.x; - int fillMinX; - int fillMaxX; + if (slider.getOrientation() == JSlider.HORIZONTAL) { + int middleOfThumb = thumbRect.x + thumbRect.width / 2 - paintRect.x; - if (middleOfThumb > 0) { - g.setColor(chooseColor(drawInverted, - MetalLookAndFeel.getPrimaryControlDarkShadow(), - MetalLookAndFeel.getControlDarkShadow())); - g.drawRect(0, 0, middleOfThumb - 1, h - 1); - } - if (middleOfThumb < w) { - g.setColor(chooseColor(drawInverted, - MetalLookAndFeel.getControlDarkShadow(), - MetalLookAndFeel.getPrimaryControlDarkShadow())); - g.drawRect(middleOfThumb, 0, w - middleOfThumb - 1, h - 1); - } - g.setColor(MetalLookAndFeel.getPrimaryControlShadow()); - if (drawInverted) { - fillMinX = middleOfThumb; - fillMaxX = w - 2; - g.drawLine(1, 1, middleOfThumb, 1); - } - else { - fillMinX = 1; - fillMaxX = middleOfThumb; - g.drawLine(middleOfThumb, 1, w - 1, 1); - } - if (h == 6) { - g.setColor(MetalLookAndFeel.getWhite()); - g.drawLine(fillMinX, 1, fillMaxX, 1); - g.setColor(sliderAltTrackColor); - g.drawLine(fillMinX, 2, fillMaxX, 2); + if (slider.isEnabled()) { + int fillMinX; + int fillMaxX; + + if (middleOfThumb > 0) { + g.setColor(drawInverted ? MetalLookAndFeel.getControlDarkShadow() : + MetalLookAndFeel.getPrimaryControlDarkShadow()); + + g.drawRect(0, 0, middleOfThumb - 1, h - 1); + } + + if (middleOfThumb < w) { + g.setColor(drawInverted ? MetalLookAndFeel.getPrimaryControlDarkShadow() : + MetalLookAndFeel.getControlDarkShadow()); + + g.drawRect(middleOfThumb, 0, w - middleOfThumb - 1, h - 1); + } + + if (filledSlider) { + g.setColor(MetalLookAndFeel.getPrimaryControlShadow()); + if (drawInverted) { + fillMinX = middleOfThumb; + fillMaxX = w - 2; + g.drawLine(1, 1, middleOfThumb, 1); + } else { + fillMinX = 1; + fillMaxX = middleOfThumb; + g.drawLine(middleOfThumb, 1, w - 1, 1); + } + if (h == 6) { + g.setColor(MetalLookAndFeel.getWhite()); + g.drawLine(fillMinX, 1, fillMaxX, 1); + g.setColor(sliderAltTrackColor); + g.drawLine(fillMinX, 2, fillMaxX, 2); + g.setColor(MetalLookAndFeel.getControlShadow()); + g.drawLine(fillMinX, 3, fillMaxX, 3); + g.setColor(MetalLookAndFeel.getPrimaryControlShadow()); + g.drawLine(fillMinX, 4, fillMaxX, 4); + } + } + } else { g.setColor(MetalLookAndFeel.getControlShadow()); - g.drawLine(fillMinX, 3, fillMaxX, 3); - g.setColor(MetalLookAndFeel.getPrimaryControlShadow()); - g.drawLine(fillMinX, 4, fillMaxX, 4); - } - } - else { - int middleOfThumb = thumbRect.y + (thumbRect.height / 2) - - paintRect.y; - int fillMinY; - int fillMaxY; - if (middleOfThumb > 0) { - g.setColor(chooseColor(drawInverted, - MetalLookAndFeel.getControlDarkShadow(), - MetalLookAndFeel.getPrimaryControlDarkShadow())); - g.drawRect(0, 0, w - 1, middleOfThumb - 1); - } - if (middleOfThumb < h) { - g.setColor(chooseColor(drawInverted, - MetalLookAndFeel.getPrimaryControlDarkShadow(), - MetalLookAndFeel.getControlDarkShadow())); - g.drawRect(0, middleOfThumb, w - 1, h - middleOfThumb - 1); - } - g.setColor(MetalLookAndFeel.getPrimaryControlShadow()); - if (drawInverted()) { - fillMinY = 1; - fillMaxY = middleOfThumb; - if (leftToRight) { - g.drawLine(1, middleOfThumb, 1, h - 1); + if (middleOfThumb > 0) { + if (!drawInverted && filledSlider) { + g.fillRect(0, 0, middleOfThumb - 1, h - 1); + } else { + g.drawRect(0, 0, middleOfThumb - 1, h - 1); + } } - else { - g.drawLine(w - 2, middleOfThumb, w - 2, h - 1); + + if (middleOfThumb < w) { + if (drawInverted && filledSlider) { + g.fillRect(middleOfThumb, 0, w - middleOfThumb - 1, h - 1); + } else { + g.drawRect(middleOfThumb, 0, w - middleOfThumb - 1, h - 1); + } } } - else { - fillMinY = middleOfThumb; - fillMaxY = h - 2; - if (leftToRight) { - g.drawLine(1, 1, 1, middleOfThumb); + } else { + int middleOfThumb = thumbRect.y + (thumbRect.height / 2) - paintRect.y; + + if (slider.isEnabled()) { + int fillMinY; + int fillMaxY; + + if (middleOfThumb > 0) { + g.setColor(drawInverted ? MetalLookAndFeel.getPrimaryControlDarkShadow() : + MetalLookAndFeel.getControlDarkShadow()); + + g.drawRect(0, 0, w - 1, middleOfThumb - 1); } - else { - g.drawLine(w - 2, 1, w - 2, middleOfThumb); + + if (middleOfThumb < h) { + g.setColor(drawInverted ? MetalLookAndFeel.getControlDarkShadow() : + MetalLookAndFeel.getPrimaryControlDarkShadow()); + + g.drawRect(0, middleOfThumb, w - 1, h - middleOfThumb - 1); + } + + if (filledSlider) { + g.setColor(MetalLookAndFeel.getPrimaryControlShadow()); + if (drawInverted()) { + fillMinY = 1; + fillMaxY = middleOfThumb; + if (leftToRight) { + g.drawLine(1, middleOfThumb, 1, h - 1); + } else { + g.drawLine(w - 2, middleOfThumb, w - 2, h - 1); + } + } else { + fillMinY = middleOfThumb; + fillMaxY = h - 2; + if (leftToRight) { + g.drawLine(1, 1, 1, middleOfThumb); + } else { + g.drawLine(w - 2, 1, w - 2, middleOfThumb); + } + } + if (w == 6) { + g.setColor(leftToRight ? MetalLookAndFeel.getWhite() : MetalLookAndFeel.getPrimaryControlShadow()); + g.drawLine(1, fillMinY, 1, fillMaxY); + g.setColor(leftToRight ? sliderAltTrackColor : MetalLookAndFeel.getControlShadow()); + g.drawLine(2, fillMinY, 2, fillMaxY); + g.setColor(leftToRight ? MetalLookAndFeel.getControlShadow() : sliderAltTrackColor); + g.drawLine(3, fillMinY, 3, fillMaxY); + g.setColor(leftToRight ? MetalLookAndFeel.getPrimaryControlShadow() : MetalLookAndFeel.getWhite()); + g.drawLine(4, fillMinY, 4, fillMaxY); + } + } + } else { + g.setColor(MetalLookAndFeel.getControlShadow()); + + if (middleOfThumb > 0) { + if (drawInverted && filledSlider) { + g.fillRect(0, 0, w - 1, middleOfThumb - 1); + } else { + g.drawRect(0, 0, w - 1, middleOfThumb - 1); + } + } + + if (middleOfThumb < h) { + if (!drawInverted && filledSlider) { + g.fillRect(0, middleOfThumb, w - 1, h - middleOfThumb - 1); + } else { + g.drawRect(0, middleOfThumb, w - 1, h - middleOfThumb - 1); + } } - } - if (w == 6) { - g.setColor(chooseColor(!leftToRight, - MetalLookAndFeel.getWhite(), - MetalLookAndFeel.getPrimaryControlShadow())); - g.drawLine(1, fillMinY, 1, fillMaxY); - g.setColor(chooseColor(!leftToRight, sliderAltTrackColor, - MetalLookAndFeel.getControlShadow())); - g.drawLine(2, fillMinY, 2, fillMaxY); - g.setColor(chooseColor(!leftToRight, - MetalLookAndFeel.getControlShadow(), - sliderAltTrackColor)); - g.drawLine(3, fillMinY, 3, fillMaxY); - g.setColor(chooseColor(!leftToRight, - MetalLookAndFeel.getPrimaryControlShadow(), - MetalLookAndFeel.getWhite())); - g.drawLine(4, fillMinY, 4, fillMaxY); } } diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalToolBarUI.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalToolBarUI.java index eed7d630351..24e4e54f394 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalToolBarUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalToolBarUI.java @@ -61,7 +61,7 @@ public class MetalToolBarUI extends BasicToolBarUI * instances of JToolBars and JMenuBars and is used to find * JToolBars/JMenuBars that border each other. */ - private static java.util.List components = new ArrayList(); + private static List> components = new ArrayList>(); /** * This protected field is implemenation specific. Do not access directly @@ -95,7 +95,7 @@ public class MetalToolBarUI extends BasicToolBarUI // typed to throw an NPE. throw new NullPointerException("JComponent must be non-null"); } - components.add(new WeakReference(c)); + components.add(new WeakReference(c)); } /** @@ -105,8 +105,7 @@ public class MetalToolBarUI extends BasicToolBarUI for (int counter = components.size() - 1; counter >= 0; counter--) { // Search for the component, removing any flushed references // along the way. - WeakReference ref = (WeakReference)components.get(counter); - Object target = ((WeakReference)components.get(counter)).get(); + JComponent target = components.get(counter).get(); if (target == c || target == null) { components.remove(counter); diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/DefaultMenuLayout.java b/jdk/src/share/classes/javax/swing/plaf/synth/DefaultMenuLayout.java index 678452328d9..1757a2e661a 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/DefaultMenuLayout.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/DefaultMenuLayout.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,19 +47,22 @@ class DefaultMenuLayout extends BoxLayout implements UIResource { super(target, axis); } - public void invalidateLayout(Container target) { - if (target instanceof JPopupMenu) { - SynthPopupMenuUI popupUI = (SynthPopupMenuUI)((JPopupMenu)target). - getUI(); - popupUI.resetAlignmentHints(); - } - super.invalidateLayout(target); - } - public Dimension preferredLayoutSize(Container target) { - if (target instanceof JPopupMenu && target.getComponentCount() == 0) { - return new Dimension(0, 0); + if (target instanceof JPopupMenu) { + JPopupMenu popupMenu = (JPopupMenu) target; + + popupMenu.putClientProperty( + SynthMenuItemLayoutHelper.MAX_ACC_OR_ARROW_WIDTH, null); + sun.swing.MenuItemLayoutHelper.clearUsedClientProperties(popupMenu); + + if (popupMenu.getComponentCount() == 0) { + return new Dimension(0, 0); + } } + + // Make BoxLayout recalculate cached preferred sizes + super.invalidateLayout(target); + return super.preferredLayoutSize(target); } } diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/DefaultSynthStyleFactory.java b/jdk/src/share/classes/javax/swing/plaf/synth/DefaultSynthStyleFactory.java index 93512afb46d..bbcbbad8168 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/DefaultSynthStyleFactory.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/DefaultSynthStyleFactory.java @@ -63,7 +63,7 @@ class DefaultSynthStyleFactory extends SynthStyleFactory { /** * Maps from a List (BakedArrayList to be precise) to the merged style. */ - private Map _resolvedStyles; + private Map _resolvedStyles; /** * Used if there are no styles matching a widget. @@ -74,7 +74,7 @@ class DefaultSynthStyleFactory extends SynthStyleFactory { DefaultSynthStyleFactory() { _tmpList = new BakedArrayList(5); _styles = new ArrayList(); - _resolvedStyles = new HashMap(); + _resolvedStyles = new HashMap(); } public synchronized void addStyle(DefaultSynthStyle style, @@ -138,7 +138,7 @@ class DefaultSynthStyleFactory extends SynthStyleFactory { * Fetches any styles that match the passed into arguments into * matches. */ - private void getMatchingStyles(java.util.List matches, JComponent c, + private void getMatchingStyles(List matches, JComponent c, Region id) { String idName = id.getLowerCaseName(); String cName = c.getName(); @@ -166,7 +166,7 @@ class DefaultSynthStyleFactory extends SynthStyleFactory { /** * Caches the specified style. */ - private void cacheStyle(java.util.List styles, SynthStyle style) { + private void cacheStyle(List styles, SynthStyle style) { BakedArrayList cachedStyles = new BakedArrayList(styles); _resolvedStyles.put(cachedStyles, style); @@ -175,11 +175,11 @@ class DefaultSynthStyleFactory extends SynthStyleFactory { /** * Returns the cached style from the passed in arguments. */ - private SynthStyle getCachedStyle(java.util.List styles) { + private SynthStyle getCachedStyle(List styles) { if (styles.size() == 0) { return null; } - return (SynthStyle)_resolvedStyles.get(styles); + return _resolvedStyles.get(styles); } /** @@ -187,7 +187,7 @@ class DefaultSynthStyleFactory extends SynthStyleFactory { * is reverse sorted, that is the most recently added style found to * match will be first. */ - private SynthStyle mergeStyles(java.util.List styles) { + private SynthStyle mergeStyles(List styles) { int size = styles.size(); if (size == 0) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/ImagePainter.java b/jdk/src/share/classes/javax/swing/plaf/synth/ImagePainter.java index b9a02a61931..943e91dbde7 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/ImagePainter.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/ImagePainter.java @@ -66,7 +66,7 @@ class ImagePainter extends SynthPainter { Paint9Painter painter; if (cacheRef == null || (painter = cacheRef.get()) == null) { painter = new Paint9Painter(30); - cacheRef = new WeakReference(painter); + cacheRef = new WeakReference(painter); AppContext.getAppContext().put(CACHE_KEY, cacheRef); } return painter; diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/Region.java b/jdk/src/share/classes/javax/swing/plaf/synth/Region.java index ef934264668..bd144bf6828 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/Region.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/Region.java @@ -67,8 +67,8 @@ import java.util.*; * @author Scott Violet */ public class Region { - private static final Map uiToRegionMap = new HashMap(); - private static final Map lowerCaseNameMap = new HashMap(); + private static final Map uiToRegionMap = new HashMap(); + private static final Map lowerCaseNameMap = new HashMap(); /** * ArrowButton's are special types of buttons that also render a @@ -451,15 +451,11 @@ public class Region { static Region getRegion(JComponent c) { - return (Region)uiToRegionMap.get(c.getUIClassID()); + return uiToRegionMap.get(c.getUIClassID()); } static void registerUIs(UIDefaults table) { - Iterator uis = uiToRegionMap.keySet().iterator(); - - while (uis.hasNext()) { - Object key = uis.next(); - + for (String key : uiToRegionMap.keySet()) { table.put(key, "javax.swing.plaf.synth.SynthLookAndFeel"); } } @@ -521,7 +517,7 @@ public class Region { */ String getLowerCaseName() { synchronized(lowerCaseNameMap) { - String lowerCaseName = (String)lowerCaseNameMap.get(this); + String lowerCaseName = lowerCaseNameMap.get(this); if (lowerCaseName == null) { lowerCaseName = getName().toLowerCase(); lowerCaseNameMap.put(this, lowerCaseName); diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthButtonUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthButtonUI.java index 78dd60bd3e3..e0f057e9037 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthButtonUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthButtonUI.java @@ -262,7 +262,7 @@ class SynthButtonUI extends BasicButtonUI implements * Returns the default icon. This should NOT callback * to the JComponent. * - * @param b AbstractButton the iocn is associated with + * @param b AbstractButton the icon is associated with * @return default icon */ @@ -445,9 +445,7 @@ class SynthButtonUI extends BasicButtonUI implements * Returns the Icon used in calculating the pref/min/max size. */ protected Icon getSizingIcon(AbstractButton b) { - // NOTE: this is slightly different than BasicButtonUI, where it - // would just use getIcon, but this should be ok. - Icon icon = (b.isEnabled()) ? b.getIcon() : b.getDisabledIcon(); + Icon icon = getEnabledIcon(b, b.getIcon()); if (icon == null) { icon = getDefaultIcon(b); } diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthComboBoxUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthComboBoxUI.java index 926c31e56e2..b4b0b9db4e1 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthComboBoxUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthComboBoxUI.java @@ -336,7 +336,7 @@ class SynthComboBoxUI extends BasicComboBoxUI implements return oldValue; } else { // Must take the value from the editor and get the value and cast it to the new type. - Class cls = oldValue.getClass(); + Class cls = oldValue.getClass(); try { Method method = cls.getMethod("valueOf", new Class[]{String.class}); newValue = method.invoke(oldValue, new Object[] { editor.getText()}); diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthContext.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthContext.java index 3b3b0b8e072..f63c3abcfdd 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthContext.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthContext.java @@ -39,7 +39,7 @@ import java.util.*; * @author Scott Violet */ public class SynthContext { - private static final Map contextMap; + private static final Map> contextMap; private JComponent component; private Region region; @@ -48,7 +48,7 @@ public class SynthContext { static { - contextMap = new HashMap(); + contextMap = new HashMap>(); } @@ -58,13 +58,13 @@ public class SynthContext { SynthContext context = null; synchronized(contextMap) { - java.util.List instances = (java.util.List)contextMap.get(type); + List instances = contextMap.get(type); if (instances != null) { int size = instances.size(); if (size > 0) { - context = (SynthContext)instances.remove(size - 1); + context = instances.remove(size - 1); } } } @@ -81,11 +81,10 @@ public class SynthContext { static void releaseContext(SynthContext context) { synchronized(contextMap) { - java.util.List instances = (java.util.List)contextMap.get( - context.getClass()); + List instances = contextMap.get(context.getClass()); if (instances == null) { - instances = new ArrayList(5); + instances = new ArrayList(5); contextMap.put(context.getClass(), instances); } instances.add(context); diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthEditorPaneUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthEditorPaneUI.java index b63ab2a60cd..f99741a0138 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthEditorPaneUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthEditorPaneUI.java @@ -45,8 +45,8 @@ class SynthEditorPaneUI extends BasicEditorPaneUI implements SynthUI { * I would prefer to use UIResource instad of this. * Unfortunately Boolean is a final class */ - private Boolean localTrue = new Boolean(true); - private Boolean localFalse = new Boolean(false); + private Boolean localTrue = Boolean.TRUE; + private Boolean localFalse = Boolean.FALSE; /** * Creates a UI for the JTextPane. @@ -69,7 +69,7 @@ class SynthEditorPaneUI extends BasicEditorPaneUI implements SynthUI { c.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, localTrue); } - updateStyle((JTextComponent)getComponent()); + updateStyle(getComponent()); } protected void uninstallDefaults() { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthGraphicsUtils.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthGraphicsUtils.java index 7d8bade8675..a8ec7728a64 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthGraphicsUtils.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthGraphicsUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,8 @@ package javax.swing.plaf.synth; import sun.swing.SwingUtilities2; +import sun.swing.MenuItemLayoutHelper; + import java.awt.*; import javax.swing.*; import javax.swing.plaf.basic.BasicHTML; @@ -411,12 +413,204 @@ public class SynthGraphicsUtils { } + /** + * A quick note about how preferred sizes are calculated... Generally + * speaking, SynthPopupMenuUI will run through the list of its children + * (from top to bottom) and ask each for its preferred size. Each menu + * item will add up the max width of each element (icons, text, + * accelerator spacing, accelerator text or arrow icon) encountered thus + * far, so by the time all menu items have been calculated, we will + * know the maximum (preferred) menu item size for that popup menu. + * Later when it comes time to paint each menu item, we can use those + * same accumulated max element sizes in order to layout the item. + */ + static Dimension getPreferredMenuItemSize(SynthContext context, + SynthContext accContext, JComponent c, + Icon checkIcon, Icon arrowIcon, int defaultTextIconGap, + String acceleratorDelimiter, boolean useCheckAndArrow, + String propertyPrefix) { + + JMenuItem mi = (JMenuItem) c; + SynthMenuItemLayoutHelper lh = new SynthMenuItemLayoutHelper( + context, accContext, mi, checkIcon, arrowIcon, + MenuItemLayoutHelper.createMaxRect(), defaultTextIconGap, + acceleratorDelimiter, SynthLookAndFeel.isLeftToRight(mi), + useCheckAndArrow, propertyPrefix); + + Dimension result = new Dimension(); + + // Calculate the result width + int gap = lh.getGap(); + result.width = 0; + MenuItemLayoutHelper.addMaxWidth(lh.getCheckSize(), gap, result); + MenuItemLayoutHelper.addMaxWidth(lh.getLabelSize(), gap, result); + MenuItemLayoutHelper.addWidth(lh.getMaxAccOrArrowWidth(), 5 * gap, result); + // The last gap is unnecessary + result.width -= gap; + + // Calculate the result height + result.height = MenuItemLayoutHelper.max(lh.getCheckSize().getHeight(), + lh.getLabelSize().getHeight(), lh.getAccSize().getHeight(), + lh.getArrowSize().getHeight()); + + // Take into account menu item insets + Insets insets = lh.getMenuItem().getInsets(); + if (insets != null) { + result.width += insets.left + insets.right; + result.height += insets.top + insets.bottom; + } + + // if the width is even, bump it up one. This is critical + // for the focus dash lhne to draw properly + if (result.width % 2 == 0) { + result.width++; + } + + // if the height is even, bump it up one. This is critical + // for the text to center properly + if (result.height % 2 == 0) { + result.height++; + } + + return result; + } + + static void applyInsets(Rectangle rect, Insets insets) { + if (insets != null) { + rect.x += insets.left; + rect.y += insets.top; + rect.width -= (insets.right + rect.x); + rect.height -= (insets.bottom + rect.y); + } + } + + static void paint(SynthContext context, SynthContext accContext, Graphics g, + Icon checkIcon, Icon arrowIcon, String acceleratorDelimiter, + int defaultTextIconGap, String propertyPrefix) { + JMenuItem mi = (JMenuItem) context.getComponent(); + SynthStyle style = context.getStyle(); + g.setFont(style.getFont(context)); + + Rectangle viewRect = new Rectangle(0, 0, mi.getWidth(), mi.getHeight()); + applyInsets(viewRect, mi.getInsets()); + + SynthMenuItemLayoutHelper lh = new SynthMenuItemLayoutHelper( + context, accContext, mi, checkIcon, + arrowIcon, viewRect, defaultTextIconGap, acceleratorDelimiter, + SynthLookAndFeel.isLeftToRight(mi), + MenuItemLayoutHelper.useCheckAndArrow(mi), propertyPrefix); + MenuItemLayoutHelper.LayoutResult lr = lh.layoutMenuItem(); + + paintMenuItem(g, lh, lr); + } + + static void paintMenuItem(Graphics g, SynthMenuItemLayoutHelper lh, + MenuItemLayoutHelper.LayoutResult lr) { + // Save original graphics font and color + Font holdf = g.getFont(); + Color holdc = g.getColor(); + + paintBackground(g, lh); + paintCheckIcon(g, lh, lr); + paintIcon(g, lh, lr); + paintText(g, lh, lr); + paintAccText(g, lh, lr); + paintArrowIcon(g, lh, lr); + + // Restore original graphics font and color + g.setColor(holdc); + g.setFont(holdf); + } + + static void paintBackground(Graphics g, SynthMenuItemLayoutHelper lh) { + paintBackground(lh.getContext(), g, lh.getMenuItem()); + } + + static void paintBackground(SynthContext context, Graphics g, JComponent c) { + context.getPainter().paintMenuItemBackground(context, g, 0, 0, + c.getWidth(), c.getHeight()); + } + + static void paintIcon(Graphics g, SynthMenuItemLayoutHelper lh, + MenuItemLayoutHelper.LayoutResult lr) { + if (lh.getIcon() != null) { + Icon icon; + JMenuItem mi = lh.getMenuItem(); + ButtonModel model = mi.getModel(); + if (!model.isEnabled()) { + icon = mi.getDisabledIcon(); + } else if (model.isPressed() && model.isArmed()) { + icon = mi.getPressedIcon(); + if (icon == null) { + // Use default icon + icon = mi.getIcon(); + } + } else { + icon = mi.getIcon(); + } + + if (icon != null) { + Rectangle iconRect = lr.getIconRect(); + SynthIcon.paintIcon(icon, lh.getContext(), g, iconRect.x, + iconRect.y, iconRect.width, iconRect.height); + } + } + } + + static void paintCheckIcon(Graphics g, SynthMenuItemLayoutHelper lh, + MenuItemLayoutHelper.LayoutResult lr) { + if (lh.getCheckIcon() != null) { + Rectangle checkRect = lr.getCheckRect(); + SynthIcon.paintIcon(lh.getCheckIcon(), lh.getContext(), g, + checkRect.x, checkRect.y, checkRect.width, checkRect.height); + } + } + + static void paintAccText(Graphics g, SynthMenuItemLayoutHelper lh, + MenuItemLayoutHelper.LayoutResult lr) { + String accText = lh.getAccText(); + if (accText != null && !accText.equals("")) { + g.setColor(lh.getAccStyle().getColor(lh.getAccContext(), + ColorType.TEXT_FOREGROUND)); + g.setFont(lh.getAccStyle().getFont(lh.getAccContext())); + lh.getAccGraphicsUtils().paintText(lh.getAccContext(), g, accText, + lr.getAccRect().x, lr.getAccRect().y, -1); + } + } + + static void paintText(Graphics g, SynthMenuItemLayoutHelper lh, + MenuItemLayoutHelper.LayoutResult lr) { + if (!lh.getText().equals("")) { + if (lh.getHtmlView() != null) { + // Text is HTML + lh.getHtmlView().paint(g, lr.getTextRect()); + } else { + // Text isn't HTML + g.setColor(lh.getStyle().getColor( + lh.getContext(), ColorType.TEXT_FOREGROUND)); + g.setFont(lh.getStyle().getFont(lh.getContext())); + lh.getGraphicsUtils().paintText(lh.getContext(), g, lh.getText(), + lr.getTextRect().x, lr.getTextRect().y, + lh.getMenuItem().getDisplayedMnemonicIndex()); + } + } + } + + static void paintArrowIcon(Graphics g, SynthMenuItemLayoutHelper lh, + MenuItemLayoutHelper.LayoutResult lr) { + if (lh.getArrowIcon() != null) { + Rectangle arrowRect = lr.getArrowRect(); + SynthIcon.paintIcon(lh.getArrowIcon(), lh.getContext(), g, + arrowRect.x, arrowRect.y, arrowRect.width, arrowRect.height); + } + } + /** * Wraps a SynthIcon around the Icon interface, forwarding calls to * the SynthIcon with a given SynthContext. */ private static class SynthIconWrapper implements Icon { - private static final java.util.List CACHE = new java.util.ArrayList(1); + private static final java.util.List CACHE = new java.util.ArrayList(1); private SynthIcon synthIcon; private SynthContext context; @@ -425,8 +619,7 @@ public class SynthGraphicsUtils { synchronized(CACHE) { int size = CACHE.size(); if (size > 0) { - SynthIconWrapper wrapper = (SynthIconWrapper)CACHE.remove( - size - 1); + SynthIconWrapper wrapper = CACHE.remove(size - 1); wrapper.reset(icon, context); return wrapper; } diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthInternalFrameTitlePane.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthInternalFrameTitlePane.java index 19d218871bc..f1c888952a4 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthInternalFrameTitlePane.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthInternalFrameTitlePane.java @@ -197,25 +197,25 @@ class SynthInternalFrameTitlePane extends BasicInternalFrameTitlePane protected void addSystemMenuItems(JPopupMenu menu) { // PENDING: this should all be localizable! - JMenuItem mi = (JMenuItem)menu.add(restoreAction); + JMenuItem mi = menu.add(restoreAction); mi.setMnemonic('R'); - mi = (JMenuItem)menu.add(moveAction); + mi = menu.add(moveAction); mi.setMnemonic('M'); - mi = (JMenuItem)menu.add(sizeAction); + mi = menu.add(sizeAction); mi.setMnemonic('S'); - mi = (JMenuItem)menu.add(iconifyAction); + mi = menu.add(iconifyAction); mi.setMnemonic('n'); - mi = (JMenuItem)menu.add(maximizeAction); + mi = menu.add(maximizeAction); mi.setMnemonic('x'); menu.add(new JSeparator()); - mi = (JMenuItem)menu.add(closeAction); + mi = menu.add(closeAction); mi.setMnemonic('C'); } protected void showSystemMenu() { Insets insets = frame.getInsets(); if (!frame.isIcon()) { - systemPopupMenu.show(frame, insets.left, getY() + getHeight()); + systemPopupMenu.show(frame, menuButton.getX(), getY() + getHeight()); } else { systemPopupMenu.show(menuButton, getX() - insets.left - insets.right, diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java index af3d687715c..c9f6f7687e3 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java @@ -107,7 +107,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel { * Map of defaults table entries. This is populated via the load * method. */ - private Map defaultsMap; + private Map defaultsMap; private Handler _handler; @@ -308,8 +308,8 @@ public class SynthLookAndFeel extends BasicLookAndFeel { children = ((Container)c).getComponents(); } if (children != null) { - for(int i = 0; i < children.length; i++) { - updateStyles(children[i]); + for (Component child : children) { + updateStyles(child); } } } @@ -581,7 +581,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel { } if (defaultsMap == null) { - defaultsMap = new HashMap(); + defaultsMap = new HashMap(); } new SynthParser().parse(input, (DefaultSynthStyleFactory) factory, @@ -611,7 +611,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel { } if (defaultsMap == null) { - defaultsMap = new HashMap(); + defaultsMap = new HashMap(); } InputStream input = url.openStream(); @@ -771,7 +771,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel { */ private static Object getAATextInfo() { String language = Locale.getDefault().getLanguage(); - String desktop = (String) + String desktop = AccessController.doPrivileged(new GetPropertyAction("sun.desktop")); boolean isCjkLocale = (Locale.CHINESE.getLanguage().equals(language) || @@ -786,7 +786,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel { return aaTextInfo; } - private static ReferenceQueue queue = new ReferenceQueue(); + private static ReferenceQueue queue = new ReferenceQueue(); private static void flushUnreferenced() { AATextListener aatl; @@ -796,7 +796,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel { } private static class AATextListener - extends WeakReference implements PropertyChangeListener { + extends WeakReference implements PropertyChangeListener { private String key = SunToolkit.DESKTOPFONTHINTS; AATextListener(LookAndFeel laf) { @@ -812,7 +812,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel { return; } - LookAndFeel laf = (LookAndFeel) get(); + LookAndFeel laf = get(); if (laf == null || laf != UIManager.getLookAndFeel()) { dispose(); return; @@ -835,8 +835,8 @@ public class SynthLookAndFeel extends BasicLookAndFeel { private static void updateWindowUI(Window window) { updateStyles(window); Window ownedWins[] = window.getOwnedWindows(); - for (int i = 0; i < ownedWins.length; i++) { - updateWindowUI(ownedWins[i]); + for (Window w : ownedWins) { + updateWindowUI(w); } } @@ -845,8 +845,8 @@ public class SynthLookAndFeel extends BasicLookAndFeel { */ private static void updateAllUIs() { Frame appFrames[] = Frame.getFrames(); - for (int i = 0; i < appFrames.length; i++) { - updateWindowUI(appFrames[i]); + for (Frame frame : appFrames) { + updateWindowUI(frame); } } @@ -909,7 +909,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel { // register it on the new one. KeyboardFocusManager manager = (KeyboardFocusManager)evt.getSource(); - if (((Boolean)newValue).equals(Boolean.FALSE)) { + if (newValue.equals(Boolean.FALSE)) { manager.removePropertyChangeListener(_handler); } else { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuItemLayoutHelper.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuItemLayoutHelper.java new file mode 100644 index 00000000000..4ca139a709d --- /dev/null +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuItemLayoutHelper.java @@ -0,0 +1,308 @@ +/* + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.swing.plaf.synth; + +import sun.swing.StringUIClientPropertyKey; +import sun.swing.MenuItemLayoutHelper; +import sun.swing.plaf.synth.SynthIcon; + +import javax.swing.*; +import javax.swing.text.View; +import java.awt.*; + +/** + * Calculates preferred size and layouts synth menu items. + * + * All JMenuItems (and JMenus) include enough space for the insets + * plus one or more elements. When we say "label" below, we mean + * "icon and/or text." + * + * Cases to consider for SynthMenuItemUI (visualized here in a + * LTR orientation; the RTL case would be reversed): + * label + * check icon + label + * check icon + label + accelerator + * label + accelerator + * + * Cases to consider for SynthMenuUI (again visualized here in a + * LTR orientation): + * label + arrow + * + * Note that in the above scenarios, accelerator and arrow icon are + * mutually exclusive. This means that if a popup menu contains a mix + * of JMenus and JMenuItems, we only need to allow enough space for + * max(maxAccelerator, maxArrow), and both accelerators and arrow icons + * can occupy the same "column" of space in the menu. + */ +class SynthMenuItemLayoutHelper extends MenuItemLayoutHelper { + + public static final StringUIClientPropertyKey MAX_ACC_OR_ARROW_WIDTH = + new StringUIClientPropertyKey("maxAccOrArrowWidth"); + + public static final ColumnAlignment LTR_ALIGNMENT_1 = + new ColumnAlignment( + SwingConstants.LEFT, + SwingConstants.LEFT, + SwingConstants.LEFT, + SwingConstants.RIGHT, + SwingConstants.RIGHT + ); + public static final ColumnAlignment LTR_ALIGNMENT_2 = + new ColumnAlignment( + SwingConstants.LEFT, + SwingConstants.LEFT, + SwingConstants.LEFT, + SwingConstants.LEFT, + SwingConstants.RIGHT + ); + public static final ColumnAlignment RTL_ALIGNMENT_1 = + new ColumnAlignment( + SwingConstants.RIGHT, + SwingConstants.RIGHT, + SwingConstants.RIGHT, + SwingConstants.LEFT, + SwingConstants.LEFT + ); + public static final ColumnAlignment RTL_ALIGNMENT_2 = + new ColumnAlignment( + SwingConstants.RIGHT, + SwingConstants.RIGHT, + SwingConstants.RIGHT, + SwingConstants.RIGHT, + SwingConstants.LEFT + ); + + private SynthContext context; + private SynthContext accContext; + private SynthStyle style; + private SynthStyle accStyle; + private SynthGraphicsUtils gu; + private SynthGraphicsUtils accGu; + private boolean alignAcceleratorText; + private int maxAccOrArrowWidth; + + public SynthMenuItemLayoutHelper(SynthContext context, SynthContext accContext, + JMenuItem mi, Icon checkIcon, Icon arrowIcon, + Rectangle viewRect, int gap, String accDelimiter, + boolean isLeftToRight, boolean useCheckAndArrow, + String propertyPrefix) { + this.context = context; + this.accContext = accContext; + this.style = context.getStyle(); + this.accStyle = accContext.getStyle(); + this.gu = style.getGraphicsUtils(context); + this.accGu = accStyle.getGraphicsUtils(accContext); + this.alignAcceleratorText = getAlignAcceleratorText(propertyPrefix); + reset(mi, checkIcon, arrowIcon, viewRect, gap, accDelimiter, + isLeftToRight, style.getFont(context), accStyle.getFont(accContext), + useCheckAndArrow, propertyPrefix); + setLeadingGap(0); + } + + private boolean getAlignAcceleratorText(String propertyPrefix) { + return style.getBoolean(context, + propertyPrefix + ".alignAcceleratorText", true); + } + + protected void calcWidthsAndHeights() { + // iconRect + if (getIcon() != null) { + getIconSize().setWidth(SynthIcon.getIconWidth(getIcon(), context)); + getIconSize().setHeight(SynthIcon.getIconHeight(getIcon(), context)); + } + + // accRect + if (!getAccText().equals("")) { + getAccSize().setWidth(accGu.computeStringWidth(getAccContext(), + getAccFontMetrics().getFont(), getAccFontMetrics(), + getAccText())); + getAccSize().setHeight(getAccFontMetrics().getHeight()); + } + + // textRect + if (getText() == null) { + setText(""); + } else if (!getText().equals("")) { + if (getHtmlView() != null) { + // Text is HTML + getTextSize().setWidth( + (int) getHtmlView().getPreferredSpan(View.X_AXIS)); + getTextSize().setHeight( + (int) getHtmlView().getPreferredSpan(View.Y_AXIS)); + } else { + // Text isn't HTML + getTextSize().setWidth(gu.computeStringWidth(context, + getFontMetrics().getFont(), getFontMetrics(), + getText())); + getTextSize().setHeight(getFontMetrics().getHeight()); + } + } + + if (useCheckAndArrow()) { + // checkIcon + if (getCheckIcon() != null) { + getCheckSize().setWidth( + SynthIcon.getIconWidth(getCheckIcon(), context)); + getCheckSize().setHeight( + SynthIcon.getIconHeight(getCheckIcon(), context)); + } + // arrowRect + if (getArrowIcon() != null) { + getArrowSize().setWidth( + SynthIcon.getIconWidth(getArrowIcon(), context)); + getArrowSize().setHeight( + SynthIcon.getIconHeight(getArrowIcon(), context)); + } + } + + // labelRect + if (isColumnLayout()) { + getLabelSize().setWidth(getIconSize().getWidth() + + getTextSize().getWidth() + getGap()); + getLabelSize().setHeight(MenuItemLayoutHelper.max( + getCheckSize().getHeight(), + getIconSize().getHeight(), + getTextSize().getHeight(), + getAccSize().getHeight(), + getArrowSize().getHeight())); + } else { + Rectangle textRect = new Rectangle(); + Rectangle iconRect = new Rectangle(); + gu.layoutText(context, getFontMetrics(), getText(), getIcon(), + getHorizontalAlignment(), getVerticalAlignment(), + getHorizontalTextPosition(), getVerticalTextPosition(), + getViewRect(), iconRect, textRect, getGap()); + textRect.width += getLeftTextExtraWidth() + getRightTextExtraWidth(); + Rectangle labelRect = iconRect.union(textRect); + getLabelSize().setHeight(labelRect.height); + getLabelSize().setWidth(labelRect.width); + } + } + + protected void calcMaxWidths() { + calcMaxWidth(getCheckSize(), MAX_CHECK_WIDTH); + maxAccOrArrowWidth = + calcMaxValue(MAX_ACC_OR_ARROW_WIDTH, getArrowSize().getWidth()); + maxAccOrArrowWidth = + calcMaxValue(MAX_ACC_OR_ARROW_WIDTH, getAccSize().getWidth()); + + if (isColumnLayout()) { + calcMaxWidth(getIconSize(), MAX_ICON_WIDTH); + calcMaxWidth(getTextSize(), MAX_TEXT_WIDTH); + int curGap = getGap(); + if ((getIconSize().getMaxWidth() == 0) + || (getTextSize().getMaxWidth() == 0)) { + curGap = 0; + } + getLabelSize().setMaxWidth( + calcMaxValue(MAX_LABEL_WIDTH, getIconSize().getMaxWidth() + + getTextSize().getMaxWidth() + curGap)); + } else { + // We shouldn't use current icon and text widths + // in maximal widths calculation for complex layout. + getIconSize().setMaxWidth(getParentIntProperty( + MAX_ICON_WIDTH)); + calcMaxWidth(getLabelSize(), MAX_LABEL_WIDTH); + // If maxLabelWidth is wider + // than the widest icon + the widest text + gap, + // we should update the maximal text witdh + int candidateTextWidth = getLabelSize().getMaxWidth() - + getIconSize().getMaxWidth(); + if (getIconSize().getMaxWidth() > 0) { + candidateTextWidth -= getGap(); + } + getTextSize().setMaxWidth(calcMaxValue( + MAX_TEXT_WIDTH, candidateTextWidth)); + } + } + + public SynthContext getContext() { + return context; + } + + public SynthContext getAccContext() { + return accContext; + } + + public SynthStyle getStyle() { + return style; + } + + public SynthStyle getAccStyle() { + return accStyle; + } + + public SynthGraphicsUtils getGraphicsUtils() { + return gu; + } + + public SynthGraphicsUtils getAccGraphicsUtils() { + return accGu; + } + + public boolean alignAcceleratorText() { + return alignAcceleratorText; + } + + public int getMaxAccOrArrowWidth() { + return maxAccOrArrowWidth; + } + + protected void prepareForLayout(LayoutResult lr) { + lr.getCheckRect().width = getCheckSize().getMaxWidth(); + // An item can have an arrow or a check icon at once + if (useCheckAndArrow() && (!"".equals(getAccText()))) { + lr.getAccRect().width = maxAccOrArrowWidth; + } else { + lr.getArrowRect().width = maxAccOrArrowWidth; + } + } + + public ColumnAlignment getLTRColumnAlignment() { + if (alignAcceleratorText()) { + return LTR_ALIGNMENT_2; + } else { + return LTR_ALIGNMENT_1; + } + } + + public ColumnAlignment getRTLColumnAlignment() { + if (alignAcceleratorText()) { + return RTL_ALIGNMENT_2; + } else { + return RTL_ALIGNMENT_1; + } + } + + protected void layoutIconAndTextInLabelRect(LayoutResult lr) { + lr.setTextRect(new Rectangle()); + lr.setIconRect(new Rectangle()); + gu.layoutText(context, getFontMetrics(), getText(), getIcon(), + getHorizontalAlignment(), getVerticalAlignment(), + getHorizontalTextPosition(), getVerticalTextPosition(), + lr.getLabelRect(), lr.getIconRect(), lr.getTextRect(), getGap()); + } +} diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuItemUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuItemUI.java index a921f9d4ba4..3bcc044a12e 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuItemUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuItemUI.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ import javax.swing.plaf.*; import javax.swing.plaf.basic.*; import javax.swing.text.View; import sun.swing.plaf.synth.*; -import sun.swing.SwingUtilities2; +import sun.swing.MenuItemLayoutHelper; /** @@ -59,542 +59,16 @@ class SynthMenuItemUI extends BasicMenuItemUI implements return new SynthMenuItemUI(); } - // - // The next handful of static methods are used by both SynthMenuUI - // and SynthMenuItemUI. This is necessitated by SynthMenuUI not - // extending SynthMenuItemUI. - // - - /* - * All JMenuItems (and JMenus) include enough space for the insets - * plus one or more elements. When we say "icon(s)" below, we mean - * "check/radio indicator and/or user icon." If both are defined for - * a given menu item, then in a LTR orientation the check/radio indicator - * is on the left side followed by the user icon to the right; it is - * just the opposite in a RTL orientation. - * - * Cases to consider for SynthMenuItemUI (visualized here in a - * LTR orientation; the RTL case would be reversed): - * text - * icon(s) + text - * icon(s) + text + accelerator - * text + accelerator - * - * Cases to consider for SynthMenuUI (again visualized here in a - * LTR orientation): - * text + arrow - * (user)icon + text + arrow - * - * Note that in the above scenarios, accelerator and arrow icon are - * mutually exclusive. This means that if a popup menu contains a mix - * of JMenus and JMenuItems, we only need to allow enough space for - * max(maxAccelerator, maxArrow), and both accelerators and arrow icons - * can occupy the same "column" of space in the menu. - * - * A quick note about how preferred sizes are calculated... Generally - * speaking, SynthPopupMenuUI will run through the list of its children - * (from top to bottom) and ask each for its preferred size. Each menu - * item will add up the max width of each element (icons, text, - * accelerator spacing, accelerator text or arrow icon) encountered thus - * far, so by the time all menu items have been calculated, we will - * know the maximum (preferred) menu item size for that popup menu. - * Later when it comes time to paint each menu item, we can use those - * same accumulated max element sizes in order to layout the item. - */ - static Dimension getPreferredMenuItemSize(SynthContext context, - SynthContext accContext, JComponent c, - Icon checkIcon, Icon arrowIcon, int defaultTextIconGap, - String acceleratorDelimiter) { - JMenuItem b = (JMenuItem) c; - Icon icon = (Icon) b.getIcon(); - String text = b.getText(); - KeyStroke accelerator = b.getAccelerator(); - String acceleratorText = ""; - - if (accelerator != null) { - int modifiers = accelerator.getModifiers(); - if (modifiers > 0) { - acceleratorText = KeyEvent.getKeyModifiersText(modifiers); - acceleratorText += acceleratorDelimiter; - } - int keyCode = accelerator.getKeyCode(); - if (keyCode != 0) { - acceleratorText += KeyEvent.getKeyText(keyCode); - } else { - acceleratorText += accelerator.getKeyChar(); - } - } - - Font font = context.getStyle().getFont(context); - FontMetrics fm = b.getFontMetrics(font); - FontMetrics fmAccel = b.getFontMetrics(accContext.getStyle(). - getFont(accContext)); - - resetRects(); - - layoutMenuItem( - context, fm, accContext, text, fmAccel, acceleratorText, - icon, checkIcon, arrowIcon, b.getVerticalAlignment(), - b.getHorizontalAlignment(), b.getVerticalTextPosition(), - b.getHorizontalTextPosition(), viewRect, iconRect, textRect, - acceleratorRect, checkIconRect, arrowIconRect, - text == null ? 0 : defaultTextIconGap, defaultTextIconGap); - - r.setBounds(textRect); - - int totalIconWidth = 0; - int maxIconHeight = 0; - if (icon != null) { - // Add in the user icon - totalIconWidth += iconRect.width; - if (textRect.width > 0) { - // Allow for some room between the user icon and the text - totalIconWidth += defaultTextIconGap; - } - maxIconHeight = Math.max(iconRect.height, maxIconHeight); - } - if (checkIcon != null) { - // Add in the checkIcon - totalIconWidth += checkIconRect.width; - if (textRect.width > 0 || icon != null) { - // Allow for some room between the check/radio indicator - // and the text (or user icon, if both are specified) - totalIconWidth += defaultTextIconGap; - } - maxIconHeight = Math.max(checkIconRect.height, maxIconHeight); - } - - int arrowWidth = 0; - if (arrowIcon != null) { - // Add in the arrowIcon - arrowWidth += defaultTextIconGap; - arrowWidth += arrowIconRect.width; - maxIconHeight = Math.max(arrowIconRect.height, maxIconHeight); - } - - int accelSpacing = 0; - if (acceleratorRect.width > 0) { - // Allow for some room between the text and the accelerator - accelSpacing += 4*defaultTextIconGap; - } - - // Take text and all icons into account when determining height - r.height = Math.max(r.height, maxIconHeight); - - // To make the accelerator texts appear in a column, - // find the widest MenuItem text and the widest accelerator text. - - // Get the parent, which stores the information. - Container parent = b.getParent(); - - if (parent instanceof JPopupMenu) { - SynthPopupMenuUI popupUI = (SynthPopupMenuUI)SynthLookAndFeel. - getUIOfType(((JPopupMenu)parent).getUI(), - SynthPopupMenuUI.class); - - if (popupUI != null) { - // This gives us the widest MenuItem text encountered thus - // far in the parent JPopupMenu - r.width = popupUI.adjustTextWidth(r.width); - - // Add in the widest icon (includes both user and - // check/radio icons) encountered thus far - r.width += popupUI.adjustIconWidth(totalIconWidth); - - // Add in the widest text/accelerator spacing - // encountered thus far - r.width += popupUI.adjustAccelSpacingWidth(accelSpacing); - - // Add in the widest accelerator text (or arrow) - // encountered thus far (at least one of these values - // will always be zero, so we combine them here to - // avoid double counting) - int totalAccelOrArrow = acceleratorRect.width + arrowWidth; - r.width += popupUI.adjustAcceleratorWidth(totalAccelOrArrow); - } - } - else if (parent != null && !(b instanceof JMenu && - ((JMenu)b).isTopLevelMenu())) { - r.width += - totalIconWidth + accelSpacing + - acceleratorRect.width + arrowWidth; - } - - Insets insets = b.getInsets(); - if(insets != null) { - r.width += insets.left + insets.right; - r.height += insets.top + insets.bottom; - } - - // if the width is even, bump it up one. This is critical - // for the focus dash line to draw properly - if(r.width%2 == 0) { - r.width++; - } - - // if the height is even, bump it up one. This is critical - // for the text to center properly - if(r.height%2 == 0) { - r.height++; - } - return r.getSize(); - } - - static void paint(SynthContext context, SynthContext accContext, - Graphics g, Icon checkIcon, Icon arrowIcon, - String acceleratorDelimiter, - int defaultTextIconGap) { - JComponent c = context.getComponent(); - JMenuItem b = (JMenuItem)c; - ButtonModel model = b.getModel(); - Insets i = b.getInsets(); - - resetRects(); - - viewRect.setBounds(0, 0, b.getWidth(), b.getHeight()); - - viewRect.x += i.left; - viewRect.y += i.top; - viewRect.width -= (i.right + viewRect.x); - viewRect.height -= (i.bottom + viewRect.y); - - SynthStyle style = context.getStyle(); - Font f = style.getFont(context); - g.setFont(f); - FontMetrics fm = SwingUtilities2.getFontMetrics(c, g, f); - FontMetrics accFM = SwingUtilities2.getFontMetrics(c, g, - accContext.getStyle(). - getFont(accContext)); - - // get Accelerator text - KeyStroke accelerator = b.getAccelerator(); - String acceleratorText = ""; - if (accelerator != null) { - int modifiers = accelerator.getModifiers(); - if (modifiers > 0) { - acceleratorText = KeyEvent.getKeyModifiersText(modifiers); - acceleratorText += acceleratorDelimiter; - } - - int keyCode = accelerator.getKeyCode(); - if (keyCode != 0) { - acceleratorText += KeyEvent.getKeyText(keyCode); - } else { - acceleratorText += accelerator.getKeyChar(); - } - } - - // Layout the text and icon - String text = layoutMenuItem(context, fm, accContext, - b.getText(), accFM, acceleratorText, b.getIcon(), - checkIcon, arrowIcon, - b.getVerticalAlignment(), b.getHorizontalAlignment(), - b.getVerticalTextPosition(), b.getHorizontalTextPosition(), - viewRect, iconRect, textRect, acceleratorRect, - checkIconRect, arrowIconRect, - b.getText() == null ? 0 : defaultTextIconGap, - defaultTextIconGap - ); - - // Paint the Check - if (checkIcon != null) { - SynthIcon.paintIcon(checkIcon, context, g, checkIconRect.x, - checkIconRect.y, checkIconRect.width, checkIconRect.height); - } - - // Paint the Icon - if(b.getIcon() != null) { - Icon icon; - if(!model.isEnabled()) { - icon = (Icon) b.getDisabledIcon(); - } else if(model.isPressed() && model.isArmed()) { - icon = (Icon) b.getPressedIcon(); - if(icon == null) { - // Use default icon - icon = (Icon) b.getIcon(); - } - } else { - icon = (Icon) b.getIcon(); - } - - if (icon!=null) { - SynthIcon.paintIcon(icon, context, g, iconRect.x, - iconRect.y, iconRect.width, iconRect.height); - } - } - - // Draw the Text - if(text != null) { - View v = (View) c.getClientProperty(BasicHTML.propertyKey); - if (v != null) { - v.paint(g, textRect); - } else { - g.setColor(style.getColor(context, ColorType.TEXT_FOREGROUND)); - g.setFont(style.getFont(context)); - style.getGraphicsUtils(context).paintText(context, g, text, - textRect.x, textRect.y, b.getDisplayedMnemonicIndex()); - } - } - - // Draw the Accelerator Text - if(acceleratorText != null && !acceleratorText.equals("")) { - // Get the maxAccWidth from the parent to calculate the offset. - int accOffset = 0; - Container parent = b.getParent(); - if (parent != null && parent instanceof JPopupMenu) { - SynthPopupMenuUI popupUI = (SynthPopupMenuUI) - ((JPopupMenu)parent).getUI(); - - // Note that we can only get here for SynthMenuItemUI - // (not SynthMenuUI) since acceleratorText is defined, - // so this cast should be safe - SynthMenuItemUI miUI = (SynthMenuItemUI) - SynthLookAndFeel.getUIOfType(b.getUI(), - SynthMenuItemUI.class); - - if (popupUI != null && miUI != null) { - String prop = - miUI.getPropertyPrefix() + ".alignAcceleratorText"; - boolean align = style.getBoolean(context, prop, true); - - // Calculate the offset, with which the accelerator texts - // will be drawn. - if (align) { - // When align==true and we're in the LTR case, - // we add an offset here so that all accelerators - // will be left-justified in their own column. - int max = popupUI.getMaxAcceleratorWidth(); - if (max > 0) { - accOffset = max - acceleratorRect.width; - if (!SynthLookAndFeel.isLeftToRight(c)) { - // In the RTL, flip the sign so that all - // accelerators will be right-justified. - accOffset = -accOffset; - } - } - } //else { - // Don't need to do anything special here; in the - // LTR case, the accelerator is already justified - // against the right edge of the menu (and against - // the left edge in the RTL case). - //} - } - } - - SynthStyle accStyle = accContext.getStyle(); - - g.setColor(accStyle.getColor(accContext, - ColorType.TEXT_FOREGROUND)); - g.setFont(accStyle.getFont(accContext)); - accStyle.getGraphicsUtils(accContext).paintText( - accContext, g, acceleratorText, acceleratorRect.x - - accOffset, acceleratorRect.y, -1); - } - - // Paint the Arrow - if (arrowIcon != null) { - SynthIcon.paintIcon(arrowIcon, context, g, arrowIconRect.x, - arrowIconRect.y, arrowIconRect.width, arrowIconRect.height); + public void uninstallUI(JComponent c) { + super.uninstallUI(c); + // Remove values from the parent's Client Properties. + JComponent p = MenuItemLayoutHelper.getMenuItemParent((JMenuItem) c); + if (p != null) { + p.putClientProperty( + SynthMenuItemLayoutHelper.MAX_ACC_OR_ARROW_WIDTH, null); } } - /** - * Compute and return the location of the icons origin, the - * location of origin of the text baseline, and a possibly clipped - * version of the compound labels string. Locations are computed - * relative to the viewRect rectangle. - */ - - private static String layoutMenuItem( - SynthContext context, - FontMetrics fm, - SynthContext accContext, - String text, - FontMetrics fmAccel, - String acceleratorText, - Icon icon, - Icon checkIcon, - Icon arrowIcon, - int verticalAlignment, - int horizontalAlignment, - int verticalTextPosition, - int horizontalTextPosition, - Rectangle viewRect, - Rectangle iconRect, - Rectangle textRect, - Rectangle acceleratorRect, - Rectangle checkIconRect, - Rectangle arrowIconRect, - int textIconGap, - int menuItemGap - ) - { - // If parent is JPopupMenu, get and store it's UI - SynthPopupMenuUI popupUI = null; - JComponent b = context.getComponent(); - Container parent = b.getParent(); - if(parent instanceof JPopupMenu) { - popupUI = (SynthPopupMenuUI)SynthLookAndFeel. - getUIOfType(((JPopupMenu)parent).getUI(), - SynthPopupMenuUI.class); - } - - context.getStyle().getGraphicsUtils(context).layoutText( - context, fm, text, icon,horizontalAlignment, verticalAlignment, - horizontalTextPosition, verticalTextPosition, viewRect, - iconRect, textRect, textIconGap); - - /* Initialize the acceleratorText bounds rectangle textRect. If a null - * or and empty String was specified we substitute "" here - * and use 0,0,0,0 for acceleratorTextRect. - */ - if( (acceleratorText == null) || acceleratorText.equals("") ) { - acceleratorRect.width = acceleratorRect.height = 0; - acceleratorText = ""; - } - else { - SynthStyle style = accContext.getStyle(); - acceleratorRect.width = style.getGraphicsUtils(accContext). - computeStringWidth(accContext, fmAccel.getFont(), fmAccel, - acceleratorText); - acceleratorRect.height = fmAccel.getHeight(); - } - - // Initialize the checkIcon bounds rectangle width & height. - if (checkIcon != null) { - checkIconRect.width = SynthIcon.getIconWidth(checkIcon, - context); - checkIconRect.height = SynthIcon.getIconHeight(checkIcon, - context); - } - else { - checkIconRect.width = checkIconRect.height = 0; - } - - // Initialize the arrowIcon bounds rectangle width & height. - if (arrowIcon != null) { - arrowIconRect.width = SynthIcon.getIconWidth(arrowIcon, - context); - arrowIconRect.height = SynthIcon.getIconHeight(arrowIcon, - context); - } else { - arrowIconRect.width = arrowIconRect.height = 0; - } - - // Note: layoutText() has already left room for - // the user icon, so no need to adjust textRect below - // to account for the user icon. However, we do have to - // reposition textRect when the check icon is visible. - - Rectangle labelRect = iconRect.union(textRect); - if( SynthLookAndFeel.isLeftToRight(context.getComponent()) ) { - // Position the check and user icons - iconRect.x = viewRect.x; - if (checkIcon != null) { - checkIconRect.x = viewRect.x; - iconRect.x += menuItemGap + checkIconRect.width; - textRect.x += menuItemGap + checkIconRect.width; - } - - // Position the arrow icon - arrowIconRect.x = - viewRect.x + viewRect.width - arrowIconRect.width; - - // Position the accelerator text rect - acceleratorRect.x = - viewRect.x + viewRect.width - acceleratorRect.width; - - /* Align icons and text horizontally */ - if(popupUI != null) { - int thisTextOffset = popupUI.adjustTextOffset(textRect.x - - viewRect.x); - textRect.x = thisTextOffset + viewRect.x; - - if(icon != null) { - // REMIND: The following code currently assumes the - // default (TRAILING) horizontalTextPosition, which means - // it will always place the icon to the left of the text. - // Other values of horizontalTextPosition aren't very - // useful for menu items, so we ignore them for now, but - // someday we might want to fix this situation. - int thisIconOffset = - popupUI.adjustIconOffset(iconRect.x - viewRect.x); - iconRect.x = thisIconOffset + viewRect.x; - } - } - } else { - // Position the accelerator text rect - acceleratorRect.x = viewRect.x; - - // Position the arrow icon - arrowIconRect.x = viewRect.x; - - // Position the check and user icons - iconRect.x = - viewRect.x + viewRect.width - iconRect.width; - if (checkIcon != null) { - checkIconRect.x = - viewRect.x + viewRect.width - checkIconRect.width; - textRect.x -= menuItemGap + checkIconRect.width; - iconRect.x -= menuItemGap + checkIconRect.width; - } - - /* Align icons and text horizontally */ - if(popupUI != null) { - int thisTextOffset = viewRect.x + viewRect.width - - textRect.x - textRect.width; - thisTextOffset = popupUI.adjustTextOffset(thisTextOffset); - textRect.x = viewRect.x + viewRect.width - - thisTextOffset - textRect.width; - if(icon != null) { - // REMIND: The following code currently assumes the - // default (TRAILING) horizontalTextPosition, which means - // it will always place the icon to the right of the text. - // Other values of horizontalTextPosition aren't very - // useful for menu items, so we ignore them for now, but - // someday we might want to fix this situation. - int thisIconOffset = viewRect.x + viewRect.width - - iconRect.x - iconRect.width; - thisIconOffset = - popupUI.adjustIconOffset(thisIconOffset); - iconRect.x = viewRect.x + viewRect.width - - thisIconOffset - iconRect.width; - } - } - } - - // Align the accelerator text and all icons vertically - // with the center of the label rect. - int midY = labelRect.y + (labelRect.height/2); - iconRect.y = midY - (iconRect.height/2); - acceleratorRect.y = midY - (acceleratorRect.height/2); - arrowIconRect.y = midY - (arrowIconRect.height/2); - checkIconRect.y = midY - (checkIconRect.height/2); - - return text; - } - - // these rects are used for painting and preferredsize calculations. - // they used to be regenerated constantly. Now they are reused. - static Rectangle iconRect = new Rectangle(); - static Rectangle textRect = new Rectangle(); - static Rectangle acceleratorRect = new Rectangle(); - static Rectangle checkIconRect = new Rectangle(); - static Rectangle arrowIconRect = new Rectangle(); - static Rectangle viewRect = new Rectangle(Short.MAX_VALUE,Short.MAX_VALUE); - static Rectangle r = new Rectangle(); - - private static void resetRects() { - iconRect.setBounds(0, 0, 0, 0); - textRect.setBounds(0, 0, 0, 0); - acceleratorRect.setBounds(0, 0, 0, 0); - checkIconRect.setBounds(0, 0, 0, 0); - arrowIconRect.setBounds(0, 0, 0, 0); - viewRect.setBounds(0,0,Short.MAX_VALUE, Short.MAX_VALUE); - r.setBounds(0, 0, 0, 0); - } - - protected void installDefaults() { updateStyle(menuItem); } @@ -718,9 +192,11 @@ class SynthMenuItemUI extends BasicMenuItemUI implements int defaultTextIconGap) { SynthContext context = getContext(c); SynthContext accContext = getContext(c, Region.MENU_ITEM_ACCELERATOR); - Dimension value = getPreferredMenuItemSize(context, accContext, - c, checkIcon, arrowIcon, defaultTextIconGap, - acceleratorDelimiter); + Dimension value = SynthGraphicsUtils.getPreferredMenuItemSize( + context, accContext, c, checkIcon, arrowIcon, + defaultTextIconGap, acceleratorDelimiter, + MenuItemLayoutHelper.useCheckAndArrow(menuItem), + getPropertyPrefix()); context.dispose(); accContext.dispose(); return value; @@ -751,14 +227,13 @@ class SynthMenuItemUI extends BasicMenuItemUI implements String prefix = getPropertyPrefix(); Icon checkIcon = style.getIcon(context, prefix + ".checkIcon"); Icon arrowIcon = style.getIcon(context, prefix + ".arrowIcon"); - paint(context, accContext, g, checkIcon, arrowIcon, - acceleratorDelimiter, defaultTextIconGap); + SynthGraphicsUtils.paint(context, accContext, g, checkIcon, arrowIcon, + acceleratorDelimiter, defaultTextIconGap, getPropertyPrefix()); accContext.dispose(); } void paintBackground(SynthContext context, Graphics g, JComponent c) { - context.getPainter().paintMenuItemBackground(context, g, 0, 0, - c.getWidth(), c.getHeight()); + SynthGraphicsUtils.paintBackground(context, g, c); } public void paintBorder(SynthContext context, Graphics g, int x, diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuUI.java index c59acb09b28..78835abf141 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuUI.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ import javax.swing.border.*; import java.util.Arrays; import java.util.ArrayList; import sun.swing.plaf.synth.SynthUI; - +import sun.swing.MenuItemLayoutHelper; /** * Synth's MenuUI. @@ -86,7 +86,7 @@ class SynthMenuUI extends BasicMenuUI implements PropertyChangeListener, acceleratorDelimiter = style.getString(context, prefix + ".acceleratorDelimiter", "+"); - if (useCheckAndArrow()) { + if (MenuItemLayoutHelper.useCheckAndArrow(menuItem)) { checkIcon = style.getIcon(context, prefix + ".checkIcon"); arrowIcon = style.getIcon(context, prefix + ".arrowIcon"); } else { @@ -111,6 +111,16 @@ class SynthMenuUI extends BasicMenuUI implements PropertyChangeListener, accContext.dispose(); } + public void uninstallUI(JComponent c) { + super.uninstallUI(c); + // Remove values from the parent's Client Properties. + JComponent p = MenuItemLayoutHelper.getMenuItemParent((JMenuItem) c); + if (p != null) { + p.putClientProperty( + SynthMenuItemLayoutHelper.MAX_ACC_OR_ARROW_WIDTH, null); + } + } + protected void uninstallDefaults() { SynthContext context = getContext(menuItem, ENABLED); style.uninstallDefaults(context); @@ -182,9 +192,11 @@ class SynthMenuUI extends BasicMenuUI implements PropertyChangeListener, int defaultTextIconGap) { SynthContext context = getContext(c); SynthContext accContext = getContext(c, Region.MENU_ITEM_ACCELERATOR); - Dimension value = SynthMenuItemUI.getPreferredMenuItemSize( - context, accContext, c, checkIcon, arrowIcon, - defaultTextIconGap, acceleratorDelimiter); + Dimension value = SynthGraphicsUtils.getPreferredMenuItemSize( + context, accContext, c, checkIcon, arrowIcon, + defaultTextIconGap, acceleratorDelimiter, + MenuItemLayoutHelper.useCheckAndArrow(menuItem), + getPropertyPrefix()); context.dispose(); accContext.dispose(); return value; @@ -211,21 +223,12 @@ class SynthMenuUI extends BasicMenuUI implements PropertyChangeListener, protected void paint(SynthContext context, Graphics g) { SynthContext accContext = getContext(menuItem, Region.MENU_ITEM_ACCELERATOR); - SynthStyle style = context.getStyle(); - Icon checkIcon; - Icon arrowIcon; - if (useCheckAndArrow()) { - // Refetch the appropriate icons for the current state - String prefix = getPropertyPrefix(); - checkIcon = style.getIcon(context, prefix + ".checkIcon"); - arrowIcon = style.getIcon(context, prefix + ".arrowIcon"); - } else { - // Not needed in this case - checkIcon = null; - arrowIcon = null; - } - SynthMenuItemUI.paint(context, accContext, g, checkIcon, arrowIcon, - acceleratorDelimiter, defaultTextIconGap); + // Refetch the appropriate check indicator for the current state + String prefix = getPropertyPrefix(); + Icon checkIcon = style.getIcon(context, prefix + ".checkIcon"); + Icon arrowIcon = style.getIcon(context, prefix + ".arrowIcon"); + SynthGraphicsUtils.paint(context, accContext, g, checkIcon, arrowIcon, + acceleratorDelimiter, defaultTextIconGap, getPropertyPrefix()); accContext.dispose(); } @@ -239,8 +242,4 @@ class SynthMenuUI extends BasicMenuUI implements PropertyChangeListener, updateStyle((JMenu)e.getSource()); } } - - private boolean useCheckAndArrow() { - return !((JMenu)menuItem).isTopLevelMenu(); - } } diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthParser.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthParser.java index 4b7d7994b5e..5f7a9b6c282 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthParser.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthParser.java @@ -40,6 +40,7 @@ import java.net.URLClassLoader; import java.text.ParseException; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.StringTokenizer; @@ -136,7 +137,7 @@ class SynthParser extends HandlerBase { * Array of state infos for the current style. These are pushed to the * style when is received. */ - private java.util.List _stateInfos; + private List _stateInfos; /** * Current style. @@ -151,7 +152,7 @@ class SynthParser extends HandlerBase { /** * Bindings for the current InputMap */ - private java.util.List _inputMapBindings; + private List _inputMapBindings; /** * ID for the input map. This is cached as @@ -177,30 +178,30 @@ class SynthParser extends HandlerBase { /** * List of ColorTypes. This is populated in startColorType. */ - private java.util.List _colorTypes; + private List _colorTypes; /** * defaultsPropertys are placed here. */ - private Map _defaultsMap; + private Map _defaultsMap; /** * List of SynthStyle.Painters that will be applied to the current style. */ - private java.util.List _stylePainters; + private List _stylePainters; /** * List of SynthStyle.Painters that will be applied to the current state. */ - private java.util.List _statePainters; + private List _statePainters; SynthParser() { _mapping = new HashMap(); - _stateInfos = new ArrayList(); - _colorTypes = new ArrayList(); - _inputMapBindings = new ArrayList(); - _stylePainters = new ArrayList(); - _statePainters = new ArrayList(); + _stateInfos = new ArrayList(); + _colorTypes = new ArrayList(); + _inputMapBindings = new ArrayList(); + _stylePainters = new ArrayList(); + _statePainters = new ArrayList(); } /** @@ -219,7 +220,7 @@ class SynthParser extends HandlerBase { public void parse(InputStream inputStream, DefaultSynthStyleFactory factory, URL urlResourceBase, Class classResourceBase, - Map defaultsMap) + Map defaultsMap) throws ParseException, IllegalArgumentException { if (inputStream == null || factory == null || (urlResourceBase == null && classResourceBase == null)) { @@ -333,7 +334,7 @@ class SynthParser extends HandlerBase { * type type, this will throw an exception. */ private Object lookup(String key, Class type) throws SAXException { - Object value = null; + Object value; if (_handler != null) { if ((value = _handler.lookup(key)) != null) { return checkCast(value, type); @@ -423,15 +424,12 @@ class SynthParser extends HandlerBase { private void endStyle() throws SAXException { int size = _stylePainters.size(); if (size > 0) { - _style.setPainters((ParsedSynthStyle.PainterInfo[]) - _stylePainters.toArray(new ParsedSynthStyle. - PainterInfo[size])); + _style.setPainters(_stylePainters.toArray(new ParsedSynthStyle.PainterInfo[size])); _stylePainters.clear(); } size = _stateInfos.size(); if (size > 0) { - _style.setStateInfo((ParsedSynthStyle.StateInfo[])_stateInfos. - toArray(new ParsedSynthStyle.StateInfo[size])); + _style.setStateInfo(_stateInfos.toArray(new ParsedSynthStyle.StateInfo[size])); _stateInfos.clear(); } _style = null; @@ -501,9 +499,7 @@ class SynthParser extends HandlerBase { private void endState() throws SAXException { int size = _statePainters.size(); if (size > 0) { - _stateInfo.setPainters((ParsedSynthStyle.PainterInfo[]) - _statePainters.toArray(new ParsedSynthStyle. - PainterInfo[size])); + _stateInfo.setPainters(_statePainters.toArray(new ParsedSynthStyle.PainterInfo[size])); _statePainters.clear(); } _stateInfo = null; @@ -684,8 +680,7 @@ class SynthParser extends HandlerBase { int max = 0; for (int counter = _colorTypes.size() - 1; counter >= 0; counter--) { - max = Math.max(max, ((ColorType)_colorTypes.get(counter)). - getID()); + max = Math.max(max, _colorTypes.get(counter).getID()); } if (colors == null || colors.length <= max) { Color[] newColors = new Color[max + 1]; @@ -696,7 +691,7 @@ class SynthParser extends HandlerBase { } for (int counter = _colorTypes.size() - 1; counter >= 0; counter--) { - colors[((ColorType)_colorTypes.get(counter)).getID()] = color; + colors[_colorTypes.get(counter).getID()] = color; } _stateInfo.setColors(colors); } @@ -705,7 +700,7 @@ class SynthParser extends HandlerBase { private void startProperty(AttributeList attributes, Object property) throws SAXException { Object value = null; - Object key = null; + String key = null; // Type of the value: 0=idref, 1=boolean, 2=dimension, 3=insets, // 4=integer,5=string int iType = 0; @@ -1027,7 +1022,7 @@ class SynthParser extends HandlerBase { } } - private void addPainterOrMerge(java.util.List painters, String method, + private void addPainterOrMerge(List painters, String method, SynthPainter painter, int direction) { ParsedSynthStyle.PainterInfo painterInfo; painterInfo = new ParsedSynthStyle.PainterInfo(method, diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthPopupMenuUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthPopupMenuUI.java index e8fb73bc156..50d1c2781ac 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthPopupMenuUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthPopupMenuUI.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,34 +58,6 @@ import sun.swing.plaf.synth.SynthUI; */ class SynthPopupMenuUI extends BasicPopupMenuUI implements PropertyChangeListener, SynthUI { - /** - * Maximum size of the text portion of the children menu items. - */ - private int maxTextWidth; - - /** - * Maximum size of the icon portion of the children menu items. - */ - private int maxIconWidth; - - /** - * Maximum size of the spacing between the text and accelerator - * portions of the children menu items. - */ - private int maxAccelSpacingWidth; - - /** - * Maximum size of the text for the accelerator portion of the children - * menu items. - */ - private int maxAcceleratorWidth; - - /* - * Maximum icon and text offsets of the children menu items. - */ - private int maxTextOffset; - private int maxIconOffset; - private SynthStyle style; public static ComponentUI createUI(JComponent x) { @@ -153,90 +125,6 @@ class SynthPopupMenuUI extends BasicPopupMenuUI implements return SynthLookAndFeel.getComponentState(c); } - /** - * Resets the max text and accerator widths, - * text and icon offsets. - */ - void resetAlignmentHints() { - maxTextWidth = maxIconWidth - = maxAccelSpacingWidth = maxAcceleratorWidth - = maxTextOffset = maxIconOffset = 0; - } - - /** - * Adjusts the width needed to display the maximum menu item string. - * - * @param width Text width. - * @return max width - */ - int adjustTextWidth(int width) { - maxTextWidth = Math.max(maxTextWidth, width); - return maxTextWidth; - } - - /** - * Adjusts the width needed to display the maximum menu item icon. - * - * @param width Icon width. - * @return max width - */ - int adjustIconWidth(int width) { - maxIconWidth = Math.max(maxIconWidth, width); - return maxIconWidth; - } - - /** - * Adjusts the width needed to pad between the maximum menu item - * text and accelerator. - * - * @param width Spacing width. - * @return max width - */ - int adjustAccelSpacingWidth(int width) { - maxAccelSpacingWidth = Math.max(maxAccelSpacingWidth, width); - return maxAccelSpacingWidth; - } - - /** - * Adjusts the width needed to display the maximum accelerator. - * - * @param width Text width. - * @return max width - */ - int adjustAcceleratorWidth(int width) { - maxAcceleratorWidth = Math.max(maxAcceleratorWidth, width); - return maxAcceleratorWidth; - } - - /** - * Maximum size needed to display accelerators of children menu items. - */ - int getMaxAcceleratorWidth() { - return maxAcceleratorWidth; - } - - /** - * Adjusts the text offset needed to align text horizontally. - * - * @param offset Text offset - * @return max offset - */ - int adjustTextOffset(int offset) { - maxTextOffset = Math.max(maxTextOffset, offset); - return maxTextOffset; - } - - /** - * Adjusts the icon offset needed to align icons horizontally - * - * @param offset Icon offset - * @return max offset - */ - int adjustIconOffset(int offset) { - maxIconOffset = Math.max(maxIconOffset, offset); - return maxIconOffset; - } - public void update(Graphics g, JComponent c) { SynthContext context = getContext(c); diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthSplitPaneUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthSplitPaneUI.java index 00f5d955f97..6cf4da962a2 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthSplitPaneUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthSplitPaneUI.java @@ -48,13 +48,13 @@ class SynthSplitPaneUI extends BasicSplitPaneUI implements * Keys to use for forward focus traversal when the JComponent is * managing focus. */ - private static Set managingFocusForwardTraversalKeys; + private static Set managingFocusForwardTraversalKeys; /** * Keys to use for backward focus traversal when the JComponent is * managing focus. */ - private static Set managingFocusBackwardTraversalKeys; + private static Set managingFocusBackwardTraversalKeys; /** * Style for the JSplitPane. @@ -96,7 +96,7 @@ class SynthSplitPaneUI extends BasicSplitPaneUI implements // focus forward traversal key if (managingFocusForwardTraversalKeys==null) { - managingFocusForwardTraversalKeys = new HashSet(); + managingFocusForwardTraversalKeys = new HashSet(); managingFocusForwardTraversalKeys.add( KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0)); } @@ -104,7 +104,7 @@ class SynthSplitPaneUI extends BasicSplitPaneUI implements managingFocusForwardTraversalKeys); // focus backward traversal key if (managingFocusBackwardTraversalKeys==null) { - managingFocusBackwardTraversalKeys = new HashSet(); + managingFocusBackwardTraversalKeys = new HashSet(); managingFocusBackwardTraversalKeys.add( KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK)); } diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthStyle.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthStyle.java index c9475f91b54..ab9e42b41e5 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthStyle.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthStyle.java @@ -53,7 +53,7 @@ public abstract class SynthStyle { /** * Contains the default values for certain properties. */ - private static Map DEFAULT_VALUES; + private static Map DEFAULT_VALUES; /** * Shared SynthGraphics. @@ -715,7 +715,7 @@ public abstract class SynthStyle { private static Object getDefaultValue(Object key) { synchronized(SynthStyle.class) { if (DEFAULT_VALUES == null) { - DEFAULT_VALUES = new HashMap(); + DEFAULT_VALUES = new HashMap(); populateDefaultValues(); } Object value = DEFAULT_VALUES.get(key); diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextAreaUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextAreaUI.java index f52d3a68b0d..d07c4d5ad88 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextAreaUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextAreaUI.java @@ -66,7 +66,7 @@ class SynthTextAreaUI extends BasicTextAreaUI implements SynthUI { protected void installDefaults() { // Installs the text cursor on the component super.installDefaults(); - updateStyle((JTextComponent)getComponent()); + updateStyle(getComponent()); } protected void uninstallDefaults() { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextFieldUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextFieldUI.java index 5b7cbd0a5f5..28bbdf843c4 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextFieldUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextFieldUI.java @@ -232,7 +232,7 @@ class SynthTextFieldUI protected void installDefaults() { // Installs the text cursor on the component super.installDefaults(); - updateStyle((JTextComponent)getComponent()); + updateStyle(getComponent()); getComponent().addFocusListener(this); } diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTreeUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTreeUI.java index 1e12a820ece..464b947b071 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTreeUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTreeUI.java @@ -390,7 +390,7 @@ class SynthTreeUI extends BasicTreeUI implements PropertyChangeListener, } private Rectangle getDropLineRect(JTree.DropLocation loc) { - Rectangle rect = null; + Rectangle rect; TreePath path = loc.getPath(); int index = loc.getChildIndex(); boolean ltr = tree.getComponentOrientation().isLeftToRight(); @@ -523,7 +523,7 @@ class SynthTreeUI extends BasicTreeUI implements PropertyChangeListener, // Don't paint the renderer if editing this row. boolean selected = tree.isRowSelected(row); - JTree.DropLocation dropLocation = (JTree.DropLocation)tree.getDropLocation(); + JTree.DropLocation dropLocation = tree.getDropLocation(); boolean isDrop = dropLocation != null && dropLocation.getChildIndex() == -1 && path == dropLocation.getPath(); diff --git a/jdk/src/share/classes/javax/swing/table/AbstractTableModel.java b/jdk/src/share/classes/javax/swing/table/AbstractTableModel.java index 4a9474cb258..9d6f4cafdcb 100644 --- a/jdk/src/share/classes/javax/swing/table/AbstractTableModel.java +++ b/jdk/src/share/classes/javax/swing/table/AbstractTableModel.java @@ -176,8 +176,7 @@ public abstract class AbstractTableModel implements TableModel, Serializable * @since 1.4 */ public TableModelListener[] getTableModelListeners() { - return (TableModelListener[])listenerList.getListeners( - TableModelListener.class); + return listenerList.getListeners(TableModelListener.class); } // diff --git a/jdk/src/share/classes/javax/swing/table/DefaultTableModel.java b/jdk/src/share/classes/javax/swing/table/DefaultTableModel.java index c2e97a9a2dd..0a63bfa73cd 100644 --- a/jdk/src/share/classes/javax/swing/table/DefaultTableModel.java +++ b/jdk/src/share/classes/javax/swing/table/DefaultTableModel.java @@ -681,9 +681,9 @@ public class DefaultTableModel extends AbstractTableModel implements Serializabl if (anArray == null) { return null; } - Vector v = new Vector(anArray.length); - for (int i=0; i < anArray.length; i++) { - v.addElement(anArray[i]); + Vector v = new Vector(anArray.length); + for (Object o : anArray) { + v.addElement(o); } return v; } @@ -698,9 +698,9 @@ public class DefaultTableModel extends AbstractTableModel implements Serializabl if (anArray == null) { return null; } - Vector v = new Vector(anArray.length); - for (int i=0; i < anArray.length; i++) { - v.addElement(convertToVector(anArray[i])); + Vector v = new Vector(anArray.length); + for (Object[] o : anArray) { + v.addElement(convertToVector(o)); } return v; } diff --git a/jdk/src/share/classes/javax/swing/text/AbstractDocument.java b/jdk/src/share/classes/javax/swing/text/AbstractDocument.java index fb081199ebe..0d815e0f6e9 100644 --- a/jdk/src/share/classes/javax/swing/text/AbstractDocument.java +++ b/jdk/src/share/classes/javax/swing/text/AbstractDocument.java @@ -123,15 +123,15 @@ public abstract class AbstractDocument implements Document, Serializable { if (defaultI18NProperty == null) { // determine default setting for i18n support - Object o = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + String o = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public String run() { return System.getProperty(I18NProperty); } } ); if (o != null) { - defaultI18NProperty = Boolean.valueOf((String)o); + defaultI18NProperty = Boolean.valueOf(o); } else { defaultI18NProperty = Boolean.FALSE; } @@ -163,7 +163,7 @@ public abstract class AbstractDocument implements Document, Serializable { */ public Dictionary getDocumentProperties() { if (documentProperties == null) { - documentProperties = new Hashtable(2); + documentProperties = new Hashtable(2); } return documentProperties; } @@ -467,8 +467,7 @@ public abstract class AbstractDocument implements Document, Serializable { * @since 1.4 */ public DocumentListener[] getDocumentListeners() { - return (DocumentListener[])listenerList.getListeners( - DocumentListener.class); + return listenerList.getListeners(DocumentListener.class); } /** @@ -508,8 +507,7 @@ public abstract class AbstractDocument implements Document, Serializable { * @since 1.4 */ public UndoableEditListener[] getUndoableEditListeners() { - return (UndoableEditListener[])listenerList.getListeners( - UndoableEditListener.class); + return listenerList.getListeners(UndoableEditListener.class); } /** @@ -610,7 +608,7 @@ public abstract class AbstractDocument implements Document, Serializable { DefaultDocumentEvent chng = new DefaultDocumentEvent(offs, len, DocumentEvent.EventType.REMOVE); - boolean isComposedTextElement = false; + boolean isComposedTextElement; // Check whether the position of interest is the composed text isComposedTextElement = Utilities.isComposedTextElement(this, offs); @@ -1051,7 +1049,7 @@ public abstract class AbstractDocument implements Document, Serializable { byte levels[] = calculateBidiLevels( firstPStart, lastPEnd ); - Vector newElements = new Vector(); + Vector newElements = new Vector(); // Calculate the first span of characters in the affected range with // the same bidi level. If this level is the same as the level of the @@ -1831,7 +1829,6 @@ public abstract class AbstractDocument implements Document, Serializable { } out.println("["+contentStr+"]"); } catch (BadLocationException e) { - ; } } else { @@ -2460,7 +2457,7 @@ public abstract class AbstractDocument implements Document, Serializable { if(nchildren == 0) return null; - Vector tempVector = new Vector(nchildren); + Vector tempVector = new Vector(nchildren); for(int counter = 0; counter < nchildren; counter++) tempVector.addElement(children[counter]); @@ -2749,7 +2746,7 @@ public abstract class AbstractDocument implements Document, Serializable { // if the number of changes gets too great, start using // a hashtable for to locate the change for a given element. if ((changeLookup == null) && (edits.size() > 10)) { - changeLookup = new Hashtable(); + changeLookup = new Hashtable(); int n = edits.size(); for (int i = 0; i < n; i++) { Object o = edits.elementAt(i); @@ -2918,7 +2915,7 @@ public abstract class AbstractDocument implements Document, Serializable { */ public DocumentEvent.ElementChange getChange(Element elem) { if (changeLookup != null) { - return (DocumentEvent.ElementChange) changeLookup.get(elem); + return changeLookup.get(elem); } int n = edits.size(); for (int i = 0; i < n; i++) { @@ -2937,7 +2934,7 @@ public abstract class AbstractDocument implements Document, Serializable { private int offset; private int length; - private Hashtable changeLookup; + private Hashtable changeLookup; private DocumentEvent.EventType type; } diff --git a/jdk/src/share/classes/javax/swing/text/AsyncBoxView.java b/jdk/src/share/classes/javax/swing/text/AsyncBoxView.java index 54a0e973553..ae11bde8122 100644 --- a/jdk/src/share/classes/javax/swing/text/AsyncBoxView.java +++ b/jdk/src/share/classes/javax/swing/text/AsyncBoxView.java @@ -25,6 +25,7 @@ package javax.swing.text; import java.util.*; +import java.util.List; import java.awt.*; import javax.swing.SwingUtilities; import javax.swing.event.DocumentEvent; @@ -58,7 +59,7 @@ public class AsyncBoxView extends View { */ public AsyncBoxView(Element elem, int axis) { super(elem); - stats = new ArrayList(); + stats = new ArrayList(); this.axis = axis; locator = new ChildLocator(); flushTask = new FlushTask(); @@ -197,7 +198,7 @@ public class AsyncBoxView extends View { protected ChildState getChildState(int index) { synchronized(stats) { if ((index >= 0) && (index < stats.size())) { - return (ChildState) stats.get(index); + return stats.get(index); } return null; } @@ -357,7 +358,7 @@ public class AsyncBoxView extends View { synchronized(stats) { // remove the replaced state records for (int i = 0; i < length; i++) { - ChildState cs = (ChildState)stats.remove(offset); + ChildState cs = stats.remove(offset); float csSpan = cs.getMajorSpan(); cs.getChildView().setParent(null); @@ -863,7 +864,7 @@ public class AsyncBoxView extends View { /** * The children and their layout statistics. */ - java.util.List stats; + List stats; /** * Current span along the major axis. This @@ -1110,7 +1111,7 @@ public class AsyncBoxView extends View { */ int updateChildOffsets(float targetOffset) { int n = getViewCount(); - int targetIndex = n - 1;; + int targetIndex = n - 1; int pos = lastValidOffset.getChildView().getStartOffset(); int startIndex = getViewIndex(pos, Position.Bias.Forward); float start = lastValidOffset.getMajorOffset(); @@ -1394,7 +1395,6 @@ public class AsyncBoxView extends View { private float min; private float pref; private float max; - private float align; private boolean minorValid; // major axis diff --git a/jdk/src/share/classes/javax/swing/text/ComponentView.java b/jdk/src/share/classes/javax/swing/text/ComponentView.java index 62e4bd02acb..085d999675d 100644 --- a/jdk/src/share/classes/javax/swing/text/ComponentView.java +++ b/jdk/src/share/classes/javax/swing/text/ComponentView.java @@ -27,6 +27,7 @@ package javax.swing.text; import java.awt.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.util.Set; import javax.swing.SwingUtilities; import javax.swing.event.*; @@ -434,7 +435,7 @@ public class ComponentView extends View { /** * Shows or hides this component depending on the value of parameter * b. - * @param b If true, shows this component; + * @param b If true, shows this component; * otherwise, hides this component. * @see #isVisible * @since JDK1.1 @@ -480,7 +481,7 @@ public class ComponentView extends View { return yalign; } - public java.util.Set getFocusTraversalKeys(int id) { + public Set getFocusTraversalKeys(int id) { return KeyboardFocusManager.getCurrentKeyboardFocusManager(). getDefaultFocusTraversalKeys(id); } diff --git a/jdk/src/share/classes/javax/swing/text/DefaultCaret.java b/jdk/src/share/classes/javax/swing/text/DefaultCaret.java index 22ec280ba09..e0e15681188 100644 --- a/jdk/src/share/classes/javax/swing/text/DefaultCaret.java +++ b/jdk/src/share/classes/javax/swing/text/DefaultCaret.java @@ -774,8 +774,7 @@ public class DefaultCaret extends Rectangle implements Caret, FocusListener, Mou * @since 1.4 */ public ChangeListener[] getChangeListeners() { - return (ChangeListener[])listenerList.getListeners( - ChangeListener.class); + return listenerList.getListeners(ChangeListener.class); } /** @@ -1330,7 +1329,7 @@ public class DefaultCaret extends Rectangle implements Caret, FocusListener, Mou if (this.dot != this.mark && component != null) { Clipboard clip = getSystemSelection(); if (clip != null) { - String selectedText = null; + String selectedText; if (component instanceof JPasswordField && component.getClientProperty("JPasswordField.cutCopyAllowed") != Boolean.TRUE) { diff --git a/jdk/src/share/classes/javax/swing/text/DefaultFormatter.java b/jdk/src/share/classes/javax/swing/text/DefaultFormatter.java index 79419047273..51dab601ca1 100644 --- a/jdk/src/share/classes/javax/swing/text/DefaultFormatter.java +++ b/jdk/src/share/classes/javax/swing/text/DefaultFormatter.java @@ -68,7 +68,7 @@ public class DefaultFormatter extends JFormattedTextField.AbstractFormatter private boolean commitOnEdit; /** Class used to create new instances. */ - private Class valueClass; + private Class valueClass; /** NavigationFilter that forwards calls back to DefaultFormatter. */ private NavigationFilter navigationFilter; @@ -231,7 +231,7 @@ public class DefaultFormatter extends JFormattedTextField.AbstractFormatter * @return Object representation of text */ public Object stringToValue(String string) throws ParseException { - Class vc = getValueClass(); + Class vc = getValueClass(); JFormattedTextField ftf = getFormattedTextField(); if (vc == null && ftf != null) { diff --git a/jdk/src/share/classes/javax/swing/text/DefaultHighlighter.java b/jdk/src/share/classes/javax/swing/text/DefaultHighlighter.java index 9e3202130d3..028b24c0ea6 100644 --- a/jdk/src/share/classes/javax/swing/text/DefaultHighlighter.java +++ b/jdk/src/share/classes/javax/swing/text/DefaultHighlighter.java @@ -56,7 +56,7 @@ public class DefaultHighlighter extends LayeredHighlighter { // PENDING(prinz) - should cull ranges not visible int len = highlights.size(); for (int i = 0; i < len; i++) { - HighlightInfo info = (HighlightInfo) highlights.elementAt(i); + HighlightInfo info = highlights.elementAt(i); if (!(info instanceof LayeredHighlightInfo)) { // Avoid allocing unless we need it. Rectangle a = component.getBounds(); @@ -66,7 +66,7 @@ public class DefaultHighlighter extends LayeredHighlighter { a.width -= insets.left + insets.right; a.height -= insets.top + insets.bottom; for (; i < len; i++) { - info = (HighlightInfo)highlights.elementAt(i); + info = highlights.elementAt(i); if (!(info instanceof LayeredHighlightInfo)) { Highlighter.HighlightPainter p = info.getPainter(); p.paint(g, info.getStartOffset(), info.getEndOffset(), @@ -159,7 +159,7 @@ public class DefaultHighlighter extends LayeredHighlighter { int p0 = -1; int p1 = -1; for (int i = 0; i < len; i++) { - HighlightInfo hi = (HighlightInfo)highlights.elementAt(i); + HighlightInfo hi = highlights.elementAt(i); if (hi instanceof LayeredHighlightInfo) { LayeredHighlightInfo info = (LayeredHighlightInfo)hi; minX = Math.min(minX, info.x); @@ -195,7 +195,7 @@ public class DefaultHighlighter extends LayeredHighlighter { int p0 = Integer.MAX_VALUE; int p1 = 0; for (int i = 0; i < len; i++) { - HighlightInfo info = (HighlightInfo) highlights.elementAt(i); + HighlightInfo info = highlights.elementAt(i); p0 = Math.min(p0, info.p0.getOffset()); p1 = Math.max(p1, info.p1.getOffset()); } @@ -282,7 +282,7 @@ public class DefaultHighlighter extends LayeredHighlighter { Shape viewBounds, JTextComponent editor, View view) { for (int counter = highlights.size() - 1; counter >= 0; counter--) { - Object tag = highlights.elementAt(counter); + HighlightInfo tag = highlights.elementAt(counter); if (tag instanceof LayeredHighlightInfo) { LayeredHighlightInfo lhi = (LayeredHighlightInfo)tag; int start = lhi.getStartOffset(); @@ -333,7 +333,7 @@ public class DefaultHighlighter extends LayeredHighlighter { private final static Highlighter.Highlight[] noHighlights = new Highlighter.Highlight[0]; - private Vector highlights = new Vector(); // Vector + private Vector highlights = new Vector(); private JTextComponent component; private boolean drawsLayeredHighlights; private SafeDamager safeDamager = new SafeDamager(); @@ -573,8 +573,8 @@ public class DefaultHighlighter extends LayeredHighlighter { * call. */ class SafeDamager implements Runnable { - private Vector p0 = new Vector(10); - private Vector p1 = new Vector(10); + private Vector p0 = new Vector(10); + private Vector p1 = new Vector(10); private Document lastDoc = null; /** @@ -589,8 +589,8 @@ public class DefaultHighlighter extends LayeredHighlighter { int len = p0.size(); for (int i = 0; i < len; i++){ mapper.damageRange(component, - ((Position)p0.get(i)).getOffset(), - ((Position)p1.get(i)).getOffset()); + p0.get(i).getOffset(), + p1.get(i).getOffset()); } } } diff --git a/jdk/src/share/classes/javax/swing/text/DefaultStyledDocument.java b/jdk/src/share/classes/javax/swing/text/DefaultStyledDocument.java index 4939a7615c3..d3ba5d98df8 100644 --- a/jdk/src/share/classes/javax/swing/text/DefaultStyledDocument.java +++ b/jdk/src/share/classes/javax/swing/text/DefaultStyledDocument.java @@ -84,7 +84,7 @@ public class DefaultStyledDocument extends AbstractDocument implements StyledDoc */ public DefaultStyledDocument(Content c, StyleContext styles) { super(c, styles); - listeningStyles = new Vector(); + listeningStyles = new Vector