This file often describes specific requirements for what we call the
- "minimum build environments" (MBE) for the JDK.
+ "minimum build environments" (MBE) for this
+ specific release of 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.
@@ -116,22 +117,22 @@
+ These same sources do indeed build on many more systems than the
+ above older generation systems, again the above is just a minimum.
+
+ Compilation problems with newer or different C/C++ compilers is a
+ common problem.
+ Similarly, compilation problems related to changes to the
+ /usr/include or system header files is also a
+ common problem with newer or unreleased OS versions.
+ Please report these types of problems as bugs so that they
+ can be dealt with accordingly.
@@ -488,7 +500,7 @@
not work due to a lack of support for MS-DOS drive letter paths
like C:/ or C:\.
Use a 3.80 version, or find a newer
- version that has this problem fixed, like 3.82.
+ version that has this problem fixed.
The older 3.80 version of make.exe can be downloaded with this
link.
@@ -575,8 +587,8 @@
Install
- Ant, set
- ANT_HOME.
+ Ant,
+ make sure it is in your PATH.
@@ -592,7 +604,7 @@
Approximately 1.4 GB of free disk
space is needed for a 32-bit build.
- If you are building the 64bit version, you should
+ If you are building the 64-bit version, you should
run the command "isainfo -v" to verify that you have a
64-bit installation, it should say sparcv9 or
amd64.
@@ -640,8 +652,8 @@
Install
- Ant, set
- ANT_HOME.
+ Ant,
+ make sure it is in your PATH.
i586 only:
- The minimum recommended hardware for building the 32bit or X86
+ The minimum recommended hardware for building the 32-bit 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
+ NOTE: The Windows 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.
@@ -719,8 +731,11 @@
Setup all environment variables for compilers
@@ -732,7 +747,8 @@
Install
- Ant, set
+ Ant,
+ make sure it is in your PATH and set
ANT_HOME.
@@ -787,7 +803,9 @@
you must first download and install the appropriate
binary plug bundles for the OpenJDK, go to the
OpenJDK site and select
- the "Bundles(7)" link and download the binaryplugs for
+ the
+ "Bundles(7)"
+ link and download the binaryplugs for
your particular platform.
The file downloaded is a jar file that must be extracted by running
the jar file with:
@@ -823,14 +841,12 @@
The Ant tool is available from the
Ant download site.
- You should always set
+ You should always make sure ant is in your PATH, and
+ on Windows you may also need to set
ANT_HOME
to point to the location of
the Ant installation, this is the directory pathname
that contains a bin and lib.
- It's also a good idea to also place its bin directory
- in the PATH environment variable, although it's
- not absolutely required.
- 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 GNU gcc compiler version should be 4 or newer.
The compiler used should be the default compiler installed
in /usr/bin.
-
- Older Linux systems may require a gcc and bunutils update.
- The Redhat Enterprise Advanced Server 2.1 update 2 system
- is one of these systems.
- RedHat Linux users can obtain this binutils package from
- Redhat web site.
- You will need to remove the default compiler and binutils
- packages and install the required packages
- into the default location on the system.
- However if you have a new video card driver, like
- Geforce 4 it is best to use
- the same compiler as the kernel was built with to
- build the new video card driver module.
- So you should build the modules before making this change.
The 32-bit OpenJDK Windows build
- requires Microsoft Visual Studio .NET 2003 (VS2003) Professional
+ requires
+ Microsoft Visual Studio C++ 2008 (VS2008) Standard
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.
+ in the location defined by the variable
+ VS90COMNTOOLS which
+ is set by the Microsoft Visual Studio 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
@@ -923,16 +924,12 @@
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.
-
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.
On X64, the Microsoft Platform Software
Development Kit (SDK), April 2005 Edition compiler,
@@ -953,10 +950,9 @@
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.
+ This Platform SDK compiler is only used on X64 builds
+ but other parts of the Platform SDK may be used
+ for the X86 builds.
i586 only:
- The OpenJDK 32bit build requires access to
- MSVCRT.DLL version 6.00.8337.0 or newer.
+ The OpenJDK 32-bit build requires access to a redistributable
+ MSVCRT.DLL.
If the MSVCRT.DLL is not installed in
the system32 directory set the
ALT_MSVCRT_DLL_PATH
- variable to the location.
+ variable to the location of this file.
X64 only:
- The OpenJDK 64bit build requires access to
- MSVCRT.DLL version 7.0.3790.0 or newer, which is
+ The OpenJDK 64-bit build requires access to a redistributable
+ MSVCRT.DLL, 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.
+ variable to the location of this file.
i586 only:
The
OpenJDK
- build requires access to
- MSVCR71.DLL version 7.10.3052.4 or newer which should be
+ build requires access to a redistributable
+ MSVCR90.DLL which should be
supplied by the
- Visual Studio product
- If the MSVCR71.DLL is not available from the
+ Visual Studio product.
+ If the MSVCR90.DLL is not available from the
Visual Studio product
set the
- ALT_MSVCR71_DLL_PATH
- variable to the location.
+ ALT_MSVCR90_DLL_PATH
+ variable to the location of this file.
@@ -1359,13 +1355,38 @@
document) that can impact the build are:
The location of the Bootstrap JDK 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)
+
+
+
MILESTONE
- 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.
+ The milestone name for the build (e.g."beta").
+ The default value is "internal".
+
+
BUILD_NUMBER
+
+ The build number for the build (e.g. "b27").
+ The default value is "b00".
+
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.
+ 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.
+
+ 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.
+
- These are useful in managing builds on multiple platforms.
- The default network location for all of the binary plug images
- for all platforms.
- If ALT_BINARY_PLUGS_PATH
- is not set, this directory will be used and should contain
- the following directories:
- solaris-sparc,
- solaris-i586,
- solaris-sparcv9,
- solaris-amd64,
- linux-i586,
- linux-amd64,
- windows-i586,
- and
- windows-amd64.
- Where each of these directories contain the binary plugs image
- for that platform.
+ The location of the FreeType shared library.
+ See FreeType information for details.
+
+ The location of tools like the
+ zip and unzip
+ binaries, but might also contain the GNU make utility
+ (gmake).
+ So this area is a bit of a grab bag, especially on Windows.
+ The default value depends on the platform and
+ Unix Commands being used.
+ On Linux the default will be
+ $(ALT_JDK_DEVTOOLS_PATH)/linux/bin,
+ on Solaris
+ $(ALT_JDK_DEVTOOLS_PATH)/{sparc,i386}/bin,
+ and on Windows with CYGWIN
+ /usr/bin.
+
+ The default root location for many of the ALT path locations
+ of the following ALT variables.
+ The default value is
+ "/java" on Solaris and Linux,
+ "J:" on Windows.
- 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.
-
- The location of tools like the
- zip and unzip
- binaries, but might also contain the GNU make utility
- (gmake).
- So this area is a bit of a grab bag, especially on Windows.
- The default value depends on the platform and
- Unix Commands being used.
- On Linux the default will be
- $(ALT_JDK_DEVTOOLS_PATH)/linux/bin,
- on Solaris
- $(ALT_JDK_DEVTOOLS_PATH)/{sparc,i386}/bin,
- on Windows with MKS
- %SYSTEMDRIVE%/UTILS,
- and on Windows with CYGWIN
- /usr/bin.
-
- Windows Only:
- 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.
-
- Windows Only:
- The location of the Microsoft Visual Studio .NET 2003
- tools 'bin' directory.
- The default is usually derived from
- ALT_COMPILER_PATH.
-
- Windows i586 only:
- The location of the
- MSVCR71.DLL.
+ These are useful in managing builds on multiple platforms.
+ The default network location for all of the binary plug images
+ for all platforms.
+ If ALT_BINARY_PLUGS_PATH
+ is not set, this directory will be used and should contain
+ the following directories:
+ solaris-sparc,
+ solaris-i586,
+ solaris-sparcv9,
+ solaris-amd64,
+ linux-i586,
+ linux-amd64,
+ windows-i586,
+ and
+ windows-amd64.
+ Where each of these directories contain the binary plugs image
+ for that platform.
- The default root location for many of the ALT path locations
- of the following ALT variables.
- The default value is
- "/java" on Solaris and Linux,
- "J:" on Windows.
-
- An override for specifying where the
- Unix command set are located.
- The default location varies depending on the platform,
- "%SYSTEMDRIVE%/MKSNT" or
- $(ROOTDIR) on Windows with MKS, otherwise it's
- "/bin" or /usr/bin.
-
- An override for specifying where the
- Unix /usr/bin commands are located. You usually do not need
- to set this variable: the default location is /usr/bin)
-
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.
-
-
BUILD_NUMBER
-
- The build number for the build (e.g. "b27").
- The default value is "b00".
-
-
MILESTONE
-
- The milestone name for the build (e.g."beta").
- The default value is "internal".
-
+ 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.
+
+ i586 only:
+ The location of the
+ MSVCR90.DLL.
+
+
@@ -1661,8 +1637,8 @@
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.
+ By default some 64-bit Linux versions (e.g. Fedora)
+ only install the 64-bit 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.
diff -r 773df43a0f6a -r 3cb2a607c347 corba/.hgtags
--- a/corba/.hgtags Wed Jul 05 16:43:43 2017 +0200
+++ b/corba/.hgtags Wed Jul 05 16:44:09 2017 +0200
@@ -14,3 +14,4 @@
59d5848bdedebe91cc2753acce78911bcb4a66db jdk7-b37
08be802754b0296c91a7713b6d85a015dbcd5349 jdk7-b38
55078b6661e286e90387d1d9950bd865f5cc436e jdk7-b39
+184e21992f47a8d730df1adc5b21a108f3125489 jdk7-b40
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/.hgtags
--- a/hotspot/.hgtags Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/.hgtags Wed Jul 05 16:44:09 2017 +0200
@@ -14,3 +14,4 @@
9ee9cf798b59e7d51f8c0a686959f313867a55d6 jdk7-b37
d9bc824aa078573829bb66572af847e26e1bd12e jdk7-b38
49ca90d77f34571b0757ebfcb8a7848ef2696b88 jdk7-b39
+81a0cbe3b28460ce836109934ece03db7afaf9cc jdk7-b40
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/hotspot_version
--- a/hotspot/make/hotspot_version Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/hotspot_version Wed Jul 05 16:44:09 2017 +0200
@@ -35,7 +35,7 @@
HS_MAJOR_VER=14
HS_MINOR_VER=0
-HS_BUILD_NUMBER=07
+HS_BUILD_NUMBER=08
JDK_MAJOR_VER=1
JDK_MINOR_VER=7
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/linux/makefiles/top.make
--- a/hotspot/make/linux/makefiles/top.make Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/linux/makefiles/top.make Wed Jul 05 16:44:09 2017 +0200
@@ -85,9 +85,9 @@
AD_Dir = $(GENERATED)/adfiles
ADLC = $(AD_Dir)/adlc
-AD_Spec = $(GAMMADIR)/src/cpu/$(Platform_arch)/vm/$(Platform_arch).ad
+AD_Spec = $(GAMMADIR)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad
AD_Src = $(GAMMADIR)/src/share/vm/adlc
-AD_Names = ad_$(Platform_arch).hpp ad_$(Platform_arch).cpp
+AD_Names = ad_$(Platform_arch_model).hpp ad_$(Platform_arch_model).cpp
AD_Files = $(AD_Names:%=$(AD_Dir)/%)
# AD_Files_If_Required/COMPILER1 = ad_stuff
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/solaris/makefiles/amd64.make
--- a/hotspot/make/solaris/makefiles/amd64.make Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/solaris/makefiles/amd64.make Wed Jul 05 16:44:09 2017 +0200
@@ -26,7 +26,6 @@
CFLAGS += -DVM_LITTLE_ENDIAN
# Not included in includeDB because it has no dependencies
-# Obj_Files += solaris_amd64.o
Obj_Files += solaris_x86_64.o
#
@@ -38,8 +37,6 @@
# _lwp_create_interpose must have a frame
OPT_CFLAGS/os_solaris_x86_64.o = -xO1
-# force C++ interpreter to be full optimization
-#OPT_CFLAGS/interpret.o = -fast -O4
# Temporary until SS10 C++ compiler is fixed
OPT_CFLAGS/generateOptoStub.o = -xO2
@@ -51,8 +48,6 @@
# gcc
# The serviceability agent relies on frame pointer (%rbp) to walk thread stack
CFLAGS += -fno-omit-frame-pointer
-# force C++ interpreter to be full optimization
-#OPT_CFLAGS/interpret.o = -O3
else
# error
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/solaris/makefiles/debug.make
--- a/hotspot/make/solaris/makefiles/debug.make Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/solaris/makefiles/debug.make Wed Jul 05 16:44:09 2017 +0200
@@ -30,7 +30,7 @@
ifeq ("${Platform_compiler}", "sparcWorks")
-ifeq ($(COMPILER_REV),5.8)
+ifeq ($(COMPILER_REV_NUMERIC),508)
# SS11 SEGV when compiling with -g and -xarch=v8, using different backend
DEBUG_CFLAGS/compileBroker.o = $(DEBUG_CFLAGS) -xO0
DEBUG_CFLAGS/jvmtiTagMap.o = $(DEBUG_CFLAGS) -xO0
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/solaris/makefiles/dtrace.make
--- a/hotspot/make/solaris/makefiles/dtrace.make Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/solaris/makefiles/dtrace.make Wed Jul 05 16:44:09 2017 +0200
@@ -87,17 +87,16 @@
XLIBJVM_DB = 64/$(LIBJVM_DB)
XLIBJVM_DTRACE = 64/$(LIBJVM_DTRACE)
-XARCH = $(subst sparcv9,v9,$(shell echo $(ISA)))
$(XLIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE)
@echo Making $@
$(QUIETLY) mkdir -p 64/ ; \
- $(CC) $(SYMFLAG) $(ARCHFLAG/$(XARCH)) -D$(TYPE) -I. -I$(GENERATED) \
+ $(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. -I$(GENERATED) \
$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
$(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
@echo Making $@
$(QUIETLY) mkdir -p 64/ ; \
- $(CC) $(SYMFLAG) $(ARCHFLAG/$(XARCH)) -D$(TYPE) -I. \
+ $(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. \
$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
endif # ifneq ("${ISA}","${BUILDARCH}")
@@ -116,27 +115,25 @@
$(QUIETLY) $(LINK.CC) -z nodefs -o $@ $(DTRACE_SRCDIR)/$(GENOFFS)Main.c \
./lib$(GENOFFS).so
-# $@.tmp is created first. It's to avoid empty $(JVMOFFS).h produced in error case.
+CONDITIONALLY_UPDATE_JVMOFFS_TARGET = \
+ cmp -s $@ $@.tmp; \
+ case $$? in \
+ 0) rm -f $@.tmp;; \
+ *) rm -f $@ && mv $@.tmp $@ && echo Updated $@;; \
+ esac
+
+# $@.tmp is created first to avoid an empty $(JVMOFFS).h if an error occurs.
$(JVMOFFS).h: $(GENOFFS)
- $(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -header > $@.tmp ; \
- if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
- then rm -f $@; mv $@.tmp $@; echo Updated $@ ; \
- else rm -f $@.tmp; \
- fi
+ $(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -header > $@.tmp
+ $(QUIETLY) $(CONDITIONALLY_UPDATE_JVMOFFS_TARGET)
$(JVMOFFS)Index.h: $(GENOFFS)
- $(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -index > $@.tmp ; \
- if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
- then rm -f $@; mv $@.tmp $@; echo Updated $@ ; \
- else rm -f $@.tmp; \
- fi
+ $(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -index > $@.tmp
+ $(QUIETLY) $(CONDITIONALLY_UPDATE_JVMOFFS_TARGET)
$(JVMOFFS).cpp: $(GENOFFS) $(JVMOFFS).h $(JVMOFFS)Index.h
- $(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -table > $@.tmp ; \
- if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
- then rm -f $@; mv $@.tmp $@; echo Updated $@ ; \
- else rm -f $@.tmp; \
- fi
+ $(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -table > $@.tmp
+ $(QUIETLY) $(CONDITIONALLY_UPDATE_JVMOFFS_TARGET)
$(JVMOFFS.o): $(JVMOFFS).h $(JVMOFFS).cpp
$(QUIETLY) $(CCC) -c -I. -o $@ $(ARCHFLAG) -D$(TYPE) $(JVMOFFS).cpp
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/solaris/makefiles/fastdebug.make
--- a/hotspot/make/solaris/makefiles/fastdebug.make Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/solaris/makefiles/fastdebug.make Wed Jul 05 16:44:09 2017 +0200
@@ -37,7 +37,7 @@
OPT_CFLAGS/SLOWER = -xO2
# Problem with SS12 compiler, dtrace doesn't like the .o files (bug 6693876)
-ifeq ($(COMPILER_REV), 5.9)
+ifeq ($(COMPILER_REV_NUMERIC), 509)
# To avoid jvm98 crash
OPT_CFLAGS/instanceKlass.o = $(OPT_CFLAGS/SLOWER)
# Not clear this workaround could be skipped in some cases.
@@ -46,47 +46,41 @@
OPT_CFLAGS/jni.o = $(OPT_CFLAGS/SLOWER)
endif
-ifeq ($(COMPILER_REV), 5.5)
+ifeq ($(COMPILER_REV_NUMERIC), 505)
# CC 5.5 has bug 4908364 with -xO4 (Fixed in 5.6)
OPT_CFLAGS/library_call.o = $(OPT_CFLAGS/SLOWER)
-endif # COMPILER_REV == 5.5
+endif # COMPILER_REV_NUMERIC == 505
-ifeq ($(shell expr $(COMPILER_REV) \<= 5.4), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \<= 504), 1)
# Compilation of *_.cpp can take an hour or more at O3. Use O2
# See comments at top of sparc.make.
-OPT_CFLAGS/ad_$(Platform_arch).o = $(OPT_CFLAGS/SLOWER)
-OPT_CFLAGS/dfa_$(Platform_arch).o = $(OPT_CFLAGS/SLOWER)
-endif # COMPILER_REV <= 5.4
+OPT_CFLAGS/ad_$(Platform_arch_model).o = $(OPT_CFLAGS/SLOWER)
+OPT_CFLAGS/dfa_$(Platform_arch_model).o = $(OPT_CFLAGS/SLOWER)
+endif # COMPILER_REV_NUMERIC <= 504
-ifeq (${COMPILER_REV}, 5.0)
-# Avoid a compiler bug caused by using -xO -g
-# Since the bug also occurs with -xO0, use an innocuous value (must not be null)
-OPT_CFLAGS/c1_LIROptimizer_i486.o = -c
-endif
-
-ifeq ($(shell expr $(COMPILER_REV) \< 5.5), 1)
-# Same problem with Solaris/x86 compiler (both 5.0 and 5.2) on ad_i486.cpp.
-# CC build time is also too long for ad_i486_{gen,misc}.o
-OPT_CFLAGS/ad_i486.o = -c
-OPT_CFLAGS/ad_i486_gen.o = -c
-OPT_CFLAGS/ad_i486_misc.o = -c
-ifeq ($(Platform_arch), i486)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 505), 1)
+# Same problem with Solaris/x86 compiler (both 5.0 and 5.2) on ad_x86_{32,64}.cpp.
+# CC build time is also too long for ad_$(Platform_arch_model)_{gen,misc}.o
+OPT_CFLAGS/ad_$(Platform_arch_model).o = -c
+OPT_CFLAGS/ad_$(Platform_arch_model)_gen.o = -c
+OPT_CFLAGS/ad_$(Platform_arch_model)_misc.o = -c
+ifeq ($(Platform_arch), x86)
# Same problem for the wrapper roosts: jni.o jvm.o
OPT_CFLAGS/jni.o = -c
OPT_CFLAGS/jvm.o = -c
# Same problem in parse2.o (probably the Big Switch over bytecodes)
OPT_CFLAGS/parse2.o = -c
-endif # Platform_arch == i486
+endif # Platform_arch == x86
endif
# Frame size > 100k if we allow inlining via -g0!
DEBUG_CFLAGS/bytecodeInterpreter.o = -g
DEBUG_CFLAGS/bytecodeInterpreterWithChecks.o = -g
-ifeq ($(Platform_arch), i486)
+ifeq ($(Platform_arch), x86)
# ube explodes on x86
OPT_CFLAGS/bytecodeInterpreter.o = -xO1
OPT_CFLAGS/bytecodeInterpreterWithChecks.o = -xO1
-endif # Platform_arch == i486
+endif # Platform_arch == x86
endif # Platform_compiler == sparcWorks
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/solaris/makefiles/i486.make
--- a/hotspot/make/solaris/makefiles/i486.make Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/solaris/makefiles/i486.make Wed Jul 05 16:44:09 2017 +0200
@@ -35,17 +35,13 @@
ifeq ("${Platform_compiler}", "sparcWorks")
# _lwp_create_interpose must have a frame
-OPT_CFLAGS/os_solaris_i486.o = -xO1
-# force C++ interpreter to be full optimization
-OPT_CFLAGS/interpret.o = -fast -O4
+OPT_CFLAGS/os_solaris_x86.o = -xO1
else
ifeq ("${Platform_compiler}", "gcc")
# gcc
# _lwp_create_interpose must have a frame
-OPT_CFLAGS/os_solaris_i486.o = -fno-omit-frame-pointer
-# force C++ interpreter to be full optimization
-OPT_CFLAGS/interpret.o = -O3
+OPT_CFLAGS/os_solaris_x86.o = -fno-omit-frame-pointer
#
else
# error
@@ -57,7 +53,7 @@
ifeq ("${Platform_compiler}", "sparcWorks")
# ILD is gone as of SS11 (5.8), not supported in SS10 (5.7)
-ifeq ($(shell expr $(COMPILER_REV) \< 5.7), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 507), 1)
#
# Bug in ild causes it to fail randomly. Until we get a fix we can't
# use ild.
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/solaris/makefiles/jvmg.make
--- a/hotspot/make/solaris/makefiles/jvmg.make Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/solaris/makefiles/jvmg.make Wed Jul 05 16:44:09 2017 +0200
@@ -30,7 +30,7 @@
ifeq ("${Platform_compiler}", "sparcWorks")
-ifeq ($(COMPILER_REV),5.8)
+ifeq ($(COMPILER_REV_NUMERIC),508)
# SS11 SEGV when compiling with -g and -xarch=v8, using different backend
DEBUG_CFLAGS/compileBroker.o = $(DEBUG_CFLAGS) -xO0
DEBUG_CFLAGS/jvmtiTagMap.o = $(DEBUG_CFLAGS) -xO0
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/solaris/makefiles/optimized.make
--- a/hotspot/make/solaris/makefiles/optimized.make Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/solaris/makefiles/optimized.make Wed Jul 05 16:44:09 2017 +0200
@@ -33,7 +33,7 @@
ifeq ("${Platform_compiler}", "sparcWorks")
# Problem with SS12 compiler, dtrace doesn't like the .o files (bug 6693876)
-ifeq ($(COMPILER_REV),5.9)
+ifeq ($(COMPILER_REV_NUMERIC),509)
# Not clear this workaround could be skipped in some cases.
OPT_CFLAGS/vmGCOperations.o = $(OPT_CFLAGS/SLOWER) -g
OPT_CFLAGS/java.o = $(OPT_CFLAGS/SLOWER) -g
@@ -41,9 +41,9 @@
endif
# Workaround SS11 bug 6345274 (all platforms) (Fixed in SS11 patch and SS12)
-ifeq ($(COMPILER_REV),5.8))
+ifeq ($(COMPILER_REV_NUMERIC),508))
OPT_CFLAGS/ciTypeFlow.o = $(OPT_CFLAGS/O2)
-endif # COMPILER_REV == 5.8
+endif # COMPILER_REV_NUMERIC == 508
endif # Platform_compiler == sparcWorks
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/solaris/makefiles/product.make
--- a/hotspot/make/solaris/makefiles/product.make Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/solaris/makefiles/product.make Wed Jul 05 16:44:09 2017 +0200
@@ -41,7 +41,7 @@
ifeq ("${Platform_compiler}", "sparcWorks")
# Problem with SS12 compiler, dtrace doesn't like the .o files (bug 6693876)
-ifeq ($(COMPILER_REV),5.9)
+ifeq ($(COMPILER_REV_NUMERIC),509)
# Not clear this workaround could be skipped in some cases.
OPT_CFLAGS/vmGCOperations.o = $(OPT_CFLAGS/SLOWER) -g
OPT_CFLAGS/java.o = $(OPT_CFLAGS/SLOWER) -g
@@ -49,9 +49,9 @@
endif
# Workaround SS11 bug 6345274 (all platforms) (Fixed in SS11 patch and SS12)
-ifeq ($(COMPILER_REV),5.8)
+ifeq ($(COMPILER_REV_NUMERIC),508)
OPT_CFLAGS/ciTypeFlow.o = $(OPT_CFLAGS/O2)
-endif # COMPILER_REV == 5.8
+endif # COMPILER_REV_NUMERIC == 508
endif # Platform_compiler == sparcWorks
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/solaris/makefiles/sparc.make
--- a/hotspot/make/solaris/makefiles/sparc.make Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/solaris/makefiles/sparc.make Wed Jul 05 16:44:09 2017 +0200
@@ -26,7 +26,7 @@
ASFLAGS += $(AS_ARCHFLAG)
ifeq ("${Platform_compiler}", "sparcWorks")
-ifeq ($(shell expr $(COMPILER_REV) \< 5.5), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 505), 1)
# For 5.2 ad_sparc file is compiled with -O2 %%%% remove when adlc is fixed
OPT_CFLAGS/ad_sparc.o = $(OPT_CFLAGS/SLOWER)
OPT_CFLAGS/dfa_sparc.o = $(OPT_CFLAGS/SLOWER)
@@ -39,7 +39,7 @@
OPT_CFLAGS/jniHandles.o = $(OPT_CFLAGS/O2)
# CC brings an US-II to its knees compiling the vmStructs asserts under -xO4
OPT_CFLAGS/vmStructs.o = $(OPT_CFLAGS/O2)
-endif
+endif # COMPILER_REV_NUMERIC < 505
else
# Options for gcc
OPT_CFLAGS/ad_sparc.o = $(OPT_CFLAGS/SLOWER)
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/solaris/makefiles/sparcWorks.make
--- a/hotspot/make/solaris/makefiles/sparcWorks.make Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/solaris/makefiles/sparcWorks.make Wed Jul 05 16:44:09 2017 +0200
@@ -41,9 +41,9 @@
# Get the last thing on the line that looks like x.x+ (x is a digit).
COMPILER_REV := \
-$(shell $(CPP) -V 2>&1 | sed -e 's/^.*\([1-9]\.[0-9][0-9]*\).*/\1/')
+$(shell $(CPP) -V 2>&1 | sed -n 's/^.*[ ,\t]C++[ ,\t]\([1-9]\.[0-9][0-9]*\).*/\1/p')
C_COMPILER_REV := \
-$(shell $(CC) -V 2>&1 | grep -i "cc:" | sed -e 's/^.*\([1-9]\.[0-9][0-9]*\).*/\1/')
+$(shell $(CC) -V 2>&1 | sed -n 's/^.*[ ,\t]C[ ,\t]\([1-9]\.[0-9][0-9]*\).*/\1/p')
# Pick which compiler is validated
ifeq ($(JDK_MINOR_VERSION),6)
@@ -60,17 +60,19 @@
ENFORCE_COMPILER_REV${ENFORCE_COMPILER_REV} := ${VALIDATED_COMPILER_REV}
ifneq (${COMPILER_REV},${ENFORCE_COMPILER_REV})
dummy_target_to_enforce_compiler_rev:=\
-$(info WARNING: You are using CC version ${COMPILER_REV} \
-and should be using version ${ENFORCE_COMPILER_REV})
+$(shell echo >&2 WARNING: You are using CC version ${COMPILER_REV} \
+and should be using version ${ENFORCE_COMPILER_REV}. Set ENFORCE_COMPILER_REV=${COMPILER_REV} to avoid this warning.)
endif
ENFORCE_C_COMPILER_REV${ENFORCE_C_COMPILER_REV} := ${VALIDATED_C_COMPILER_REV}
ifneq (${C_COMPILER_REV},${ENFORCE_C_COMPILER_REV})
dummy_target_to_enforce_c_compiler_rev:=\
-$(info WARNING: You are using cc version ${C_COMPILER_REV} \
-and should be using version ${ENFORCE_C_COMPILER_REV})
+$(shell echo >&2 WARNING: You are using cc version ${C_COMPILER_REV} \
+and should be using version ${ENFORCE_C_COMPILER_REV}. Set ENFORCE_C_COMPILER_REV=${C_COMPILER_REV} to avoid this warning.)
endif
+COMPILER_REV_NUMERIC := $(shell echo $(COMPILER_REV) | awk -F. '{ print $$1 * 100 + $$2 }')
+
# Fail the build if __fabsf is used. __fabsf exists only in Solaris 8 2/04
# and newer; objects with a dependency on this symbol will not run on older
# Solaris 8.
@@ -120,7 +122,7 @@
ARCHFLAG_NEW/amd64 = -m64
# Select the ARCHFLAGs and other SS12 (5.9) options
-ifeq ($(shell expr $(COMPILER_REV) \>= 5.9), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 509), 1)
ARCHFLAG/sparc = $(ARCHFLAG_NEW/sparc)
ARCHFLAG/sparcv9 = $(ARCHFLAG_NEW/sparcv9)
ARCHFLAG/i486 = $(ARCHFLAG_NEW/i486)
@@ -150,7 +152,7 @@
# Begin current (>=5.6) Forte compiler options #
#################################################
-ifeq ($(shell expr $(COMPILER_REV) \>= 5.6), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 506), 1)
ifeq ("${Platform_arch}", "sparc")
@@ -167,7 +169,7 @@
# Begin current (>=5.5) Forte compiler options #
#################################################
-ifeq ($(shell expr $(COMPILER_REV) \>= 5.5), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 505), 1)
CFLAGS += $(ARCHFLAG)
AOUT_FLAGS += $(ARCHFLAG)
@@ -255,7 +257,7 @@
LFLAGS += -mt
-endif # COMPILER_REV >= 5.5
+endif # COMPILER_REV_NUMERIC >= 505
######################################
# End 5.5 Forte compiler options #
@@ -265,7 +267,7 @@
# Begin 5.2 Forte compiler options #
######################################
-ifeq ($(COMPILER_REV), 5.2)
+ifeq ($(COMPILER_REV_NUMERIC), 502)
CFLAGS += $(ARCHFLAG)
AOUT_FLAGS += $(ARCHFLAG)
@@ -324,7 +326,7 @@
LFLAGS += -library=Crun
LIBS += -library=Crun -lCrun
-endif # COMPILER_REV == 5.2
+endif # COMPILER_REV_NUMERIC == 502
##################################
# End 5.2 Forte compiler options #
@@ -333,7 +335,7 @@
##################################
# Begin old 5.1 compiler options #
##################################
-ifeq ($(COMPILER_REV), 5.1)
+ifeq ($(COMPILER_REV_NUMERIC), 501)
_JUNK_ := $(shell echo >&2 \
"*** ERROR: sparkWorks.make incomplete for 5.1 compiler")
@@ -347,7 +349,7 @@
# Begin old 5.0 compiler options #
##################################
-ifeq (${COMPILER_REV}, 5.0)
+ifeq (${COMPILER_REV_NUMERIC}, 500)
# Had to hoist this higher apparently because of other changes. Must
# come before -xarch specification.
@@ -379,7 +381,7 @@
ifeq ("${Platform_arch_model}", "x86_32")
OPT_CFLAGS=-xtarget=pentium $(EXTRA_OPT_CFLAGS)
-ifeq ("${COMPILER_REV}", "5.0")
+ifeq ("${COMPILER_REV_NUMERIC}", "500")
# SC5.0 tools on x86 are flakey at -xO4
OPT_CFLAGS+=-xO3
else
@@ -405,13 +407,13 @@
PICFLAG/BETTER = $(PICFLAG/DEFAULT)
PICFLAG/BYFILE = $(PICFLAG/$@)$(PICFLAG/DEFAULT$(PICFLAG/$@))
-endif # COMPILER_REV = 5.0
+endif # COMPILER_REV_NUMERIC = 500
################################
# End old 5.0 compiler options #
################################
-ifeq ("${COMPILER_REV}", "4.2")
+ifeq ("${COMPILER_REV_NUMERIC}", "402")
# 4.2 COMPILERS SHOULD NO LONGER BE USED
_JUNK_ := $(shell echo >&2 \
"*** ERROR: SC4.2 compilers are not supported by this code base!")
@@ -443,7 +445,7 @@
LINK_MODE/optimized = -Bsymbolic -znodefs
# Have thread local errnos
-ifeq ($(shell expr $(COMPILER_REV) \>= 5.5), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 505), 1)
CFLAGS += -mt
else
CFLAGS += -D_REENTRANT
@@ -460,7 +462,7 @@
# The -g0 setting allows the C++ frontend to inline, which is a big win.
# Special global options for SS12
-ifeq ($(COMPILER_REV),5.9)
+ifeq ($(COMPILER_REV_NUMERIC),509)
# There appears to be multiple issues with the new Dwarf2 debug format, so
# we tell the compiler to use the older 'stabs' debug format all the time.
# Note that this needs to be used in optimized compiles too to be 100%.
@@ -479,8 +481,8 @@
#DEBUG_CFLAGS += -Qoption ccfe -xglobalstatic
#FASTDEBUG_CFLAGS += -Qoption ccfe -xglobalstatic
-ifeq (${COMPILER_REV}, 5.2)
-COMPILER_DATE := $(shell $(CPP) -V 2>&1 | awk '{ print $$NF; }')
+ifeq (${COMPILER_REV_NUMERIC}, 502)
+COMPILER_DATE := $(shell $(CPP) -V 2>&1 | sed -n '/^.*[ ]C++[ ]\([1-9]\.[0-9][0-9]*\)/p' | awk '{ print $$NF; }')
ifeq (${COMPILER_DATE}, 2001/01/31)
# disable -g0 in fastdebug since SC6.1 dated 2001/01/31 seems to be buggy
# use an innocuous value because it will get -g if it's empty
@@ -493,7 +495,7 @@
CFLAGS += $(CFLAGS_BROWSE)
# ILD is gone as of SS11 (5.8), not supportted in SS10 (5.7)
-ifeq ($(shell expr $(COMPILER_REV) \< 5.7), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 507), 1)
# use ild when debugging (but when optimizing we want reproducible results)
ILDFLAG = $(ILDFLAG/$(VERSION))
ILDFLAG/debug = -xildon
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/solaris/makefiles/sparcv9.make
--- a/hotspot/make/solaris/makefiles/sparcv9.make Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/solaris/makefiles/sparcv9.make Wed Jul 05 16:44:09 2017 +0200
@@ -26,7 +26,7 @@
ASFLAGS += $(AS_ARCHFLAG)
ifeq ("${Platform_compiler}", "sparcWorks")
-ifeq ($(shell expr $(COMPILER_REV) \< 5.5), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 505), 1)
# When optimized fully, stubGenerator_sparc.cpp
# has bogus code for the routine
# StubGenerator::generate_flush_callers_register_windows()
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/solaris/makefiles/top.make
--- a/hotspot/make/solaris/makefiles/top.make Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/solaris/makefiles/top.make Wed Jul 05 16:44:09 2017 +0200
@@ -83,9 +83,9 @@
AD_Dir = $(GENERATED)/adfiles
ADLC = $(AD_Dir)/adlc
-AD_Spec = $(GAMMADIR)/src/cpu/$(Platform_arch)/vm/$(Platform_arch).ad
+AD_Spec = $(GAMMADIR)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad
AD_Src = $(GAMMADIR)/src/share/vm/adlc
-AD_Names = ad_$(Platform_arch).hpp ad_$(Platform_arch).cpp
+AD_Names = ad_$(Platform_arch_model).hpp ad_$(Platform_arch_model).cpp
AD_Files = $(AD_Names:%=$(AD_Dir)/%)
# AD_Files_If_Required/COMPILER1 = ad_stuff
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/solaris/makefiles/vm.make
--- a/hotspot/make/solaris/makefiles/vm.make Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/solaris/makefiles/vm.make Wed Jul 05 16:44:09 2017 +0200
@@ -101,7 +101,7 @@
ifeq ("${Platform_compiler}", "sparcWorks")
# The whole megilla:
-ifeq ($(shell expr $(COMPILER_REV) \>= 5.5), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 505), 1)
# Old Comment: List the libraries in the order the compiler was designed for
# Not sure what the 'designed for' comment is referring too above.
# The order may not be too significant anymore, but I have placed this
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/windows/makefiles/adlc.make
--- a/hotspot/make/windows/makefiles/adlc.make Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/windows/makefiles/adlc.make Wed Jul 05 16:44:09 2017 +0200
@@ -102,6 +102,12 @@
adlc.exe: main.obj adlparse.obj archDesc.obj arena.obj dfa.obj dict2.obj filebuff.obj \
forms.obj formsopt.obj formssel.obj opcodes.obj output_c.obj output_h.obj
$(LINK) $(LINK_FLAGS) /subsystem:console /out:$@ $**
+!if "$(MT)" != ""
+# The previous link command created a .manifest file that we want to
+# insert into the linked artifact so we do not need to track it
+# separately. Use ";#2" for .dll and ";#1" for .exe:
+ $(MT) /manifest $@.manifest /outputresource:$@;#1
+!endif
$(GENERATED_NAMES_IN_INCL): $(Platform_arch_model).ad adlc.exe includeDB.current
rm -f $(GENERATED_NAMES)
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/windows/makefiles/compile.make
--- a/hotspot/make/windows/makefiles/compile.make Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/windows/makefiles/compile.make Wed Jul 05 16:44:09 2017 +0200
@@ -30,7 +30,7 @@
# /W3 Warning level 3
# /Zi Include debugging information
# /WX Treat any warning error as a fatal error
-# /MD Use dynamic multi-threaded runtime (msvcrt.dll or msvc*71.dll)
+# /MD Use dynamic multi-threaded runtime (msvcrt.dll or msvc*NN.dll)
# /MTd Use static multi-threaded runtime debug versions
# /O1 Optimize for size (/Os), skips /Oi
# /O2 Optimize for speed (/Ot), adds /Oi to /O1
@@ -80,8 +80,10 @@
CPP=ARCH_ERROR
!endif
-# MSC_VER is a 4 digit number that tells us what compiler is being used, it is
-# generated when the local.make file is created by the script gen_msc_ver.sh.
+# MSC_VER is a 4 digit number that tells us what compiler is being used
+# and is generated when the local.make file is created by build.make
+# via the script get_msc_ver.sh
+#
# If MSC_VER is set, it overrides the above default setting.
# But it should be set.
# Possible values:
@@ -89,13 +91,14 @@
# 1300 and 1310 is VS2003 or VC7
# 1399 is our fake number for the VS2005 compiler that really isn't 1400
# 1400 is for VS2005
+# 1500 is for VS2008
# Do not confuse this MSC_VER with the predefined macro _MSC_VER that the
# compiler provides, when MSC_VER==1399, _MSC_VER will be 1400.
# Normally they are the same, but a pre-release of the VS2005 compilers
# in the Windows 64bit Platform SDK said it was 1400 when it was really
# closer to VS2003 in terms of option spellings, so we use 1399 for that
# 1400 version that really isn't 1400.
-# See the file gen_msc_ver.sh for more info.
+# See the file get_msc_ver.sh for more info.
!if "x$(MSC_VER)" == "x"
COMPILER_NAME=$(DEFAULT_COMPILER_NAME)
!else
@@ -115,6 +118,9 @@
!if "$(MSC_VER)" == "1400"
COMPILER_NAME=VS2005
!endif
+!if "$(MSC_VER)" == "1500"
+COMPILER_NAME=VS2008
+!endif
!endif
# Add what version of the compiler we think this is to the compile line
@@ -160,7 +166,25 @@
# externals at link time. Even with /GS-, you need bufferoverflowU.lib.
# NOTE: Currently we decided to not use /GS-
BUFFEROVERFLOWLIB = bufferoverflowU.lib
-LINK_FLAGS = $(LINK_FLAGS) $(BUFFEROVERFLOWLIB)
+LINK_FLAGS = /manifest $(LINK_FLAGS) $(BUFFEROVERFLOWLIB)
+# Manifest Tool - used in VS2005 and later to adjust manifests stored
+# as resources inside build artifacts.
+MT=mt.exe
+!if "$(BUILDARCH)" == "i486"
+# VS2005 on x86 restricts the use of certain libc functions without this
+CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_DEPRECATE
+!endif
+!endif
+
+!if "$(COMPILER_NAME)" == "VS2008"
+PRODUCT_OPT_OPTION = /O2 /Oy-
+FASTDEBUG_OPT_OPTION = /O2 /Oy-
+DEBUG_OPT_OPTION = /Od
+GX_OPTION = /EHsc
+LINK_FLAGS = /manifest $(LINK_FLAGS)
+# Manifest Tool - used in VS2005 and later to adjust manifests stored
+# as resources inside build artifacts.
+MT=mt.exe
!if "$(BUILDARCH)" == "i486"
# VS2005 on x86 restricts the use of certain libc functions without this
CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_DEPRECATE
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/windows/makefiles/debug.make
--- a/hotspot/make/windows/makefiles/debug.make Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/windows/makefiles/debug.make Wed Jul 05 16:44:09 2017 +0200
@@ -50,6 +50,12 @@
$(LINK) @<<
$(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
<<
+!if "$(MT)" != ""
+# The previous link command created a .manifest file that we want to
+# insert into the linked artifact so we do not need to track it
+# separately. Use ";#2" for .dll and ";#1" for .exe:
+ $(MT) /manifest $@.manifest /outputresource:$@;#2
+!endif
!include $(WorkSpace)/make/windows/makefiles/shared.make
!include $(WorkSpace)/make/windows/makefiles/sa.make
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/windows/makefiles/defs.make
--- a/hotspot/make/windows/makefiles/defs.make Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/windows/makefiles/defs.make Wed Jul 05 16:44:09 2017 +0200
@@ -25,7 +25,7 @@
# The common definitions for hotspot windows builds.
# Include the top level defs.make under make directory instead of this one.
# This file is included into make/defs.make.
-# On windows it is only used to construct parameters for
+# On windows it is only used to construct parameters for
# make/windows/build.make when make/Makefile is used to build VM.
SLASH_JAVA ?= J:
@@ -69,7 +69,7 @@
JDK_INCLUDE_SUBDIR=win32
-# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined
+# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined
# and added to MAKE_ARGS list in $(GAMMADIR)/make/defs.make.
# next parameters are defined in $(GAMMADIR)/make/defs.make.
@@ -125,7 +125,7 @@
endif
ifeq ($(BUILD_WIN_SA), 1)
- ifeq ($(ARCH),ia64)
+ ifeq ($(ARCH),ia64)
BUILD_WIN_SA = 0
endif
endif
@@ -154,7 +154,7 @@
EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.dll
EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.pdb
EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.map
- EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar
+ EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar
# Must pass this down to nmake.
MAKE_ARGS += BUILD_WIN_SA=1
endif
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/windows/makefiles/fastdebug.make
--- a/hotspot/make/windows/makefiles/fastdebug.make Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/windows/makefiles/fastdebug.make Wed Jul 05 16:44:09 2017 +0200
@@ -50,6 +50,13 @@
$(LINK) @<<
$(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
<<
+!if "$(MT)" != ""
+# The previous link command created a .manifest file that we want to
+# insert into the linked artifact so we do not need to track it
+# separately. Use ";#2" for .dll and ";#1" for .exe:
+ $(MT) /manifest $@.manifest /outputresource:$@;#2
+!endif
+
!include $(WorkSpace)/make/windows/makefiles/shared.make
!include $(WorkSpace)/make/windows/makefiles/sa.make
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/windows/makefiles/product.make
--- a/hotspot/make/windows/makefiles/product.make Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/windows/makefiles/product.make Wed Jul 05 16:44:09 2017 +0200
@@ -61,6 +61,12 @@
$(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
<<
!endif
+!if "$(MT)" != ""
+# The previous link command created a .manifest file that we want to
+# insert into the linked artifact so we do not need to track it
+# separately. Use ";#2" for .dll and ";#1" for .exe:
+ $(MT) /manifest $@.manifest /outputresource:$@;#2
+!endif
!include $(WorkSpace)/make/windows/makefiles/shared.make
!include $(WorkSpace)/make/windows/makefiles/sa.make
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/windows/makefiles/sa.make
--- a/hotspot/make/windows/makefiles/sa.make Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/windows/makefiles/sa.make Wed Jul 05 16:44:09 2017 +0200
@@ -92,13 +92,18 @@
!else
SA_CFLAGS = /nologo $(MS_RUNTIME_OPTION) /W3 /Gm $(GX_OPTION) /ZI /Od /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
!endif
-
+!if "$(MT)" != ""
+ SA_LINK_FLAGS = /manifest $(SA_LINK_FLAGS)
+!endif
SASRCFILE = $(AGENT_DIR)/src/os/win32/windbg/sawindbg.cpp
SA_LFLAGS = $(SA_LINK_FLAGS) /nologo /subsystem:console /map /debug /machine:$(MACHINE)
# Note that we do not keep sawindbj.obj around as it would then
# get included in the dumpbin command in build_vm_def.sh
+# In VS2005 or VS2008 the link command creates a .manifest file that we want
+# to insert into the linked artifact so we do not need to track it separately.
+# Use ";#2" for .dll and ";#1" for .exe in the MT command below:
$(SAWINDBG): $(SASRCFILE)
set INCLUDE=$(SA_INCLUDE)$(INCLUDE)
$(CPP) @<<
@@ -109,6 +114,9 @@
<<
set LIB=$(SA_LIB)$(LIB)
$(LINK) /out:$@ /DLL sawindbg.obj dbgeng.lib $(SA_LFLAGS)
+!if "$(MT)" != ""
+ $(MT) /manifest $(@F).manifest /outputresource:$(@F);#2
+!endif
-@rm -f sawindbg.obj
cleanall :
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/make/windows/projectfiles/common/Makefile
--- a/hotspot/make/windows/projectfiles/common/Makefile Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/make/windows/projectfiles/common/Makefile Wed Jul 05 16:44:09 2017 +0200
@@ -56,7 +56,8 @@
$(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_shared \
$(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_parNew \
$(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge \
- $(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep
+ $(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep \
+ $(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_g1
IncludeDBs_kernel =$(IncludeDBs_base) \
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/cpu/x86/vm/register_definitions_x86.cpp
--- a/hotspot/src/cpu/x86/vm/register_definitions_x86.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/register_definitions_x86.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -22,9 +22,6 @@
*
*/
-// make sure the defines don't screw up the declarations later on in this file
-#define DONT_USE_REGISTER_DEFINES
-
#include "incls/_precompiled.incl"
#include "incls/_register_definitions_x86.cpp.incl"
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/os/solaris/vm/os_solaris.cpp
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -3756,7 +3756,6 @@
int maxClamped = MIN2(iaLimits.maxPrio, (int)iaInfo->ia_uprilim);
iaInfo->ia_upri = scale_to_lwp_priority(iaLimits.minPrio, maxClamped, newPrio);
iaInfo->ia_uprilim = IA_NOCHANGE;
- iaInfo->ia_nice = IA_NOCHANGE;
iaInfo->ia_mode = IA_NOCHANGE;
if (ThreadPriorityVerbose) {
tty->print_cr ("IA: [%d...%d] %d->%d\n",
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/adlc/archDesc.cpp
--- a/hotspot/src/share/vm/adlc/archDesc.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/adlc/archDesc.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -212,9 +212,9 @@
// Initialize I/O Files
_ADL_file._name = NULL; _ADL_file._fp = NULL;
// Machine dependent output files
- _DFA_file._name = "dfa_i486.cpp"; _DFA_file._fp = NULL;
- _HPP_file._name = "ad_i486.hpp"; _HPP_file._fp = NULL;
- _CPP_file._name = "ad_i486.cpp"; _CPP_file._fp = NULL;
+ _DFA_file._name = NULL; _DFA_file._fp = NULL;
+ _HPP_file._name = NULL; _HPP_file._fp = NULL;
+ _CPP_file._name = NULL; _CPP_file._fp = NULL;
_bug_file._name = "bugs.out"; _bug_file._fp = NULL;
// Initialize Register & Pipeline Form Pointers
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/c1/c1_IR.cpp
--- a/hotspot/src/share/vm/c1/c1_IR.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/c1/c1_IR.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -574,12 +574,23 @@
TRACE_LINEAR_SCAN(3, tty->print_cr("backward branch"));
assert(is_visited(cur), "block must be visisted when block is active");
assert(parent != NULL, "must have parent");
- assert(parent->number_of_sux() == 1, "loop end blocks must have one successor (critical edges are split)");
cur->set(BlockBegin::linear_scan_loop_header_flag);
cur->set(BlockBegin::backward_branch_target_flag);
parent->set(BlockBegin::linear_scan_loop_end_flag);
+
+ // When a loop header is also the start of an exception handler, then the backward branch is
+ // an exception edge. Because such edges are usually critical edges which cannot be split, the
+ // loop must be excluded here from processing.
+ if (cur->is_set(BlockBegin::exception_entry_flag)) {
+ // Make sure that dominators are correct in this weird situation
+ _iterative_dominators = true;
+ return;
+ }
+ assert(parent->number_of_sux() == 1 && parent->sux_at(0) == cur,
+ "loop end blocks must have one successor (critical edges are split)");
+
_loop_end_blocks.append(parent);
return;
}
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/ci/ciEnv.cpp
--- a/hotspot/src/share/vm/ci/ciEnv.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -484,11 +484,16 @@
} else if (tag.is_double()) {
return ciConstant((jdouble)cpool->double_at(index));
} else if (tag.is_string() || tag.is_unresolved_string()) {
- oop string = cpool->string_at(index, THREAD);
- if (HAS_PENDING_EXCEPTION) {
- CLEAR_PENDING_EXCEPTION;
- record_out_of_memory_failure();
- return ciConstant();
+ oop string = NULL;
+ if (cpool->is_pseudo_string_at(index)) {
+ string = cpool->pseudo_string_at(index);
+ } else {
+ string = cpool->string_at(index, THREAD);
+ if (HAS_PENDING_EXCEPTION) {
+ CLEAR_PENDING_EXCEPTION;
+ record_out_of_memory_failure();
+ return ciConstant();
+ }
}
ciObject* constant = get_object(string);
assert (constant->is_instance(), "must be an instance, or not? ");
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/classfile/classFileParser.cpp
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -168,11 +168,23 @@
// Got utf8 string, guarantee utf8_length+1 bytes, set stream position forward.
cfs->guarantee_more(utf8_length+1, CHECK); // utf8 string, tag/access_flags
cfs->skip_u1_fast(utf8_length);
+
// Before storing the symbol, make sure it's legal
if (_need_verify) {
verify_legal_utf8((unsigned char*)utf8_buffer, utf8_length, CHECK);
}
+ if (AnonymousClasses && has_cp_patch_at(index)) {
+ Handle patch = clear_cp_patch_at(index);
+ guarantee_property(java_lang_String::is_instance(patch()),
+ "Illegal utf8 patch at %d in class file %s",
+ index, CHECK);
+ char* str = java_lang_String::as_utf8_string(patch());
+ // (could use java_lang_String::as_symbol instead, but might as well batch them)
+ utf8_buffer = (u1*) str;
+ utf8_length = (int) strlen(str);
+ }
+
unsigned int hash;
symbolOop result = SymbolTable::lookup_only((char*)utf8_buffer, utf8_length, hash);
if (result == NULL) {
@@ -245,7 +257,7 @@
int klass_ref_index = cp->klass_ref_index_at(index);
int name_and_type_ref_index = cp->name_and_type_ref_index_at(index);
check_property(valid_cp_range(klass_ref_index, length) &&
- cp->tag_at(klass_ref_index).is_klass_reference(),
+ is_klass_reference(cp, klass_ref_index),
"Invalid constant pool index %u in class file %s",
klass_ref_index,
CHECK_(nullHandle));
@@ -326,16 +338,46 @@
} // end of switch
} // end of for
+ if (_cp_patches != NULL) {
+ // need to treat this_class specially...
+ assert(AnonymousClasses, "");
+ int this_class_index;
+ {
+ cfs->guarantee_more(8, CHECK_(nullHandle)); // flags, this_class, super_class, infs_len
+ u1* mark = cfs->current();
+ u2 flags = cfs->get_u2_fast();
+ this_class_index = cfs->get_u2_fast();
+ cfs->set_current(mark); // revert to mark
+ }
+
+ for (index = 1; index < length; index++) { // Index 0 is unused
+ if (has_cp_patch_at(index)) {
+ guarantee_property(index != this_class_index,
+ "Illegal constant pool patch to self at %d in class file %s",
+ index, CHECK_(nullHandle));
+ patch_constant_pool(cp, index, cp_patch_at(index), CHECK_(nullHandle));
+ }
+ }
+ // Ensure that all the patches have been used.
+ for (index = 0; index < _cp_patches->length(); index++) {
+ guarantee_property(!has_cp_patch_at(index),
+ "Unused constant pool patch at %d in class file %s",
+ index, CHECK_(nullHandle));
+ }
+ }
+
if (!_need_verify) {
return cp;
}
// second verification pass - checks the strings are of the right format.
+ // but not yet to the other entries
for (index = 1; index < length; index++) {
jbyte tag = cp->tag_at(index).value();
switch (tag) {
case JVM_CONSTANT_UnresolvedClass: {
symbolHandle class_name(THREAD, cp->unresolved_klass_at(index));
+ // check the name, even if _cp_patches will overwrite it
verify_legal_class_name(class_name, CHECK_(nullHandle));
break;
}
@@ -378,6 +420,73 @@
}
+void ClassFileParser::patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS) {
+ assert(AnonymousClasses, "");
+ BasicType patch_type = T_VOID;
+ switch (cp->tag_at(index).value()) {
+
+ case JVM_CONSTANT_UnresolvedClass :
+ // Patching a class means pre-resolving it.
+ // The name in the constant pool is ignored.
+ if (patch->klass() == SystemDictionary::class_klass()) { // %%% java_lang_Class::is_instance
+ guarantee_property(!java_lang_Class::is_primitive(patch()),
+ "Illegal class patch at %d in class file %s",
+ index, CHECK);
+ cp->klass_at_put(index, java_lang_Class::as_klassOop(patch()));
+ } else {
+ guarantee_property(java_lang_String::is_instance(patch()),
+ "Illegal class patch at %d in class file %s",
+ index, CHECK);
+ symbolHandle name = java_lang_String::as_symbol(patch(), CHECK);
+ cp->unresolved_klass_at_put(index, name());
+ }
+ break;
+
+ case JVM_CONSTANT_UnresolvedString :
+ // Patching a string means pre-resolving it.
+ // The spelling in the constant pool is ignored.
+ // The constant reference may be any object whatever.
+ // If it is not a real interned string, the constant is referred
+ // to as a "pseudo-string", and must be presented to the CP
+ // explicitly, because it may require scavenging.
+ cp->pseudo_string_at_put(index, patch());
+ break;
+
+ case JVM_CONSTANT_Integer : patch_type = T_INT; goto patch_prim;
+ case JVM_CONSTANT_Float : patch_type = T_FLOAT; goto patch_prim;
+ case JVM_CONSTANT_Long : patch_type = T_LONG; goto patch_prim;
+ case JVM_CONSTANT_Double : patch_type = T_DOUBLE; goto patch_prim;
+ patch_prim:
+ {
+ jvalue value;
+ BasicType value_type = java_lang_boxing_object::get_value(patch(), &value);
+ guarantee_property(value_type == patch_type,
+ "Illegal primitive patch at %d in class file %s",
+ index, CHECK);
+ switch (value_type) {
+ case T_INT: cp->int_at_put(index, value.i); break;
+ case T_FLOAT: cp->float_at_put(index, value.f); break;
+ case T_LONG: cp->long_at_put(index, value.j); break;
+ case T_DOUBLE: cp->double_at_put(index, value.d); break;
+ default: assert(false, "");
+ }
+ }
+ break;
+
+ default:
+ // %%% TODO: put method handles into CONSTANT_InterfaceMethodref, etc.
+ guarantee_property(!has_cp_patch_at(index),
+ "Illegal unexpected patch at %d in class file %s",
+ index, CHECK);
+ return;
+ }
+
+ // On fall-through, mark the patch as used.
+ clear_cp_patch_at(index);
+}
+
+
+
class NameSigHash: public ResourceObj {
public:
symbolOop _name; // name
@@ -448,25 +557,32 @@
int index;
for (index = 0; index < length; index++) {
u2 interface_index = cfs->get_u2(CHECK_(nullHandle));
+ KlassHandle interf;
check_property(
valid_cp_range(interface_index, cp->length()) &&
- cp->tag_at(interface_index).is_unresolved_klass(),
+ is_klass_reference(cp, interface_index),
"Interface name has bad constant pool index %u in class file %s",
interface_index, CHECK_(nullHandle));
- symbolHandle unresolved_klass (THREAD, cp->klass_name_at(interface_index));
-
- // Don't need to check legal name because it's checked when parsing constant pool.
- // But need to make sure it's not an array type.
- guarantee_property(unresolved_klass->byte_at(0) != JVM_SIGNATURE_ARRAY,
- "Bad interface name in class file %s", CHECK_(nullHandle));
-
- vmtimer->suspend(); // do not count recursive loading twice
- // Call resolve_super so classcircularity is checked
- klassOop k = SystemDictionary::resolve_super_or_fail(class_name,
- unresolved_klass, class_loader, protection_domain,
- false, CHECK_(nullHandle));
- KlassHandle interf (THREAD, k);
- vmtimer->resume();
+ if (cp->tag_at(interface_index).is_klass()) {
+ interf = KlassHandle(THREAD, cp->resolved_klass_at(interface_index));
+ } else {
+ symbolHandle unresolved_klass (THREAD, cp->klass_name_at(interface_index));
+
+ // Don't need to check legal name because it's checked when parsing constant pool.
+ // But need to make sure it's not an array type.
+ guarantee_property(unresolved_klass->byte_at(0) != JVM_SIGNATURE_ARRAY,
+ "Bad interface name in class file %s", CHECK_(nullHandle));
+
+ vmtimer->suspend(); // do not count recursive loading twice
+ // Call resolve_super so classcircularity is checked
+ klassOop k = SystemDictionary::resolve_super_or_fail(class_name,
+ unresolved_klass, class_loader, protection_domain,
+ false, CHECK_(nullHandle));
+ interf = KlassHandle(THREAD, k);
+ vmtimer->resume();
+
+ cp->klass_at_put(interface_index, interf()); // eagerly resolve
+ }
if (!Klass::cast(interf())->is_interface()) {
THROW_MSG_(vmSymbols::java_lang_IncompatibleClassChangeError(), "Implementing class", nullHandle);
@@ -877,8 +993,7 @@
"Illegal exception table handler in class file %s", CHECK_(nullHandle));
if (catch_type_index != 0) {
guarantee_property(valid_cp_range(catch_type_index, cp->length()) &&
- (cp->tag_at(catch_type_index).is_klass() ||
- cp->tag_at(catch_type_index).is_unresolved_klass()),
+ is_klass_reference(cp, catch_type_index),
"Catch type in exception table has bad constant type in class file %s", CHECK_(nullHandle));
}
}
@@ -1117,7 +1232,7 @@
} else if (tag == ITEM_Object) {
u2 class_index = u2_array[i2++] = cfs->get_u2(CHECK);
guarantee_property(valid_cp_range(class_index, cp->length()) &&
- cp->tag_at(class_index).is_unresolved_klass(),
+ is_klass_reference(cp, class_index),
"Bad class index %u in StackMap in class file %s",
class_index, CHECK);
} else if (tag == ITEM_Uninitialized) {
@@ -1183,7 +1298,7 @@
checked_exception = cfs->get_u2_fast();
check_property(
valid_cp_range(checked_exception, cp->length()) &&
- cp->tag_at(checked_exception).is_klass_reference(),
+ is_klass_reference(cp, checked_exception),
"Exception name has bad type at constant pool %u in class file %s",
checked_exception, CHECK_NULL);
}
@@ -1918,7 +2033,7 @@
check_property(
inner_class_info_index == 0 ||
(valid_cp_range(inner_class_info_index, cp_size) &&
- cp->tag_at(inner_class_info_index).is_klass_reference()),
+ is_klass_reference(cp, inner_class_info_index)),
"inner_class_info_index %u has bad constant type in class file %s",
inner_class_info_index, CHECK_0);
// Outer class index
@@ -1926,7 +2041,7 @@
check_property(
outer_class_info_index == 0 ||
(valid_cp_range(outer_class_info_index, cp_size) &&
- cp->tag_at(outer_class_info_index).is_klass_reference()),
+ is_klass_reference(cp, outer_class_info_index)),
"outer_class_info_index %u has bad constant type in class file %s",
outer_class_info_index, CHECK_0);
// Inner class name
@@ -2088,7 +2203,7 @@
}
// Validate the constant pool indices and types
if (!cp->is_within_bounds(class_index) ||
- !cp->tag_at(class_index).is_klass_reference()) {
+ !is_klass_reference(cp, class_index)) {
classfile_parse_error("Invalid or out-of-bounds class index in EnclosingMethod attribute in class file %s", CHECK);
}
if (method_index != 0 &&
@@ -2349,6 +2464,7 @@
instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
Handle class_loader,
Handle protection_domain,
+ GrowableArray* cp_patches,
symbolHandle& parsed_name,
TRAPS) {
// So that JVMTI can cache class file in the state before retransformable agents
@@ -2380,6 +2496,7 @@
}
}
+ _cp_patches = cp_patches;
instanceKlassHandle nullHandle;
@@ -2510,14 +2627,22 @@
CHECK_(nullHandle));
} else {
check_property(valid_cp_range(super_class_index, cp_size) &&
- cp->tag_at(super_class_index).is_unresolved_klass(),
+ is_klass_reference(cp, super_class_index),
"Invalid superclass index %u in class file %s",
super_class_index,
CHECK_(nullHandle));
// The class name should be legal because it is checked when parsing constant pool.
// However, make sure it is not an array type.
+ bool is_array = false;
+ if (cp->tag_at(super_class_index).is_klass()) {
+ super_klass = instanceKlassHandle(THREAD, cp->resolved_klass_at(super_class_index));
+ if (_need_verify)
+ is_array = super_klass->oop_is_array();
+ } else if (_need_verify) {
+ is_array = (cp->unresolved_klass_at(super_class_index)->byte_at(0) == JVM_SIGNATURE_ARRAY);
+ }
if (_need_verify) {
- guarantee_property(cp->unresolved_klass_at(super_class_index)->byte_at(0) != JVM_SIGNATURE_ARRAY,
+ guarantee_property(!is_array,
"Bad superclass name in class file %s", CHECK_(nullHandle));
}
}
@@ -2557,7 +2682,7 @@
objArrayHandle methods_default_annotations(THREAD, methods_default_annotations_oop);
// We check super class after class file is parsed and format is checked
- if (super_class_index > 0) {
+ if (super_class_index > 0 && super_klass.is_null()) {
symbolHandle sk (THREAD, cp->klass_name_at(super_class_index));
if (access_flags.is_interface()) {
// Before attempting to resolve the superclass, check for class format
@@ -2574,6 +2699,9 @@
CHECK_(nullHandle));
KlassHandle kh (THREAD, k);
super_klass = instanceKlassHandle(THREAD, kh());
+ cp->klass_at_put(super_class_index, super_klass()); // eagerly resolve
+ }
+ if (super_klass.not_null()) {
if (super_klass->is_interface()) {
ResourceMark rm(THREAD);
Exceptions::fthrow(
@@ -3000,6 +3128,7 @@
this_klass->set_method_ordering(method_ordering());
this_klass->set_initial_method_idnum(methods->length());
this_klass->set_name(cp->klass_name_at(this_class_index));
+ cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve
this_klass->set_protection_domain(protection_domain());
this_klass->set_fields_annotations(fields_annotations());
this_klass->set_methods_annotations(methods_annotations());
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/classfile/classFileParser.hpp
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp Wed Jul 05 16:44:09 2017 +0200
@@ -33,6 +33,7 @@
u2 _major_version;
u2 _minor_version;
symbolHandle _class_name;
+ GrowableArray* _cp_patches; // overrides for CP entries
bool _has_finalizer;
bool _has_empty_finalizer;
@@ -203,6 +204,35 @@
char* skip_over_field_name(char* name, bool slash_ok, unsigned int length);
char* skip_over_field_signature(char* signature, bool void_ok, unsigned int length, TRAPS);
+ bool has_cp_patch_at(int index) {
+ assert(AnonymousClasses, "");
+ assert(index >= 0, "oob");
+ return (_cp_patches != NULL
+ && index < _cp_patches->length()
+ && _cp_patches->adr_at(index)->not_null());
+ }
+ Handle cp_patch_at(int index) {
+ assert(has_cp_patch_at(index), "oob");
+ return _cp_patches->at(index);
+ }
+ Handle clear_cp_patch_at(int index) {
+ Handle patch = cp_patch_at(index);
+ _cp_patches->at_put(index, Handle());
+ assert(!has_cp_patch_at(index), "");
+ return patch;
+ }
+ void patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS);
+
+ // Wrapper for constantTag.is_klass_[or_]reference.
+ // In older versions of the VM, klassOops cannot sneak into early phases of
+ // constant pool construction, but in later versions they can.
+ // %%% Let's phase out the old is_klass_reference.
+ bool is_klass_reference(constantPoolHandle cp, int index) {
+ return ((LinkWellKnownClasses || AnonymousClasses)
+ ? cp->tag_at(index).is_klass_or_reference()
+ : cp->tag_at(index).is_klass_reference());
+ }
+
public:
// Constructor
ClassFileParser(ClassFileStream* st) { set_stream(st); }
@@ -218,6 +248,14 @@
Handle class_loader,
Handle protection_domain,
symbolHandle& parsed_name,
+ TRAPS) {
+ return parseClassFile(name, class_loader, protection_domain, NULL, parsed_name, THREAD);
+ }
+ instanceKlassHandle parseClassFile(symbolHandle name,
+ Handle class_loader,
+ Handle protection_domain,
+ GrowableArray* cp_patches,
+ symbolHandle& parsed_name,
TRAPS);
// Verifier checks
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/classfile/systemDictionary.cpp
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -937,6 +937,8 @@
Handle class_loader,
Handle protection_domain,
ClassFileStream* st,
+ KlassHandle host_klass,
+ GrowableArray* cp_patches,
TRAPS) {
symbolHandle parsed_name;
@@ -953,10 +955,10 @@
instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,
class_loader,
protection_domain,
+ cp_patches,
parsed_name,
THREAD);
-
// We don't redefine the class, so we just need to clean up whether there
// was an error or not (don't want to modify any system dictionary
// data structures).
@@ -973,6 +975,30 @@
}
}
+ if (host_klass.not_null() && k.not_null()) {
+ assert(AnonymousClasses, "");
+ // If it's anonymous, initialize it now, since nobody else will.
+ k->set_host_klass(host_klass());
+
+ {
+ MutexLocker mu_r(Compile_lock, THREAD);
+
+ // Add to class hierarchy, initialize vtables, and do possible
+ // deoptimizations.
+ add_to_hierarchy(k, CHECK_NULL); // No exception, but can block
+
+ // But, do not add to system dictionary.
+ }
+
+ k->eager_initialize(THREAD);
+
+ // notify jvmti
+ if (JvmtiExport::should_post_class_load()) {
+ assert(THREAD->is_Java_thread(), "thread->is_Java_thread()");
+ JvmtiExport::post_class_load((JavaThread *) THREAD, k());
+ }
+ }
+
return k();
}
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/classfile/systemDictionary.hpp
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Wed Jul 05 16:44:09 2017 +0200
@@ -228,6 +228,16 @@
Handle class_loader,
Handle protection_domain,
ClassFileStream* st,
+ TRAPS) {
+ KlassHandle nullHandle;
+ return parse_stream(class_name, class_loader, protection_domain, st, nullHandle, NULL, THREAD);
+ }
+ static klassOop parse_stream(symbolHandle class_name,
+ Handle class_loader,
+ Handle protection_domain,
+ ClassFileStream* st,
+ KlassHandle host_klass,
+ GrowableArray* cp_patches,
TRAPS);
// Resolve from stream (called by jni_DefineClass and JVM_DefineClass)
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/classfile/verifier.cpp
--- a/hotspot/src/share/vm/classfile/verifier.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/classfile/verifier.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -1600,7 +1600,11 @@
types = (1 << JVM_CONSTANT_Double) | (1 << JVM_CONSTANT_Long);
verify_cp_type(index, cp, types, CHECK_VERIFY(this));
}
- if (tag.is_string() || tag.is_unresolved_string()) {
+ if (tag.is_string() && cp->is_pseudo_string_at(index)) {
+ current_frame->push_stack(
+ VerificationType::reference_type(
+ vmSymbols::java_lang_Object()), CHECK_VERIFY(this));
+ } else if (tag.is_string() || tag.is_unresolved_string()) {
current_frame->push_stack(
VerificationType::reference_type(
vmSymbols::java_lang_String()), CHECK_VERIFY(this));
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.cpp
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.cpp Wed Jul 05 16:43:43 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,314 +0,0 @@
-/*
- * Copyright 2001-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.
- *
- */
-
-// CopyrightVersion 1.2
-
-# include "incls/_precompiled.incl"
-# include "incls/_concurrentGCThread.cpp.incl"
-
-bool ConcurrentGCThread::_should_terminate = false;
-bool ConcurrentGCThread::_has_terminated = false;
-int ConcurrentGCThread::_CGC_flag = CGC_nil;
-
-SuspendibleThreadSet ConcurrentGCThread::_sts;
-
-ConcurrentGCThread::ConcurrentGCThread() {
- _sts.initialize();
-};
-
-void ConcurrentGCThread::stopWorldAndDo(VoidClosure* op) {
- MutexLockerEx x(Heap_lock,
- Mutex::_no_safepoint_check_flag);
- // warning("CGC: about to try stopping world");
- SafepointSynchronize::begin();
- // warning("CGC: successfully stopped world");
- op->do_void();
- SafepointSynchronize::end();
- // warning("CGC: successfully restarted world");
-}
-
-void ConcurrentGCThread::safepoint_synchronize() {
- _sts.suspend_all();
-}
-
-void ConcurrentGCThread::safepoint_desynchronize() {
- _sts.resume_all();
-}
-
-void ConcurrentGCThread::create_and_start() {
- if (os::create_thread(this, os::cgc_thread)) {
- // XXX: need to set this to low priority
- // unless "agressive mode" set; priority
- // should be just less than that of VMThread.
- os::set_priority(this, NearMaxPriority);
- if (!_should_terminate && !DisableStartThread) {
- os::start_thread(this);
- }
- }
-}
-
-void ConcurrentGCThread::initialize_in_thread() {
- this->record_stack_base_and_size();
- this->initialize_thread_local_storage();
- this->set_active_handles(JNIHandleBlock::allocate_block());
- // From this time Thread::current() should be working.
- assert(this == Thread::current(), "just checking");
-}
-
-void ConcurrentGCThread::wait_for_universe_init() {
- MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
- while (!is_init_completed() && !_should_terminate) {
- CGC_lock->wait(Mutex::_no_safepoint_check_flag, 200);
- }
-}
-
-void ConcurrentGCThread::terminate() {
- // Signal that it is terminated
- {
- MutexLockerEx mu(Terminator_lock,
- Mutex::_no_safepoint_check_flag);
- _has_terminated = true;
- Terminator_lock->notify();
- }
-
- // Thread destructor usually does this..
- ThreadLocalStorage::set_thread(NULL);
-}
-
-
-void SuspendibleThreadSet::initialize_work() {
- MutexLocker x(STS_init_lock);
- if (!_initialized) {
- _m = new Monitor(Mutex::leaf,
- "SuspendibleThreadSetLock", true);
- _async = 0;
- _async_stop = false;
- _async_stopped = 0;
- _initialized = true;
- }
-}
-
-void SuspendibleThreadSet::join() {
- initialize();
- MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
- while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag);
- _async++;
- assert(_async > 0, "Huh.");
-}
-
-void SuspendibleThreadSet::leave() {
- assert(_initialized, "Must be initialized.");
- MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
- _async--;
- assert(_async >= 0, "Huh.");
- if (_async_stop) _m->notify_all();
-}
-
-void SuspendibleThreadSet::yield(const char* id) {
- assert(_initialized, "Must be initialized.");
- if (_async_stop) {
- MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
- if (_async_stop) {
- _async_stopped++;
- assert(_async_stopped > 0, "Huh.");
- if (_async_stopped == _async) {
- if (ConcGCYieldTimeout > 0) {
- double now = os::elapsedTime();
- guarantee((now - _suspend_all_start) * 1000.0 <
- (double)ConcGCYieldTimeout,
- "Long delay; whodunit?");
- }
- }
- _m->notify_all();
- while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag);
- _async_stopped--;
- assert(_async >= 0, "Huh");
- _m->notify_all();
- }
- }
-}
-
-void SuspendibleThreadSet::suspend_all() {
- initialize(); // If necessary.
- if (ConcGCYieldTimeout > 0) {
- _suspend_all_start = os::elapsedTime();
- }
- MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
- assert(!_async_stop, "Only one at a time.");
- _async_stop = true;
- while (_async_stopped < _async) _m->wait(Mutex::_no_safepoint_check_flag);
-}
-
-void SuspendibleThreadSet::resume_all() {
- assert(_initialized, "Must be initialized.");
- MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
- assert(_async_stopped == _async, "Huh.");
- _async_stop = false;
- _m->notify_all();
-}
-
-static void _sltLoop(JavaThread* thread, TRAPS) {
- SurrogateLockerThread* slt = (SurrogateLockerThread*)thread;
- slt->loop();
-}
-
-SurrogateLockerThread::SurrogateLockerThread() :
- JavaThread(&_sltLoop),
- _monitor(Mutex::nonleaf, "SLTMonitor"),
- _buffer(empty)
-{}
-
-SurrogateLockerThread* SurrogateLockerThread::make(TRAPS) {
- klassOop k =
- SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_Thread(),
- true, CHECK_NULL);
- instanceKlassHandle klass (THREAD, k);
- instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL);
-
- const char thread_name[] = "Surrogate Locker Thread (CMS)";
- Handle string = java_lang_String::create_from_str(thread_name, CHECK_NULL);
-
- // Initialize thread_oop to put it into the system threadGroup
- Handle thread_group (THREAD, Universe::system_thread_group());
- JavaValue result(T_VOID);
- JavaCalls::call_special(&result, thread_oop,
- klass,
- vmSymbolHandles::object_initializer_name(),
- vmSymbolHandles::threadgroup_string_void_signature(),
- thread_group,
- string,
- CHECK_NULL);
-
- SurrogateLockerThread* res;
- {
- MutexLocker mu(Threads_lock);
- res = new SurrogateLockerThread();
-
- // At this point it may be possible that no osthread was created for the
- // JavaThread due to lack of memory. We would have to throw an exception
- // in that case. However, since this must work and we do not allow
- // exceptions anyway, check and abort if this fails.
- if (res == NULL || res->osthread() == NULL) {
- vm_exit_during_initialization("java.lang.OutOfMemoryError",
- "unable to create new native thread");
- }
- java_lang_Thread::set_thread(thread_oop(), res);
- java_lang_Thread::set_priority(thread_oop(), NearMaxPriority);
- java_lang_Thread::set_daemon(thread_oop());
-
- res->set_threadObj(thread_oop());
- Threads::add(res);
- Thread::start(res);
- }
- os::yield(); // This seems to help with initial start-up of SLT
- return res;
-}
-
-void SurrogateLockerThread::manipulatePLL(SLT_msg_type msg) {
- MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
- assert(_buffer == empty, "Should be empty");
- assert(msg != empty, "empty message");
- _buffer = msg;
- while (_buffer != empty) {
- _monitor.notify();
- _monitor.wait(Mutex::_no_safepoint_check_flag);
- }
-}
-
-// ======= Surrogate Locker Thread =============
-
-void SurrogateLockerThread::loop() {
- BasicLock pll_basic_lock;
- SLT_msg_type msg;
- debug_only(unsigned int owned = 0;)
-
- while (/* !isTerminated() */ 1) {
- {
- MutexLocker x(&_monitor);
- // Since we are a JavaThread, we can't be here at a safepoint.
- assert(!SafepointSynchronize::is_at_safepoint(),
- "SLT is a JavaThread");
- // wait for msg buffer to become non-empty
- while (_buffer == empty) {
- _monitor.notify();
- _monitor.wait();
- }
- msg = _buffer;
- }
- switch(msg) {
- case acquirePLL: {
- instanceRefKlass::acquire_pending_list_lock(&pll_basic_lock);
- debug_only(owned++;)
- break;
- }
- case releaseAndNotifyPLL: {
- assert(owned > 0, "Don't have PLL");
- instanceRefKlass::release_and_notify_pending_list_lock(&pll_basic_lock);
- debug_only(owned--;)
- break;
- }
- case empty:
- default: {
- guarantee(false,"Unexpected message in _buffer");
- break;
- }
- }
- {
- MutexLocker x(&_monitor);
- // Since we are a JavaThread, we can't be here at a safepoint.
- assert(!SafepointSynchronize::is_at_safepoint(),
- "SLT is a JavaThread");
- _buffer = empty;
- _monitor.notify();
- }
- }
- assert(!_monitor.owned_by_self(), "Should unlock before exit.");
-}
-
-
-// ===== STS Access From Outside CGCT =====
-
-void ConcurrentGCThread::stsYield(const char* id) {
- assert( Thread::current()->is_ConcurrentGC_thread(),
- "only a conc GC thread can call this" );
- _sts.yield(id);
-}
-
-bool ConcurrentGCThread::stsShouldYield() {
- assert( Thread::current()->is_ConcurrentGC_thread(),
- "only a conc GC thread can call this" );
- return _sts.should_yield();
-}
-
-void ConcurrentGCThread::stsJoin() {
- assert( Thread::current()->is_ConcurrentGC_thread(),
- "only a conc GC thread can call this" );
- _sts.join();
-}
-
-void ConcurrentGCThread::stsLeave() {
- assert( Thread::current()->is_ConcurrentGC_thread(),
- "only a conc GC thread can call this" );
- _sts.leave();
-}
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.hpp
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.hpp Wed Jul 05 16:43:43 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,167 +0,0 @@
-/*
- * Copyright 2001-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.
- *
- */
-
-class VoidClosure;
-
-// A SuspendibleThreadSet is (obviously) a set of threads that can be
-// suspended. A thread can join and later leave the set, and periodically
-// yield. If some thread (not in the set) requests, via suspend_all, that
-// the threads be suspended, then the requesting thread is blocked until
-// all the threads in the set have yielded or left the set. (Threads may
-// not enter the set when an attempted suspension is in progress.) The
-// suspending thread later calls resume_all, allowing the suspended threads
-// to continue.
-
-class SuspendibleThreadSet {
- Monitor* _m;
- int _async;
- bool _async_stop;
- int _async_stopped;
- bool _initialized;
- double _suspend_all_start;
-
- void initialize_work();
-
- public:
- SuspendibleThreadSet() : _initialized(false) {}
-
- // Add the current thread to the set. May block if a suspension
- // is in progress.
- void join();
- // Removes the current thread from the set.
- void leave();
- // Returns "true" iff an suspension is in progress.
- bool should_yield() { return _async_stop; }
- // Suspends the current thread if a suspension is in progress (for
- // the duration of the suspension.)
- void yield(const char* id);
- // Return when all threads in the set are suspended.
- void suspend_all();
- // Allow suspended threads to resume.
- void resume_all();
- // Redundant initializations okay.
- void initialize() {
- // Double-check dirty read idiom.
- if (!_initialized) initialize_work();
- }
-};
-
-
-class ConcurrentGCThread: public NamedThread {
- friend class VMStructs;
-
-protected:
- static bool _should_terminate;
- static bool _has_terminated;
-
- enum CGC_flag_type {
- CGC_nil = 0x0,
- CGC_dont_suspend = 0x1,
- CGC_CGC_safepoint = 0x2,
- CGC_VM_safepoint = 0x4
- };
-
- static int _CGC_flag;
-
- static bool CGC_flag_is_set(int b) { return (_CGC_flag & b) != 0; }
- static int set_CGC_flag(int b) { return _CGC_flag |= b; }
- static int reset_CGC_flag(int b) { return _CGC_flag &= ~b; }
-
- void stopWorldAndDo(VoidClosure* op);
-
- // All instances share this one set.
- static SuspendibleThreadSet _sts;
-
- // Create and start the thread (setting it's priority high.)
- void create_and_start();
-
- // Do initialization steps in the thread: record stack base and size,
- // init thread local storage, set JNI handle block.
- void initialize_in_thread();
-
- // Wait until Universe::is_fully_initialized();
- void wait_for_universe_init();
-
- // Record that the current thread is terminating, and will do more
- // concurrent work.
- void terminate();
-
-public:
- // Constructor
-
- ConcurrentGCThread();
- ~ConcurrentGCThread() {} // Exists to call NamedThread destructor.
-
- // Tester
- bool is_ConcurrentGC_thread() const { return true; }
-
- static void safepoint_synchronize();
- static void safepoint_desynchronize();
-
- // All overridings should probably do _sts::yield, but we allow
- // overriding for distinguished debugging messages. Default is to do
- // nothing.
- virtual void yield() {}
-
- bool should_yield() { return _sts.should_yield(); }
-
- // they are prefixed by sts since there are already yield() and
- // should_yield() (non-static) methods in this class and it was an
- // easy way to differentiate them.
- static void stsYield(const char* id);
- static bool stsShouldYield();
- static void stsJoin();
- static void stsLeave();
-
-};
-
-// The SurrogateLockerThread is used by concurrent GC threads for
-// manipulating Java monitors, in particular, currently for
-// manipulating the pending_list_lock. XXX
-class SurrogateLockerThread: public JavaThread {
- friend class VMStructs;
- public:
- enum SLT_msg_type {
- empty = 0, // no message
- acquirePLL, // acquire pending list lock
- releaseAndNotifyPLL // notify and release pending list lock
- };
- private:
- // the following are shared with the CMSThread
- SLT_msg_type _buffer; // communication buffer
- Monitor _monitor; // monitor controlling buffer
- BasicLock _basicLock; // used for PLL locking
-
- public:
- static SurrogateLockerThread* make(TRAPS);
-
- SurrogateLockerThread();
-
- bool is_hidden_from_external_view() const { return true; }
-
- void loop(); // main method
-
- void manipulatePLL(SLT_msg_type msg);
-
-};
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp
--- a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -30,7 +30,7 @@
_perm(perm), _lock(NULL)
{}
-PtrQueue::~PtrQueue() {
+void PtrQueue::flush() {
if (!_perm && _buf != NULL) {
if (_index == _sz) {
// No work to do.
@@ -41,8 +41,9 @@
_buf[byte_index_to_index((int)i)] = NULL;
}
qset()->enqueue_complete_buffer(_buf);
- _buf = NULL;
}
+ _buf = NULL;
+ _index = 0;
}
}
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp
--- a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp Wed Jul 05 16:44:09 2017 +0200
@@ -62,7 +62,9 @@
// given PtrQueueSet.
PtrQueue(PtrQueueSet*, bool perm = false);
// Release any contained resources.
- ~PtrQueue();
+ void flush();
+ // Calls flush() when destroyed.
+ ~PtrQueue() { flush(); }
// Associate a lock with a ptr queue.
void set_lock(Mutex* lock) { _lock = lock; }
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -90,10 +90,10 @@
*/
bool skip_dead = ((PSMarkSweep::total_invocations() % MarkSweepAlwaysCompactCount) != 0);
- ssize_t allowed_deadspace = 0;
+ size_t allowed_deadspace = 0;
if (skip_dead) {
- int ratio = allowed_dead_ratio();
- allowed_deadspace = (space()->capacity_in_bytes() * ratio / 100) / HeapWordSize;
+ const size_t ratio = allowed_dead_ratio();
+ allowed_deadspace = space()->capacity_in_words() * ratio / 100;
}
// Fetch the current destination decorator
@@ -271,10 +271,10 @@
dest->set_compaction_top(compact_top);
}
-bool PSMarkSweepDecorator::insert_deadspace(ssize_t& allowed_deadspace_words,
- HeapWord* q, size_t deadlength) {
- allowed_deadspace_words -= deadlength;
- if (allowed_deadspace_words >= 0) {
+bool PSMarkSweepDecorator::insert_deadspace(size_t& allowed_deadspace_words,
+ HeapWord* q, size_t deadlength) {
+ if (allowed_deadspace_words >= deadlength) {
+ allowed_deadspace_words -= deadlength;
oop(q)->set_mark(markOopDesc::prototype()->set_marked());
const size_t aligned_min_int_array_size =
align_object_size(typeArrayOopDesc::header_size(T_INT));
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp Wed Jul 05 16:44:09 2017 +0200
@@ -39,14 +39,16 @@
HeapWord* _first_dead;
HeapWord* _end_of_live;
HeapWord* _compaction_top;
- unsigned int _allowed_dead_ratio;
+ size_t _allowed_dead_ratio;
- bool insert_deadspace(ssize_t& allowed_deadspace_words, HeapWord* q, size_t word_len);
+ bool insert_deadspace(size_t& allowed_deadspace_words, HeapWord* q,
+ size_t word_len);
public:
PSMarkSweepDecorator(MutableSpace* space, ObjectStartArray* start_array,
- unsigned int allowed_dead_ratio) :
- _space(space), _start_array(start_array), _allowed_dead_ratio(allowed_dead_ratio) { }
+ size_t allowed_dead_ratio) :
+ _space(space), _start_array(start_array),
+ _allowed_dead_ratio(allowed_dead_ratio) { }
// During a compacting collection, we need to collapse objects into
// spaces in a given order. We want to fill space A, space B, and so
@@ -57,14 +59,14 @@
static PSMarkSweepDecorator* destination_decorator();
// Accessors
- MutableSpace* space() { return _space; }
- ObjectStartArray* start_array() { return _start_array; }
+ MutableSpace* space() { return _space; }
+ ObjectStartArray* start_array() { return _start_array; }
- HeapWord* compaction_top() { return _compaction_top; }
- void set_compaction_top(HeapWord* value) { _compaction_top = value; }
+ HeapWord* compaction_top() { return _compaction_top; }
+ void set_compaction_top(HeapWord* value) { _compaction_top = value; }
- unsigned int allowed_dead_ratio() { return _allowed_dead_ratio; }
- void set_allowed_dead_ratio(unsigned int value) { _allowed_dead_ratio = value; }
+ size_t allowed_dead_ratio() { return _allowed_dead_ratio; }
+ void set_allowed_dead_ratio(size_t value) { _allowed_dead_ratio = value; }
// Work methods
void adjust_pointers();
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/includeDB_gc_parallel
--- a/hotspot/src/share/vm/includeDB_gc_parallel Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/includeDB_gc_parallel Wed Jul 05 16:44:09 2017 +0200
@@ -30,6 +30,12 @@
compiledICHolderKlass.cpp oop.pcgc.inline.hpp
+constantPoolKlass.cpp cardTableRS.hpp
+constantPoolKlass.cpp oop.pcgc.inline.hpp
+constantPoolKlass.cpp psPromotionManager.inline.hpp
+constantPoolKlass.cpp psScavenge.inline.hpp
+constantPoolKlass.cpp parOopClosures.inline.hpp
+
genCollectedHeap.cpp concurrentMarkSweepThread.hpp
genCollectedHeap.cpp vmCMSOperations.hpp
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/memory/space.cpp
--- a/hotspot/src/share/vm/memory/space.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/memory/space.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -997,11 +997,11 @@
}
-int TenuredSpace::allowed_dead_ratio() const {
+size_t TenuredSpace::allowed_dead_ratio() const {
return MarkSweepDeadRatio;
}
-int ContigPermSpace::allowed_dead_ratio() const {
+size_t ContigPermSpace::allowed_dead_ratio() const {
return PermMarkSweepDeadRatio;
}
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/memory/space.hpp
--- a/hotspot/src/share/vm/memory/space.hpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/memory/space.hpp Wed Jul 05 16:44:09 2017 +0200
@@ -421,7 +421,7 @@
// The maximum percentage of objects that can be dead in the compacted
// live part of a compacted space ("deadwood" support.)
- virtual int allowed_dead_ratio() const { return 0; };
+ virtual size_t allowed_dead_ratio() const { return 0; };
// Some contiguous spaces may maintain some data structures that should
// be updated whenever an allocation crosses a boundary. This function
@@ -507,7 +507,7 @@
\
size_t allowed_deadspace = 0; \
if (skip_dead) { \
- int ratio = allowed_dead_ratio(); \
+ const size_t ratio = allowed_dead_ratio(); \
allowed_deadspace = (capacity() * ratio / 100) / HeapWordSize; \
} \
\
@@ -1079,7 +1079,7 @@
friend class VMStructs;
protected:
// Mark sweep support
- int allowed_dead_ratio() const;
+ size_t allowed_dead_ratio() const;
public:
// Constructor
TenuredSpace(BlockOffsetSharedArray* sharedOffsetArray,
@@ -1094,7 +1094,7 @@
friend class VMStructs;
protected:
// Mark sweep support
- int allowed_dead_ratio() const;
+ size_t allowed_dead_ratio() const;
public:
// Constructor
ContigPermSpace(BlockOffsetSharedArray* sharedOffsetArray, MemRegion mr) :
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/memory/tenuredGeneration.hpp
--- a/hotspot/src/share/vm/memory/tenuredGeneration.hpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/memory/tenuredGeneration.hpp Wed Jul 05 16:44:09 2017 +0200
@@ -73,7 +73,6 @@
// Mark sweep support
void compute_new_size();
- int allowed_dead_ratio() const;
virtual void gc_prologue(bool full);
virtual void gc_epilogue(bool full);
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/oops/constantPoolKlass.cpp
--- a/hotspot/src/share/vm/oops/constantPoolKlass.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/oops/constantPoolKlass.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -35,6 +35,7 @@
c->set_tags(NULL);
c->set_cache(NULL);
c->set_pool_holder(NULL);
+ c->set_flags(0);
// only set to non-zero if constant pool is merged by RedefineClasses
c->set_orig_length(0);
// all fields are initialized; needed for GC
@@ -261,10 +262,32 @@
void constantPoolKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) {
assert(obj->is_constantPool(), "should be constant pool");
+ constantPoolOop cp = (constantPoolOop) obj;
+ if (AnonymousClasses && cp->has_pseudo_string() && cp->tags() != NULL) {
+ oop* base = (oop*)cp->base();
+ for (int i = 0; i < cp->length(); ++i, ++base) {
+ if (cp->tag_at(i).is_string()) {
+ if (PSScavenge::should_scavenge(base)) {
+ pm->claim_or_forward_breadth(base);
+ }
+ }
+ }
+ }
}
void constantPoolKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
assert(obj->is_constantPool(), "should be constant pool");
+ constantPoolOop cp = (constantPoolOop) obj;
+ if (AnonymousClasses && cp->has_pseudo_string() && cp->tags() != NULL) {
+ oop* base = (oop*)cp->base();
+ for (int i = 0; i < cp->length(); ++i, ++base) {
+ if (cp->tag_at(i).is_string()) {
+ if (PSScavenge::should_scavenge(base)) {
+ pm->claim_or_forward_depth(base);
+ }
+ }
+ }
+ }
}
#endif // SERIALGC
@@ -278,6 +301,11 @@
assert(obj->is_constantPool(), "must be constantPool");
Klass::oop_print_on(obj, st);
constantPoolOop cp = constantPoolOop(obj);
+ if (cp->flags() != 0) {
+ st->print(" - flags : 0x%x", cp->flags());
+ if (cp->has_pseudo_string()) st->print(" has_pseudo_string");
+ st->cr();
+ }
// Temp. remove cache so we can do lookups with original indicies.
constantPoolCacheHandle cache (THREAD, cp->cache());
@@ -302,7 +330,11 @@
break;
case JVM_CONSTANT_UnresolvedString :
case JVM_CONSTANT_String :
- anObj = cp->string_at(index, CATCH);
+ if (cp->is_pseudo_string_at(index)) {
+ anObj = cp->pseudo_string_at(index);
+ } else {
+ anObj = cp->string_at(index, CATCH);
+ }
anObj->print_value_on(st);
st->print(" {0x%lx}", (address)anObj);
break;
@@ -382,8 +414,12 @@
"should be symbol or instance");
}
if (cp->tag_at(i).is_string()) {
- guarantee((*base)->is_perm(), "should be in permspace");
- guarantee((*base)->is_instance(), "should be instance");
+ if (!cp->has_pseudo_string()) {
+ guarantee((*base)->is_perm(), "should be in permspace");
+ guarantee((*base)->is_instance(), "should be instance");
+ } else {
+ // can be non-perm, can be non-instance (array)
+ }
}
base++;
}
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/oops/constantPoolOop.cpp
--- a/hotspot/src/share/vm/oops/constantPoolOop.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/oops/constantPoolOop.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -25,6 +25,18 @@
# include "incls/_precompiled.incl"
# include "incls/_constantPoolOop.cpp.incl"
+void constantPoolOopDesc::set_flag_at(FlagBit fb) {
+ const int MAX_STATE_CHANGES = 2;
+ for (int i = MAX_STATE_CHANGES + 10; i > 0; i--) {
+ int oflags = _flags;
+ int nflags = oflags | (1 << (int)fb);
+ if (Atomic::cmpxchg(nflags, &_flags, oflags) == oflags)
+ return;
+ }
+ assert(false, "failed to cmpxchg flags");
+ _flags |= (1 << (int)fb); // better than nothing
+}
+
klassOop constantPoolOopDesc::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS) {
// A resolved constantPool entry will contain a klassOop, otherwise a symbolOop.
// It is not safe to rely on the tag bit's here, since we don't have a lock, and the entry and
@@ -333,8 +345,10 @@
oop entry = *(obj_at_addr(which));
if (entry->is_symbol()) {
return ((symbolOop)entry)->as_C_string();
+ } else if (java_lang_String::is_instance(entry)) {
+ return java_lang_String::as_utf8_string(entry);
} else {
- return java_lang_String::as_utf8_string(entry);
+ return (char*)"";
}
}
@@ -385,6 +399,19 @@
}
+bool constantPoolOopDesc::is_pseudo_string_at(int which) {
+ oop entry = *(obj_at_addr(which));
+ if (entry->is_symbol())
+ // Not yet resolved, but it will resolve to a string.
+ return false;
+ else if (java_lang_String::is_instance(entry))
+ return false; // actually, it might be a non-interned or non-perm string
+ else
+ // truly pseudo
+ return true;
+}
+
+
bool constantPoolOopDesc::klass_name_at_matches(instanceKlassHandle k,
int which) {
// Names are interned, so we can compare symbolOops directly
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/oops/constantPoolOop.hpp
--- a/hotspot/src/share/vm/oops/constantPoolOop.hpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/oops/constantPoolOop.hpp Wed Jul 05 16:44:09 2017 +0200
@@ -41,6 +41,7 @@
typeArrayOop _tags; // the tag array describing the constant pool's contents
constantPoolCacheOop _cache; // the cache holding interpreter runtime information
klassOop _pool_holder; // the corresponding class
+ int _flags; // a few header bits to describe contents for GC
int _length; // number of elements in the array
// only set to non-zero if constant pool is merged by RedefineClasses
int _orig_length;
@@ -49,6 +50,16 @@
void tag_at_put(int which, jbyte t) { tags()->byte_at_put(which, t); }
void release_tag_at_put(int which, jbyte t) { tags()->release_byte_at_put(which, t); }
+ enum FlagBit {
+ FB_has_pseudo_string = 2
+ };
+
+ int flags() const { return _flags; }
+ void set_flags(int f) { _flags = f; }
+ bool flag_at(FlagBit fb) const { return (_flags & (1 << (int)fb)) != 0; }
+ void set_flag_at(FlagBit fb);
+ // no clear_flag_at function; they only increase
+
private:
intptr_t* base() const { return (intptr_t*) (((char*) this) + sizeof(constantPoolOopDesc)); }
oop* tags_addr() { return (oop*)&_tags; }
@@ -82,6 +93,9 @@
public:
typeArrayOop tags() const { return _tags; }
+ bool has_pseudo_string() const { return flag_at(FB_has_pseudo_string); }
+ void set_pseudo_string() { set_flag_at(FB_has_pseudo_string); }
+
// Klass holding pool
klassOop pool_holder() const { return _pool_holder; }
void set_pool_holder(klassOop k) { oop_store_without_check((oop*)&_pool_holder, (oop) k); }
@@ -272,6 +286,27 @@
return string_at_impl(h_this, which, CHECK_NULL);
}
+ // A "pseudo-string" is an non-string oop that has found is way into
+ // a String entry.
+ // Under AnonymousClasses this can happen if the user patches a live
+ // object into a CONSTANT_String entry of an anonymous class.
+ // Method oops internally created for method handles may also
+ // use pseudo-strings to link themselves to related metaobjects.
+
+ bool is_pseudo_string_at(int which);
+
+ oop pseudo_string_at(int which) {
+ assert(tag_at(which).is_string(), "Corrupted constant pool");
+ return *obj_at_addr(which);
+ }
+
+ void pseudo_string_at_put(int which, oop x) {
+ assert(AnonymousClasses, "");
+ set_pseudo_string(); // mark header
+ assert(tag_at(which).is_string() || tag_at(which).is_unresolved_string(), "Corrupted constant pool");
+ string_at_put(which, x); // this works just fine
+ }
+
// only called when we are sure a string entry is already resolved (via an
// earlier string_at call.
oop resolved_string_at(int which) {
@@ -293,6 +328,7 @@
// UTF8 char* representation was chosen to avoid conversion of
// java_lang_Strings at resolved entries into symbolOops
// or vice versa.
+ // Caller is responsible for checking for pseudo-strings.
char* string_at_noresolve(int which);
jint name_and_type_at(int which) {
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/oops/instanceKlass.hpp
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Wed Jul 05 16:44:09 2017 +0200
@@ -147,6 +147,10 @@
oop _class_loader;
// Protection domain.
oop _protection_domain;
+ // Host class, which grants its access privileges to this class also.
+ // This is only non-null for an anonymous class (AnonymousClasses enabled).
+ // The host class is either named, or a previously loaded anonymous class.
+ klassOop _host_klass;
// Class signers.
objArrayOop _signers;
// Name of source file containing this klass, NULL if not specified.
@@ -375,6 +379,11 @@
oop protection_domain() { return _protection_domain; }
void set_protection_domain(oop pd) { oop_store((oop*) &_protection_domain, pd); }
+ // host class
+ oop host_klass() const { return _host_klass; }
+ void set_host_klass(oop host) { oop_store((oop*) &_host_klass, host); }
+ bool is_anonymous() const { return _host_klass != NULL; }
+
// signers
objArrayOop signers() const { return _signers; }
void set_signers(objArrayOop s) { oop_store((oop*) &_signers, oop(s)); }
@@ -709,6 +718,7 @@
oop* adr_constants() const { return (oop*)&this->_constants;}
oop* adr_class_loader() const { return (oop*)&this->_class_loader;}
oop* adr_protection_domain() const { return (oop*)&this->_protection_domain;}
+ oop* adr_host_klass() const { return (oop*)&this->_host_klass;}
oop* adr_signers() const { return (oop*)&this->_signers;}
oop* adr_source_file_name() const { return (oop*)&this->_source_file_name;}
oop* adr_source_debug_extension() const { return (oop*)&this->_source_debug_extension;}
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/oops/instanceKlassKlass.cpp
--- a/hotspot/src/share/vm/oops/instanceKlassKlass.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/oops/instanceKlassKlass.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -81,6 +81,7 @@
MarkSweep::mark_and_push(ik->adr_source_debug_extension());
MarkSweep::mark_and_push(ik->adr_inner_classes());
MarkSweep::mark_and_push(ik->adr_protection_domain());
+ MarkSweep::mark_and_push(ik->adr_host_klass());
MarkSweep::mark_and_push(ik->adr_signers());
MarkSweep::mark_and_push(ik->adr_generic_signature());
MarkSweep::mark_and_push(ik->adr_class_annotations());
@@ -120,6 +121,7 @@
PSParallelCompact::mark_and_push(cm, ik->adr_source_debug_extension());
PSParallelCompact::mark_and_push(cm, ik->adr_inner_classes());
PSParallelCompact::mark_and_push(cm, ik->adr_protection_domain());
+ PSParallelCompact::mark_and_push(cm, ik->adr_host_klass());
PSParallelCompact::mark_and_push(cm, ik->adr_signers());
PSParallelCompact::mark_and_push(cm, ik->adr_generic_signature());
PSParallelCompact::mark_and_push(cm, ik->adr_class_annotations());
@@ -159,6 +161,7 @@
blk->do_oop(ik->adr_constants());
blk->do_oop(ik->adr_class_loader());
blk->do_oop(ik->adr_protection_domain());
+ blk->do_oop(ik->adr_host_klass());
blk->do_oop(ik->adr_signers());
blk->do_oop(ik->adr_source_file_name());
blk->do_oop(ik->adr_source_debug_extension());
@@ -211,6 +214,8 @@
if (mr.contains(adr)) blk->do_oop(adr);
adr = ik->adr_protection_domain();
if (mr.contains(adr)) blk->do_oop(adr);
+ adr = ik->adr_host_klass();
+ if (mr.contains(adr)) blk->do_oop(adr);
adr = ik->adr_signers();
if (mr.contains(adr)) blk->do_oop(adr);
adr = ik->adr_source_file_name();
@@ -260,6 +265,7 @@
MarkSweep::adjust_pointer(ik->adr_constants());
MarkSweep::adjust_pointer(ik->adr_class_loader());
MarkSweep::adjust_pointer(ik->adr_protection_domain());
+ MarkSweep::adjust_pointer(ik->adr_host_klass());
MarkSweep::adjust_pointer(ik->adr_signers());
MarkSweep::adjust_pointer(ik->adr_source_file_name());
MarkSweep::adjust_pointer(ik->adr_source_debug_extension());
@@ -295,6 +301,11 @@
pm->claim_or_forward_breadth(pd_addr);
}
+ oop* hk_addr = ik->adr_host_klass();
+ if (PSScavenge::should_scavenge(hk_addr)) {
+ pm->claim_or_forward_breadth(hk_addr);
+ }
+
oop* sg_addr = ik->adr_signers();
if (PSScavenge::should_scavenge(sg_addr)) {
pm->claim_or_forward_breadth(sg_addr);
@@ -318,6 +329,11 @@
pm->claim_or_forward_depth(pd_addr);
}
+ oop* hk_addr = ik->adr_host_klass();
+ if (PSScavenge::should_scavenge(hk_addr)) {
+ pm->claim_or_forward_depth(hk_addr);
+ }
+
oop* sg_addr = ik->adr_signers();
if (PSScavenge::should_scavenge(sg_addr)) {
pm->claim_or_forward_depth(sg_addr);
@@ -421,6 +437,7 @@
ik->set_constants(NULL);
ik->set_class_loader(NULL);
ik->set_protection_domain(NULL);
+ ik->set_host_klass(NULL);
ik->set_signers(NULL);
ik->set_source_file_name(NULL);
ik->set_source_debug_extension(NULL);
@@ -526,6 +543,7 @@
st->print(" - constants: "); ik->constants()->print_value_on(st); st->cr();
st->print(" - class loader: "); ik->class_loader()->print_value_on(st); st->cr();
st->print(" - protection domain: "); ik->protection_domain()->print_value_on(st); st->cr();
+ st->print(" - host class: "); ik->host_klass()->print_value_on(st); st->cr();
st->print(" - signers: "); ik->signers()->print_value_on(st); st->cr();
if (ik->source_file_name() != NULL) {
st->print(" - source file: ");
@@ -626,7 +644,7 @@
ik->_verify_count = Universe::verify_count();
#endif
// Verify that klass is present in SystemDictionary
- if (ik->is_loaded()) {
+ if (ik->is_loaded() && !ik->is_anonymous()) {
symbolHandle h_name (thread, ik->name());
Handle h_loader (thread, ik->class_loader());
Handle h_obj(thread, obj);
@@ -764,6 +782,9 @@
if (ik->protection_domain() != NULL) {
guarantee(ik->protection_domain()->is_oop(), "should be oop");
}
+ if (ik->host_klass() != NULL) {
+ guarantee(ik->host_klass()->is_oop(), "should be oop");
+ }
if (ik->signers() != NULL) {
guarantee(ik->signers()->is_objArray(), "should be obj array");
}
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/oops/klass.cpp
--- a/hotspot/src/share/vm/oops/klass.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/oops/klass.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -478,6 +478,24 @@
const char* Klass::external_name() const {
+ if (oop_is_instance()) {
+ instanceKlass* ik = (instanceKlass*) this;
+ if (ik->is_anonymous()) {
+ assert(AnonymousClasses, "");
+ intptr_t hash = ik->java_mirror()->identity_hash();
+ char hash_buf[40];
+ sprintf(hash_buf, "/" UINTX_FORMAT, (uintx)hash);
+ size_t hash_len = strlen(hash_buf);
+
+ size_t result_len = name()->utf8_length();
+ char* result = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1);
+ name()->as_klass_external_name(result, (int) result_len + 1);
+ assert(strlen(result) == result_len, "");
+ strcpy(result + result_len, hash_buf);
+ assert(strlen(result) == result_len + hash_len, "");
+ return result;
+ }
+ }
return name()->as_klass_external_name();
}
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/opto/c2_globals.hpp
--- a/hotspot/src/share/vm/opto/c2_globals.hpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp Wed Jul 05 16:44:09 2017 +0200
@@ -256,10 +256,10 @@
develop(intx, PrintIdealGraphPort, 4444, \
"Ideal graph printer to network port") \
\
- develop(ccstr, PrintIdealGraphAddress, "127.0.0.1", \
+ notproduct(ccstr, PrintIdealGraphAddress, "127.0.0.1", \
"IP address to connect to visualizer") \
\
- develop(ccstr, PrintIdealGraphFile, NULL, \
+ notproduct(ccstr, PrintIdealGraphFile, NULL, \
"File to dump ideal graph to. If set overrides the " \
"use of the network") \
\
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/opto/macro.cpp
--- a/hotspot/src/share/vm/opto/macro.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/opto/macro.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -1673,7 +1673,6 @@
if (klass_node == NULL) {
Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes());
klass_node = transform_later( LoadKlassNode::make(_igvn, mem, k_adr, _igvn.type(k_adr)->is_ptr()) );
- klass_node->init_req(0, ctrl);
}
Node *proto_node = make_load(ctrl, mem, klass_node, Klass::prototype_header_offset_in_bytes() + sizeof(oopDesc), TypeX_X, TypeX_X->basic_type());
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/opto/parse.hpp
--- a/hotspot/src/share/vm/opto/parse.hpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/opto/parse.hpp Wed Jul 05 16:44:09 2017 +0200
@@ -175,7 +175,7 @@
bool is_SEL_backedge(Block* pred) const{ return is_SEL_head() && pred->rpo() >= rpo(); }
bool is_invariant_local(uint i) const {
const JVMState* jvms = start_map()->jvms();
- if (!jvms->is_loc(i)) return false;
+ if (!jvms->is_loc(i) || flow()->outer()->has_irreducible_entry()) return false;
return flow()->is_invariant_local(i - jvms->locoff());
}
bool can_elide_SEL_phi(uint i) const { assert(is_SEL_head(),""); return is_invariant_local(i); }
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/prims/jvm.cpp
--- a/hotspot/src/share/vm/prims/jvm.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/prims/jvm.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -744,6 +744,7 @@
// common code for JVM_DefineClass() and JVM_DefineClassWithSource()
static jclass jvm_define_class_common(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source, TRAPS) {
+ if (source == NULL) source = "__JVM_DefineClass__";
// Since exceptions can be thrown, class initialization can take place
// if name is NULL no check for class name in .class stream has to be made.
@@ -782,7 +783,7 @@
JVM_ENTRY(jclass, JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd))
JVMWrapper2("JVM_DefineClass %s", name);
- return jvm_define_class_common(env, name, loader, buf, len, pd, "__JVM_DefineClass__", THREAD);
+ return jvm_define_class_common(env, name, loader, buf, len, pd, NULL, THREAD);
JVM_END
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/prims/jvm.h
--- a/hotspot/src/share/vm/prims/jvm.h Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/prims/jvm.h Wed Jul 05 16:44:09 2017 +0200
@@ -422,6 +422,14 @@
const jbyte *buf, jsize len, jobject pd,
const char *source);
+/* Define a class with a source (MLVM) */
+JNIEXPORT jclass JNICALL
+JVM_DefineClassWithCP(JNIEnv *env, const char *name, jobject loader,
+ const jbyte *buf, jsize len, jobject pd,
+ const char *source,
+ // same args as JVM_DefineClassWithSource to this point
+ jobjectArray constants);
+
/*
* Reflection support functions
*/
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/prims/unsafe.cpp
--- a/hotspot/src/share/vm/prims/unsafe.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/prims/unsafe.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -837,6 +837,163 @@
}
UNSAFE_END
+#define DAC_Args CLS"[B["OBJ
+// define a class but do not make it known to the class loader or system dictionary
+// - host_class: supplies context for linkage, access control, protection domain, and class loader
+// - data: bytes of a class file, a raw memory address (length gives the number of bytes)
+// - cp_patches: where non-null entries exist, they replace corresponding CP entries in data
+
+// When you load an anonymous class U, it works as if you changed its name just before loading,
+// to a name that you will never use again. Since the name is lost, no other class can directly
+// link to any member of U. Just after U is loaded, the only way to use it is reflectively,
+// through java.lang.Class methods like Class.newInstance.
+
+// Access checks for linkage sites within U continue to follow the same rules as for named classes.
+// The package of an anonymous class is given by the package qualifier on the name under which it was loaded.
+// An anonymous class also has special privileges to access any member of its host class.
+// This is the main reason why this loading operation is unsafe. The purpose of this is to
+// allow language implementations to simulate "open classes"; a host class in effect gets
+// new code when an anonymous class is loaded alongside it. A less convenient but more
+// standard way to do this is with reflection, which can also be set to ignore access
+// restrictions.
+
+// Access into an anonymous class is possible only through reflection. Therefore, there
+// are no special access rules for calling into an anonymous class. The relaxed access
+// rule for the host class is applied in the opposite direction: A host class reflectively
+// access one of its anonymous classes.
+
+// If you load the same bytecodes twice, you get two different classes. You can reload
+// the same bytecodes with or without varying CP patches.
+
+// By using the CP patching array, you can have a new anonymous class U2 refer to an older one U1.
+// The bytecodes for U2 should refer to U1 by a symbolic name (doesn't matter what the name is).
+// The CONSTANT_Class entry for that name can be patched to refer directly to U1.
+
+// This allows, for example, U2 to use U1 as a superclass or super-interface, or as
+// an outer class (so that U2 is an anonymous inner class of anonymous U1).
+// It is not possible for a named class, or an older anonymous class, to refer by
+// name (via its CP) to a newer anonymous class.
+
+// CP patching may also be used to modify (i.e., hack) the names of methods, classes,
+// or type descriptors used in the loaded anonymous class.
+
+// Finally, CP patching may be used to introduce "live" objects into the constant pool,
+// instead of "dead" strings. A compiled statement like println((Object)"hello") can
+// be changed to println(greeting), where greeting is an arbitrary object created before
+// the anonymous class is loaded. This is useful in dynamic languages, in which
+// various kinds of metaobjects must be introduced as constants into bytecode.
+// Note the cast (Object), which tells the verifier to expect an arbitrary object,
+// not just a literal string. For such ldc instructions, the verifier uses the
+// type Object instead of String, if the loaded constant is not in fact a String.
+
+static oop
+Unsafe_DefineAnonymousClass_impl(JNIEnv *env,
+ jclass host_class, jbyteArray data, jobjectArray cp_patches_jh,
+ HeapWord* *temp_alloc,
+ TRAPS) {
+
+ if (UsePerfData) {
+ ClassLoader::unsafe_defineClassCallCounter()->inc();
+ }
+
+ if (data == NULL) {
+ THROW_0(vmSymbols::java_lang_NullPointerException());
+ }
+
+ jint length = typeArrayOop(JNIHandles::resolve_non_null(data))->length();
+ jint word_length = (length + sizeof(HeapWord)-1) / sizeof(HeapWord);
+ HeapWord* body = NEW_C_HEAP_ARRAY(HeapWord, word_length);
+ if (body == NULL) {
+ THROW_0(vmSymbols::java_lang_OutOfMemoryError());
+ }
+
+ // caller responsible to free it:
+ (*temp_alloc) = body;
+
+ {
+ jbyte* array_base = typeArrayOop(JNIHandles::resolve_non_null(data))->byte_at_addr(0);
+ Copy::conjoint_words((HeapWord*) array_base, body, word_length);
+ }
+
+ u1* class_bytes = (u1*) body;
+ int class_bytes_length = (int) length;
+ if (class_bytes_length < 0) class_bytes_length = 0;
+ if (class_bytes == NULL
+ || host_class == NULL
+ || length != class_bytes_length)
+ THROW_0(vmSymbols::java_lang_IllegalArgumentException());
+
+ objArrayHandle cp_patches_h;
+ if (cp_patches_jh != NULL) {
+ oop p = JNIHandles::resolve_non_null(cp_patches_jh);
+ if (!p->is_objArray())
+ THROW_0(vmSymbols::java_lang_IllegalArgumentException());
+ cp_patches_h = objArrayHandle(THREAD, (objArrayOop)p);
+ }
+
+ KlassHandle host_klass(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(host_class)));
+ const char* host_source = host_klass->external_name();
+ Handle host_loader(THREAD, host_klass->class_loader());
+ Handle host_domain(THREAD, host_klass->protection_domain());
+
+ GrowableArray* cp_patches = NULL;
+ if (cp_patches_h.not_null()) {
+ int alen = cp_patches_h->length();
+ for (int i = alen-1; i >= 0; i--) {
+ oop p = cp_patches_h->obj_at(i);
+ if (p != NULL) {
+ Handle patch(THREAD, p);
+ if (cp_patches == NULL)
+ cp_patches = new GrowableArray(i+1, i+1, Handle());
+ cp_patches->at_put(i, patch);
+ }
+ }
+ }
+
+ ClassFileStream st(class_bytes, class_bytes_length, (char*) host_source);
+
+ instanceKlassHandle anon_klass;
+ {
+ symbolHandle no_class_name;
+ klassOop anonk = SystemDictionary::parse_stream(no_class_name,
+ host_loader, host_domain,
+ &st, host_klass, cp_patches,
+ CHECK_NULL);
+ if (anonk == NULL) return NULL;
+ anon_klass = instanceKlassHandle(THREAD, anonk);
+ }
+
+ // let caller initialize it as needed...
+
+ return anon_klass->java_mirror();
+}
+
+UNSAFE_ENTRY(jclass, Unsafe_DefineAnonymousClass(JNIEnv *env, jobject unsafe, jclass host_class, jbyteArray data, jobjectArray cp_patches_jh))
+{
+ UnsafeWrapper("Unsafe_DefineAnonymousClass");
+ ResourceMark rm(THREAD);
+
+ HeapWord* temp_alloc = NULL;
+
+ jobject res_jh = NULL;
+
+ { oop res_oop = Unsafe_DefineAnonymousClass_impl(env,
+ host_class, data, cp_patches_jh,
+ &temp_alloc, THREAD);
+ if (res_oop != NULL)
+ res_jh = JNIHandles::make_local(env, res_oop);
+ }
+
+ // try/finally clause:
+ if (temp_alloc != NULL) {
+ FREE_C_HEAP_ARRAY(HeapWord, temp_alloc);
+ }
+
+ return (jclass) res_jh;
+}
+UNSAFE_END
+
+
UNSAFE_ENTRY(void, Unsafe_MonitorEnter(JNIEnv *env, jobject unsafe, jobject jobj))
UnsafeWrapper("Unsafe_MonitorEnter");
@@ -1292,6 +1449,9 @@
{CC"copyMemory", CC"("ADR ADR"J)V", FN_PTR(Unsafe_CopyMemory)}
};
+JNINativeMethod anonk_methods[] = {
+ {CC"defineAnonymousClass", CC"("DAC_Args")"CLS, FN_PTR(Unsafe_DefineAnonymousClass)},
+};
#undef CC
#undef FN_PTR
@@ -1354,6 +1514,15 @@
}
}
}
+ if (AnonymousClasses) {
+ env->RegisterNatives(unsafecls, anonk_methods, sizeof(anonk_methods)/sizeof(JNINativeMethod));
+ if (env->ExceptionOccurred()) {
+ if (PrintMiscellaneous && (Verbose || WizardMode)) {
+ tty->print_cr("Warning: SDK 1.7 Unsafe.defineClass (anonymous version) not found.");
+ }
+ env->ExceptionClear();
+ }
+ }
int status = env->RegisterNatives(unsafecls, methods, sizeof(methods)/sizeof(JNINativeMethod));
if (env->ExceptionOccurred()) {
if (PrintMiscellaneous && (Verbose || WizardMode)) {
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/runtime/globals.hpp
--- a/hotspot/src/share/vm/runtime/globals.hpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/runtime/globals.hpp Wed Jul 05 16:44:09 2017 +0200
@@ -493,7 +493,7 @@
develop(bool, DeoptimizeALot, false, \
"deoptimize at every exit from the runtime system") \
\
- develop(ccstrlist, DeoptimizeOnlyAt, "", \
+ notproduct(ccstrlist, DeoptimizeOnlyAt, "", \
"a comma separated list of bcis to deoptimize at") \
\
product(bool, DeoptimizeRandom, false, \
@@ -2792,7 +2792,7 @@
product(intx, TargetSurvivorRatio, 50, \
"Desired percentage of survivor space used after scavenge") \
\
- product(intx, MarkSweepDeadRatio, 5, \
+ product(uintx, MarkSweepDeadRatio, 5, \
"Percentage (0-100) of the old gen allowed as dead wood." \
"Serial mark sweep treats this as both the min and max value." \
"CMS uses this value only if it falls back to mark sweep." \
@@ -2801,7 +2801,7 @@
"either completely full or completely empty. Par compact also" \
"has a smaller default value; see arguments.cpp.") \
\
- product(intx, PermMarkSweepDeadRatio, 20, \
+ product(uintx, PermMarkSweepDeadRatio, 20, \
"Percentage (0-100) of the perm gen allowed as dead wood." \
"See MarkSweepDeadRatio for collector-specific comments.") \
\
@@ -3230,6 +3230,9 @@
"Skip assert() and verify() which page-in unwanted shared " \
"objects. ") \
\
+ product(bool, AnonymousClasses, false, \
+ "support sun.misc.Unsafe.defineAnonymousClass") \
+ \
product(bool, TaggedStackInterpreter, false, \
"Insert tags in interpreter execution stack for oopmap generaion")\
\
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/runtime/perfMemory.cpp
--- a/hotspot/src/share/vm/runtime/perfMemory.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/runtime/perfMemory.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -25,6 +25,14 @@
# include "incls/_precompiled.incl"
# include "incls/_perfMemory.cpp.incl"
+// Prefix of performance data file.
+const char PERFDATA_NAME[] = "hsperfdata";
+
+// Add 1 for the '_' character between PERFDATA_NAME and pid. The '\0' terminating
+// character will be included in the sizeof(PERFDATA_NAME) operation.
+static const size_t PERFDATA_FILENAME_LEN = sizeof(PERFDATA_NAME) +
+ UINT_CHARS + 1;
+
char* PerfMemory::_start = NULL;
char* PerfMemory::_end = NULL;
char* PerfMemory::_top = NULL;
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/runtime/perfMemory.hpp
--- a/hotspot/src/share/vm/runtime/perfMemory.hpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/runtime/perfMemory.hpp Wed Jul 05 16:44:09 2017 +0200
@@ -95,7 +95,7 @@
} PerfDataEntry;
// Prefix of performance data file.
-static const char PERFDATA_NAME[] = "hsperfdata";
+extern const char PERFDATA_NAME[];
// UINT_CHARS contains the number of characters holding a process id
// (i.e. pid). pid is defined as unsigned "int" so the maximum possible pid value
@@ -103,11 +103,6 @@
// string.
static const size_t UINT_CHARS = 10;
-// Add 1 for the '_' character between PERFDATA_NAME and pid. The '\0' terminating
-// character will be included in the sizeof(PERFDATA_NAME) operation.
-static const size_t PERFDATA_FILENAME_LEN = sizeof(PERFDATA_NAME) +
- UINT_CHARS + 1;
-
/* the PerfMemory class manages creation, destruction,
* and allocation of the PerfData region.
*/
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/runtime/reflection.cpp
--- a/hotspot/src/share/vm/runtime/reflection.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/runtime/reflection.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -456,10 +456,32 @@
return can_relax_access_check_for(current_class, new_class, classloader_only);
}
+static bool under_host_klass(instanceKlass* ik, klassOop host_klass) {
+ DEBUG_ONLY(int inf_loop_check = 1000 * 1000 * 1000);
+ for (;;) {
+ klassOop hc = (klassOop) ik->host_klass();
+ if (hc == NULL) return false;
+ if (hc == host_klass) return true;
+ ik = instanceKlass::cast(hc);
+
+ // There's no way to make a host class loop short of patching memory.
+ // Therefore there cannot be a loop here unles there's another bug.
+ // Still, let's check for it.
+ assert(--inf_loop_check > 0, "no host_klass loop");
+ }
+}
+
bool Reflection::can_relax_access_check_for(
klassOop accessor, klassOop accessee, bool classloader_only) {
instanceKlass* accessor_ik = instanceKlass::cast(accessor);
instanceKlass* accessee_ik = instanceKlass::cast(accessee);
+
+ // If either is on the other's host_klass chain, access is OK,
+ // because one is inside the other.
+ if (under_host_klass(accessor_ik, accessee) ||
+ under_host_klass(accessee_ik, accessor))
+ return true;
+
if (RelaxAccessControlCheck ||
(accessor_ik->major_version() < JAVA_1_5_VERSION &&
accessee_ik->major_version() < JAVA_1_5_VERSION)) {
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/runtime/thread.cpp
--- a/hotspot/src/share/vm/runtime/thread.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/runtime/thread.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -1422,6 +1422,7 @@
thread->clear_pending_exception();
}
+
// For any new cleanup additions, please check to see if they need to be applied to
// cleanup_failed_attach_current_thread as well.
void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
@@ -1592,39 +1593,62 @@
JvmtiExport::cleanup_thread(this);
}
+#ifndef SERIALGC
+ // We must flush G1-related buffers before removing a thread from
+ // the list of active threads.
+ if (UseG1GC) {
+ flush_barrier_queues();
+ }
+#endif
+
// Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread
Threads::remove(this);
}
+#ifndef SERIALGC
+// Flush G1-related queues.
+void JavaThread::flush_barrier_queues() {
+ satb_mark_queue().flush();
+ dirty_card_queue().flush();
+}
+#endif
+
void JavaThread::cleanup_failed_attach_current_thread() {
-
- if (get_thread_profiler() != NULL) {
- get_thread_profiler()->disengage();
- ResourceMark rm;
- get_thread_profiler()->print(get_thread_name());
- }
-
- if (active_handles() != NULL) {
- JNIHandleBlock* block = active_handles();
- set_active_handles(NULL);
- JNIHandleBlock::release_block(block);
- }
-
- if (free_handle_block() != NULL) {
- JNIHandleBlock* block = free_handle_block();
- set_free_handle_block(NULL);
- JNIHandleBlock::release_block(block);
- }
-
- if (UseTLAB) {
- tlab().make_parsable(true); // retire TLAB, if any
- }
-
- Threads::remove(this);
- delete this;
+ if (get_thread_profiler() != NULL) {
+ get_thread_profiler()->disengage();
+ ResourceMark rm;
+ get_thread_profiler()->print(get_thread_name());
+ }
+
+ if (active_handles() != NULL) {
+ JNIHandleBlock* block = active_handles();
+ set_active_handles(NULL);
+ JNIHandleBlock::release_block(block);
+ }
+
+ if (free_handle_block() != NULL) {
+ JNIHandleBlock* block = free_handle_block();
+ set_free_handle_block(NULL);
+ JNIHandleBlock::release_block(block);
+ }
+
+ if (UseTLAB) {
+ tlab().make_parsable(true); // retire TLAB, if any
+ }
+
+#ifndef SERIALGC
+ if (UseG1GC) {
+ flush_barrier_queues();
+ }
+#endif
+
+ Threads::remove(this);
+ delete this;
}
+
+
JavaThread* JavaThread::active() {
Thread* thread = ThreadLocalStorage::thread();
assert(thread != NULL, "just checking");
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/runtime/thread.hpp
--- a/hotspot/src/share/vm/runtime/thread.hpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/runtime/thread.hpp Wed Jul 05 16:44:09 2017 +0200
@@ -793,6 +793,8 @@
DirtyCardQueue _dirty_card_queue; // Thread-local log for dirty cards.
// Set of all such queues.
static DirtyCardQueueSet _dirty_card_queue_set;
+
+ void flush_barrier_queues();
#endif // !SERIALGC
friend class VMThread;
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/utilities/array.hpp
--- a/hotspot/src/share/vm/utilities/array.hpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/utilities/array.hpp Wed Jul 05 16:44:09 2017 +0200
@@ -40,11 +40,18 @@
_length = 0;
_data = NULL;
DEBUG_ONLY(init_nesting();)
+ // client may call initialize, at most once
}
ResourceArray(size_t esize, int length) {
+ DEBUG_ONLY(_data = NULL);
+ initialize(esize, length);
+ }
+
+ void initialize(size_t esize, int length) {
assert(length >= 0, "illegal length");
+ assert(_data == NULL, "must be new object");
_length = length;
_data = resource_allocate_bytes(esize * length);
DEBUG_ONLY(init_nesting();)
@@ -111,7 +118,10 @@
/* creation */ \
array_name() : base_class() {} \
array_name(const int length) : base_class(esize, length) {} \
- array_name(const int length, const etype fx) : base_class(esize, length) { \
+ array_name(const int length, const etype fx) { initialize(length, fx); } \
+ void initialize(const int length) { base_class::initialize(esize, length); } \
+ void initialize(const int length, const etype fx) { \
+ initialize(length); \
for (int i = 0; i < length; i++) ((etype*)_data)[i] = fx; \
} \
\
@@ -157,16 +167,29 @@
\
public: \
/* creation */ \
- stack_name() : array_name() { _size = 0; } \
- stack_name(const int size) : array_name(size){ _length = 0; _size = size; } \
- stack_name(const int size, const etype fx) : array_name(size, fx) { _size = size; } \
+ stack_name() : array_name() { _size = 0; } \
+ stack_name(const int size) { initialize(size); } \
+ stack_name(const int size, const etype fx) { initialize(size, fx); } \
+ void initialize(const int size, const etype fx) { \
+ _size = size; \
+ array_name::initialize(size, fx); \
+ /* _length == size, allocation and size are the same */ \
+ } \
+ void initialize(const int size) { \
+ _size = size; \
+ array_name::initialize(size); \
+ _length = 0; /* reset length to zero; _size records the allocation */ \
+ } \
\
/* standard operations */ \
int size() const { return _size; } \
\
- void push(const etype x) { \
- if (length() >= size()) expand(esize, length(), _size); \
- ((etype*)_data)[_length++] = x; \
+ int push(const etype x) { \
+ int len = length(); \
+ if (len >= size()) expand(esize, len, _size); \
+ ((etype*)_data)[len] = x; \
+ _length = len+1; \
+ return len; \
} \
\
etype pop() { \
@@ -235,7 +258,7 @@
int capacity() const { return size(); } \
void clear() { truncate(0); } \
void trunc_to(const int length) { truncate(length); } \
- void append(const etype x) { push(x); } \
+ int append(const etype x) { return push(x); } \
void appendAll(const stack_name* stack) { push_all(stack); } \
etype last() const { return top(); } \
}; \
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/utilities/constantTag.hpp
--- a/hotspot/src/share/vm/utilities/constantTag.hpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/utilities/constantTag.hpp Wed Jul 05 16:44:09 2017 +0200
@@ -71,6 +71,7 @@
bool is_string_index() const { return _tag == JVM_CONSTANT_StringIndex; }
bool is_klass_reference() const { return is_klass_index() || is_unresolved_klass(); }
+ bool is_klass_or_reference() const{ return is_klass() || is_klass_reference(); }
bool is_field_or_method() const { return is_field() || is_method() || is_interface_method(); }
bool is_symbol() const { return is_utf8(); }
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/utilities/debug.cpp
--- a/hotspot/src/share/vm/utilities/debug.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/utilities/debug.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -567,7 +567,7 @@
}
// the InlineCacheBuffer is using stubs generated into a buffer blob
if (InlineCacheBuffer::contains(addr)) {
- tty->print_cr(INTPTR_FORMAT "is pointing into InlineCacheBuffer", addr);
+ tty->print_cr(INTPTR_FORMAT " is pointing into InlineCacheBuffer", addr);
return;
}
VtableStub* v = VtableStubs::stub_containing(addr);
@@ -595,7 +595,7 @@
return;
}
- if (Universe::heap()->is_in_reserved(addr)) {
+ if (Universe::heap()->is_in(addr)) {
HeapWord* p = Universe::heap()->block_start(addr);
bool print = false;
// If we couldn't find it it just may mean that heap wasn't parseable
@@ -621,24 +621,28 @@
}
return;
}
+ } else if (Universe::heap()->is_in_reserved(addr)) {
+ tty->print_cr(INTPTR_FORMAT " is an unallocated location in the heap", addr);
+ return;
}
+
if (JNIHandles::is_global_handle((jobject) addr)) {
- tty->print_cr(INTPTR_FORMAT "is a global jni handle", addr);
+ tty->print_cr(INTPTR_FORMAT " is a global jni handle", addr);
return;
}
if (JNIHandles::is_weak_global_handle((jobject) addr)) {
- tty->print_cr(INTPTR_FORMAT "is a weak global jni handle", addr);
+ tty->print_cr(INTPTR_FORMAT " is a weak global jni handle", addr);
return;
}
if (JNIHandleBlock::any_contains((jobject) addr)) {
- tty->print_cr(INTPTR_FORMAT "is a local jni handle", addr);
+ tty->print_cr(INTPTR_FORMAT " is a local jni handle", addr);
return;
}
for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
- // Check for priviledge stack
+ // Check for privilege stack
if (thread->privileged_stack_top() != NULL && thread->privileged_stack_top()->contains(addr)) {
- tty->print_cr(INTPTR_FORMAT "is pointing into the priviledge stack for thread: " INTPTR_FORMAT, addr, thread);
+ tty->print_cr(INTPTR_FORMAT " is pointing into the privilege stack for thread: " INTPTR_FORMAT, addr, thread);
return;
}
// If the addr is a java thread print information about that.
@@ -659,7 +663,7 @@
return;
}
- tty->print_cr(INTPTR_FORMAT "is pointing to unknown location", addr);
+ tty->print_cr(INTPTR_FORMAT " is pointing to unknown location", addr);
}
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/utilities/growableArray.hpp
--- a/hotspot/src/share/vm/utilities/growableArray.hpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/utilities/growableArray.hpp Wed Jul 05 16:44:09 2017 +0200
@@ -111,6 +111,12 @@
}
void* raw_allocate(int elementSize);
+
+ // some uses pass the Thread explicitly for speed (4990299 tuning)
+ void* raw_allocate(Thread* thread, int elementSize) {
+ assert(on_stack(), "fast ResourceObj path only");
+ return (void*)resource_allocate_bytes(thread, elementSize * _max);
+ }
};
template class GrowableArray : public GenericGrowableArray {
@@ -121,6 +127,11 @@
void raw_at_put_grow(int i, const E& p, const E& fill);
void clear_and_deallocate();
public:
+ GrowableArray(Thread* thread, int initial_size) : GenericGrowableArray(initial_size, 0, false) {
+ _data = (E*)raw_allocate(thread, sizeof(E));
+ for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E();
+ }
+
GrowableArray(int initial_size, bool C_heap = false) : GenericGrowableArray(initial_size, 0, C_heap) {
_data = (E*)raw_allocate(sizeof(E));
for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E();
@@ -159,10 +170,12 @@
void print();
- void append(const E& elem) {
+ int append(const E& elem) {
check_nesting();
if (_len == _max) grow(_len);
- _data[_len++] = elem;
+ int idx = _len++;
+ _data[idx] = elem;
+ return idx;
}
void append_if_missing(const E& elem) {
diff -r 773df43a0f6a -r 3cb2a607c347 hotspot/src/share/vm/utilities/hashtable.cpp
--- a/hotspot/src/share/vm/utilities/hashtable.cpp Wed Jul 05 16:43:43 2017 +0200
+++ b/hotspot/src/share/vm/utilities/hashtable.cpp Wed Jul 05 16:44:09 2017 +0200
@@ -43,9 +43,11 @@
entry = _free_list;
_free_list = _free_list->next();
} else {
- const int block_size = 500;
- if (_first_free_entry == _end_block) {
+ if (_first_free_entry + _entry_size >= _end_block) {
+ int block_size = MIN2(512, MAX2((int)_table_size / 2, (int)_number_of_entries));
int len = _entry_size * block_size;
+ len = 1 << log2_intptr(len); // round down to power of 2
+ assert(len >= _entry_size, "");
_first_free_entry = NEW_C_HEAP_ARRAY(char, len);
_end_block = _first_free_entry + len;
}
@@ -53,6 +55,7 @@
_first_free_entry += _entry_size;
}
+ assert(_entry_size % HeapWordSize == 0, "");
entry->set_hash(hashValue);
return entry;
}
diff -r 773df43a0f6a -r 3cb2a607c347 jaxp/.hgtags
--- a/jaxp/.hgtags Wed Jul 05 16:43:43 2017 +0200
+++ b/jaxp/.hgtags Wed Jul 05 16:44:09 2017 +0200
@@ -14,3 +14,4 @@
af49591bc486d82aa04b832257de0d18adc9af52 jdk7-b37
e9f750f0a3a00413a7b77028b2ecdabb7129ae32 jdk7-b38
831b80be6cea8e7d7da197ccdac5fd4c701a5033 jdk7-b39
+54946f466e2c047c44c903f1bec400b685c2508e jdk7-b40
diff -r 773df43a0f6a -r 3cb2a607c347 jaxws/.hgtags
--- a/jaxws/.hgtags Wed Jul 05 16:43:43 2017 +0200
+++ b/jaxws/.hgtags Wed Jul 05 16:44:09 2017 +0200
@@ -14,3 +14,4 @@
a2a6f9edf761934faf59ea60d7fe7178371302cd jdk7-b37
9ce439969184c753a9ba3caf8ed277b05230f2e5 jdk7-b38
077bc9b1b035a409a76bd5366f73ed9dd9846934 jdk7-b39
+70a6ac6dd737fe45c2fadb57646195b2b4fe269d jdk7-b40
diff -r 773df43a0f6a -r 3cb2a607c347 jdk/.hgtags
--- a/jdk/.hgtags Wed Jul 05 16:43:43 2017 +0200
+++ b/jdk/.hgtags Wed Jul 05 16:44:09 2017 +0200
@@ -14,3 +14,4 @@
14f50aee4989b75934d385c56a83da0c23d2f68b jdk7-b37
cc5f810b5af8a3a83b0df5a29d9e24d7a0ff8086 jdk7-b38
4e51997582effa006dde5c6d8b8820b2045b9c7f jdk7-b39
+2201dad60231a3c3e0346e3a0250d69ca3b71fd4 jdk7-b40
diff -r 773df43a0f6a -r 3cb2a607c347 jdk/src/share/classes/com/sun/jmx/defaults/ServiceName.java
--- a/jdk/src/share/classes/com/sun/jmx/defaults/ServiceName.java Wed Jul 05 16:43:43 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/defaults/ServiceName.java Wed Jul 05 16:44:09 2017 +0200
@@ -69,9 +69,9 @@
/**
* The version of the JMX specification implemented by this product.
*
- * The value is 1.4.
+ * The value is 2.0.
*/
- public static final String JMX_SPEC_VERSION = "1.4";
+ public static final String JMX_SPEC_VERSION = "2.0";
/**
* The vendor of the JMX specification implemented by this product.
diff -r 773df43a0f6a -r 3cb2a607c347 jdk/src/share/classes/com/sun/jmx/event/EventParams.java
--- a/jdk/src/share/classes/com/sun/jmx/event/EventParams.java Wed Jul 05 16:43:43 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/event/EventParams.java Wed Jul 05 16:44:09 2017 +0200
@@ -41,7 +41,7 @@
@SuppressWarnings("cast") // cast for jdk 1.5
public static long getLeaseTimeout() {
- long timeout = EventClient.DEFAULT_LEASE_TIMEOUT;
+ long timeout = EventClient.DEFAULT_REQUESTED_LEASE_TIME;
try {
final GetPropertyAction act =
new GetPropertyAction(DEFAULT_LEASE_TIMEOUT);
diff -r 773df43a0f6a -r 3cb2a607c347 jdk/src/share/classes/com/sun/jmx/event/LeaseManager.java
--- a/jdk/src/share/classes/com/sun/jmx/event/LeaseManager.java Wed Jul 05 16:43:43 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/event/LeaseManager.java Wed Jul 05 16:44:09 2017 +0200
@@ -29,6 +29,7 @@
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
/**
@@ -143,9 +144,10 @@
private final Runnable callback;
private ScheduledFuture> scheduled; // If null, the lease has expired.
+ private static final ThreadFactory threadFactory =
+ new DaemonThreadFactory("JMX LeaseManager %d");
private final ScheduledExecutorService executor
- = Executors.newScheduledThreadPool(1,
- new DaemonThreadFactory("JMX LeaseManager %d"));
+ = Executors.newScheduledThreadPool(1, threadFactory);
private static final ClassLogger logger =
new ClassLogger("javax.management.event", "LeaseManager");
diff -r 773df43a0f6a -r 3cb2a607c347 jdk/src/share/classes/com/sun/jmx/interceptor/SingleMBeanForwarder.java
--- a/jdk/src/share/classes/com/sun/jmx/interceptor/SingleMBeanForwarder.java Wed Jul 05 16:43:43 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/interceptor/SingleMBeanForwarder.java Wed Jul 05 16:44:09 2017 +0200
@@ -55,9 +55,19 @@
import javax.management.namespace.MBeanServerSupport;
import javax.management.remote.IdentityMBeanServerForwarder;
+/**
+ *
An {@link MBeanServerForwarder} that simulates the existence of a
+ * given MBean. Requests for that MBean, call it X, are intercepted by the
+ * forwarder, and requests for any other MBean are forwarded to the next
+ * forwarder in the chain. Requests such as queryNames which can span both the
+ * X and other MBeans are handled by merging the results for X with the results
+ * from the next forwarder, unless the "visible" parameter is false, in which
+ * case X is invisible to such requests.
+ */
public class SingleMBeanForwarder extends IdentityMBeanServerForwarder {
private final ObjectName mbeanName;
+ private final boolean visible;
private DynamicMBean mbean;
private MBeanServer mbeanMBS = new MBeanServerSupport() {
@@ -85,10 +95,20 @@
return null;
}
+ // This will only be called if mbeanName has an empty domain.
+ // In that case a getAttribute (e.g.) of that name will have the
+ // domain replaced by MBeanServerSupport with the default domain,
+ // so we must be sure that the default domain is empty too.
+ @Override
+ public String getDefaultDomain() {
+ return mbeanName.getDomain();
+ }
};
- public SingleMBeanForwarder(ObjectName mbeanName, DynamicMBean mbean) {
+ public SingleMBeanForwarder(
+ ObjectName mbeanName, DynamicMBean mbean, boolean visible) {
this.mbeanName = mbeanName;
+ this.visible = visible;
setSingleMBean(mbean);
}
@@ -213,8 +233,10 @@
@Override
public String[] getDomains() {
- TreeSet domainSet =
- new TreeSet(Arrays.asList(super.getDomains()));
+ String[] domains = super.getDomains();
+ if (!visible)
+ return domains;
+ TreeSet domainSet = new TreeSet(Arrays.asList(domains));
domainSet.add(mbeanName.getDomain());
return domainSet.toArray(new String[domainSet.size()]);
}
@@ -222,7 +244,7 @@
@Override
public Integer getMBeanCount() {
Integer count = super.getMBeanCount();
- if (!super.isRegistered(mbeanName))
+ if (visible && !super.isRegistered(mbeanName))
count++;
return count;
}
@@ -284,7 +306,7 @@
*/
private boolean applies(ObjectName pattern) {
// we know pattern is not null.
- if (!pattern.apply(mbeanName))
+ if (!visible || !pattern.apply(mbeanName))
return false;
final String dompat = pattern.getDomain();
@@ -306,10 +328,12 @@
@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));
+ if (visible) {
+ 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;
}
@@ -317,10 +341,12 @@
@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));
+ if (visible) {
+ 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;
}
diff -r 773df43a0f6a -r 3cb2a607c347 jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java Wed Jul 05 16:43:43 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java Wed Jul 05 16:44:09 2017 +0200
@@ -122,7 +122,7 @@
* {@link javax.management.MBeanServerFactory#newMBeanServer(java.lang.String)}
* instead.
*
- * By default, {@link MBeanServerInterceptor} are disabled. Use
+ * By default, interceptors are disabled. Use
* {@link #JmxMBeanServer(java.lang.String,javax.management.MBeanServer,javax.management.MBeanServerDelegate,boolean)} to enable them.
*
* @param domain The default domain name used by this MBeanServer.
@@ -239,7 +239,7 @@
this.mBeanServerDelegateObject = delegate;
this.outerShell = outer;
- final Repository repository = new Repository(domain,fairLock);
+ final Repository repository = new Repository(domain);
this.mbsInterceptor =
new NamespaceDispatchInterceptor(outer, delegate, instantiator,
repository);
diff -r 773df43a0f6a -r 3cb2a607c347 jdk/src/share/classes/com/sun/jmx/namespace/JMXNamespaceUtils.java
--- a/jdk/src/share/classes/com/sun/jmx/namespace/JMXNamespaceUtils.java Wed Jul 05 16:43:43 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,354 +0,0 @@
-/*
- * 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 -r 773df43a0f6a -r 3cb2a607c347 jdk/src/share/classes/com/sun/jmx/namespace/ObjectNameRouter.java
--- a/jdk/src/share/classes/com/sun/jmx/namespace/ObjectNameRouter.java Wed Jul 05 16:43:43 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/namespace/ObjectNameRouter.java Wed Jul 05 16:44:09 2017 +0200
@@ -49,11 +49,6 @@
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);
@@ -186,6 +181,4 @@
b.append(NAMESPACE_SEPARATOR);
return b.toString();
}
-
-
}
diff -r 773df43a0f6a -r 3cb2a607c347 jdk/src/share/classes/com/sun/jmx/namespace/RoutingConnectionProxy.java
--- a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingConnectionProxy.java Wed Jul 05 16:43:43 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingConnectionProxy.java Wed Jul 05 16:44:09 2017 +0200
@@ -31,7 +31,6 @@
import java.util.logging.Logger;
import javax.management.MBeanServerConnection;
-import javax.management.namespace.JMXNamespaces;
/**
@@ -61,18 +60,10 @@
* 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);
+ boolean probe) {
+ super(source, sourceDir, targetDir, probe);
if (LOG.isLoggable(Level.FINER))
LOG.finer("RoutingConnectionProxy for " + getSourceNamespace() +
@@ -85,15 +76,13 @@
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+")";
+ targetNs+"\")";
}
static final RoutingProxyFactory
@@ -102,22 +91,16 @@
() {
public RoutingConnectionProxy newInstance(MBeanServerConnection source,
- String sourcePath, String targetPath,
- boolean forwardsContext) {
+ String sourcePath, String targetPath, boolean probe) {
return new RoutingConnectionProxy(source,sourcePath,
- targetPath,forwardsContext);
- }
-
- public RoutingConnectionProxy newInstance(
- MBeanServerConnection source, String sourcePath) {
- return new RoutingConnectionProxy(source,sourcePath);
+ targetPath, probe);
}
};
- public static MBeanServerConnection cd(MBeanServerConnection source,
- String sourcePath) {
+ public static MBeanServerConnection cd(
+ MBeanServerConnection source, String sourcePath, boolean probe) {
return RoutingProxy.cd(RoutingConnectionProxy.class, FACTORY,
- source, sourcePath);
+ source, sourcePath, probe);
}
}
diff -r 773df43a0f6a -r 3cb2a607c347 jdk/src/share/classes/com/sun/jmx/namespace/RoutingProxy.java
--- a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingProxy.java Wed Jul 05 16:43:43 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingProxy.java Wed Jul 05 16:44:09 2017 +0200
@@ -30,6 +30,7 @@
import java.util.logging.Level;
import java.util.logging.Logger;
+import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanRegistrationException;
@@ -90,17 +91,9 @@
// 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
+// factory method that can concatenate namespace paths in order to
// return a single RoutingProxy - rather than wrapping a RoutingProxy inside
// another RoutingProxy. See RoutingConnectionProxy.cd and
// RoutingServerProxy.cd
@@ -146,25 +139,27 @@
private final T source;
// The name space we're narrowing to (usually some name space in
- // the source MBeanServerConnection
+ // the source MBeanServerConnection), e.g. "a" for the namespace
+ // "a//". This is empty in the case of ClientContext described above.
private final String sourceNs;
- // The name space we pretend to be mounted in (usually "")
+ // The name space we pretend to be mounted in. This is empty except
+ // in the case of ClientContext described above (where it will be
+ // something like "jmx.context//foo=bar".
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) {
+ String sourceNs,
+ String targetNs,
+ boolean probe) {
if (source == null) throw new IllegalArgumentException("null");
this.sourceNs = JMXNamespaces.normalizeNamespaceName(sourceNs);
@@ -177,13 +172,17 @@
// 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);
+ if (probe) {
+ try {
+ if (!source.isRegistered(handlerName)) {
+ InstanceNotFoundException infe =
+ new InstanceNotFoundException(handlerName);
+ throw new IllegalArgumentException(sourceNs +
+ ": no such name space", infe);
+ }
+ } catch (IOException x) {
+ throw new IllegalArgumentException("source stale: "+x,x);
+ }
}
}
this.source = source;
@@ -191,7 +190,6 @@
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");
@@ -200,14 +198,6 @@
@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 {
@@ -222,8 +212,7 @@
if (defaultDomain != null)
targetName = targetName.withDomain(defaultDomain);
}
- final ObjectNameRouter r = getObjectNameRouter();
- return r.toSourceContext(targetName,true);
+ return router.toSourceContext(targetName,true);
}
@Override
@@ -243,8 +232,7 @@
public ObjectName toTarget(ObjectName sourceName)
throws MalformedObjectNameException {
if (sourceName == null) return null;
- final ObjectNameRouter r = getObjectNameRouter();
- return r.toTargetContext(sourceName,false);
+ return router.toTargetContext(sourceName,false);
}
private Object getAttributeFromHandler(String attributeName)
@@ -357,11 +345,8 @@
// instance.
static interface RoutingProxyFactory> {
- R newInstance(T source,
- String sourcePath, String targetPath,
- boolean forwardsContext);
- R newInstance(T source,
- String sourcePath);
+ public R newInstance(
+ T source, String sourcePath, String targetPath, boolean probe);
}
// Performs a narrowDownToNamespace operation.
@@ -377,7 +362,7 @@
static >
R cd(Class routingProxyClass,
RoutingProxyFactory factory,
- T source, String sourcePath) {
+ T source, String sourcePath, boolean probe) {
if (source == null) throw new IllegalArgumentException("null");
if (source.getClass().equals(routingProxyClass)) {
// cast is OK here, but findbugs complains unless we use class.cast
@@ -400,14 +385,13 @@
final String path =
JMXNamespaces.concat(other.getSourceNamespace(),
sourcePath);
- return factory.newInstance(other.source(),path,"",
- other.forwardsContext);
+ return factory.newInstance(other.source(), path, "", probe);
}
// 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);
+ return factory.newInstance(source, sourcePath, "", probe);
}
}
diff -r 773df43a0f6a -r 3cb2a607c347 jdk/src/share/classes/com/sun/jmx/namespace/RoutingServerProxy.java
--- a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingServerProxy.java Wed Jul 05 16:43:43 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingServerProxy.java Wed Jul 05 16:44:09 2017 +0200
@@ -54,7 +54,6 @@
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
@@ -76,19 +75,11 @@
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);
+ boolean probe) {
+ super(source, sourceNs, targetNs, probe);
}
/**
@@ -571,20 +562,15 @@
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);
+ String sourcePath, String targetPath, boolean probe) {
+ return new RoutingServerProxy(
+ source, sourcePath, targetPath, probe);
}
};
- public static MBeanServer cd(MBeanServer source, String sourcePath) {
+ public static MBeanServer cd(
+ MBeanServer source, String sourcePath, boolean probe) {
return RoutingProxy.cd(RoutingServerProxy.class, FACTORY,
- source, sourcePath);
+ source, sourcePath, probe);
}
}
diff -r 773df43a0f6a -r 3cb2a607c347 jdk/src/share/classes/com/sun/jmx/remote/util/EventClientConnection.java
--- a/jdk/src/share/classes/com/sun/jmx/remote/util/EventClientConnection.java Wed Jul 05 16:43:43 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/remote/util/EventClientConnection.java Wed Jul 05 16:44:09 2017 +0200
@@ -430,13 +430,11 @@
* 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
+ * @return the MBeanServerConnection.
**/
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");
diff -r 773df43a0f6a -r 3cb2a607c347 jdk/src/share/classes/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnectionOldImpl.java
--- a/jdk/src/share/classes/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnectionOldImpl.java Wed Jul 05 16:43:43 2017 +0200
+++ b/jdk/src/share/classes/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnectionOldImpl.java Wed Jul 05 16:44:09 2017 +0200
@@ -497,6 +497,10 @@
delegate.setFixedLengthStreamingMode(contentLength);
}
+ public void setFixedLengthStreamingMode(long contentLength) {
+ delegate.setFixedLengthStreamingMode(contentLength);
+ }
+
public void setChunkedStreamingMode (int chunklen) {
delegate.setChunkedStreamingMode(chunklen);
}
diff -r 773df43a0f6a -r 3cb2a607c347 jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java
--- a/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java Wed Jul 05 16:43:43 2017 +0200
+++ b/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java Wed Jul 05 16:44:09 2017 +0200
@@ -86,6 +86,8 @@
* the principal name from the configuration is used. In the
* case where the principal property is not set and the principal
* entry also does not exist, the user is prompted for the name.
+ * When this property of entry is set, and useTicketCache
+ * is set to true, only TGT belonging to this principal is used.
*
*
The following is a list of configuration options supported
* for Krb5LoginModule:
@@ -101,18 +103,19 @@
* to false if you do not want this module to use the ticket cache.
* (Default is False).
* This module will
- * search for the tickect
+ * search for the ticket
* cache in the following locations:
- * For Windows 2000, it will use Local Security Authority (LSA) API
- * to get the TGT. On Solaris and Linux
+ * On Solaris and Linux
* it will look for the ticket cache in /tmp/krb5cc_uid
* where the uid is numeric user
* identifier. If the ticket cache is
- * not available in either of the above locations, or if we are on a
- * different Windows platform, it will look for the cache as
+ * not available in the above location, or if we are on a
+ * Windows platform, it will look for the cache as
* {user.home}{file.separator}krb5cc_{user.name}.
* You can override the ticket cache location by using
- * ticketCache
+ * ticketCache.
+ * For Windows, if a ticket cannot be retrieved from the file ticket cache,
+ * it will use Local Security Authority (LSA) API to get the TGT.
*
*
ticketCache:
*
Set this to the name of the ticket
@@ -129,20 +132,20 @@
*
doNotPrompt:
*
Set this to true if you do not want to be
* prompted for the password
- * if credentials can
- * not be obtained from the cache or keytab.(Default is false)
- * If set to true authentication will fail if credentials can
- * not be obtained from the cache or keytab.
+ * if credentials can not be obtained from the cache, the keytab,
+ * or through shared state.(Default is false)
+ * If set to true, credential must be obtained through cache, keytab,
+ * or shared state. Otherwise, authentication will fail.
*
*
useKeyTab:
*
Set this to true if you
* want the module to get the principal's key from the
* the keytab.(default value is False)
- * If keyatb
+ * If keytab
* is not set then
* the module will locate the keytab from the
- * Kerberos configuration file.
- * If it is not specifed in the Kerberos configuration file
+ * Kerberos configuration file.
+ * If it is not specified in the Kerberos configuration file
* then it will look for the file
* {user.home}{file.separator}krb5.keytab.
*
@@ -210,20 +213,34 @@
* exist for the username and password in the shared
* state, or if authentication fails.
*
- * clearPass if, true, this LoginModule clears the
- * username and password stored in the module's shared
- * state after both phases of authentication
- * (login and commit) have completed.
+ * clearPass if, true, this LoginModule clears the
+ * username and password stored in the module's shared
+ * state after both phases of authentication
+ * (login and commit) have completed.
*
+ *
If the principal system property or key is already provided, the value of
+ * "javax.security.auth.login.name" in the shared state is ignored.
+ *
When multiple mechanisms to retrieve a ticket or key is provided, the
+ * preference order looks like this:
+ *
+ *
ticket cache
+ *
keytab
+ *
shared state
+ *
user prompt
+ *
+ *
Note that if any step fails, it will fallback to the next step.
+ * There's only one exception, it the shared state step fails and
+ * useFirstPass=true, no user prompt is made.
*
Examples of some configuration values for Krb5LoginModule in
* JAAS config file and the results are:
*
*
doNotPrompt=true;
*
- *
This is an illegal combination since useTicketCache
- * is not set and the user can not be prompted for the password.
+ *
This is an illegal combination since none of useTicketCache,
+ * useKeyTab, useFirstPass and tryFirstPass
+ * is set and the user can not be prompted for the password.
*
- *
ticketCache = < filename >;
+ *
ticketCache = <filename>;
*
*
This is an illegal combination since useTicketCache
* is not set to true and the ticketCache is set. A configuration error
@@ -240,9 +257,9 @@
*
*
This is an illegal combination since storeKey is set to
* true but the key can not be obtained either by prompting the user or from
- * the keytab.A configuration error will occur.
+ * the keytab, or from the shared state. A configuration error will occur.
*
- *
keyTab = < filename > doNotPrompt=true ;
+ *
keyTab = <filename> doNotPrompt=true ;
*
*
This is an illegal combination since useKeyTab is not set to true and
* the keyTab is set. A configuration error will occur.
@@ -260,7 +277,7 @@
* with the principal and TGT. If the TGT is not available,
* do not prompt the user, instead fail the authentication.
*
Get the TGT from the default cache for the principal and populate the
@@ -269,9 +286,9 @@
* authentication will fail.
*
*
useTicketCache = true
- * ticketCache=< file name >useKeyTab = true
- * keyTab=< keytab filename >
- * principal = < principal name >
+ * ticketCache=<file name>useKeyTab = true
+ * keyTab=<keytab filename>
+ * principal = <principal name>
* doNotPrompt=true;
*
*
Search the cache for the principal's TGT. If it is not available
@@ -281,7 +298,7 @@
* If the key is not available or valid then authentication will fail.
*
The TGT will be obtained from the cache specified.
* The Kerberos principal name used will be the principal name in
@@ -292,8 +309,8 @@
* The Subject will be populated with the TGT.
*
The principal's key will be retrieved from the keytab and added
- * to the Subject's private credentials. If the key
- * is not available, the
- * user will be prompted for the password; the key derived from the password
- * will be added to the Subject's private credentials set. The
- * client's TGT will be retrieved from the ticket cache and added to the
+ *
+ * The client's TGT will be retrieved from the ticket cache and added to the
* Subject's private credentials. If the TGT is not available
- * in the ticket cache, it will be obtained using the authentication
+ * in the ticket cache, or the TGT's client name does not match the principal
+ * name, Java will use a secret key to obtain the TGT using the authentication
* exchange and added to the Subject's private credentials.
+ * This secret key will be first retrieved from the keytab. If the key
+ * is not available, the user will be prompted for the password. In either
+ * case, the key derived from the password will be added to the
+ * Subject's private credentials set.
*
*
isInitiator = false
*
@@ -856,11 +875,13 @@
}
private void validateConfiguration() throws LoginException {
- if (doNotPrompt && !useTicketCache && !useKeyTab)
+ if (doNotPrompt && !useTicketCache && !useKeyTab
+ && !tryFirstPass && !useFirstPass)
throw new LoginException
("Configuration Error"
+ " - either doNotPrompt should be "
- + " false or useTicketCache/useKeyTab "
+ + " false or at least one of useTicketCache, "
+ + " useKeyTab, tryFirstPass and useFirstPass"
+ " should be true");
if (ticketCacheName != null && !useTicketCache)
throw new LoginException
@@ -872,11 +893,12 @@
throw new LoginException
("Configuration Error - useKeyTab should be set to true "
+ "to use the keytab" + keyTabName);
- if (storeKey && doNotPrompt && !useKeyTab)
+ if (storeKey && doNotPrompt && !useKeyTab
+ && !tryFirstPass && !useFirstPass)
throw new LoginException
- ("Configuration Error - either doNotPrompt "
- + "should be set to false or "
- + "useKeyTab must be set to true for storeKey option");
+ ("Configuration Error - either doNotPrompt should be set to "
+ + " false or at least one of tryFirstPass, useFirstPass "
+ + "or useKeyTab must be set to true for storeKey option");
if (renewTGT && !useTicketCache)
throw new LoginException
("Configuration Error"
diff -r 773df43a0f6a -r 3cb2a607c347 jdk/src/share/classes/java/net/HttpURLConnection.java
--- a/jdk/src/share/classes/java/net/HttpURLConnection.java Wed Jul 05 16:43:43 2017 +0200
+++ b/jdk/src/share/classes/java/net/HttpURLConnection.java Wed Jul 05 16:44:09 2017 +0200
@@ -73,11 +73,24 @@
* The fixed content-length when using fixed-length streaming mode.
* A value of -1 means fixed-length streaming mode is disabled
* for output.
+ *
+ *
NOTE: {@link #fixedContentLengthLong} is recommended instead
+ * of this field, as it allows larger content lengths to be set.
+ *
* @since 1.5
*/
protected int fixedContentLength = -1;
/**
+ * The fixed content-length when using fixed-length streaming mode.
+ * A value of {@code -1} means fixed-length streaming mode is disabled
+ * for output.
+ *
+ * @since 1.7
+ */
+ protected long fixedContentLengthLong = -1;
+
+ /**
* Returns the key for the nth header field.
* Some implementations may treat the 0th
* header field as special, i.e. as the status line returned by the HTTP
@@ -109,6 +122,9 @@
* This exception can be queried for the details of the error.
*
* This method must be called before the URLConnection is connected.
+ *
+ * NOTE: {@link #setFixedLengthStreamingMode(long)} is recommended
+ * instead of this method as it allows larger content lengths to be set.
*
* @param contentLength The number of bytes which will be written
* to the OutputStream.
@@ -135,6 +151,52 @@
fixedContentLength = contentLength;
}
+ /**
+ * This method is used to enable streaming of a HTTP request body
+ * without internal buffering, when the content length is known in
+ * advance.
+ *
+ *
An exception will be thrown if the application attempts to write
+ * more data than the indicated content-length, or if the application
+ * closes the OutputStream before writing the indicated amount.
+ *
+ *
When output streaming is enabled, authentication and redirection
+ * cannot be handled automatically. A {@linkplain HttpRetryException} will
+ * be thrown when reading the response if authentication or redirection
+ * are required. This exception can be queried for the details of the
+ * error.
+ *
+ *
This method must be called before the URLConnection is connected.
+ *
+ *
The content length set by invoking this method takes precedence
+ * over any value set by {@link #setFixedLengthStreamingMode(int)}.
+ *
+ * @param contentLength
+ * The number of bytes which will be written to the OutputStream.
+ *
+ * @throws IllegalStateException
+ * if URLConnection is already connected or if a different
+ * streaming mode is already enabled.
+ *
+ * @throws IllegalArgumentException
+ * if a content length less than zero is specified.
+ *
+ * @since 1.7
+ */
+ public void setFixedLengthStreamingMode(long contentLength) {
+ if (connected) {
+ throw new IllegalStateException("Already connected");
+ }
+ if (chunkLength != -1) {
+ throw new IllegalStateException(
+ "Chunked encoding streaming mode set");
+ }
+ if (contentLength < 0) {
+ throw new IllegalArgumentException("invalid content length");
+ }
+ fixedContentLengthLong = contentLength;
+ }
+
/* Default chunk size (including chunk header) if not specified;
* we want to keep this in sync with the one defined in
* sun.net.www.http.ChunkedOutputStream
@@ -170,7 +232,7 @@
if (connected) {
throw new IllegalStateException ("Can't set streaming mode: already connected");
}
- if (fixedContentLength != -1) {
+ if (fixedContentLength != -1 || fixedContentLengthLong != -1) {
throw new IllegalStateException ("Fixed length streaming mode set");
}
chunkLength = chunklen <=0? DEFAULT_CHUNK_SIZE : chunklen;
diff -r 773df43a0f6a -r 3cb2a607c347 jdk/src/share/classes/java/security/cert/CertPathValidatorException.java
--- a/jdk/src/share/classes/java/security/cert/CertPathValidatorException.java Wed Jul 05 16:43:43 2017 +0200
+++ b/jdk/src/share/classes/java/security/cert/CertPathValidatorException.java Wed Jul 05 16:44:09 2017 +0200
@@ -113,7 +113,7 @@
* permitted, and indicates that the cause is nonexistent or unknown.)
*/
public CertPathValidatorException(Throwable cause) {
- this(null, cause);
+ this((cause == null ? null : cause.toString()), cause);
}
/**
diff -r 773df43a0f6a -r 3cb2a607c347 jdk/src/share/classes/javax/management/AttributeList.java
--- a/jdk/src/share/classes/javax/management/AttributeList.java Wed Jul 05 16:43:43 2017 +0200
+++ b/jdk/src/share/classes/javax/management/AttributeList.java Wed Jul 05 16:44:09 2017 +0200
@@ -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
@@ -27,17 +27,23 @@
import java.util.ArrayList;
import java.util.Collection;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
/**
- * Represents a list of values for attributes of an MBean. The methods
- * used for the insertion of {@link javax.management.Attribute
- * Attribute} objects in the AttributeList overrides the
- * corresponding methods in the superclass
- * ArrayList. This is needed in order to insure that the
- * objects contained in the AttributeList are only
- * Attribute objects. This avoids getting an exception
- * when retrieving elements from the AttributeList.
+ *
Represents a list of values for attributes of an MBean. See the
+ * {@link MBeanServerConnection#getAttributes getAttributes} and
+ * {@link MBeanServerConnection#setAttributes setAttributes} methods of
+ * {@link MBeanServer} and {@link MBeanServerConnection}.
+ *
+ *
For compatibility reasons, it is possible, though
+ * highly discouraged, to add objects to an {@code AttributeList} that are
+ * not instances of {@code Attribute}. However, an {@code AttributeList}
+ * can be made type-safe, which means that an attempt to add
+ * an object that is not an {@code Attribute} will produce an {@code
+ * IllegalArgumentException}. An {@code AttributeList} becomes type-safe
+ * when the method {@link #asList()} is called on it.
*
* @since 1.5
*/
@@ -58,8 +64,8 @@
*/
public class AttributeList extends ArrayList