# HG changeset patch # User kvn # Date 1227114571 28800 # Node ID aa40969bfd4c172d5a7cb3f07c24aca8fce59837 # Parent 3c53424bbe3bb77e01b468b4b0140deec33e11fc# Parent dfb39a52c8a8661d119d28cee9fbb5b8949d9f52 Merge diff -r 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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}") diff -r 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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, \ @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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 3c53424bbe3b -r aa40969bfd4c 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 Nov 19 09:09:31 2008 -0800 @@ -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; }