# HG changeset patch # User lana # Date 1403114166 25200 # Node ID e77007eacea5c16a7ce7df499b0abbbc4d520daa # Parent 2dcf544eb7ed5ac6a3f7813a32e33acea7442405# Parent f4f07d09c544cd5a90cce7d4918b67622924db70 Merge diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/make/bsd/makefiles/fastdebug.make --- a/hotspot/make/bsd/makefiles/fastdebug.make Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/make/bsd/makefiles/fastdebug.make Wed Jun 18 10:56:06 2014 -0700 @@ -24,37 +24,30 @@ # Sets make macros for making debug version of VM +# Compiler specific DEBUG_CFLAGS are passed in from gcc.make, sparcWorks.make +# They may also specify FASTDEBUG_CFLAGS, but it defaults to DEBUG_CFLAGS. + +FASTDEBUG_CFLAGS$(FASTDEBUG_CFLAGS) = $(DEBUG_CFLAGS) + # Compiler specific OPT_CFLAGS are passed in from gcc.make, sparcWorks.make OPT_CFLAGS/DEFAULT= $(OPT_CFLAGS) OPT_CFLAGS/BYFILE = $(OPT_CFLAGS/$@)$(OPT_CFLAGS/DEFAULT$(OPT_CFLAGS/$@)) # (OPT_CFLAGS/SLOWER is also available, to alter compilation of buggy files) -ifeq ($(BUILDARCH), ia64) - # Bug in GCC, causes hang. -O1 will override the -O3 specified earlier - OPT_CFLAGS/callGenerator.o += -O1 - OPT_CFLAGS/ciTypeFlow.o += -O1 - OPT_CFLAGS/compile.o += -O1 - OPT_CFLAGS/concurrentMarkSweepGeneration.o += -O1 - OPT_CFLAGS/doCall.o += -O1 - OPT_CFLAGS/generateOopMap.o += -O1 - OPT_CFLAGS/generateOptoStub.o += -O1 - OPT_CFLAGS/graphKit.o += -O1 - OPT_CFLAGS/instanceKlass.o += -O1 - OPT_CFLAGS/interpreterRT_ia64.o += -O1 - OPT_CFLAGS/output.o += -O1 - OPT_CFLAGS/parse1.o += -O1 - OPT_CFLAGS/runtime.o += -O1 - OPT_CFLAGS/synchronizer.o += -O1 -endif - - # If you set HOTSPARC_GENERIC=yes, you disable all OPT_CFLAGS settings CFLAGS$(HOTSPARC_GENERIC) += $(OPT_CFLAGS/BYFILE) # Set the environment variable HOTSPARC_GENERIC to "true" # to inhibit the effect of the previous line on CFLAGS. +# The following lines are copied from debug.make, except that we +# consult FASTDEBUG_CFLAGS instead of DEBUG_CFLAGS. +# Compiler specific DEBUG_CFLAGS are passed in from gcc.make, sparcWorks.make +DEBUG_CFLAGS/DEFAULT= $(FASTDEBUG_CFLAGS) +DEBUG_CFLAGS/BYFILE = $(DEBUG_CFLAGS/$@)$(DEBUG_CFLAGS/DEFAULT$(DEBUG_CFLAGS/$@)) +CFLAGS += $(DEBUG_CFLAGS/BYFILE) + # Linker mapfile MAPFILE = $(GAMMADIR)/make/bsd/makefiles/mapfile-vers-debug ifeq ($(OS_VENDOR), Darwin) diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/make/bsd/makefiles/gcc.make --- a/hotspot/make/bsd/makefiles/gcc.make Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/make/bsd/makefiles/gcc.make Wed Jun 18 10:56:06 2014 -0700 @@ -19,7 +19,7 @@ # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. -# +# # OS_VENDOR = $(shell uname -s) @@ -80,7 +80,7 @@ HOSTCC = $(CC) endif - AS = $(CC) -c + AS = $(CC) -c endif ifeq ($(OS_VENDOR), Darwin) @@ -100,7 +100,7 @@ endif ifeq ($(USE_CLANG), true) - # clang has precompiled headers support by default, but the user can switch + # Clang has precompiled headers support by default, but the user can switch # it off by using 'USE_PRECOMPILED_HEADER=0'. ifdef LP64 ifeq ($(USE_PRECOMPILED_HEADER),) @@ -112,29 +112,29 @@ # Clang produces an error if the PCH file was compiled with other options than the actual compilation unit. USE_PRECOMPILED_HEADER=0 endif - + ifeq ($(USE_PRECOMPILED_HEADER),1) - + ifndef LP64 $(error " Precompiled Headers only supported on 64-bit platforms!") endif - + PRECOMPILED_HEADER_DIR=. PRECOMPILED_HEADER_SRC=$(GAMMADIR)/src/share/vm/precompiled/precompiled.hpp PRECOMPILED_HEADER=$(PRECOMPILED_HEADER_DIR)/precompiled.hpp.pch - + PCH_FLAG = -include precompiled.hpp PCH_FLAG/DEFAULT = $(PCH_FLAG) PCH_FLAG/NO_PCH = -DNO_PCH PCH_FLAG/BY_FILE = $(PCH_FLAG/$@)$(PCH_FLAG/DEFAULT$(PCH_FLAG/$@)) - + VM_PCH_FLAG/LIBJVM = $(PCH_FLAG/BY_FILE) VM_PCH_FLAG/AOUT = VM_PCH_FLAG = $(VM_PCH_FLAG/$(LINK_INTO)) - + # We only use precompiled headers for the JVM build CFLAGS += $(VM_PCH_FLAG) - + # The following files are compiled at various optimization # levels due to optimization issues encountered at the # 'OPT_CFLAGS_DEFAULT' level. The Clang compiler issues a compile @@ -149,7 +149,7 @@ PCH_FLAG/sharedRuntimeTrig.o = $(PCH_FLAG/NO_PCH) PCH_FLAG/sharedRuntimeTrans.o = $(PCH_FLAG/NO_PCH) PCH_FLAG/unsafe.o = $(PCH_FLAG/NO_PCH) - + endif else # ($(USE_CLANG), true) # check for precompiled headers support @@ -272,21 +272,24 @@ CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(WARNING_FLAGS) # Special cases -CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@)) +CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@)) # XXXDARWIN: for _dyld_bind_fully_image_containing_address ifeq ($(OS_VENDOR), Darwin) CFLAGS_WARN/os_bsd.o = $(CFLAGS_WARN/DEFAULT) -Wno-deprecated-declarations endif +# optimization control flags (Used by fastdebug and release variants) +OPT_CFLAGS/NOOPT=-O0 +ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 8 \) \))" "1" + # Allow basic optimizations which don't distrupt debugging. (Principally dead code elimination) + OPT_CFLAGS/DEBUG=-Og +else + # Allow no optimizations. + OPT_CFLAGS/DEBUG=-O0 +endif OPT_CFLAGS/SIZE=-Os OPT_CFLAGS/SPEED=-O3 -# Hotspot uses very unstrict aliasing turn this optimization off -# This option is added to CFLAGS rather than OPT_CFLAGS -# so that OPT_CFLAGS overrides get this option too. -CFLAGS += -fno-strict-aliasing - -# The flags to use for an Optimized g++ build ifeq ($(OS_VENDOR), Darwin) # use -Os by default, unless -O3 can be proved to be worth the cost, as per policy # @@ -295,6 +298,11 @@ OPT_CFLAGS_DEFAULT ?= SPEED endif +# Hotspot uses very unstrict aliasing turn this optimization off +# This option is added to CFLAGS rather than OPT_CFLAGS +# so that OPT_CFLAGS overrides get this option too. +CFLAGS += -fno-strict-aliasing + ifdef OPT_CFLAGS ifneq ("$(origin OPT_CFLAGS)", "command line") $(error " Use OPT_EXTRAS instead of OPT_CFLAGS to add extra flags to OPT_CFLAGS.") @@ -309,8 +317,6 @@ OPT_CFLAGS += -fno-expensive-optimizations endif -OPT_CFLAGS/NOOPT=-O0 - # Work around some compiler bugs. ifeq ($(USE_CLANG), true) ifeq ($(shell expr $(CC_VER_MAJOR) = 4 \& $(CC_VER_MINOR) = 2), 1) @@ -338,7 +344,7 @@ endif ifeq ($(OS_VENDOR), Darwin) - # Setting these parameters makes it an error to link to macosx APIs that are + # Setting these parameters makes it an error to link to macosx APIs that are # newer than the given OS version and makes the linked binaries compatible even # if built on a newer version of the OS. # The expected format is X.Y.Z @@ -371,10 +377,22 @@ ifeq ($(USE_CLANG),) # statically link libgcc and/or libgcc_s, libgcc does not exist before gcc-3.x. - ifneq ("${CC_VER_MAJOR}", "2") + ifneq ($(CC_VER_MAJOR), 2) STATIC_LIBGCC += -static-libgcc endif + ifneq ($(OS_VENDOR), Darwin) + ifneq (, findstring(debug,$(BUILD_FLAVOR))) + # for relocations read-only + LFLAGS += -Xlinker -z -Xlinker relro + + ifeq ($(BUILD_FLAVOR), debug) + # disable incremental relocations linking + LFLAGS += -Xlinker -z -Xlinker now + endif + endif + endif + ifeq ($(BUILDARCH), ia64) LFLAGS += -Wl,-relax endif @@ -425,6 +443,14 @@ CFLAGS += -flimit-debug-info endif +ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 8 \) \))" "1" + # Allow basic optimizations which don't distrupt debugging. (Principally dead code elimination) + DEBUG_CFLAGS=-Og +else + # Allow no optimizations. + DEBUG_CFLAGS=-O0 +endif + # DEBUG_BINARIES uses full -g debug information for all configs ifeq ($(DEBUG_BINARIES), true) CFLAGS += -g @@ -441,9 +467,14 @@ DEBUG_CFLAGS/ppc = -g DEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH)) ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),) - DEBUG_CFLAGS += -gstabs + ifeq ($(USE_CLANG), true) + # Clang doesn't understand -gstabs + DEBUG_CFLAGS += -g + else + DEBUG_CFLAGS += -gstabs + endif endif - + ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) FASTDEBUG_CFLAGS/ia64 = -g FASTDEBUG_CFLAGS/amd64 = -g @@ -458,7 +489,7 @@ FASTDEBUG_CFLAGS += -gstabs endif endif - + OPT_CFLAGS/ia64 = -g OPT_CFLAGS/amd64 = -g OPT_CFLAGS/arm = -g @@ -475,6 +506,18 @@ endif endif +ifeq ($(USE_CLANG),) + # Enable bounds checking. + # _FORTIFY_SOURCE appears in GCC 4.0+ + ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) )" "1" + # compile time size bounds checks + FASTDEBUG_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 + + # and runtime size bounds checks and paranoid stack smashing checks. + DEBUG_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fstack-protector-all --param ssp-buffer-size=1 + endif +endif + # If we are building HEADLESS, pass on to VM # so it can set the java.awt.headless property ifdef HEADLESS diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/make/linux/makefiles/fastdebug.make --- a/hotspot/make/linux/makefiles/fastdebug.make Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/make/linux/makefiles/fastdebug.make Wed Jun 18 10:56:06 2014 -0700 @@ -24,6 +24,11 @@ # Sets make macros for making debug version of VM +# Compiler specific DEBUG_CFLAGS are passed in from gcc.make, sparcWorks.make +# They may also specify FASTDEBUG_CFLAGS, but it defaults to DEBUG_CFLAGS. + +FASTDEBUG_CFLAGS$(FASTDEBUG_CFLAGS) = $(DEBUG_CFLAGS) + # Compiler specific OPT_CFLAGS are passed in from gcc.make, sparcWorks.make OPT_CFLAGS/DEFAULT= $(OPT_CFLAGS) OPT_CFLAGS/BYFILE = $(OPT_CFLAGS/$@)$(OPT_CFLAGS/DEFAULT$(OPT_CFLAGS/$@)) @@ -54,6 +59,12 @@ # Set the environment variable HOTSPARC_GENERIC to "true" # to inhibit the effect of the previous line on CFLAGS. +# The following lines are copied from debug.make, except that we +# consult FASTDEBUG_CFLAGS instead of DEBUG_CFLAGS. +# Compiler specific DEBUG_CFLAGS are passed in from gcc.make, sparcWorks.make +DEBUG_CFLAGS/DEFAULT= $(FASTDEBUG_CFLAGS) +DEBUG_CFLAGS/BYFILE = $(DEBUG_CFLAGS/$@)$(DEBUG_CFLAGS/DEFAULT$(DEBUG_CFLAGS/$@)) +CFLAGS += $(DEBUG_CFLAGS/BYFILE) # Linker mapfile MAPFILE = $(GAMMADIR)/make/linux/makefiles/mapfile-vers-debug diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/make/linux/makefiles/gcc.make --- a/hotspot/make/linux/makefiles/gcc.make Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/make/linux/makefiles/gcc.make Wed Jun 18 10:56:06 2014 -0700 @@ -19,7 +19,7 @@ # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. -# +# # #------------------------------------------------------------------------ @@ -62,7 +62,6 @@ CC_VER_MINOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f2) endif - ifeq ($(USE_CLANG), true) # Clang has precompiled headers support by default, but the user can switch # it off by using 'USE_PRECOMPILED_HEADER=0'. @@ -104,7 +103,7 @@ # But Clang doesn't support a precompiled header which was compiled with -O3 # to be used in a compilation unit which uses '-O0'. We could also prepare an # extra '-O0' PCH file for the opt build and use it here, but it's probably - # not worth the effoert as long as only two files need this special handling. + # not worth the effort as long as only two files need this special handling. PCH_FLAG/loopTransform.o = $(PCH_FLAG/NO_PCH) PCH_FLAG/sharedRuntimeTrig.o = $(PCH_FLAG/NO_PCH) PCH_FLAG/sharedRuntimeTrans.o = $(PCH_FLAG/NO_PCH) @@ -226,19 +225,28 @@ endif CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(WARNING_FLAGS) + # Special cases -CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@)) +CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@)) -# The flags to use for an Optimized g++ build +# optimization control flags (Used by fastdebug and release variants) +OPT_CFLAGS/NOOPT=-O0 +ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 8 \) \))" "1" + # Allow basic optimizations which don't distrupt debugging. (Principally dead code elimination) + OPT_CFLAGS/DEBUG=-Og +else + # Allow no optimizations. + OPT_CFLAGS/DEBUG=-O0 +endif OPT_CFLAGS/SIZE=-Os OPT_CFLAGS/SPEED=-O3 +OPT_CFLAGS_DEFAULT ?= SPEED + # Hotspot uses very unstrict aliasing turn this optimization off # This option is added to CFLAGS rather than OPT_CFLAGS # so that OPT_CFLAGS overrides get this option too. -CFLAGS += -fno-strict-aliasing - -OPT_CFLAGS_DEFAULT ?= SPEED +CFLAGS += -fno-strict-aliasing ifdef OPT_CFLAGS ifneq ("$(origin OPT_CFLAGS)", "command line") @@ -248,14 +256,12 @@ OPT_CFLAGS = $(OPT_CFLAGS/$(OPT_CFLAGS_DEFAULT)) $(OPT_EXTRAS) -# The gcc compiler segv's on ia64 when compiling bytecodeInterpreter.cpp +# The gcc compiler segv's on ia64 when compiling bytecodeInterpreter.cpp # if we use expensive-optimizations ifeq ($(BUILDARCH), ia64) OPT_CFLAGS += -fno-expensive-optimizations endif -OPT_CFLAGS/NOOPT=-O0 - # Work around some compiler bugs. ifeq ($(USE_CLANG), true) ifeq ($(shell expr $(CC_VER_MAJOR) = 4 \& $(CC_VER_MINOR) = 2), 1) @@ -271,7 +277,7 @@ # Flags for generating make dependency flags. DEPFLAGS = -MMD -MP -MF $(DEP_DIR)/$(@:%=%.d) ifeq ($(USE_CLANG),) - ifneq ("${CC_VER_MAJOR}", "2") + ifneq ($(CC_VER_MAJOR), 2) DEPFLAGS += -fpch-deps endif endif @@ -282,21 +288,26 @@ # statically link libstdc++.so, work with gcc but ignored by g++ STATIC_STDCXX = -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic +# Enable linker optimization +LFLAGS += -Xlinker -O1 + ifeq ($(USE_CLANG),) - # statically link libgcc and/or libgcc_s, libgcc does not exist before gcc-3.x. - ifneq ("${CC_VER_MAJOR}", "2") - STATIC_LIBGCC += -static-libgcc + STATIC_LIBGCC += -static-libgcc + + ifneq (, findstring(debug,$(BUILD_FLAVOR))) + # for relocations read-only + LFLAGS += -Xlinker -z -Xlinker relro + + ifeq ($(BUILD_FLAVOR), debug) + # disable incremental relocations linking + LFLAGS += -Xlinker -z -Xlinker now + endif endif ifeq ($(BUILDARCH), ia64) LFLAGS += -Wl,-relax endif -endif -# Enable linker optimization -LFLAGS += -Xlinker -O1 - -ifeq ($(USE_CLANG),) # If this is a --hash-style=gnu system, use --hash-style=both # The gnu .hash section won't work on some Linux systems like SuSE 10. _HAS_HASH_STYLE_GNU:=$(shell $(CC) -dumpspecs | grep -- '--hash-style=gnu') @@ -333,6 +344,14 @@ CFLAGS += -flimit-debug-info endif +ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 8 \) \))" "1" + # Allow basic optimizations which don't distrupt debugging. (Principally dead code elimination) + DEBUG_CFLAGS=-Og +else + # Allow no optimizations. + DEBUG_CFLAGS=-O0 +endif + # DEBUG_BINARIES uses full -g debug information for all configs ifeq ($(DEBUG_BINARIES), true) CFLAGS += -g @@ -355,6 +374,18 @@ endif endif +ifeq ($(USE_CLANG),) + # Enable bounds checking. + # _FORTIFY_SOURCE appears in GCC 4.0+ + ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) )" "1" + # compile time size bounds checks + FASTDEBUG_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 + + # and runtime size bounds checks and paranoid stack smashing checks. + DEBUG_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fstack-protector-all --param ssp-buffer-size=1 + endif +endif + # If we are building HEADLESS, pass on to VM # so it can set the java.awt.headless property ifdef HEADLESS diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/make/solaris/makefiles/gcc.make --- a/hotspot/make/solaris/makefiles/gcc.make Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/make/solaris/makefiles/gcc.make Wed Jun 18 10:56:06 2014 -0700 @@ -19,7 +19,7 @@ # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. -# +# # #------------------------------------------------------------------------ @@ -40,7 +40,7 @@ CC_VER_MAJOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f1) CC_VER_MINOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f2) -# Check for the versions of C++ and C compilers ($CXX and $CC) used. +# Check for the versions of C++ and C compilers ($CXX and $CC) used. # Get the last thing on the line that looks like x.x+ (x is a digit). COMPILER_REV := \ @@ -98,7 +98,7 @@ ifeq ($(BUILDARCH), amd64) ASFLAGS += -march=k8 -march=amd64 -LFLAGS += -march=k8 +LFLAGS += -march=k8 endif @@ -115,21 +115,44 @@ endif -# Compiler warnings are treated as errors -WARNINGS_ARE_ERRORS = -Werror +# Compiler warnings are treated as errors +WARNINGS_ARE_ERRORS = -Werror + # Enable these warnings. See 'info gcc' about details on these options WARNING_FLAGS = -Wpointer-arith -Wconversion -Wsign-compare -Wundef -Wformat=2 CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(WARNING_FLAGS) -# Special cases -CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@)) + +# Special cases +CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@)) -# The flags to use for an Optimized g++ build -OPT_CFLAGS += -O3 +# optimization control flags (Used by fastdebug and release variants) +OPT_CFLAGS/NOOPT=-O0 +ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 8 \) \))" "1" + # Allow basic optimizations which don't distrupt debugging. (Principally dead code elimination) + OPT_CFLAGS/DEBUG=-Og ++else + # Allow no optimizations. + OPT_CFLAGS/DEBUG=-O0 +endif +OPT_CFLAGS/SIZE=-Os +OPT_CFLAGS/SPEED=-O3 + +OPT_CFLAGS_DEFAULT ?= SPEED # Hotspot uses very unstrict aliasing turn this optimization off -OPT_CFLAGS += -fno-strict-aliasing +# This option is added to CFLAGS rather than OPT_CFLAGS +# so that OPT_CFLAGS overrides get this option too. +CFLAGS += -fno-strict-aliasing -# The gcc compiler segv's on ia64 when compiling bytecodeInterpreter.cpp +ifdef OPT_CFLAGS + ifneq ("$(origin OPT_CFLAGS)", "command line") + $(error " Use OPT_EXTRAS instead of OPT_CFLAGS to add extra flags to OPT_CFLAGS.") + endif +endif + +OPT_CFLAGS = $(OPT_CFLAGS/$(OPT_CFLAGS_DEFAULT)) $(OPT_EXTRAS) + +# The gcc compiler segv's on ia64 when compiling bytecodeInterpreter.cpp # if we use expensive-optimizations # Note: all ia64 setting reflect the ones for linux # No actial testing was performed: there is no Solaris on ia64 presently @@ -137,10 +160,20 @@ OPT_CFLAGS/bytecodeInterpreter.o += -fno-expensive-optimizations endif -OPT_CFLAGS/NOOPT=-O0 +# Work around some compiler bugs. +ifeq ($(USE_CLANG), true) + ifeq ($(shell expr $(CC_VER_MAJOR) = 4 \& $(CC_VER_MINOR) = 2), 1) + OPT_CFLAGS/loopTransform.o += $(OPT_CFLAGS/NOOPT) + endif +else + # 6835796. Problem in GCC 4.3.0 with mulnode.o optimized compilation. + ifeq ($(shell expr $(CC_VER_MAJOR) = 4 \& $(CC_VER_MINOR) = 3), 1) + OPT_CFLAGS/mulnode.o += $(OPT_CFLAGS/NOOPT) + endif +endif # Flags for generating make dependency flags. -ifneq ("${CC_VER_MAJOR}", "2") +ifneq ($(CC_VER_MAJOR), 2) DEPFLAGS = -fpch-deps -MMD -MP -MF $(DEP_DIR)/$(@:%=%.d) endif @@ -155,26 +188,37 @@ # statically link libstdc++.so, work with gcc but ignored by g++ STATIC_STDCXX = -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic -# statically link libgcc and/or libgcc_s, libgcc does not exist before gcc-3.x. -ifneq ("${CC_VER_MAJOR}", "2") -STATIC_LIBGCC += -static-libgcc -endif - -ifeq ($(BUILDARCH), ia64) -# Note: all ia64 setting reflect the ones for linux -# No actial testing was performed: there is no Solaris on ia64 presently -LFLAGS += -Wl,-relax -endif ifdef USE_GNULD -# Enable linker optimization -LFLAGS += -Xlinker -O1 + # statically link libgcc and/or libgcc_s, libgcc does not exist before gcc-3.x. + ifneq ($(CC_VER_MAJOR), 2) + STATIC_LIBGCC += -static-libgcc + endif + + # Enable linker optimization + LFLAGS += -Xlinker -O1 + + ifneq (, findstring(debug,$(BUILD_FLAVOR))) + # for relocations read-only + LFLAGS += -Xlinker -z -Xlinker relro -# Use $(MAPFLAG:FILENAME=real_file_name) to specify a map file. -MAPFLAG = -Xlinker --version-script=FILENAME -else -MAPFLAG = -Xlinker -M -Xlinker FILENAME -endif + ifeq ($(BUILD_FLAVOR), debug) + # disable incremental relocations linking + LFLAGS += -Xlinker -z -Xlinker now + endif + endif + + ifeq ($(BUILDARCH), ia64) + # Note: all ia64 setting reflect the ones for linux + # No actual testing was performed: there is no Solaris on ia64 presently + LFLAGS += -Wl,-relax + endif + + # Use $(MAPFLAG:FILENAME=real_file_name) to specify a map file. + MAPFLAG = -Xlinker --version-script=FILENAME +else + MAPFLAG = -Xlinker -M -Xlinker FILENAME +endif # Use $(SONAMEFLAG:SONAME=soname) to specify the intrinsic name of a shared obj SONAMEFLAG = -Xlinker -soname=SONAME @@ -185,15 +229,34 @@ #------------------------------------------------------------------------ # Debug flags -# Use the stabs format for debugging information (this is the default -# on gcc-2.91). It's good enough, has all the information about line -# numbers and local variables, and libjvm.so is only about 16M. -# Change this back to "-g" if you want the most expressive format. -# (warning: that could easily inflate libjvm.so to 150M!) -# Note: The Itanium gcc compiler crashes when using -gstabs. -DEBUG_CFLAGS/ia64 = -g -DEBUG_CFLAGS/amd64 = -g -DEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH)) -ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),) -DEBUG_CFLAGS += -gstabs -endif +ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 8 \) \))" "1" + # Allow basic optimizations which don't distrupt debugging. (Principally dead code elimination) + DEBUG_CFLAGS=-Og +else + # Allow no optimizations. + DEBUG_CFLAGS=-O0 +endif + + +# Use the stabs format for debugging information (this is the default +# on gcc-2.91). It's good enough, has all the information about line +# numbers and local variables, and libjvm.so is only about 16M. +# Change this back to "-g" if you want the most expressive format. +# (warning: that could easily inflate libjvm.so to 150M!) +# Note: The Itanium gcc compiler crashes when using -gstabs. +DEBUG_CFLAGS/ia64 = -g +DEBUG_CFLAGS/amd64 = -g +DEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH)) +ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),) + DEBUG_CFLAGS += -gstabs +endif + +# Enable bounds checking. +# _FORTIFY_SOURCE appears in GCC 4.0+ +ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) )" "1" + # compile time size bounds checks + FASTDEBUG_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 + + # and runtime size bounds checks and paranoid stack smashing checks. + DEBUG_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fstack-protector-all --param ssp-buffer-size=1 +endif diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/cpu/ppc/vm/ppc.ad --- a/hotspot/src/cpu/ppc/vm/ppc.ad Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/cpu/ppc/vm/ppc.ad Wed Jun 18 10:56:06 2014 -0700 @@ -1285,9 +1285,9 @@ void MachConstantBaseNode::postalloc_expand(GrowableArray *nodes, PhaseRegAlloc *ra_) { Compile *C = ra_->C; - iRegPdstOper *op_dst = new (C) iRegPdstOper(); - MachNode *m1 = new (C) loadToc_hiNode(); - MachNode *m2 = new (C) loadToc_loNode(); + iRegPdstOper *op_dst = new iRegPdstOper(); + MachNode *m1 = new loadToc_hiNode(); + MachNode *m2 = new loadToc_loNode(); m1->add_req(NULL); m2->add_req(NULL, m1); @@ -2232,9 +2232,9 @@ MachTypeNode *Matcher::make_decode_node(Compile *C) { assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0, "This method is only implemented for unscaled cOops mode so far"); - MachTypeNode *decode = new (C) decodeN_unscaledNode(); - decode->set_opnd_array(0, new (C) iRegPdstOper()); - decode->set_opnd_array(1, new (C) iRegNsrcOper()); + MachTypeNode *decode = new decodeN_unscaledNode(); + decode->set_opnd_array(0, new iRegPdstOper()); + decode->set_opnd_array(1, new iRegNsrcOper()); return decode; } */ @@ -2600,20 +2600,20 @@ const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; if (large_constant_pool) { // Create new nodes. - loadConL_hiNode *m1 = new (C) loadConL_hiNode(); - loadConL_loNode *m2 = new (C) loadConL_loNode(); + loadConL_hiNode *m1 = new loadConL_hiNode(); + loadConL_loNode *m2 = new loadConL_loNode(); // inputs for new nodes m1->add_req(NULL, toc); m2->add_req(NULL, m1); // operands for new nodes - m1->_opnds[0] = new (C) iRegLdstOper(); // dst - m1->_opnds[1] = immSrc; // src - m1->_opnds[2] = new (C) iRegPdstOper(); // toc - m2->_opnds[0] = new (C) iRegLdstOper(); // dst - m2->_opnds[1] = immSrc; // src - m2->_opnds[2] = new (C) iRegLdstOper(); // base + m1->_opnds[0] = new iRegLdstOper(); // dst + m1->_opnds[1] = immSrc; // src + m1->_opnds[2] = new iRegPdstOper(); // toc + m2->_opnds[0] = new iRegLdstOper(); // dst + m2->_opnds[1] = immSrc; // src + m2->_opnds[2] = new iRegLdstOper(); // base // Initialize ins_attrib TOC fields. m1->_const_toc_offset = -1; @@ -2633,15 +2633,15 @@ nodes._last = nodes._large_lo; assert(m2->bottom_type()->isa_long(), "must be long"); } else { - loadConLNode *m2 = new (C) loadConLNode(); + loadConLNode *m2 = new loadConLNode(); // inputs for new nodes m2->add_req(NULL, toc); // operands for new nodes - m2->_opnds[0] = new (C) iRegLdstOper(); // dst - m2->_opnds[1] = immSrc; // src - m2->_opnds[2] = new (C) iRegPdstOper(); // toc + m2->_opnds[0] = new iRegLdstOper(); // dst + m2->_opnds[1] = immSrc; // src + m2->_opnds[2] = new iRegPdstOper(); // toc // Initialize ins_attrib instruction offset. m2->_cbuf_insts_offset = -1; @@ -2750,20 +2750,20 @@ const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; if (large_constant_pool) { // Create new nodes. - loadConP_hiNode *m1 = new (C) loadConP_hiNode(); - loadConP_loNode *m2 = new (C) loadConP_loNode(); + loadConP_hiNode *m1 = new loadConP_hiNode(); + loadConP_loNode *m2 = new loadConP_loNode(); // inputs for new nodes m1->add_req(NULL, n_toc); m2->add_req(NULL, m1); // operands for new nodes - m1->_opnds[0] = new (C) iRegPdstOper(); // dst - m1->_opnds[1] = op_src; // src - m1->_opnds[2] = new (C) iRegPdstOper(); // toc - m2->_opnds[0] = new (C) iRegPdstOper(); // dst - m2->_opnds[1] = op_src; // src - m2->_opnds[2] = new (C) iRegLdstOper(); // base + m1->_opnds[0] = new iRegPdstOper(); // dst + m1->_opnds[1] = op_src; // src + m1->_opnds[2] = new iRegPdstOper(); // toc + m2->_opnds[0] = new iRegPdstOper(); // dst + m2->_opnds[1] = op_src; // src + m2->_opnds[2] = new iRegLdstOper(); // base // Initialize ins_attrib TOC fields. m1->_const_toc_offset = -1; @@ -2777,15 +2777,15 @@ nodes->push(m2); assert(m2->bottom_type()->isa_ptr(), "must be ptr"); } else { - loadConPNode *m2 = new (C) loadConPNode(); + loadConPNode *m2 = new loadConPNode(); // inputs for new nodes m2->add_req(NULL, n_toc); // operands for new nodes - m2->_opnds[0] = new (C) iRegPdstOper(); // dst - m2->_opnds[1] = op_src; // src - m2->_opnds[2] = new (C) iRegPdstOper(); // toc + m2->_opnds[0] = new iRegPdstOper(); // dst + m2->_opnds[1] = op_src; // src + m2->_opnds[2] = new iRegPdstOper(); // toc // Register allocation for new nodes. ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); @@ -2802,9 +2802,9 @@ MachNode *m2; if (large_constant_pool) { - m2 = new (C) loadConFCompNode(); + m2 = new loadConFCompNode(); } else { - m2 = new (C) loadConFNode(); + m2 = new loadConFNode(); } // inputs for new nodes m2->add_req(NULL, n_toc); @@ -2812,7 +2812,7 @@ // operands for new nodes m2->_opnds[0] = op_dst; m2->_opnds[1] = op_src; - m2->_opnds[2] = new (C) iRegPdstOper(); // constanttablebase + m2->_opnds[2] = new iRegPdstOper(); // constanttablebase // register allocation for new nodes ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); @@ -2826,9 +2826,9 @@ MachNode *m2; if (large_constant_pool) { - m2 = new (C) loadConDCompNode(); + m2 = new loadConDCompNode(); } else { - m2 = new (C) loadConDNode(); + m2 = new loadConDNode(); } // inputs for new nodes m2->add_req(NULL, n_toc); @@ -2836,7 +2836,7 @@ // operands for new nodes m2->_opnds[0] = op_dst; m2->_opnds[1] = op_src; - m2->_opnds[2] = new (C) iRegPdstOper(); // constanttablebase + m2->_opnds[2] = new iRegPdstOper(); // constanttablebase // register allocation for new nodes ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); @@ -2918,15 +2918,15 @@ if (VM_Version::has_isel()) { // use isel instruction with Power 7 - cmpP_reg_imm16Node *n_compare = new (C) cmpP_reg_imm16Node(); - encodeP_subNode *n_sub_base = new (C) encodeP_subNode(); - encodeP_shiftNode *n_shift = new (C) encodeP_shiftNode(); - cond_set_0_oopNode *n_cond_set = new (C) cond_set_0_oopNode(); + cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); + encodeP_subNode *n_sub_base = new encodeP_subNode(); + encodeP_shiftNode *n_shift = new encodeP_shiftNode(); + cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); n_compare->add_req(n_region, n_src); n_compare->_opnds[0] = op_crx; n_compare->_opnds[1] = op_src; - n_compare->_opnds[2] = new (C) immL16Oper(0); + n_compare->_opnds[2] = new immL16Oper(0); n_sub_base->add_req(n_region, n_src); n_sub_base->_opnds[0] = op_dst; @@ -2956,10 +2956,10 @@ } else { // before Power 7 - moveRegNode *n_move = new (C) moveRegNode(); - cmpP_reg_imm16Node *n_compare = new (C) cmpP_reg_imm16Node(); - encodeP_shiftNode *n_shift = new (C) encodeP_shiftNode(); - cond_sub_baseNode *n_sub_base = new (C) cond_sub_baseNode(); + moveRegNode *n_move = new moveRegNode(); + cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); + encodeP_shiftNode *n_shift = new encodeP_shiftNode(); + cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); n_move->add_req(n_region, n_src); n_move->_opnds[0] = op_dst; @@ -2971,7 +2971,7 @@ n_compare->_opnds[0] = op_crx; n_compare->_opnds[1] = op_src; - n_compare->_opnds[2] = new (C) immL16Oper(0); + n_compare->_opnds[2] = new immL16Oper(0); n_sub_base->add_req(n_region, n_compare, n_src); n_sub_base->_opnds[0] = op_dst; @@ -3000,13 +3000,13 @@ enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ - encodeP_subNode *n1 = new (C) encodeP_subNode(); + encodeP_subNode *n1 = new encodeP_subNode(); n1->add_req(n_region, n_src); n1->_opnds[0] = op_dst; n1->_opnds[1] = op_src; n1->_bottom_type = _bottom_type; - encodeP_shiftNode *n2 = new (C) encodeP_shiftNode(); + encodeP_shiftNode *n2 = new encodeP_shiftNode(); n2->add_req(n_region, n1); n2->_opnds[0] = op_dst; n2->_opnds[1] = op_dst; @@ -3020,13 +3020,13 @@ %} enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ - decodeN_shiftNode *n_shift = new (C) decodeN_shiftNode(); - cmpN_reg_imm0Node *n_compare = new (C) cmpN_reg_imm0Node(); + decodeN_shiftNode *n_shift = new decodeN_shiftNode(); + cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); n_compare->add_req(n_region, n_src); n_compare->_opnds[0] = op_crx; n_compare->_opnds[1] = op_src; - n_compare->_opnds[2] = new (C) immN_0Oper(TypeNarrowOop::NULL_PTR); + n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); n_shift->add_req(n_region, n_src); n_shift->_opnds[0] = op_dst; @@ -3036,13 +3036,13 @@ if (VM_Version::has_isel()) { // use isel instruction with Power 7 - decodeN_addNode *n_add_base = new (C) decodeN_addNode(); + decodeN_addNode *n_add_base = new decodeN_addNode(); n_add_base->add_req(n_region, n_shift); n_add_base->_opnds[0] = op_dst; n_add_base->_opnds[1] = op_dst; n_add_base->_bottom_type = _bottom_type; - cond_set_0_ptrNode *n_cond_set = new (C) cond_set_0_ptrNode(); + cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); n_cond_set->add_req(n_region, n_compare, n_add_base); n_cond_set->_opnds[0] = op_dst; n_cond_set->_opnds[1] = op_crx; @@ -3064,7 +3064,7 @@ } else { // before Power 7 - cond_add_baseNode *n_add_base = new (C) cond_add_baseNode(); + cond_add_baseNode *n_add_base = new cond_add_baseNode(); n_add_base->add_req(n_region, n_compare, n_shift); n_add_base->_opnds[0] = op_dst; @@ -3086,13 +3086,13 @@ %} enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ - decodeN_shiftNode *n1 = new (C) decodeN_shiftNode(); + decodeN_shiftNode *n1 = new decodeN_shiftNode(); n1->add_req(n_region, n_src); n1->_opnds[0] = op_dst; n1->_opnds[1] = op_src; n1->_bottom_type = _bottom_type; - decodeN_addNode *n2 = new (C) decodeN_addNode(); + decodeN_addNode *n2 = new decodeN_addNode(); n2->add_req(n_region, n1); n2->_opnds[0] = op_dst; n2->_opnds[1] = op_dst; @@ -3388,7 +3388,7 @@ // Create new nodes. // Make an operand with the bit pattern to load as float. - immLOper *op_repl = new (C) immLOper((jlong)replicate_immF(op_src->constantF())); + immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); loadConLNodesTuple loadConLNodes = loadConLNodesTuple_create(C, ra_, n_toc, op_repl, @@ -3611,11 +3611,11 @@ // Create the nodes for loading the IC from the TOC. loadConLNodesTuple loadConLNodes_IC = - loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper((jlong)Universe::non_oop_word()), + loadConLNodesTuple_create(C, ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); // Create the call node. - CallDynamicJavaDirectSchedNode *call = new (C) CallDynamicJavaDirectSchedNode(); + CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); call->_method_handle_invoke = _method_handle_invoke; call->_vtable_index = _vtable_index; call->_method = _method; @@ -3765,7 +3765,7 @@ #if defined(ABI_ELFv2) jlong entry_address = (jlong) this->entry_point(); assert(entry_address, "need address here"); - loadConLNodes_Entry = loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper(entry_address), + loadConLNodes_Entry = loadConLNodesTuple_create(C, ra_, n_toc, new immLOper(entry_address), OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); #else // Get the struct that describes the function we are about to call. @@ -3777,42 +3777,42 @@ loadConLNodesTuple loadConLNodes_Toc; // Create nodes and operands for loading the entry point. - loadConLNodes_Entry = loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper(entry_address), + loadConLNodes_Entry = loadConLNodesTuple_create(C, ra_, n_toc, new immLOper(entry_address), OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); // Create nodes and operands for loading the env pointer. if (fd->env() != NULL) { - loadConLNodes_Env = loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper((jlong) fd->env()), + loadConLNodes_Env = loadConLNodesTuple_create(C, ra_, n_toc, new immLOper((jlong) fd->env()), OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); } else { loadConLNodes_Env._large_hi = NULL; loadConLNodes_Env._large_lo = NULL; loadConLNodes_Env._small = NULL; - loadConLNodes_Env._last = new (C) loadConL16Node(); - loadConLNodes_Env._last->_opnds[0] = new (C) iRegLdstOper(); - loadConLNodes_Env._last->_opnds[1] = new (C) immL16Oper(0); + loadConLNodes_Env._last = new loadConL16Node(); + loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); + loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); } // Create nodes and operands for loading the Toc point. - loadConLNodes_Toc = loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper((jlong) fd->toc()), + loadConLNodes_Toc = loadConLNodesTuple_create(C, ra_, n_toc, new immLOper((jlong) fd->toc()), OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); #endif // ABI_ELFv2 // mtctr node - MachNode *mtctr = new (C) CallLeafDirect_mtctrNode(); + MachNode *mtctr = new CallLeafDirect_mtctrNode(); assert(loadConLNodes_Entry._last != NULL, "entry must exist"); mtctr->add_req(0, loadConLNodes_Entry._last); - mtctr->_opnds[0] = new (C) iRegLdstOper(); - mtctr->_opnds[1] = new (C) iRegLdstOper(); + mtctr->_opnds[0] = new iRegLdstOper(); + mtctr->_opnds[1] = new iRegLdstOper(); // call node - MachCallLeafNode *call = new (C) CallLeafDirectNode(); + MachCallLeafNode *call = new CallLeafDirectNode(); call->_opnds[0] = _opnds[0]; - call->_opnds[1] = new (C) methodOper((intptr_t) entry_address); // May get set later. + call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. // Make the new call node look like the old one. call->_name = _name; @@ -6050,9 +6050,9 @@ format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask postalloc_expand %{ - MachNode *m1 = new (C) loadConN_hiNode(); - MachNode *m2 = new (C) loadConN_loNode(); - MachNode *m3 = new (C) clearMs32bNode(); + MachNode *m1 = new loadConN_hiNode(); + MachNode *m2 = new loadConN_loNode(); + MachNode *m3 = new clearMs32bNode(); m1->add_req(NULL); m2->add_req(NULL, m1); m3->add_req(NULL, m2); @@ -6117,7 +6117,7 @@ format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask postalloc_expand %{ // Load high bits into register. Sign extended. - MachNode *m1 = new (C) loadConNKlass_hiNode(); + MachNode *m1 = new loadConNKlass_hiNode(); m1->add_req(NULL); m1->_opnds[0] = op_dst; m1->_opnds[1] = op_src; @@ -6127,7 +6127,7 @@ MachNode *m2 = m1; if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { // Value might be 1-extended. Mask out these bits. - m2 = new (C) clearMs32bNode(); + m2 = new clearMs32bNode(); m2->add_req(NULL, m1); m2->_opnds[0] = op_dst; m2->_opnds[1] = op_dst; @@ -6135,7 +6135,7 @@ nodes->push(m2); } - MachNode *m3 = new (C) loadConNKlass_loNode(); + MachNode *m3 = new loadConNKlass_loNode(); m3->add_req(NULL, m2); m3->_opnds[0] = op_dst; m3->_opnds[1] = op_src; @@ -6987,14 +6987,14 @@ format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} postalloc_expand %{ - encodePKlass_sub_baseNode *n1 = new (C) encodePKlass_sub_baseNode(); + encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); n1->add_req(n_region, n_base, n_src); n1->_opnds[0] = op_dst; n1->_opnds[1] = op_base; n1->_opnds[2] = op_src; n1->_bottom_type = _bottom_type; - encodePKlass_shiftNode *n2 = new (C) encodePKlass_shiftNode(); + encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); n2->add_req(n_region, n1); n2->_opnds[0] = op_dst; n2->_opnds[1] = op_dst; @@ -7064,14 +7064,14 @@ format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} postalloc_expand %{ - decodeNKlass_add_baseNode *n1 = new (C) decodeNKlass_add_baseNode(); + decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); n1->add_req(n_region, n_base, n_src); n1->_opnds[0] = op_dst; n1->_opnds[1] = op_base; n1->_opnds[2] = op_src; n1->_bottom_type = _bottom_type; - decodeNKlass_shiftNode *n2 = new (C) decodeNKlass_shiftNode(); + decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); n2->add_req(n_region, n1); n2->_opnds[0] = op_dst; n2->_opnds[1] = op_dst; @@ -9773,8 +9773,8 @@ // // Create new nodes. - MachNode *m1 = new (C) loadConI16Node(); - MachNode *m2 = new (C) cmovI_bso_stackSlotLNode(); + MachNode *m1 = new loadConI16Node(); + MachNode *m2 = new cmovI_bso_stackSlotLNode(); // inputs for new nodes m1->add_req(n_region); @@ -9785,7 +9785,7 @@ // operands for new nodes m1->_opnds[0] = op_dst; - m1->_opnds[1] = new (C) immI16Oper(0); + m1->_opnds[1] = new immI16Oper(0); m2->_opnds[0] = op_dst; m2->_opnds[1] = op_crx; @@ -9942,8 +9942,8 @@ // // Create new nodes. - MachNode *m1 = new (C) loadConL16Node(); - MachNode *m2 = new (C) cmovL_bso_stackSlotLNode(); + MachNode *m1 = new loadConL16Node(); + MachNode *m2 = new cmovL_bso_stackSlotLNode(); // inputs for new nodes m1->add_req(n_region); @@ -9952,7 +9952,7 @@ // operands for new nodes m1->_opnds[0] = op_dst; - m1->_opnds[1] = new (C) immL16Oper(0); + m1->_opnds[1] = new immL16Oper(0); m2->_opnds[0] = op_dst; m2->_opnds[1] = op_crx; m2->_opnds[2] = op_mem; @@ -10288,8 +10288,8 @@ // // Create new nodes. - MachNode *m1 = new (C) loadConI16Node(); - MachNode *m2 = new (C) cmovI_conIvalueMinus1_conIvalue1Node(); + MachNode *m1 = new loadConI16Node(); + MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); // inputs for new nodes m1->add_req(n_region); @@ -10298,7 +10298,7 @@ // operands for new nodes m1->_opnds[0] = op_dst; - m1->_opnds[1] = new (C) immI16Oper(0); + m1->_opnds[1] = new immI16Oper(0); m2->_opnds[0] = op_dst; m2->_opnds[1] = op_crx; @@ -10623,8 +10623,8 @@ // // Create new nodes. - MachNode *m1 = new (C) cmpFUnordered_reg_regNode(); - MachNode *m2 = new (C) cmov_bns_lessNode(); + MachNode *m1 = new cmpFUnordered_reg_regNode(); + MachNode *m2 = new cmov_bns_lessNode(); // inputs for new nodes m1->add_req(n_region, n_src1, n_src2); @@ -10698,8 +10698,8 @@ // // create new nodes - MachNode *m1 = new (C) cmpDUnordered_reg_regNode(); - MachNode *m2 = new (C) cmov_bns_lessNode(); + MachNode *m1 = new cmpDUnordered_reg_regNode(); + MachNode *m2 = new cmov_bns_lessNode(); // inputs for new nodes m1->add_req(n_region, n_src1, n_src2); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/cpu/sparc/vm/assembler_sparc.hpp --- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -123,6 +123,7 @@ fpop2_op3 = 0x35, impdep1_op3 = 0x36, aes3_op3 = 0x36, + sha_op3 = 0x36, alignaddr_op3 = 0x36, faligndata_op3 = 0x36, flog3_op3 = 0x36, @@ -223,7 +224,11 @@ mwtos_opf = 0x119, aes_kexpand0_opf = 0x130, - aes_kexpand2_opf = 0x131 + aes_kexpand2_opf = 0x131, + + sha1_opf = 0x141, + sha256_opf = 0x142, + sha512_opf = 0x143 }; enum op5s { @@ -595,6 +600,11 @@ // AES crypto instructions supported only on certain processors static void aes_only() { assert( VM_Version::has_aes(), "This instruction only works on SPARC with AES instructions support"); } + // SHA crypto instructions supported only on certain processors + static void sha1_only() { assert( VM_Version::has_sha1(), "This instruction only works on SPARC with SHA1"); } + static void sha256_only() { assert( VM_Version::has_sha256(), "This instruction only works on SPARC with SHA256"); } + static void sha512_only() { assert( VM_Version::has_sha512(), "This instruction only works on SPARC with SHA512"); } + // instruction only in VIS1 static void vis1_only() { assert( VM_Version::has_vis1(), "This instruction only works on SPARC with VIS1"); } @@ -1179,7 +1189,6 @@ u_field(3, 29, 25) | immed(true) | simm(simm13a, 13)); } inline void wrfprs( Register d) { v9_only(); emit_int32( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(6, 29, 25)); } - // VIS1 instructions void alignaddr( Register s1, Register s2, Register d ) { vis1_only(); emit_int32( op(arith_op) | rd(d) | op3(alignaddr_op3) | rs1(s1) | opf(alignaddr_opf) | rs2(s2)); } @@ -1203,6 +1212,12 @@ void movwtos( Register s, FloatRegister d ) { vis3_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::S) | op3(mftoi_op3) | opf(mwtos_opf) | rs2(s)); } void movxtod( Register s, FloatRegister d ) { vis3_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(mftoi_op3) | opf(mxtod_opf) | rs2(s)); } + // Crypto SHA instructions + + void sha1() { sha1_only(); emit_int32( op(arith_op) | op3(sha_op3) | opf(sha1_opf)); } + void sha256() { sha256_only(); emit_int32( op(arith_op) | op3(sha_op3) | opf(sha256_opf)); } + void sha512() { sha512_only(); emit_int32( op(arith_op) | op3(sha_op3) | opf(sha512_opf)); } + // Creation Assembler(CodeBuffer* code) : AbstractAssembler(code) { #ifdef CHECK_DELAY diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -1612,13 +1612,10 @@ __ set((intptr_t)os::get_polling_page(), tmp->as_register()); if (info != NULL) { add_debug_info_for_branch(info); - } else { - __ relocate(relocInfo::poll_type); } - int offset = __ offset(); + __ relocate(relocInfo::poll_type); __ ld_ptr(tmp->as_register(), 0, G0); - return offset; } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -872,21 +872,19 @@ void LIRGenerator::do_NewInstance(NewInstance* x) { + print_if_not_loaded(x); + // This instruction can be deoptimized in the slow path : use // O0 as result register. const LIR_Opr reg = result_register_for(x->type()); -#ifndef PRODUCT - if (PrintNotLoaded && !x->klass()->is_loaded()) { - tty->print_cr(" ###class not loaded at new bci %d", x->printable_bci()); - } -#endif + CodeEmitInfo* info = state_for(x, x->state()); LIR_Opr tmp1 = FrameMap::G1_oop_opr; LIR_Opr tmp2 = FrameMap::G3_oop_opr; LIR_Opr tmp3 = FrameMap::G4_oop_opr; LIR_Opr tmp4 = FrameMap::O1_oop_opr; LIR_Opr klass_reg = FrameMap::G5_metadata_opr; - new_instance(reg, x->klass(), tmp1, tmp2, tmp3, tmp4, klass_reg, info); + new_instance(reg, x->klass(), x->is_unresolved(), tmp1, tmp2, tmp3, tmp4, klass_reg, info); LIR_Opr result = rlock_result(x); __ move(reg, result); } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/cpu/sparc/vm/compiledIC_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/compiledIC_sparc.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/cpu/sparc/vm/compiledIC_sparc.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -135,7 +135,7 @@ if (TraceICs) { ResourceMark rm; tty->print_cr("CompiledStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s", - instruction_address(), + p2i(instruction_address()), callee->name_and_sig_as_C_string()); } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/cpu/sparc/vm/debug_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/debug_sparc.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/cpu/sparc/vm/debug_sparc.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -42,20 +42,24 @@ intptr_t *pc = NULL; intptr_t *next_pc = NULL; int count = 0; - tty->print("register window backtrace from %#x:\n", sp); + tty->print_cr("register window backtrace from " INTPTR_FORMAT ":", p2i(sp)); while (sp != NULL && ((intptr_t)sp & 7) == 0 && sp > prev_sp && sp < prev_sp+1000) { pc = next_pc; next_pc = (intptr_t*) sp[I7->sp_offset_in_saved_window()]; - tty->print("[%d] sp=%#x pc=", count, sp); + tty->print("[%d] sp=" INTPTR_FORMAT " pc=", count, p2i(sp)); findpc((intptr_t)pc); if (WizardMode && Verbose) { // print register window contents also - tty->print_cr(" L0..L7: {%#x %#x %#x %#x %#x %#x %#x %#x}", - sp[0+0],sp[0+1],sp[0+2],sp[0+3], - sp[0+4],sp[0+5],sp[0+6],sp[0+7]); - tty->print_cr(" I0..I7: {%#x %#x %#x %#x %#x %#x %#x %#x}", - sp[8+0],sp[8+1],sp[8+2],sp[8+3], - sp[8+4],sp[8+5],sp[8+6],sp[8+7]); + tty->print_cr(" L0..L7: {" + INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " + INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " ", + sp[0+0], sp[0+1], sp[0+2], sp[0+3], + sp[0+4], sp[0+5], sp[0+6], sp[0+7]); + tty->print_cr(" I0..I7: {" + INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " + INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " ", + sp[8+0], sp[8+1], sp[8+2], sp[8+3], + sp[8+4], sp[8+5], sp[8+6], sp[8+7]); // (and print stack frame contents too??) CodeBlob *b = CodeCache::find_blob((address) pc); @@ -74,7 +78,7 @@ count += 1; } if (sp != NULL) - tty->print("[%d] sp=%#x [bogus sp!]", count, sp); + tty->print("[%d] sp=" INTPTR_FORMAT " [bogus sp!]", count, p2i(sp)); } #endif // PRODUCT diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/cpu/sparc/vm/frame_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -557,7 +557,8 @@ // QQQ this assert is invalid (or too strong anyway) sice _pc could // be original pc and frame could have the deopt pc. // assert(_pc == *O7_addr() + pc_return_offset, "frame has wrong pc"); - tty->print_cr("patch_pc at address 0x%x [0x%x -> 0x%x] ", O7_addr(), _pc, pc); + tty->print_cr("patch_pc at address " INTPTR_FORMAT " [" INTPTR_FORMAT " -> " INTPTR_FORMAT "]", + p2i(O7_addr()), p2i(_pc), p2i(pc)); } _cb = CodeCache::find_blob(pc); *O7_addr() = pc - pc_return_offset; diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -1202,7 +1202,7 @@ if ( j != last ) s->print(" - f%d", last); s->print(" = %f", val); s->fill_to(25); - s->print_cr(" (0x%x)", val); + s->print_cr(" (0x%x)", *(int*)&val); j = last + 1; } s->cr(); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -483,7 +483,7 @@ const char* mh_reg_name = has_mh ? "G3_mh" : "G3"; tty->print_cr("MH %s %s="INTPTR_FORMAT " saved_sp=" INTPTR_FORMAT " args=" INTPTR_FORMAT, adaptername, mh_reg_name, - (intptr_t) mh, saved_sp, args); + p2i(mh), p2i(saved_sp), p2i(args)); if (Verbose) { // dumping last frame with frame::describe diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/cpu/sparc/vm/nativeInst_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/nativeInst_sparc.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/cpu/sparc/vm/nativeInst_sparc.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -78,7 +78,7 @@ } void NativeInstruction::print() { - tty->print_cr(INTPTR_FORMAT ": 0x%x", addr_at(0), long_at(0)); + tty->print_cr(INTPTR_FORMAT ": 0x%x", p2i(addr_at(0)), long_at(0)); } void NativeInstruction::set_long_at(int offset, int i) { @@ -142,7 +142,7 @@ } void NativeCall::print() { - tty->print_cr(INTPTR_FORMAT ": call " INTPTR_FORMAT, instruction_address(), destination()); + tty->print_cr(INTPTR_FORMAT ": call " INTPTR_FORMAT, p2i(instruction_address()), p2i(destination())); } @@ -271,7 +271,7 @@ } void NativeFarCall::print() { - tty->print_cr(INTPTR_FORMAT ": call " INTPTR_FORMAT, instruction_address(), destination()); + tty->print_cr(INTPTR_FORMAT ": call " INTPTR_FORMAT, p2i(instruction_address()), p2i(destination())); } bool NativeFarCall::destination_is_compiled_verified_entry_point() { @@ -324,7 +324,7 @@ void NativeMovConstReg::print() { - tty->print_cr(INTPTR_FORMAT ": mov reg, " INTPTR_FORMAT, instruction_address(), data()); + tty->print_cr(INTPTR_FORMAT ": mov reg, " INTPTR_FORMAT, p2i(instruction_address()), data()); } @@ -446,7 +446,7 @@ void NativeMovConstRegPatching::print() { - tty->print_cr(INTPTR_FORMAT ": mov reg, " INTPTR_FORMAT, instruction_address(), data()); + tty->print_cr(INTPTR_FORMAT ": mov reg, 0x%x", p2i(instruction_address()), data()); } @@ -585,9 +585,10 @@ void NativeMovRegMem::print() { if (is_immediate()) { - tty->print_cr(INTPTR_FORMAT ": mov reg, [reg + %x]", instruction_address(), offset()); + // offset is a signed 13-bit immediate, so casting it to int will not lose significant bits + tty->print_cr(INTPTR_FORMAT ": mov reg, [reg + %d]", p2i(instruction_address()), (int)offset()); } else { - tty->print_cr(INTPTR_FORMAT ": mov reg, [reg + reg]", instruction_address()); + tty->print_cr(INTPTR_FORMAT ": mov reg, [reg + reg]", p2i(instruction_address())); } } @@ -689,149 +690,6 @@ // End code for unit testing implementation of NativeMovRegMem class -//-------------------------------------------------------------------------------- - - -void NativeMovRegMemPatching::copy_instruction_to(address new_instruction_address) { - Untested("copy_instruction_to"); - int instruction_size = next_instruction_address() - instruction_address(); - for (int i = 0; i < instruction_size; i += wordSize) { - *(long*)(new_instruction_address + i) = *(long*)(address(this) + i); - } -} - - -void NativeMovRegMemPatching::verify() { - NativeInstruction::verify(); - // make sure code pattern is actually a "ld" or "st" of some sort. - int i0 = long_at(0); - int op3 = inv_op3(i0); - - assert((int)nop_offset == (int)NativeMovConstReg::add_offset, "sethi size ok"); - - if (!(is_op(i0, Assembler::ldst_op) && - inv_immed(i0) && - 0 != (op3 < op3_ldst_int_limit - ? (1 << op3 ) & (op3_mask_ld | op3_mask_st) - : (1 << (op3 - op3_ldst_int_limit)) & (op3_mask_ldf | op3_mask_stf)))) { - int i1 = long_at(ldst_offset); - Register rd = inv_rd(i0); - - op3 = inv_op3(i1); - if (!is_op(i1, Assembler::ldst_op) && rd == inv_rs2(i1) && - 0 != (op3 < op3_ldst_int_limit - ? (1 << op3 ) & (op3_mask_ld | op3_mask_st) - : (1 << (op3 - op3_ldst_int_limit)) & (op3_mask_ldf | op3_mask_stf))) { - fatal("not a ld* or st* op"); - } - } -} - - -void NativeMovRegMemPatching::print() { - if (is_immediate()) { - tty->print_cr(INTPTR_FORMAT ": mov reg, [reg + %x]", instruction_address(), offset()); - } else { - tty->print_cr(INTPTR_FORMAT ": mov reg, [reg + reg]", instruction_address()); - } -} - - -// Code for unit testing implementation of NativeMovRegMemPatching class -void NativeMovRegMemPatching::test() { -#ifdef ASSERT - ResourceMark rm; - CodeBuffer cb("test", 1000, 1000); - MacroAssembler* a = new MacroAssembler(&cb); - NativeMovRegMemPatching* nm; - uint idx = 0; - uint idx1; - int offsets[] = { - 0x0, - 0xffffffff, - 0x7fffffff, - 0x80000000, - 4096, - 4097, - 0x20, - 0x4000, - }; - - VM_Version::allow_all(); - - AddressLiteral al(0xffffffff, relocInfo::external_word_type); - a->ldsw( G5, al.low10(), G4); idx++; - a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3); - a->ldsw( G5, I3, G4 ); idx++; - a->ldsb( G5, al.low10(), G4); idx++; - a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3); - a->ldsb( G5, I3, G4 ); idx++; - a->ldsh( G5, al.low10(), G4); idx++; - a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3); - a->ldsh( G5, I3, G4 ); idx++; - a->lduw( G5, al.low10(), G4); idx++; - a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3); - a->lduw( G5, I3, G4 ); idx++; - a->ldub( G5, al.low10(), G4); idx++; - a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3); - a->ldub( G5, I3, G4 ); idx++; - a->lduh( G5, al.low10(), G4); idx++; - a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3); - a->lduh( G5, I3, G4 ); idx++; - a->ldx( G5, al.low10(), G4); idx++; - a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3); - a->ldx( G5, I3, G4 ); idx++; - a->ldd( G5, al.low10(), G4); idx++; - a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3); - a->ldd( G5, I3, G4 ); idx++; - a->ldf( FloatRegisterImpl::D, O2, -1, F14 ); idx++; - a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3); - a->ldf( FloatRegisterImpl::S, O0, I3, F15 ); idx++; - - a->stw( G5, G4, al.low10()); idx++; - a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3); - a->stw( G5, G4, I3 ); idx++; - a->stb( G5, G4, al.low10()); idx++; - a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3); - a->stb( G5, G4, I3 ); idx++; - a->sth( G5, G4, al.low10()); idx++; - a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3); - a->sth( G5, G4, I3 ); idx++; - a->stx( G5, G4, al.low10()); idx++; - a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3); - a->stx( G5, G4, I3 ); idx++; - a->std( G5, G4, al.low10()); idx++; - a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3); - a->std( G5, G4, I3 ); idx++; - a->stf( FloatRegisterImpl::S, F18, O2, -1 ); idx++; - a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3); - a->stf( FloatRegisterImpl::S, F15, O0, I3 ); idx++; - - nm = nativeMovRegMemPatching_at( cb.insts_begin() ); - nm->print(); - nm->set_offset( low10(0) ); - nm->print(); - nm->add_offset_in_bytes( low10(0xbb) * wordSize ); - nm->print(); - - while (--idx) { - nm = nativeMovRegMemPatching_at( nm->next_instruction_address() ); - nm->print(); - for (idx1 = 0; idx1 < ARRAY_SIZE(offsets); idx1++) { - nm->set_offset( nm->is_immediate() ? low10(offsets[idx1]) : offsets[idx1] ); - assert(nm->offset() == (nm->is_immediate() ? low10(offsets[idx1]) : offsets[idx1]), - "check unit test"); - nm->print(); - } - nm->add_offset_in_bytes( low10(0xbb) * wordSize ); - nm->print(); - } - - VM_Version::revert(); -#endif // ASSERT -} -// End code for unit testing implementation of NativeMovRegMemPatching class - //-------------------------------------------------------------------------------- @@ -863,7 +721,7 @@ void NativeJump::print() { - tty->print_cr(INTPTR_FORMAT ": jmpl reg, " INTPTR_FORMAT, instruction_address(), jump_destination()); + tty->print_cr(INTPTR_FORMAT ": jmpl reg, " INTPTR_FORMAT, p2i(instruction_address()), p2i(jump_destination())); } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/cpu/sparc/vm/nativeInst_sparc.hpp --- a/hotspot/src/cpu/sparc/vm/nativeInst_sparc.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/cpu/sparc/vm/nativeInst_sparc.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -38,7 +38,6 @@ // - - NativeMovConstReg // - - NativeMovConstRegPatching // - - NativeMovRegMem -// - - NativeMovRegMemPatching // - - NativeJump // - - NativeGeneralJump // - - NativeIllegalInstruction @@ -710,96 +709,6 @@ }; -// An interface for accessing/manipulating native memory ops -// ld* [reg + offset], reg -// st* reg, [reg + offset] -// sethi %hi(imm), reg; nop; add reg, %lo(imm), reg; ld* [reg1 + reg], reg2 -// sethi %hi(imm), reg; nop; add reg, %lo(imm), reg; st* reg2, [reg1 + reg] -// Ops covered: {lds,ldu,st}{w,b,h}, {ld,st}{d,x} -// -// Note that it is identical to NativeMovRegMem with the exception of a nop between the -// sethi and the add. The nop is required to be in the delay slot of the call instruction -// which overwrites the sethi during patching. -class NativeMovRegMemPatching; -inline NativeMovRegMemPatching* nativeMovRegMemPatching_at (address address); -class NativeMovRegMemPatching: public NativeInstruction { - public: - enum Sparc_specific_constants { - op3_mask_ld = 1 << Assembler::lduw_op3 | - 1 << Assembler::ldub_op3 | - 1 << Assembler::lduh_op3 | - 1 << Assembler::ldd_op3 | - 1 << Assembler::ldsw_op3 | - 1 << Assembler::ldsb_op3 | - 1 << Assembler::ldsh_op3 | - 1 << Assembler::ldx_op3, - op3_mask_st = 1 << Assembler::stw_op3 | - 1 << Assembler::stb_op3 | - 1 << Assembler::sth_op3 | - 1 << Assembler::std_op3 | - 1 << Assembler::stx_op3, - op3_ldst_int_limit = Assembler::ldf_op3, - op3_mask_ldf = 1 << (Assembler::ldf_op3 - op3_ldst_int_limit) | - 1 << (Assembler::lddf_op3 - op3_ldst_int_limit), - op3_mask_stf = 1 << (Assembler::stf_op3 - op3_ldst_int_limit) | - 1 << (Assembler::stdf_op3 - op3_ldst_int_limit), - - offset_width = 13, - sethi_offset = 0, -#ifdef _LP64 - nop_offset = 7 * BytesPerInstWord, -#else - nop_offset = 4, -#endif - add_offset = nop_offset + BytesPerInstWord, - ldst_offset = add_offset + BytesPerInstWord - }; - bool is_immediate() const { - // check if instruction is ld* [reg + offset], reg or st* reg, [reg + offset] - int i0 = long_at(0); - return (is_op(i0, Assembler::ldst_op)); - } - - address instruction_address() const { return addr_at(0); } - address next_instruction_address() const { - return addr_at(is_immediate()? 4 : 16); - } - int offset() const { - return is_immediate()? inv_simm(long_at(0), offset_width) : - nativeMovConstRegPatching_at(addr_at(0))->data(); - } - void set_offset(int x) { - if (is_immediate()) { - guarantee(fits_in_simm(x, offset_width), "data block offset overflow"); - set_long_at(0, set_simm(long_at(0), x, offset_width)); - } - else - nativeMovConstRegPatching_at(addr_at(0))->set_data(x); - } - - void add_offset_in_bytes(intptr_t radd_offset) { - set_offset (offset() + radd_offset); - } - - void copy_instruction_to(address new_instruction_address); - - void verify(); - void print (); - - // unit test stuff - static void test(); - - private: - friend inline NativeMovRegMemPatching* nativeMovRegMemPatching_at (address address) { - NativeMovRegMemPatching* test = (NativeMovRegMemPatching*)address; - #ifdef ASSERT - test->verify(); - #endif - return test; - } -}; - - // An interface for accessing/manipulating native jumps // jump_to addr // == sethi %hi22(addr), temp ; jumpl reg, %lo10(addr), G0 ; diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/cpu/sparc/vm/sparc.ad --- a/hotspot/src/cpu/sparc/vm/sparc.ad Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/cpu/sparc/vm/sparc.ad Wed Jun 18 10:56:06 2014 -0700 @@ -1206,10 +1206,10 @@ } if (Assembler::is_simm13(-framesize)) { - st->print ("SAVE R_SP,-%d,R_SP",framesize); + st->print ("SAVE R_SP,-" SIZE_FORMAT ",R_SP",framesize); } else { - st->print_cr("SETHI R_SP,hi%%(-%d),R_G3",framesize); st->print("\t"); - st->print_cr("ADD R_G3,lo%%(-%d),R_G3",framesize); st->print("\t"); + st->print_cr("SETHI R_SP,hi%%(-" SIZE_FORMAT "),R_G3",framesize); st->print("\t"); + st->print_cr("ADD R_G3,lo%%(-" SIZE_FORMAT "),R_G3",framesize); st->print("\t"); st->print ("SAVE R_SP,R_G3,R_SP"); } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -4575,6 +4575,219 @@ return start; } + address generate_sha1_implCompress(bool multi_block, const char *name) { + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", name); + address start = __ pc(); + + Label L_sha1_loop, L_sha1_unaligned_input, L_sha1_unaligned_input_loop; + int i; + + Register buf = O0; // byte[] source+offset + Register state = O1; // int[] SHA.state + Register ofs = O2; // int offset + Register limit = O3; // int limit + + // load state into F0-F4 + for (i = 0; i < 5; i++) { + __ ldf(FloatRegisterImpl::S, state, i*4, as_FloatRegister(i)); + } + + __ andcc(buf, 7, G0); + __ br(Assembler::notZero, false, Assembler::pn, L_sha1_unaligned_input); + __ delayed()->nop(); + + __ BIND(L_sha1_loop); + // load buf into F8-F22 + for (i = 0; i < 8; i++) { + __ ldf(FloatRegisterImpl::D, buf, i*8, as_FloatRegister(i*2 + 8)); + } + __ sha1(); + if (multi_block) { + __ add(ofs, 64, ofs); + __ add(buf, 64, buf); + __ cmp_and_brx_short(ofs, limit, Assembler::lessEqual, Assembler::pt, L_sha1_loop); + __ mov(ofs, O0); // to be returned + } + + // store F0-F4 into state and return + for (i = 0; i < 4; i++) { + __ stf(FloatRegisterImpl::S, as_FloatRegister(i), state, i*4); + } + __ retl(); + __ delayed()->stf(FloatRegisterImpl::S, F4, state, 0x10); + + __ BIND(L_sha1_unaligned_input); + __ alignaddr(buf, G0, buf); + + __ BIND(L_sha1_unaligned_input_loop); + // load buf into F8-F22 + for (i = 0; i < 9; i++) { + __ ldf(FloatRegisterImpl::D, buf, i*8, as_FloatRegister(i*2 + 8)); + } + for (i = 0; i < 8; i++) { + __ faligndata(as_FloatRegister(i*2 + 8), as_FloatRegister(i*2 + 10), as_FloatRegister(i*2 + 8)); + } + __ sha1(); + if (multi_block) { + __ add(ofs, 64, ofs); + __ add(buf, 64, buf); + __ cmp_and_brx_short(ofs, limit, Assembler::lessEqual, Assembler::pt, L_sha1_unaligned_input_loop); + __ mov(ofs, O0); // to be returned + } + + // store F0-F4 into state and return + for (i = 0; i < 4; i++) { + __ stf(FloatRegisterImpl::S, as_FloatRegister(i), state, i*4); + } + __ retl(); + __ delayed()->stf(FloatRegisterImpl::S, F4, state, 0x10); + + return start; + } + + address generate_sha256_implCompress(bool multi_block, const char *name) { + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", name); + address start = __ pc(); + + Label L_sha256_loop, L_sha256_unaligned_input, L_sha256_unaligned_input_loop; + int i; + + Register buf = O0; // byte[] source+offset + Register state = O1; // int[] SHA2.state + Register ofs = O2; // int offset + Register limit = O3; // int limit + + // load state into F0-F7 + for (i = 0; i < 8; i++) { + __ ldf(FloatRegisterImpl::S, state, i*4, as_FloatRegister(i)); + } + + __ andcc(buf, 7, G0); + __ br(Assembler::notZero, false, Assembler::pn, L_sha256_unaligned_input); + __ delayed()->nop(); + + __ BIND(L_sha256_loop); + // load buf into F8-F22 + for (i = 0; i < 8; i++) { + __ ldf(FloatRegisterImpl::D, buf, i*8, as_FloatRegister(i*2 + 8)); + } + __ sha256(); + if (multi_block) { + __ add(ofs, 64, ofs); + __ add(buf, 64, buf); + __ cmp_and_brx_short(ofs, limit, Assembler::lessEqual, Assembler::pt, L_sha256_loop); + __ mov(ofs, O0); // to be returned + } + + // store F0-F7 into state and return + for (i = 0; i < 7; i++) { + __ stf(FloatRegisterImpl::S, as_FloatRegister(i), state, i*4); + } + __ retl(); + __ delayed()->stf(FloatRegisterImpl::S, F7, state, 0x1c); + + __ BIND(L_sha256_unaligned_input); + __ alignaddr(buf, G0, buf); + + __ BIND(L_sha256_unaligned_input_loop); + // load buf into F8-F22 + for (i = 0; i < 9; i++) { + __ ldf(FloatRegisterImpl::D, buf, i*8, as_FloatRegister(i*2 + 8)); + } + for (i = 0; i < 8; i++) { + __ faligndata(as_FloatRegister(i*2 + 8), as_FloatRegister(i*2 + 10), as_FloatRegister(i*2 + 8)); + } + __ sha256(); + if (multi_block) { + __ add(ofs, 64, ofs); + __ add(buf, 64, buf); + __ cmp_and_brx_short(ofs, limit, Assembler::lessEqual, Assembler::pt, L_sha256_unaligned_input_loop); + __ mov(ofs, O0); // to be returned + } + + // store F0-F7 into state and return + for (i = 0; i < 7; i++) { + __ stf(FloatRegisterImpl::S, as_FloatRegister(i), state, i*4); + } + __ retl(); + __ delayed()->stf(FloatRegisterImpl::S, F7, state, 0x1c); + + return start; + } + + address generate_sha512_implCompress(bool multi_block, const char *name) { + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", name); + address start = __ pc(); + + Label L_sha512_loop, L_sha512_unaligned_input, L_sha512_unaligned_input_loop; + int i; + + Register buf = O0; // byte[] source+offset + Register state = O1; // long[] SHA5.state + Register ofs = O2; // int offset + Register limit = O3; // int limit + + // load state into F0-F14 + for (i = 0; i < 8; i++) { + __ ldf(FloatRegisterImpl::D, state, i*8, as_FloatRegister(i*2)); + } + + __ andcc(buf, 7, G0); + __ br(Assembler::notZero, false, Assembler::pn, L_sha512_unaligned_input); + __ delayed()->nop(); + + __ BIND(L_sha512_loop); + // load buf into F16-F46 + for (i = 0; i < 16; i++) { + __ ldf(FloatRegisterImpl::D, buf, i*8, as_FloatRegister(i*2 + 16)); + } + __ sha512(); + if (multi_block) { + __ add(ofs, 128, ofs); + __ add(buf, 128, buf); + __ cmp_and_brx_short(ofs, limit, Assembler::lessEqual, Assembler::pt, L_sha512_loop); + __ mov(ofs, O0); // to be returned + } + + // store F0-F14 into state and return + for (i = 0; i < 7; i++) { + __ stf(FloatRegisterImpl::D, as_FloatRegister(i*2), state, i*8); + } + __ retl(); + __ delayed()->stf(FloatRegisterImpl::D, F14, state, 0x38); + + __ BIND(L_sha512_unaligned_input); + __ alignaddr(buf, G0, buf); + + __ BIND(L_sha512_unaligned_input_loop); + // load buf into F16-F46 + for (i = 0; i < 17; i++) { + __ ldf(FloatRegisterImpl::D, buf, i*8, as_FloatRegister(i*2 + 16)); + } + for (i = 0; i < 16; i++) { + __ faligndata(as_FloatRegister(i*2 + 16), as_FloatRegister(i*2 + 18), as_FloatRegister(i*2 + 16)); + } + __ sha512(); + if (multi_block) { + __ add(ofs, 128, ofs); + __ add(buf, 128, buf); + __ cmp_and_brx_short(ofs, limit, Assembler::lessEqual, Assembler::pt, L_sha512_unaligned_input_loop); + __ mov(ofs, O0); // to be returned + } + + // store F0-F14 into state and return + for (i = 0; i < 7; i++) { + __ stf(FloatRegisterImpl::D, as_FloatRegister(i*2), state, i*8); + } + __ retl(); + __ delayed()->stf(FloatRegisterImpl::D, F14, state, 0x38); + + return start; + } + void generate_initial() { // Generates all stubs and initializes the entry points @@ -4647,6 +4860,20 @@ StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt(); StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel(); } + + // generate SHA1/SHA256/SHA512 intrinsics code + if (UseSHA1Intrinsics) { + StubRoutines::_sha1_implCompress = generate_sha1_implCompress(false, "sha1_implCompress"); + StubRoutines::_sha1_implCompressMB = generate_sha1_implCompress(true, "sha1_implCompressMB"); + } + if (UseSHA256Intrinsics) { + StubRoutines::_sha256_implCompress = generate_sha256_implCompress(false, "sha256_implCompress"); + StubRoutines::_sha256_implCompressMB = generate_sha256_implCompress(true, "sha256_implCompressMB"); + } + if (UseSHA512Intrinsics) { + StubRoutines::_sha512_implCompress = generate_sha512_implCompress(false, "sha512_implCompress"); + StubRoutines::_sha512_implCompressMB = generate_sha512_implCompress(true, "sha512_implCompressMB"); + } } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/cpu/sparc/vm/stubRoutines_sparc.hpp --- a/hotspot/src/cpu/sparc/vm/stubRoutines_sparc.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/cpu/sparc/vm/stubRoutines_sparc.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -41,7 +41,7 @@ enum /* platform_dependent_constants */ { // %%%%%%%% May be able to shrink this a lot code_size1 = 20000, // simply increase if too small (assembler will crash if too small) - code_size2 = 22000 // simply increase if too small (assembler will crash if too small) + code_size2 = 23000 // simply increase if too small (assembler will crash if too small) }; class Sparc { diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -1722,15 +1722,15 @@ if (caller->is_interpreted_frame()) { tty->print("interpreted "); } - tty->print_cr("caller fp=0x%x sp=0x%x", caller->fp(), caller->sp()); - tty->print_cr("save area = 0x%x, 0x%x", caller->sp(), caller->sp() + 16); - tty->print_cr("save area = 0x%x, 0x%x", caller->fp(), caller->fp() + 16); - tty->print_cr("interpreter fp=0x%x sp=0x%x", interpreter_frame->fp(), interpreter_frame->sp()); - tty->print_cr("save area = 0x%x, 0x%x", interpreter_frame->sp(), interpreter_frame->sp() + 16); - tty->print_cr("save area = 0x%x, 0x%x", interpreter_frame->fp(), interpreter_frame->fp() + 16); - tty->print_cr("Llocals = 0x%x", locals); - tty->print_cr("Lesp = 0x%x", esp); - tty->print_cr("Lmonitors = 0x%x", monitors); + tty->print_cr("caller fp=" INTPTR_FORMAT " sp=" INTPTR_FORMAT, p2i(caller->fp()), p2i(caller->sp())); + tty->print_cr("save area = " INTPTR_FORMAT ", " INTPTR_FORMAT, p2i(caller->sp()), p2i(caller->sp() + 16)); + tty->print_cr("save area = " INTPTR_FORMAT ", " INTPTR_FORMAT, p2i(caller->fp()), p2i(caller->fp() + 16)); + tty->print_cr("interpreter fp=" INTPTR_FORMAT ", " INTPTR_FORMAT, p2i(interpreter_frame->fp()), p2i(interpreter_frame->sp())); + tty->print_cr("save area = " INTPTR_FORMAT ", " INTPTR_FORMAT, p2i(interpreter_frame->sp()), p2i(interpreter_frame->sp() + 16)); + tty->print_cr("save area = " INTPTR_FORMAT ", " INTPTR_FORMAT, p2i(interpreter_frame->fp()), p2i(interpreter_frame->fp() + 16)); + tty->print_cr("Llocals = " INTPTR_FORMAT, p2i(locals)); + tty->print_cr("Lesp = " INTPTR_FORMAT, p2i(esp)); + tty->print_cr("Lmonitors = " INTPTR_FORMAT, p2i(monitors)); } if (method->max_locals() > 0) { diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -234,7 +234,7 @@ assert((OptoLoopAlignment % relocInfo::addr_unit()) == 0, "alignment is not a multiple of NOP size"); char buf[512]; - jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", (has_v9() ? ", v9" : (has_v8() ? ", v8" : "")), (has_hardware_popc() ? ", popc" : ""), (has_vis1() ? ", vis1" : ""), @@ -243,6 +243,9 @@ (has_blk_init() ? ", blk_init" : ""), (has_cbcond() ? ", cbcond" : ""), (has_aes() ? ", aes" : ""), + (has_sha1() ? ", sha1" : ""), + (has_sha256() ? ", sha256" : ""), + (has_sha512() ? ", sha512" : ""), (is_ultra3() ? ", ultra3" : ""), (is_sun4v() ? ", sun4v" : ""), (is_niagara_plus() ? ", niagara_plus" : (is_niagara() ? ", niagara" : "")), @@ -301,6 +304,58 @@ } } + // SHA1, SHA256, and SHA512 instructions were added to SPARC T-series at different times + if (has_sha1() || has_sha256() || has_sha512()) { + if (UseVIS > 0) { // SHA intrinsics use VIS1 instructions + if (FLAG_IS_DEFAULT(UseSHA)) { + FLAG_SET_DEFAULT(UseSHA, true); + } + } else { + if (UseSHA) { + warning("SPARC SHA intrinsics require VIS1 instruction support. Intrinsics will be disabled."); + FLAG_SET_DEFAULT(UseSHA, false); + } + } + } else if (UseSHA) { + warning("SHA instructions are not available on this CPU"); + FLAG_SET_DEFAULT(UseSHA, false); + } + + if (!UseSHA) { + FLAG_SET_DEFAULT(UseSHA1Intrinsics, false); + FLAG_SET_DEFAULT(UseSHA256Intrinsics, false); + FLAG_SET_DEFAULT(UseSHA512Intrinsics, false); + } else { + if (has_sha1()) { + if (FLAG_IS_DEFAULT(UseSHA1Intrinsics)) { + FLAG_SET_DEFAULT(UseSHA1Intrinsics, true); + } + } else if (UseSHA1Intrinsics) { + warning("SHA1 instruction is not available on this CPU."); + FLAG_SET_DEFAULT(UseSHA1Intrinsics, false); + } + if (has_sha256()) { + if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) { + FLAG_SET_DEFAULT(UseSHA256Intrinsics, true); + } + } else if (UseSHA256Intrinsics) { + warning("SHA256 instruction (for SHA-224 and SHA-256) is not available on this CPU."); + FLAG_SET_DEFAULT(UseSHA256Intrinsics, false); + } + + if (has_sha512()) { + if (FLAG_IS_DEFAULT(UseSHA512Intrinsics)) { + FLAG_SET_DEFAULT(UseSHA512Intrinsics, true); + } + } else if (UseSHA512Intrinsics) { + warning("SHA512 instruction (for SHA-384 and SHA-512) is not available on this CPU."); + FLAG_SET_DEFAULT(UseSHA512Intrinsics, false); + } + if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) { + FLAG_SET_DEFAULT(UseSHA, false); + } + } + if (FLAG_IS_DEFAULT(ContendedPaddingWidth) && (cache_line_size > ContendedPaddingWidth)) ContendedPaddingWidth = cache_line_size; diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp --- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,10 @@ T_family = 16, T1_model = 17, sparc5_instructions = 18, - aes_instructions = 19 + aes_instructions = 19, + sha1_instruction = 20, + sha256_instruction = 21, + sha512_instruction = 22 }; enum Feature_Flag_Set { @@ -77,6 +80,9 @@ T1_model_m = 1 << T1_model, sparc5_instructions_m = 1 << sparc5_instructions, aes_instructions_m = 1 << aes_instructions, + sha1_instruction_m = 1 << sha1_instruction, + sha256_instruction_m = 1 << sha256_instruction, + sha512_instruction_m = 1 << sha512_instruction, generic_v8_m = v8_instructions_m | hardware_mul32_m | hardware_div32_m | hardware_fsmuld_m, generic_v9_m = generic_v8_m | v9_instructions_m, @@ -129,6 +135,9 @@ static bool has_cbcond() { return (_features & cbcond_instructions_m) != 0; } static bool has_sparc5_instr() { return (_features & sparc5_instructions_m) != 0; } static bool has_aes() { return (_features & aes_instructions_m) != 0; } + static bool has_sha1() { return (_features & sha1_instruction_m) != 0; } + static bool has_sha256() { return (_features & sha256_instruction_m) != 0; } + static bool has_sha512() { return (_features & sha512_instruction_m) != 0; } static bool supports_compare_and_exchange() { return has_v9(); } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -111,7 +111,7 @@ if (PrintMiscellaneous && (WizardMode || Verbose)) { tty->print_cr("vtable #%d at "PTR_FORMAT"[%d] left over: %d", - vtable_index, s->entry_point(), + vtable_index, p2i(s->entry_point()), (int)(s->code_end() - s->entry_point()), (int)(s->code_end() - __ pc())); } @@ -206,7 +206,7 @@ if (PrintMiscellaneous && (WizardMode || Verbose)) { tty->print_cr("itable #%d at "PTR_FORMAT"[%d] left over: %d", - itable_index, s->entry_point(), + itable_index, p2i(s->entry_point()), (int)(s->code_end() - s->entry_point()), (int)(s->code_end() - __ pc())); } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp --- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -1085,14 +1085,11 @@ void LIRGenerator::do_NewInstance(NewInstance* x) { -#ifndef PRODUCT - if (PrintNotLoaded && !x->klass()->is_loaded()) { - tty->print_cr(" ###class not loaded at new bci %d", x->printable_bci()); - } -#endif + print_if_not_loaded(x); + CodeEmitInfo* info = state_for(x, x->state()); LIR_Opr reg = result_register_for(x->type()); - new_instance(reg, x->klass(), + new_instance(reg, x->klass(), x->is_unresolved(), FrameMap::rcx_oop_opr, FrameMap::rdi_oop_opr, FrameMap::rsi_oop_opr, diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/cpu/x86/vm/nativeInst_x86.hpp --- a/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -327,18 +327,6 @@ return test; } -class NativeMovRegMemPatching: public NativeMovRegMem { - private: - friend NativeMovRegMemPatching* nativeMovRegMemPatching_at (address address) { - NativeMovRegMemPatching* test = (NativeMovRegMemPatching*)(address - instruction_offset); - #ifdef ASSERT - test->verify(); - #endif - return test; - } -}; - - // An interface for accessing/manipulating native leal instruction of form: // leal reg, [reg + offset] diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/cpu/x86/vm/vm_version_x86.cpp --- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -590,6 +590,17 @@ FLAG_SET_DEFAULT(UseAESIntrinsics, false); } + if (UseSHA) { + warning("SHA instructions are not available on this CPU"); + FLAG_SET_DEFAULT(UseSHA, false); + } + if (UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics) { + warning("SHA intrinsics are not available on this CPU"); + FLAG_SET_DEFAULT(UseSHA1Intrinsics, false); + FLAG_SET_DEFAULT(UseSHA256Intrinsics, false); + FLAG_SET_DEFAULT(UseSHA512Intrinsics, false); + } + // Adjust RTM (Restricted Transactional Memory) flags if (!supports_rtm() && UseRTMLocking) { // Can't continue because UseRTMLocking affects UseBiasedLocking flag diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/cpu/x86/vm/x86_32.ad --- a/hotspot/src/cpu/x86/vm/x86_32.ad Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/cpu/x86/vm/x86_32.ad Wed Jun 18 10:56:06 2014 -0700 @@ -1401,22 +1401,22 @@ // No transformation necessary. return; case INDIRECT: - new_memory = new (C) indirect_win95_safeOper( ); + new_memory = new indirect_win95_safeOper( ); break; case INDOFFSET8: - new_memory = new (C) indOffset8_win95_safeOper(memory->disp(NULL, NULL, 0)); + new_memory = new indOffset8_win95_safeOper(memory->disp(NULL, NULL, 0)); break; case INDOFFSET32: - new_memory = new (C) indOffset32_win95_safeOper(memory->disp(NULL, NULL, 0)); + new_memory = new indOffset32_win95_safeOper(memory->disp(NULL, NULL, 0)); break; case INDINDEXOFFSET: - new_memory = new (C) indIndexOffset_win95_safeOper(memory->disp(NULL, NULL, 0)); + new_memory = new indIndexOffset_win95_safeOper(memory->disp(NULL, NULL, 0)); break; case INDINDEXSCALE: - new_memory = new (C) indIndexScale_win95_safeOper(memory->scale()); + new_memory = new indIndexScale_win95_safeOper(memory->scale()); break; case INDINDEXSCALEOFFSET: - new_memory = new (C) indIndexScaleOffset_win95_safeOper(memory->scale(), memory->disp(NULL, NULL, 0)); + new_memory = new indIndexScaleOffset_win95_safeOper(memory->scale(), memory->disp(NULL, NULL, 0)); break; case LOAD_LONG_INDIRECT: case LOAD_LONG_INDOFFSET32: diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/os/aix/vm/os_aix.cpp --- a/hotspot/src/os/aix/vm/os_aix.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/os/aix/vm/os_aix.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -4734,10 +4734,8 @@ // // Thread.interrupt and object.notify{All} both call Event::set. // That is, we treat thread.interrupt as a special case of notification. - // The underlying Solaris implementation, cond_timedwait, admits - // spurious/premature wakeups, but the JLS/JVM spec prevents the - // JVM from making those visible to Java code. As such, we must - // filter out spurious wakeups. We assume all ETIME returns are valid. + // We ignore spurious OS wakeups unless FilterSpuriousWakeups is false. + // We assume all ETIME returns are valid. // // TODO: properly differentiate simultaneous notify+interrupt. // In that case, we should propagate the notify to another waiter. diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/os/bsd/vm/os_bsd.cpp --- a/hotspot/src/os/bsd/vm/os_bsd.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -4299,10 +4299,8 @@ // // Thread.interrupt and object.notify{All} both call Event::set. // That is, we treat thread.interrupt as a special case of notification. - // The underlying Solaris implementation, cond_timedwait, admits - // spurious/premature wakeups, but the JLS/JVM spec prevents the - // JVM from making those visible to Java code. As such, we must - // filter out spurious wakeups. We assume all ETIME returns are valid. + // We ignore spurious OS wakeups unless FilterSpuriousWakeups is false. + // We assume all ETIME returns are valid. // // TODO: properly differentiate simultaneous notify+interrupt. // In that case, we should propagate the notify to another waiter. diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/os/linux/vm/os_linux.cpp --- a/hotspot/src/os/linux/vm/os_linux.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/os/linux/vm/os_linux.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -5538,10 +5538,8 @@ // // Thread.interrupt and object.notify{All} both call Event::set. // That is, we treat thread.interrupt as a special case of notification. - // The underlying Solaris implementation, cond_timedwait, admits - // spurious/premature wakeups, but the JLS/JVM spec prevents the - // JVM from making those visible to Java code. As such, we must - // filter out spurious wakeups. We assume all ETIME returns are valid. + // We ignore spurious OS wakeups unless FilterSpuriousWakeups is false. + // We assume all ETIME returns are valid. // // TODO: properly differentiate simultaneous notify+interrupt. // In that case, we should propagate the notify to another waiter. diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp --- a/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -234,7 +234,7 @@ SIG_REGS(sc).u_regs[CON_G3], SIG_REGS(sc).u_regs[CON_G4]); st->print_cr(" G5=" INTPTR_FORMAT " G6=" INTPTR_FORMAT - " G7=" INTPTR_FORMAT " Y=" INTPTR_FORMAT, + " G7=" INTPTR_FORMAT " Y=0x%x", SIG_REGS(sc).u_regs[CON_G5], SIG_REGS(sc).u_regs[CON_G6], SIG_REGS(sc).u_regs[CON_G7], @@ -285,7 +285,7 @@ st->cr(); st->cr(); - st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp); + st->print_cr("Top of Stack: (sp=" INTPTR_FORMAT ")", p2i(sp)); print_hex_dump(st, (address)sp, (address)(sp + 32), sizeof(intptr_t)); st->cr(); @@ -293,7 +293,7 @@ // point to garbage if entry point in an nmethod is corrupted. Leave // this at the end, and hope for the best. address pc = os::Linux::ucontext_get_pc(uc); - st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc); + st->print_cr("Instructions: (pc=" INTPTR_FORMAT ")", p2i(pc)); print_hex_dump(st, pc - 32, pc + 32, sizeof(char)); } @@ -453,7 +453,7 @@ && pc < MacroAssembler::_verify_oop_implicit_branch[1] ) { *stub = MacroAssembler::_verify_oop_implicit_branch[2]; warning("fixed up memory fault in +VerifyOops at address " - INTPTR_FORMAT, fault); + INTPTR_FORMAT, p2i(fault)); return true; } return false; diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/os_cpu/linux_sparc/vm/vm_version_linux_sparc.cpp --- a/hotspot/src/os_cpu/linux_sparc/vm/vm_version_linux_sparc.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/os_cpu/linux_sparc/vm/vm_version_linux_sparc.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -36,7 +36,7 @@ } while (!feof(fp)) { - if (fscanf(fp, "cpu\t\t: %100[^\n]", &cpu) == 1) { + if (fscanf(fp, "cpu\t\t: %100[^\n]", cpu) == 1) { if (strstr(cpu, "Niagara") != NULL) { rv = true; } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp --- a/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -137,6 +137,21 @@ #endif if (av & AV_SPARC_AES) features |= aes_instructions_m; +#ifndef AV_SPARC_SHA1 +#define AV_SPARC_SHA1 0x00400000 /* sha1 instruction supported */ +#endif + if (av & AV_SPARC_SHA1) features |= sha1_instruction_m; + +#ifndef AV_SPARC_SHA256 +#define AV_SPARC_SHA256 0x00800000 /* sha256 instruction supported */ +#endif + if (av & AV_SPARC_SHA256) features |= sha256_instruction_m; + +#ifndef AV_SPARC_SHA512 +#define AV_SPARC_SHA512 0x01000000 /* sha512 instruction supported */ +#endif + if (av & AV_SPARC_SHA512) features |= sha512_instruction_m; + } else { // getisax(2) failed, use the old legacy code. #ifndef PRODUCT diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/adlc/output_c.cpp --- a/hotspot/src/share/vm/adlc/output_c.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/adlc/output_c.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -1000,7 +1000,7 @@ fprintf(fp_cpp, "void Bundle::initialize_nops(MachNode * nop_list[%d], Compile *C) {\n", nopcnt); int i = 0; for ( _pipeline->_noplist.reset(); (nop = _pipeline->_noplist.iter()) != NULL; i++ ) { - fprintf(fp_cpp, " nop_list[%d] = (MachNode *) new (C) %sNode();\n", i, nop); + fprintf(fp_cpp, " nop_list[%d] = (MachNode *) new %sNode();\n", i, nop); } fprintf(fp_cpp, "};\n\n"); fprintf(fp_cpp, "#ifndef PRODUCT\n"); @@ -1328,7 +1328,7 @@ preplace->next_instruction(root_inst); InstructForm *root_form = globals[root_inst]->is_instruction(); assert( root_form != NULL, "Replacement instruction was not previously defined"); - fprintf(fp, " %sNode *root = new (C) %sNode();\n", root_inst, root_inst); + fprintf(fp, " %sNode *root = new %sNode();\n", root_inst, root_inst); int inst_num; const char *op_name; @@ -1497,11 +1497,11 @@ new_oper = frm->is_operand(); char *tmp = (char *)node->_exprule->_newopconst[new_id]; if (tmp == NULL) { - fprintf(fp," MachOper *op%d = new (C) %sOper();\n", + fprintf(fp," MachOper *op%d = new %sOper();\n", cnt, new_oper->_ident); } else { - fprintf(fp," MachOper *op%d = new (C) %sOper(%s);\n", + fprintf(fp," MachOper *op%d = new %sOper(%s);\n", cnt, new_oper->_ident, tmp); } } @@ -1566,7 +1566,7 @@ } // Build the node for the instruction - fprintf(fp,"\n %sNode *n%d = new (C) %sNode();\n", new_id, cnt, new_id); + fprintf(fp,"\n %sNode *n%d = new %sNode();\n", new_id, cnt, new_id); // Add control edge for this node fprintf(fp," n%d->add_req(_in[0]);\n", cnt); // Build the operand for the value this node defines. @@ -1729,7 +1729,7 @@ declared_def = true; } if (op && op->_interface && op->_interface->is_RegInterface()) { - fprintf(fp," def = new (C) MachTempNode(state->MachOperGenerator( %s, C ));\n", + fprintf(fp," def = new MachTempNode(state->MachOperGenerator( %s, C ));\n", machOperEnum(op->_ident)); fprintf(fp," add_req(def);\n"); // The operand for TEMP is already constructed during @@ -1760,7 +1760,7 @@ } fprintf(fp," kill = "); - fprintf(fp,"new (C) MachProjNode( %s, %d, (%s), Op_%s );\n", + fprintf(fp,"new MachProjNode( %s, %d, (%s), Op_%s );\n", machNode, proj_no++, regmask, ideal_type); fprintf(fp," proj_list.push(kill);\n"); } @@ -2840,7 +2840,7 @@ // generate code to create a clone for a class derived from MachOper // // (0) MachOper *MachOperXOper::clone(Compile* C) const { -// (1) return new (C) MachXOper( _ccode, _c0, _c1, ..., _cn); +// (1) return new MachXOper( _ccode, _c0, _c1, ..., _cn); // (2) } // static void defineClone(FILE *fp, FormDict &globalNames, OperandForm &oper) { @@ -2849,7 +2849,7 @@ const int num_consts = oper.num_consts(globalNames); const bool is_ideal_bool = oper.is_ideal_bool(); if( (num_consts > 0) ) { - fprintf(fp," return new (C) %sOper(", oper._ident); + fprintf(fp," return new %sOper(", oper._ident); // generate parameters for constants int i = 0; fprintf(fp,"_c%d", i); @@ -2861,7 +2861,7 @@ } else { assert( num_consts == 0, "Currently support zero or one constant per operand clone function"); - fprintf(fp," return new (C) %sOper();\n", oper._ident); + fprintf(fp," return new %sOper();\n", oper._ident); } // finish method fprintf(fp,"}\n"); @@ -3106,7 +3106,7 @@ defineIn_RegMask(_CPP_MISC_file._fp, _globalNames, *oper); fprintf(fp,"MachOper *%sOper::clone(Compile* C) const {\n", oper->_ident); - fprintf(fp," return new (C) %sOper(_label, _block_num);\n", oper->_ident); + fprintf(fp," return new %sOper(_label, _block_num);\n", oper->_ident); fprintf(fp,"}\n"); fprintf(fp,"uint %sOper::opcode() const { return %s; }\n", @@ -3125,7 +3125,7 @@ defineIn_RegMask(_CPP_MISC_file._fp, _globalNames, *oper); fprintf(fp,"MachOper *%sOper::clone(Compile* C) const {\n", oper->_ident); - fprintf(fp," return new (C) %sOper(_method);\n", oper->_ident); + fprintf(fp," return new %sOper(_method);\n", oper->_ident); fprintf(fp,"}\n"); fprintf(fp,"uint %sOper::opcode() const { return %s; }\n", @@ -3815,7 +3815,7 @@ // Generate the case statement for this opcode fprintf(fp, " case %s:", opEnumName); - fprintf(fp, "\n return new (C) %sOper(", opName); + fprintf(fp, "\n return new %sOper(", opName); // Access parameters for constructor from the stat object // // Build access to condition code value @@ -3894,7 +3894,7 @@ const char *opClass = inst->_ident; // Create the MachNode object - fprintf(fp_cpp, "%s %sNode *node = new (C) %sNode();\n",indent, opClass,opClass); + fprintf(fp_cpp, "%s %sNode *node = new %sNode();\n",indent, opClass,opClass); if ( (inst->num_post_match_opnds() != 0) ) { // Instruction that contains operands which are not in match rule. @@ -3936,7 +3936,7 @@ // Check for multiple constants and then fill them in. // Just like MachOperGenerator const char *opName = inst->_matrule->_rChild->_opType; - fprintf(fp_cpp, "new (C) %sOper(", opName); + fprintf(fp_cpp, "new %sOper(", opName); // Grab operand form OperandForm *op = (_globalNames[opName])->is_operand(); // Look up the number of constants @@ -4010,7 +4010,7 @@ fprintf(fp_cpp, "// Build CISC version of this instruction\n"); fprintf(fp_cpp, "MachNode *%sNode::cisc_version( int offset, Compile* C ) {\n", this->_ident); // Create the MachNode object - fprintf(fp_cpp, " %sNode *node = new (C) %sNode();\n", name, name); + fprintf(fp_cpp, " %sNode *node = new %sNode();\n", name, name); // Fill in the bottom_type where requested if ( this->captures_bottom_type(AD.globalNames()) ) { fprintf(fp_cpp, " node->_bottom_type = bottom_type();\n"); @@ -4026,7 +4026,7 @@ fprintf(fp_cpp, " fill_new_machnode(node, C);\n"); // Construct operand to access [stack_pointer + offset] fprintf(fp_cpp, " // Construct operand to access [stack_pointer + offset]\n"); - fprintf(fp_cpp, " node->set_opnd_array(cisc_operand(), new (C) %sOper(offset));\n", cisc_oper_name); + fprintf(fp_cpp, " node->set_opnd_array(cisc_operand(), new %sOper(offset));\n", cisc_oper_name); fprintf(fp_cpp, "\n"); // Return result and exit scope @@ -4057,7 +4057,7 @@ fprintf(fp_cpp, "// Build short branch version of this instruction\n"); fprintf(fp_cpp, "MachNode *%sNode::short_branch_version(Compile* C) {\n", this->_ident); // Create the MachNode object - fprintf(fp_cpp, " %sNode *node = new (C) %sNode();\n", name, name); + fprintf(fp_cpp, " %sNode *node = new %sNode();\n", name, name); if( is_ideal_if() ) { fprintf(fp_cpp, " node->_prob = _prob;\n"); fprintf(fp_cpp, " node->_fcnt = _fcnt;\n"); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/c1/c1_GraphBuilder.cpp --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -2054,7 +2054,7 @@ bool will_link; ciKlass* klass = stream()->get_klass(will_link); assert(klass->is_instance_klass(), "must be an instance klass"); - NewInstance* new_instance = new NewInstance(klass->as_instance_klass(), state_before); + NewInstance* new_instance = new NewInstance(klass->as_instance_klass(), state_before, stream()->is_unresolved_klass()); _memory->new_instance(new_instance); apush(append_split(new_instance)); } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/c1/c1_Instruction.hpp --- a/hotspot/src/share/vm/c1/c1_Instruction.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/c1/c1_Instruction.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -1291,16 +1291,18 @@ LEAF(NewInstance, StateSplit) private: ciInstanceKlass* _klass; + bool _is_unresolved; public: // creation - NewInstance(ciInstanceKlass* klass, ValueStack* state_before) + NewInstance(ciInstanceKlass* klass, ValueStack* state_before, bool is_unresolved) : StateSplit(instanceType, state_before) - , _klass(klass) + , _klass(klass), _is_unresolved(is_unresolved) {} // accessors ciInstanceKlass* klass() const { return _klass; } + bool is_unresolved() const { return _is_unresolved; } virtual bool needs_exception_state() const { return false; } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/c1/c1_LIRAssembler.cpp --- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -336,7 +336,6 @@ void LIR_Assembler::add_debug_info_for_branch(CodeEmitInfo* info) { - _masm->code_section()->relocate(pc(), relocInfo::poll_type); int pc_offset = code_offset(); flush_debug_info(pc_offset); info->record_debug_info(compilation()->debug_info_recorder(), pc_offset); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/c1/c1_LIRGenerator.cpp --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -466,8 +466,11 @@ } -void LIRGenerator::klass2reg_with_patching(LIR_Opr r, ciMetadata* obj, CodeEmitInfo* info) { - if (!obj->is_loaded() || PatchALot) { +void LIRGenerator::klass2reg_with_patching(LIR_Opr r, ciMetadata* obj, CodeEmitInfo* info, bool need_resolve) { + /* C2 relies on constant pool entries being resolved (ciTypeFlow), so if TieredCompilation + * is active and the class hasn't yet been resolved we need to emit a patch that resolves + * the class. */ + if ((TieredCompilation && need_resolve) || !obj->is_loaded() || PatchALot) { assert(info != NULL, "info must be set if class is not loaded"); __ klass2reg_patch(NULL, r, info); } else { @@ -660,9 +663,18 @@ __ unlock_object(hdr, object, lock, scratch, slow_path); } - -void LIRGenerator::new_instance(LIR_Opr dst, ciInstanceKlass* klass, LIR_Opr scratch1, LIR_Opr scratch2, LIR_Opr scratch3, LIR_Opr scratch4, LIR_Opr klass_reg, CodeEmitInfo* info) { - klass2reg_with_patching(klass_reg, klass, info); +#ifndef PRODUCT +void LIRGenerator::print_if_not_loaded(const NewInstance* new_instance) { + if (PrintNotLoaded && !new_instance->klass()->is_loaded()) { + tty->print_cr(" ###class not loaded at new bci %d", new_instance->printable_bci()); + } else if (PrintNotLoaded && (TieredCompilation && new_instance->is_unresolved())) { + tty->print_cr(" ###class not resolved at new bci %d", new_instance->printable_bci()); + } +} +#endif + +void LIRGenerator::new_instance(LIR_Opr dst, ciInstanceKlass* klass, bool is_unresolved, LIR_Opr scratch1, LIR_Opr scratch2, LIR_Opr scratch3, LIR_Opr scratch4, LIR_Opr klass_reg, CodeEmitInfo* info) { + klass2reg_with_patching(klass_reg, klass, info, is_unresolved); // If klass is not loaded we do not know if the klass has finalizers: if (UseFastNewInstance && klass->is_loaded() && !Klass::layout_helper_needs_slow_path(klass->layout_helper())) { diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/c1/c1_LIRGenerator.hpp --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -169,6 +169,8 @@ return this; } + void print_if_not_loaded(const NewInstance* new_instance) PRODUCT_RETURN; + #ifdef ASSERT LIR_List* lir(const char * file, int line) const { _lir->set_file_and_line(file, line); @@ -307,7 +309,7 @@ void store_stack_parameter (LIR_Opr opr, ByteSize offset_from_sp_in_bytes); - void klass2reg_with_patching(LIR_Opr r, ciMetadata* obj, CodeEmitInfo* info); + void klass2reg_with_patching(LIR_Opr r, ciMetadata* obj, CodeEmitInfo* info, bool need_resolve = false); // this loads the length and compares against the index void array_range_check (LIR_Opr array, LIR_Opr index, CodeEmitInfo* null_check_info, CodeEmitInfo* range_check_info); @@ -325,7 +327,7 @@ void monitor_enter (LIR_Opr object, LIR_Opr lock, LIR_Opr hdr, LIR_Opr scratch, int monitor_no, CodeEmitInfo* info_for_exception, CodeEmitInfo* info); void monitor_exit (LIR_Opr object, LIR_Opr lock, LIR_Opr hdr, LIR_Opr scratch, int monitor_no); - void new_instance (LIR_Opr dst, ciInstanceKlass* klass, LIR_Opr scratch1, LIR_Opr scratch2, LIR_Opr scratch3, LIR_Opr scratch4, LIR_Opr klass_reg, CodeEmitInfo* info); + void new_instance (LIR_Opr dst, ciInstanceKlass* klass, bool is_unresolved, LIR_Opr scratch1, LIR_Opr scratch2, LIR_Opr scratch3, LIR_Opr scratch4, LIR_Opr klass_reg, CodeEmitInfo* info); // machine dependent void cmp_mem_int(LIR_Condition condition, LIR_Opr base, int disp, int c, CodeEmitInfo* info); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/c1/c1_Runtime1.cpp --- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -123,24 +123,24 @@ int Runtime1::_throw_array_store_exception_count = 0; int Runtime1::_throw_count = 0; -static int _byte_arraycopy_cnt = 0; -static int _short_arraycopy_cnt = 0; -static int _int_arraycopy_cnt = 0; -static int _long_arraycopy_cnt = 0; -static int _oop_arraycopy_cnt = 0; +static int _byte_arraycopy_stub_cnt = 0; +static int _short_arraycopy_stub_cnt = 0; +static int _int_arraycopy_stub_cnt = 0; +static int _long_arraycopy_stub_cnt = 0; +static int _oop_arraycopy_stub_cnt = 0; address Runtime1::arraycopy_count_address(BasicType type) { switch (type) { case T_BOOLEAN: - case T_BYTE: return (address)&_byte_arraycopy_cnt; + case T_BYTE: return (address)&_byte_arraycopy_stub_cnt; case T_CHAR: - case T_SHORT: return (address)&_short_arraycopy_cnt; + case T_SHORT: return (address)&_short_arraycopy_stub_cnt; case T_FLOAT: - case T_INT: return (address)&_int_arraycopy_cnt; + case T_INT: return (address)&_int_arraycopy_stub_cnt; case T_DOUBLE: - case T_LONG: return (address)&_long_arraycopy_cnt; + case T_LONG: return (address)&_long_arraycopy_stub_cnt; case T_ARRAY: - case T_OBJECT: return (address)&_oop_arraycopy_cnt; + case T_OBJECT: return (address)&_oop_arraycopy_stub_cnt; default: ShouldNotReachHere(); return NULL; @@ -1479,13 +1479,13 @@ tty->print_cr(" _ic_miss_cnt: %d", SharedRuntime::_ic_miss_ctr); tty->print_cr(" _generic_arraycopy_cnt: %d", _generic_arraycopy_cnt); tty->print_cr(" _generic_arraycopystub_cnt: %d", _generic_arraycopystub_cnt); - tty->print_cr(" _byte_arraycopy_cnt: %d", _byte_arraycopy_cnt); - tty->print_cr(" _short_arraycopy_cnt: %d", _short_arraycopy_cnt); - tty->print_cr(" _int_arraycopy_cnt: %d", _int_arraycopy_cnt); - tty->print_cr(" _long_arraycopy_cnt: %d", _long_arraycopy_cnt); + tty->print_cr(" _byte_arraycopy_cnt: %d", _byte_arraycopy_stub_cnt); + tty->print_cr(" _short_arraycopy_cnt: %d", _short_arraycopy_stub_cnt); + tty->print_cr(" _int_arraycopy_cnt: %d", _int_arraycopy_stub_cnt); + tty->print_cr(" _long_arraycopy_cnt: %d", _long_arraycopy_stub_cnt); tty->print_cr(" _primitive_arraycopy_cnt: %d", _primitive_arraycopy_cnt); tty->print_cr(" _oop_arraycopy_cnt (C): %d", Runtime1::_oop_arraycopy_cnt); - tty->print_cr(" _oop_arraycopy_cnt (stub): %d", _oop_arraycopy_cnt); + tty->print_cr(" _oop_arraycopy_cnt (stub): %d", _oop_arraycopy_stub_cnt); tty->print_cr(" _arraycopy_slowcase_cnt: %d", _arraycopy_slowcase_cnt); tty->print_cr(" _arraycopy_checkcast_cnt: %d", _arraycopy_checkcast_cnt); tty->print_cr(" _arraycopy_checkcast_attempt_cnt:%d", _arraycopy_checkcast_attempt_cnt); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/classfile/vmSymbols.hpp --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -790,6 +790,26 @@ do_name( decrypt_name, "decrypt") \ do_signature(byteArray_int_int_byteArray_int_signature, "([BII[BI)I") \ \ + /* support for sun.security.provider.SHA */ \ + do_class(sun_security_provider_sha, "sun/security/provider/SHA") \ + do_intrinsic(_sha_implCompress, sun_security_provider_sha, implCompress_name, implCompress_signature, F_R) \ + do_name( implCompress_name, "implCompress") \ + do_signature(implCompress_signature, "([BI)V") \ + \ + /* support for sun.security.provider.SHA2 */ \ + do_class(sun_security_provider_sha2, "sun/security/provider/SHA2") \ + do_intrinsic(_sha2_implCompress, sun_security_provider_sha2, implCompress_name, implCompress_signature, F_R) \ + \ + /* support for sun.security.provider.SHA5 */ \ + do_class(sun_security_provider_sha5, "sun/security/provider/SHA5") \ + do_intrinsic(_sha5_implCompress, sun_security_provider_sha5, implCompress_name, implCompress_signature, F_R) \ + \ + /* support for sun.security.provider.DigestBase */ \ + do_class(sun_security_provider_digestbase, "sun/security/provider/DigestBase") \ + do_intrinsic(_digestBase_implCompressMB, sun_security_provider_digestbase, implCompressMB_name, implCompressMB_signature, F_R) \ + do_name( implCompressMB_name, "implCompressMultiBlock") \ + do_signature(implCompressMB_signature, "([BII)I") \ + \ /* support for java.util.zip */ \ do_class(java_util_zip_CRC32, "java/util/zip/CRC32") \ do_intrinsic(_updateCRC32, java_util_zip_CRC32, update_name, int2_int_signature, F_SN) \ diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/code/relocInfo.cpp --- a/hotspot/src/share/vm/code/relocInfo.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/code/relocInfo.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -877,11 +877,7 @@ void internal_word_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { address target = _target; if (target == NULL) { - if (addr_in_const()) { - target = new_addr_for(*(address*)addr(), src, dest); - } else { - target = new_addr_for(pd_get_address_from_code(), src, dest); - } + target = new_addr_for(this->target(), src, dest); } set_value(target); } @@ -890,7 +886,11 @@ address internal_word_Relocation::target() { address target = _target; if (target == NULL) { - target = pd_get_address_from_code(); + if (addr_in_const()) { + target = *(address*)addr(); + } else { + target = pd_get_address_from_code(); + } } return target; } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -1341,13 +1341,14 @@ bool CMSAdaptiveSizePolicy::print_adaptive_size_policy_on( outputStream* st) const { - if (!UseAdaptiveSizePolicy) return false; + if (!UseAdaptiveSizePolicy) { + return false; + } GenCollectedHeap* gch = GenCollectedHeap::heap(); - Generation* gen0 = gch->get_gen(0); - DefNewGeneration* def_new = gen0->as_DefNewGeneration(); - return - AdaptiveSizePolicy::print_adaptive_size_policy_on( + Generation* young = gch->get_gen(0); + DefNewGeneration* def_new = young->as_DefNewGeneration(); + return AdaptiveSizePolicy::print_adaptive_size_policy_on( st, def_new->tenuring_threshold()); } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -60,21 +60,21 @@ if (UseParNewGC) { if (UseAdaptiveSizePolicy) { _generations[0] = new GenerationSpec(Generation::ASParNew, - _initial_gen0_size, _max_gen0_size); + _initial_young_size, _max_young_size); } else { _generations[0] = new GenerationSpec(Generation::ParNew, - _initial_gen0_size, _max_gen0_size); + _initial_young_size, _max_young_size); } } else { _generations[0] = new GenerationSpec(Generation::DefNew, - _initial_gen0_size, _max_gen0_size); + _initial_young_size, _max_young_size); } if (UseAdaptiveSizePolicy) { _generations[1] = new GenerationSpec(Generation::ASConcurrentMarkSweep, - _initial_gen1_size, _max_gen1_size); + _initial_old_size, _max_old_size); } else { _generations[1] = new GenerationSpec(Generation::ConcurrentMarkSweep, - _initial_gen1_size, _max_gen1_size); + _initial_old_size, _max_old_size); } if (_generations[0] == NULL || _generations[1] == NULL) { diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -1138,8 +1138,8 @@ void CMSCollector::icms_update_allocation_limits() { - Generation* gen0 = GenCollectedHeap::heap()->get_gen(0); - EdenSpace* eden = gen0->as_DefNewGeneration()->eden(); + Generation* young = GenCollectedHeap::heap()->get_gen(0); + EdenSpace* eden = young->as_DefNewGeneration()->eden(); const unsigned int duty_cycle = stats().icms_update_duty_cycle(); if (CMSTraceIncrementalPacing) { diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -1193,10 +1193,9 @@ // Does a "full" (forced) collection invoked on this generation collect // all younger generations as well? Note that the second conjunct is a // hack to allow the collection of the younger gen first if the flag is - // set. This is better than using th policy's should_collect_gen0_first() - // since that causes us to do an extra unnecessary pair of restart-&-stop-world. + // set. virtual bool full_collects_younger_generations() const { - return UseCMSCompactAtFullCollection && !CollectGen0First; + return UseCMSCompactAtFullCollection && !ScavengeBeforeFullGC; } void space_iterate(SpaceClosure* blk, bool usedOnly = false); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -3622,7 +3622,7 @@ void G1CollectedHeap::print_tracing_info() const { // We'll overload this to mean "trace GC pause statistics." - if (TraceGen0Time || TraceGen1Time) { + if (TraceYoungGenTime || TraceOldGenTime) { // The "G1CollectorPolicy" is keeping track of these stats, so delegate // to that. g1_policy()->print_tracing_info(); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -809,7 +809,7 @@ double full_gc_time_sec = end_sec - _full_collection_start_sec; double full_gc_time_ms = full_gc_time_sec * 1000.0; - _trace_gen1_time_data.record_full_collection(full_gc_time_ms); + _trace_old_gen_time_data.record_full_collection(full_gc_time_ms); update_recent_gc_times(end_sec, full_gc_time_ms); @@ -851,7 +851,7 @@ _g1->used(), _g1->recalculate_used())); double s_w_t_ms = (start_time_sec - _stop_world_start) * 1000.0; - _trace_gen0_time_data.record_start_collection(s_w_t_ms); + _trace_young_gen_time_data.record_start_collection(s_w_t_ms); _stop_world_start = 0.0; record_heap_size_info_at_start(false /* full */); @@ -906,7 +906,7 @@ void G1CollectorPolicy::record_concurrent_pause() { if (_stop_world_start > 0.0) { double yield_ms = (os::elapsedTime() - _stop_world_start) * 1000.0; - _trace_gen0_time_data.record_yield_time(yield_ms); + _trace_young_gen_time_data.record_yield_time(yield_ms); } } @@ -993,7 +993,7 @@ evacuation_info.set_bytes_copied(_bytes_copied_during_gc); if (update_stats) { - _trace_gen0_time_data.record_end_collection(pause_time_ms, phase_times()); + _trace_young_gen_time_data.record_end_collection(pause_time_ms, phase_times()); // this is where we update the allocation rate of the application double app_time_ms = (phase_times()->cur_collection_start_sec() * 1000.0 - _prev_collection_pause_end_ms); @@ -1415,8 +1415,8 @@ } void G1CollectorPolicy::print_tracing_info() const { - _trace_gen0_time_data.print(); - _trace_gen1_time_data.print(); + _trace_young_gen_time_data.print(); + _trace_old_gen_time_data.print(); } void G1CollectorPolicy::print_yg_surv_rate_info() const { @@ -1973,9 +1973,9 @@ _last_gc_was_young = gcs_are_young() ? true : false; if (_last_gc_was_young) { - _trace_gen0_time_data.increment_young_collection_count(); + _trace_young_gen_time_data.increment_young_collection_count(); } else { - _trace_gen0_time_data.increment_mixed_collection_count(); + _trace_young_gen_time_data.increment_mixed_collection_count(); } // The young list is laid with the survivor regions from the previous @@ -2156,20 +2156,20 @@ evacuation_info.set_collectionset_regions(cset_region_length()); } -void TraceGen0TimeData::record_start_collection(double time_to_stop_the_world_ms) { - if(TraceGen0Time) { +void TraceYoungGenTimeData::record_start_collection(double time_to_stop_the_world_ms) { + if(TraceYoungGenTime) { _all_stop_world_times_ms.add(time_to_stop_the_world_ms); } } -void TraceGen0TimeData::record_yield_time(double yield_time_ms) { - if(TraceGen0Time) { +void TraceYoungGenTimeData::record_yield_time(double yield_time_ms) { + if(TraceYoungGenTime) { _all_yield_times_ms.add(yield_time_ms); } } -void TraceGen0TimeData::record_end_collection(double pause_time_ms, G1GCPhaseTimes* phase_times) { - if(TraceGen0Time) { +void TraceYoungGenTimeData::record_end_collection(double pause_time_ms, G1GCPhaseTimes* phase_times) { + if(TraceYoungGenTime) { _total.add(pause_time_ms); _other.add(pause_time_ms - phase_times->accounted_time_ms()); _root_region_scan_wait.add(phase_times->root_region_scan_wait_time_ms()); @@ -2194,34 +2194,34 @@ } } -void TraceGen0TimeData::increment_young_collection_count() { - if(TraceGen0Time) { +void TraceYoungGenTimeData::increment_young_collection_count() { + if(TraceYoungGenTime) { ++_young_pause_num; } } -void TraceGen0TimeData::increment_mixed_collection_count() { - if(TraceGen0Time) { +void TraceYoungGenTimeData::increment_mixed_collection_count() { + if(TraceYoungGenTime) { ++_mixed_pause_num; } } -void TraceGen0TimeData::print_summary(const char* str, - const NumberSeq* seq) const { +void TraceYoungGenTimeData::print_summary(const char* str, + const NumberSeq* seq) const { double sum = seq->sum(); gclog_or_tty->print_cr("%-27s = %8.2lf s (avg = %8.2lf ms)", str, sum / 1000.0, seq->avg()); } -void TraceGen0TimeData::print_summary_sd(const char* str, - const NumberSeq* seq) const { +void TraceYoungGenTimeData::print_summary_sd(const char* str, + const NumberSeq* seq) const { print_summary(str, seq); gclog_or_tty->print_cr("%+45s = %5d, std dev = %8.2lf ms, max = %8.2lf ms)", "(num", seq->num(), seq->sd(), seq->maximum()); } -void TraceGen0TimeData::print() const { - if (!TraceGen0Time) { +void TraceYoungGenTimeData::print() const { + if (!TraceYoungGenTime) { return; } @@ -2258,14 +2258,14 @@ print_summary_sd(" Yields", &_all_yield_times_ms); } -void TraceGen1TimeData::record_full_collection(double full_gc_time_ms) { - if (TraceGen1Time) { +void TraceOldGenTimeData::record_full_collection(double full_gc_time_ms) { + if (TraceOldGenTime) { _all_full_gc_times.add(full_gc_time_ms); } } -void TraceGen1TimeData::print() const { - if (!TraceGen1Time) { +void TraceOldGenTimeData::print() const { + if (!TraceOldGenTime) { return; } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -38,10 +38,10 @@ class CollectionSetChooser; class G1GCPhaseTimes; -// TraceGen0Time collects data on _both_ young and mixed evacuation pauses +// TraceYoungGenTime collects data on _both_ young and mixed evacuation pauses // (the latter may contain non-young regions - i.e. regions that are -// technically in Gen1) while TraceGen1Time collects data about full GCs. -class TraceGen0TimeData : public CHeapObj { +// technically in old) while TraceOldGenTime collects data about full GCs. +class TraceYoungGenTimeData : public CHeapObj { private: unsigned _young_pause_num; unsigned _mixed_pause_num; @@ -66,7 +66,7 @@ void print_summary_sd(const char* str, const NumberSeq* seq) const; public: - TraceGen0TimeData() : _young_pause_num(0), _mixed_pause_num(0) {}; + TraceYoungGenTimeData() : _young_pause_num(0), _mixed_pause_num(0) {}; void record_start_collection(double time_to_stop_the_world_ms); void record_yield_time(double yield_time_ms); void record_end_collection(double pause_time_ms, G1GCPhaseTimes* phase_times); @@ -75,7 +75,7 @@ void print() const; }; -class TraceGen1TimeData : public CHeapObj { +class TraceOldGenTimeData : public CHeapObj { private: NumberSeq _all_full_gc_times; @@ -187,8 +187,8 @@ TruncatedSeq* _concurrent_mark_remark_times_ms; TruncatedSeq* _concurrent_mark_cleanup_times_ms; - TraceGen0TimeData _trace_gen0_time_data; - TraceGen1TimeData _trace_gen1_time_data; + TraceYoungGenTimeData _trace_young_gen_time_data; + TraceOldGenTimeData _trace_old_gen_time_data; double _stop_world_start; @@ -202,20 +202,20 @@ // locker is active. This should be >= _young_list_target_length; uint _young_list_max_length; - bool _last_gc_was_young; + bool _last_gc_was_young; - bool _during_marking; - bool _in_marking_window; - bool _in_marking_window_im; + bool _during_marking; + bool _in_marking_window; + bool _in_marking_window_im; - SurvRateGroup* _short_lived_surv_rate_group; - SurvRateGroup* _survivor_surv_rate_group; + SurvRateGroup* _short_lived_surv_rate_group; + SurvRateGroup* _survivor_surv_rate_group; // add here any more surv rate groups - double _gc_overhead_perc; + double _gc_overhead_perc; double _reserve_factor; - uint _reserve_regions; + uint _reserve_regions; bool during_marking() { return _during_marking; diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.cpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -35,14 +35,14 @@ AdjoiningGenerations::AdjoiningGenerations(ReservedSpace old_young_rs, GenerationSizer* policy, size_t alignment) : - _virtual_spaces(old_young_rs, policy->min_gen1_size(), - policy->min_gen0_size(), alignment) { - size_t init_low_byte_size = policy->initial_gen1_size(); - size_t min_low_byte_size = policy->min_gen1_size(); - size_t max_low_byte_size = policy->max_gen1_size(); - size_t init_high_byte_size = policy->initial_gen0_size(); - size_t min_high_byte_size = policy->min_gen0_size(); - size_t max_high_byte_size = policy->max_gen0_size(); + _virtual_spaces(old_young_rs, policy->min_old_size(), + policy->min_young_size(), alignment) { + size_t init_low_byte_size = policy->initial_old_size(); + size_t min_low_byte_size = policy->min_old_size(); + size_t max_low_byte_size = policy->max_old_size(); + size_t init_high_byte_size = policy->initial_young_size(); + size_t min_high_byte_size = policy->min_young_size(); + size_t max_high_byte_size = policy->max_young_size(); assert(min_low_byte_size <= init_low_byte_size && init_low_byte_size <= max_low_byte_size, "Parameter check"); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.cpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -32,8 +32,8 @@ SIZE_FORMAT "," SIZE_FORMAT " " SIZE_FORMAT, str, - _min_gen1_size / K, _max_gen1_size / K, - _min_gen0_size / K, _max_gen0_size / K, + _min_old_size / K, _max_old_size / K, + _min_young_size / K, _max_young_size / K, _max_heap_byte_size / K); } } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -623,11 +623,11 @@ } void ParallelScavengeHeap::print_tracing_info() const { - if (TraceGen0Time) { + if (TraceYoungGenTime) { double time = PSScavenge::accumulated_time()->seconds(); tty->print_cr("[Accumulated GC generation 0 time %3.7f secs]", time); } - if (TraceGen1Time) { + if (TraceOldGenTime) { double time = UseParallelOldGC ? PSParallelCompact::accumulated_time()->seconds() : PSMarkSweep::accumulated_time()->seconds(); tty->print_cr("[Accumulated GC generation 1 time %3.7f secs]", time); } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -174,7 +174,7 @@ TraceCollectorStats tcs(counters()); TraceMemoryManagerStats tms(true /* Full GC */,gc_cause); - if (TraceGen1Time) accumulated_time()->start(); + if (TraceOldGenTime) accumulated_time()->start(); // Let the size policy know we're starting size_policy->major_collection_begin(); @@ -354,7 +354,7 @@ // We collected the heap, recalculate the metaspace capacity MetaspaceGC::compute_new_size(); - if (TraceGen1Time) accumulated_time()->stop(); + if (TraceOldGenTime) accumulated_time()->stop(); if (PrintGC) { if (PrintGCDetails) { diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -2061,7 +2061,7 @@ TraceCollectorStats tcs(counters()); TraceMemoryManagerStats tms(true /* Full GC */,gc_cause); - if (TraceGen1Time) accumulated_time()->start(); + if (TraceOldGenTime) accumulated_time()->start(); // Let the size policy know we're starting size_policy->major_collection_begin(); @@ -2188,7 +2188,7 @@ // Resize the metaspace capacity after a collection MetaspaceGC::compute_new_size(); - if (TraceGen1Time) accumulated_time()->stop(); + if (TraceOldGenTime) accumulated_time()->stop(); if (PrintGC) { if (PrintGCDetails) { diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -336,7 +336,7 @@ TraceCollectorStats tcs(counters()); TraceMemoryManagerStats tms(false /* not full GC */,gc_cause); - if (TraceGen0Time) accumulated_time()->start(); + if (TraceYoungGenTime) accumulated_time()->start(); // Let the size policy know we're starting size_policy->minor_collection_begin(); @@ -660,7 +660,7 @@ CardTableExtension::verify_all_young_refs_imprecise(); } - if (TraceGen0Time) accumulated_time()->stop(); + if (TraceYoungGenTime) accumulated_time()->stop(); if (PrintGC) { if (PrintGCDetails) { diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/memory/collectorPolicy.cpp --- a/hotspot/src/share/vm/memory/collectorPolicy.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -196,13 +196,13 @@ // GenCollectorPolicy methods GenCollectorPolicy::GenCollectorPolicy() : - _min_gen0_size(0), - _initial_gen0_size(0), - _max_gen0_size(0), + _min_young_size(0), + _initial_young_size(0), + _max_young_size(0), _gen_alignment(0), - _min_gen1_size(0), - _initial_gen1_size(0), - _max_gen1_size(0), + _min_old_size(0), + _initial_old_size(0), + _max_old_size(0), _generations(NULL) {} @@ -236,7 +236,7 @@ #ifdef ASSERT void GenCollectorPolicy::assert_flags() { CollectorPolicy::assert_flags(); - assert(NewSize >= _min_gen0_size, "Ergonomics decided on a too small young gen size"); + assert(NewSize >= _min_young_size, "Ergonomics decided on a too small young gen size"); assert(NewSize <= MaxNewSize, "Ergonomics decided on incompatible initial and maximum young gen sizes"); assert(FLAG_IS_DEFAULT(MaxNewSize) || MaxNewSize < MaxHeapSize, "Ergonomics decided on incompatible maximum young gen and heap sizes"); assert(NewSize % _gen_alignment == 0, "NewSize alignment"); @@ -249,28 +249,28 @@ CollectorPolicy::assert_size_info(); // GenCollectorPolicy::initialize_size_info may update the MaxNewSize assert(MaxNewSize < MaxHeapSize, "Ergonomics decided on incompatible maximum young and heap sizes"); - assert(NewSize == _initial_gen0_size, "Discrepancy between NewSize flag and local storage"); - assert(MaxNewSize == _max_gen0_size, "Discrepancy between MaxNewSize flag and local storage"); - assert(OldSize == _initial_gen1_size, "Discrepancy between OldSize flag and local storage"); - assert(_min_gen0_size <= _initial_gen0_size, "Ergonomics decided on incompatible minimum and initial young gen sizes"); - assert(_initial_gen0_size <= _max_gen0_size, "Ergonomics decided on incompatible initial and maximum young gen sizes"); - assert(_min_gen0_size % _gen_alignment == 0, "_min_gen0_size alignment"); - assert(_initial_gen0_size % _gen_alignment == 0, "_initial_gen0_size alignment"); - assert(_max_gen0_size % _gen_alignment == 0, "_max_gen0_size alignment"); - assert(_min_gen0_size <= bound_minus_alignment(_min_gen0_size, _min_heap_byte_size), + assert(NewSize == _initial_young_size, "Discrepancy between NewSize flag and local storage"); + assert(MaxNewSize == _max_young_size, "Discrepancy between MaxNewSize flag and local storage"); + assert(OldSize == _initial_old_size, "Discrepancy between OldSize flag and local storage"); + assert(_min_young_size <= _initial_young_size, "Ergonomics decided on incompatible minimum and initial young gen sizes"); + assert(_initial_young_size <= _max_young_size, "Ergonomics decided on incompatible initial and maximum young gen sizes"); + assert(_min_young_size % _gen_alignment == 0, "_min_young_size alignment"); + assert(_initial_young_size % _gen_alignment == 0, "_initial_young_size alignment"); + assert(_max_young_size % _gen_alignment == 0, "_max_young_size alignment"); + assert(_min_young_size <= bound_minus_alignment(_min_young_size, _min_heap_byte_size), "Ergonomics made minimum young generation larger than minimum heap"); - assert(_initial_gen0_size <= bound_minus_alignment(_initial_gen0_size, _initial_heap_byte_size), + assert(_initial_young_size <= bound_minus_alignment(_initial_young_size, _initial_heap_byte_size), "Ergonomics made initial young generation larger than initial heap"); - assert(_max_gen0_size <= bound_minus_alignment(_max_gen0_size, _max_heap_byte_size), + assert(_max_young_size <= bound_minus_alignment(_max_young_size, _max_heap_byte_size), "Ergonomics made maximum young generation lager than maximum heap"); - assert(_min_gen1_size <= _initial_gen1_size, "Ergonomics decided on incompatible minimum and initial old gen sizes"); - assert(_initial_gen1_size <= _max_gen1_size, "Ergonomics decided on incompatible initial and maximum old gen sizes"); - assert(_max_gen1_size % _gen_alignment == 0, "_max_gen1_size alignment"); - assert(_initial_gen1_size % _gen_alignment == 0, "_initial_gen1_size alignment"); - assert(_max_heap_byte_size <= (_max_gen0_size + _max_gen1_size), "Total maximum heap sizes must be sum of generation maximum sizes"); - assert(_min_gen0_size + _min_gen1_size <= _min_heap_byte_size, "Minimum generation sizes exceed minimum heap size"); - assert(_initial_gen0_size + _initial_gen1_size == _initial_heap_byte_size, "Initial generation sizes should match initial heap size"); - assert(_max_gen0_size + _max_gen1_size == _max_heap_byte_size, "Maximum generation sizes should match maximum heap size"); + assert(_min_old_size <= _initial_old_size, "Ergonomics decided on incompatible minimum and initial old gen sizes"); + assert(_initial_old_size <= _max_old_size, "Ergonomics decided on incompatible initial and maximum old gen sizes"); + assert(_max_old_size % _gen_alignment == 0, "_max_old_size alignment"); + assert(_initial_old_size % _gen_alignment == 0, "_initial_old_size alignment"); + assert(_max_heap_byte_size <= (_max_young_size + _max_old_size), "Total maximum heap sizes must be sum of generation maximum sizes"); + assert(_min_young_size + _min_old_size <= _min_heap_byte_size, "Minimum generation sizes exceed minimum heap size"); + assert(_initial_young_size + _initial_old_size == _initial_heap_byte_size, "Initial generation sizes should match initial heap size"); + assert(_max_young_size + _max_old_size == _max_heap_byte_size, "Maximum generation sizes should match maximum heap size"); } #endif // ASSERT @@ -323,8 +323,8 @@ // later when setting the initial and minimum young generation size. NewSize = bounded_new_size; } - _min_gen0_size = smallest_new_size; - _initial_gen0_size = NewSize; + _min_young_size = smallest_new_size; + _initial_young_size = NewSize; if (!FLAG_IS_DEFAULT(MaxNewSize)) { if (MaxNewSize >= MaxHeapSize) { @@ -338,14 +338,14 @@ FLAG_SET_ERGO(uintx, MaxNewSize, smaller_max_new_size); if (NewSize > MaxNewSize) { FLAG_SET_ERGO(uintx, NewSize, MaxNewSize); - _initial_gen0_size = NewSize; + _initial_young_size = NewSize; } - } else if (MaxNewSize < _initial_gen0_size) { - FLAG_SET_ERGO(uintx, MaxNewSize, _initial_gen0_size); + } else if (MaxNewSize < _initial_young_size) { + FLAG_SET_ERGO(uintx, MaxNewSize, _initial_young_size); } else if (!is_size_aligned(MaxNewSize, _gen_alignment)) { FLAG_SET_ERGO(uintx, MaxNewSize, align_size_down(MaxNewSize, _gen_alignment)); } - _max_gen0_size = MaxNewSize; + _max_young_size = MaxNewSize; } if (NewSize > MaxNewSize) { @@ -357,7 +357,7 @@ NewSize/K, MaxNewSize/K, NewSize/K); } FLAG_SET_ERGO(uintx, MaxNewSize, NewSize); - _max_gen0_size = MaxNewSize; + _max_young_size = MaxNewSize; } if (SurvivorRatio < 1 || NewRatio < 1) { @@ -393,7 +393,7 @@ double shrink_factor = (double) MaxHeapSize / calculated_size; uintx smaller_new_size = align_size_down((uintx)(NewSize * shrink_factor), _gen_alignment); FLAG_SET_ERGO(uintx, NewSize, MAX2(young_gen_size_lower_bound(), smaller_new_size)); - _initial_gen0_size = NewSize; + _initial_young_size = NewSize; // OldSize is already aligned because above we aligned MaxHeapSize to // _heap_alignment, and we just made sure that NewSize is aligned to @@ -406,16 +406,16 @@ } } - // Update NewSize, if possible, to avoid sizing gen0 to small when only + // Update NewSize, if possible, to avoid sizing the young gen too small when only // OldSize is set on the command line. if (FLAG_IS_CMDLINE(OldSize) && !FLAG_IS_CMDLINE(NewSize)) { if (OldSize < _initial_heap_byte_size) { size_t new_size = _initial_heap_byte_size - OldSize; - // Need to compare against the flag value for max since _max_gen0_size + // Need to compare against the flag value for max since _max_young_size // might not have been set yet. - if (new_size >= _min_gen0_size && new_size <= MaxNewSize) { + if (new_size >= _min_young_size && new_size <= MaxNewSize) { FLAG_SET_ERGO(uintx, NewSize, new_size); - _initial_gen0_size = NewSize; + _initial_young_size = NewSize; } } } @@ -444,97 +444,77 @@ void GenCollectorPolicy::initialize_size_info() { CollectorPolicy::initialize_size_info(); - // _space_alignment is used for alignment within a generation. - // There is additional alignment done down stream for some - // collectors that sometimes causes unwanted rounding up of - // generations sizes. + _initial_young_size = NewSize; + _max_young_size = MaxNewSize; + _initial_old_size = OldSize; - // Determine maximum size of gen0 + // Determine maximum size of the young generation. - size_t max_new_size = 0; - if (!FLAG_IS_DEFAULT(MaxNewSize)) { - max_new_size = MaxNewSize; - } else { - max_new_size = scale_by_NewRatio_aligned(_max_heap_byte_size); + if (FLAG_IS_DEFAULT(MaxNewSize)) { + _max_young_size = scale_by_NewRatio_aligned(_max_heap_byte_size); // Bound the maximum size by NewSize below (since it historically // would have been NewSize and because the NewRatio calculation could // yield a size that is too small) and bound it by MaxNewSize above. // Ergonomics plays here by previously calculating the desired // NewSize and MaxNewSize. - max_new_size = MIN2(MAX2(max_new_size, NewSize), MaxNewSize); + _max_young_size = MIN2(MAX2(_max_young_size, _initial_young_size), MaxNewSize); } - assert(max_new_size > 0, "All paths should set max_new_size"); - // Given the maximum gen0 size, determine the initial and - // minimum gen0 sizes. + // Given the maximum young size, determine the initial and + // minimum young sizes. if (_max_heap_byte_size == _initial_heap_byte_size) { - // The maxium and initial heap sizes are the same so the generation's + // The maximum and initial heap sizes are the same so the generation's // initial size must be the same as it maximum size. Use NewSize as the // size if set on command line. - size_t fixed_young_size = FLAG_IS_CMDLINE(NewSize) ? NewSize : max_new_size; - - _initial_gen0_size = fixed_young_size; - _max_gen0_size = fixed_young_size; + _max_young_size = FLAG_IS_CMDLINE(NewSize) ? NewSize : _max_young_size; + _initial_young_size = _max_young_size; // Also update the minimum size if min == initial == max. if (_max_heap_byte_size == _min_heap_byte_size) { - _min_gen0_size = fixed_young_size; + _min_young_size = _max_young_size; } } else { - size_t desired_new_size = 0; if (FLAG_IS_CMDLINE(NewSize)) { // If NewSize is set on the command line, we should use it as // the initial size, but make sure it is within the heap bounds. - desired_new_size = - MIN2(max_new_size, bound_minus_alignment(NewSize, _initial_heap_byte_size)); - _min_gen0_size = bound_minus_alignment(desired_new_size, _min_heap_byte_size); + _initial_young_size = + MIN2(_max_young_size, bound_minus_alignment(NewSize, _initial_heap_byte_size)); + _min_young_size = bound_minus_alignment(_initial_young_size, _min_heap_byte_size); } else { // For the case where NewSize is not set on the command line, use // NewRatio to size the initial generation size. Use the current // NewSize as the floor, because if NewRatio is overly large, the resulting // size can be too small. - desired_new_size = - MIN2(max_new_size, MAX2(scale_by_NewRatio_aligned(_initial_heap_byte_size), NewSize)); + _initial_young_size = + MIN2(_max_young_size, MAX2(scale_by_NewRatio_aligned(_initial_heap_byte_size), NewSize)); } - _initial_gen0_size = desired_new_size; - _max_gen0_size = max_new_size; - } - - // Write back to flags if necessary. - if (NewSize != _initial_gen0_size) { - FLAG_SET_ERGO(uintx, NewSize, _initial_gen0_size); - } - - if (MaxNewSize != _max_gen0_size) { - FLAG_SET_ERGO(uintx, MaxNewSize, _max_gen0_size); } if (PrintGCDetails && Verbose) { - gclog_or_tty->print_cr("1: Minimum gen0 " SIZE_FORMAT " Initial gen0 " - SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT, - _min_gen0_size, _initial_gen0_size, _max_gen0_size); + gclog_or_tty->print_cr("1: Minimum young " SIZE_FORMAT " Initial young " + SIZE_FORMAT " Maximum young " SIZE_FORMAT, + _min_young_size, _initial_young_size, _max_young_size); } // At this point the minimum, initial and maximum sizes - // of the overall heap and of gen0 have been determined. - // The maximum gen1 size can be determined from the maximum gen0 + // of the overall heap and of the young generation have been determined. + // The maximum old size can be determined from the maximum young // and maximum heap size since no explicit flags exist - // for setting the gen1 maximum. - _max_gen1_size = MAX2(_max_heap_byte_size - _max_gen0_size, _gen_alignment); + // for setting the old generation maximum. + _max_old_size = MAX2(_max_heap_byte_size - _max_young_size, _gen_alignment); // If no explicit command line flag has been set for the - // gen1 size, use what is left for gen1 + // old generation size, use what is left. if (!FLAG_IS_CMDLINE(OldSize)) { // The user has not specified any value but the ergonomics // may have chosen a value (which may or may not be consistent // with the overall heap size). In either case make // the minimum, maximum and initial sizes consistent - // with the gen0 sizes and the overall heap sizes. - _min_gen1_size = _gen_alignment; - _initial_gen1_size = MIN2(_max_gen1_size, MAX2(_initial_heap_byte_size - _initial_gen0_size, _min_gen1_size)); - // _max_gen1_size has already been made consistent above - FLAG_SET_ERGO(uintx, OldSize, _initial_gen1_size); + // with the young sizes and the overall heap sizes. + _min_old_size = _gen_alignment; + _initial_old_size = MIN2(_max_old_size, MAX2(_initial_heap_byte_size - _initial_young_size, _min_old_size)); + // _max_old_size has already been made consistent above. } else { // OldSize has been explicitly set on the command line. Use it // for the initial size but make sure the minimum allow a young @@ -543,69 +523,68 @@ // with other command line flags, issue a warning. // The generation minimums and the overall heap minimum should // be within one generation alignment. - if (OldSize > _max_gen1_size) { + if (_initial_old_size > _max_old_size) { warning("Inconsistency between maximum heap size and maximum " "generation sizes: using maximum heap = " SIZE_FORMAT " -XX:OldSize flag is being ignored", _max_heap_byte_size); - FLAG_SET_ERGO(uintx, OldSize, _max_gen1_size); + _initial_old_size = _max_old_size; } - _min_gen1_size = MIN2(OldSize, _min_heap_byte_size - _min_gen0_size); - _initial_gen1_size = OldSize; + _min_old_size = MIN2(_initial_old_size, _min_heap_byte_size - _min_young_size); } // The initial generation sizes should match the initial heap size, // if not issue a warning and resize the generations. This behavior // differs from JDK8 where the generation sizes have higher priority // than the initial heap size. - if ((_initial_gen1_size + _initial_gen0_size) != _initial_heap_byte_size) { + if ((_initial_old_size + _initial_young_size) != _initial_heap_byte_size) { warning("Inconsistency between generation sizes and heap size, resizing " "the generations to fit the heap."); - size_t desired_gen0_size = _initial_heap_byte_size - _initial_gen1_size; - if (_initial_heap_byte_size < _initial_gen1_size) { + size_t desired_young_size = _initial_heap_byte_size - _initial_old_size; + if (_initial_heap_byte_size < _initial_old_size) { // Old want all memory, use minimum for young and rest for old - _initial_gen0_size = _min_gen0_size; - _initial_gen1_size = _initial_heap_byte_size - _min_gen0_size; - } else if (desired_gen0_size > _max_gen0_size) { + _initial_young_size = _min_young_size; + _initial_old_size = _initial_heap_byte_size - _min_young_size; + } else if (desired_young_size > _max_young_size) { // Need to increase both young and old generation - _initial_gen0_size = _max_gen0_size; - _initial_gen1_size = _initial_heap_byte_size - _max_gen0_size; - } else if (desired_gen0_size < _min_gen0_size) { + _initial_young_size = _max_young_size; + _initial_old_size = _initial_heap_byte_size - _max_young_size; + } else if (desired_young_size < _min_young_size) { // Need to decrease both young and old generation - _initial_gen0_size = _min_gen0_size; - _initial_gen1_size = _initial_heap_byte_size - _min_gen0_size; + _initial_young_size = _min_young_size; + _initial_old_size = _initial_heap_byte_size - _min_young_size; } else { // The young generation boundaries allow us to only update the // young generation. - _initial_gen0_size = desired_gen0_size; + _initial_young_size = desired_young_size; } if (PrintGCDetails && Verbose) { - gclog_or_tty->print_cr("2: Minimum gen0 " SIZE_FORMAT " Initial gen0 " - SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT, - _min_gen0_size, _initial_gen0_size, _max_gen0_size); + gclog_or_tty->print_cr("2: Minimum young " SIZE_FORMAT " Initial young " + SIZE_FORMAT " Maximum young " SIZE_FORMAT, + _min_young_size, _initial_young_size, _max_young_size); } } - // Write back to flags if necessary - if (NewSize != _initial_gen0_size) { - FLAG_SET_ERGO(uintx, NewSize, _initial_gen0_size); + // Write back to flags if necessary. + if (NewSize != _initial_young_size) { + FLAG_SET_ERGO(uintx, NewSize, _initial_young_size); } - if (MaxNewSize != _max_gen0_size) { - FLAG_SET_ERGO(uintx, MaxNewSize, _max_gen0_size); + if (MaxNewSize != _max_young_size) { + FLAG_SET_ERGO(uintx, MaxNewSize, _max_young_size); } - if (OldSize != _initial_gen1_size) { - FLAG_SET_ERGO(uintx, OldSize, _initial_gen1_size); + if (OldSize != _initial_old_size) { + FLAG_SET_ERGO(uintx, OldSize, _initial_old_size); } if (PrintGCDetails && Verbose) { - gclog_or_tty->print_cr("Minimum gen1 " SIZE_FORMAT " Initial gen1 " - SIZE_FORMAT " Maximum gen1 " SIZE_FORMAT, - _min_gen1_size, _initial_gen1_size, _max_gen1_size); + gclog_or_tty->print_cr("Minimum old " SIZE_FORMAT " Initial old " + SIZE_FORMAT " Maximum old " SIZE_FORMAT, + _min_old_size, _initial_old_size, _max_old_size); } DEBUG_ONLY(GenCollectorPolicy::assert_size_info();) @@ -631,11 +610,11 @@ HandleMark hm; // Discard any handles allocated in each iteration. // First allocation attempt is lock-free. - Generation *gen0 = gch->get_gen(0); - assert(gen0->supports_inline_contig_alloc(), + Generation *young = gch->get_gen(0); + assert(young->supports_inline_contig_alloc(), "Otherwise, must do alloc within heap lock"); - if (gen0->should_allocate(size, is_tlab)) { - result = gen0->par_allocate(size, is_tlab); + if (young->should_allocate(size, is_tlab)) { + result = young->par_allocate(size, is_tlab); if (result != NULL) { assert(gch->is_in_reserved(result), "result not in heap"); return result; @@ -917,8 +896,8 @@ bool GenCollectorPolicy::should_try_older_generation_allocation( size_t word_size) const { GenCollectedHeap* gch = GenCollectedHeap::heap(); - size_t gen0_capacity = gch->get_gen(0)->capacity_before_gc(); - return (word_size > heap_word_size(gen0_capacity)) + size_t young_capacity = gch->get_gen(0)->capacity_before_gc(); + return (word_size > heap_word_size(young_capacity)) || GC_locker::is_active_and_needs_gc() || gch->incremental_collection_failed(); } @@ -940,11 +919,11 @@ } if (UseParNewGC) { - _generations[0] = new GenerationSpec(Generation::ParNew, _initial_gen0_size, _max_gen0_size); + _generations[0] = new GenerationSpec(Generation::ParNew, _initial_young_size, _max_young_size); } else { - _generations[0] = new GenerationSpec(Generation::DefNew, _initial_gen0_size, _max_gen0_size); + _generations[0] = new GenerationSpec(Generation::DefNew, _initial_young_size, _max_young_size); } - _generations[1] = new GenerationSpec(Generation::MarkSweepCompact, _initial_gen1_size, _max_gen1_size); + _generations[1] = new GenerationSpec(Generation::MarkSweepCompact, _initial_old_size, _max_old_size); if (_generations[0] == NULL || _generations[1] == NULL) { vm_exit_during_initialization("Unable to allocate gen spec"); @@ -978,18 +957,18 @@ flag_value = 20 * M; set_basic_flag_values(); FLAG_SET_CMDLINE(uintx, NewSize, flag_value); - verify_gen0_min(flag_value); + verify_young_min(flag_value); set_basic_flag_values(); FLAG_SET_CMDLINE(uintx, NewSize, flag_value); - verify_gen0_initial(flag_value); + verify_young_initial(flag_value); // If NewSize is set on command line, but is larger than the min // heap size, it should only be used for initial young size. flag_value = 80 * M; set_basic_flag_values(); FLAG_SET_CMDLINE(uintx, NewSize, flag_value); - verify_gen0_initial(flag_value); + verify_young_initial(flag_value); // If NewSize has been ergonomically set, the collector policy // should use it for min but calculate the initial young size @@ -997,11 +976,11 @@ flag_value = 20 * M; set_basic_flag_values(); FLAG_SET_ERGO(uintx, NewSize, flag_value); - verify_gen0_min(flag_value); + verify_young_min(flag_value); set_basic_flag_values(); FLAG_SET_ERGO(uintx, NewSize, flag_value); - verify_scaled_gen0_initial(InitialHeapSize); + verify_scaled_young_initial(InitialHeapSize); restore_flags(); } @@ -1016,11 +995,11 @@ flag_value = 20 * M; set_basic_flag_values(); FLAG_SET_CMDLINE(uintx, OldSize, flag_value); - verify_gen1_min(flag_value); + verify_old_min(flag_value); set_basic_flag_values(); FLAG_SET_CMDLINE(uintx, OldSize, flag_value); - verify_gen1_initial(flag_value); + verify_old_initial(flag_value); // If MaxNewSize is large, the maximum OldSize will be less than // what's requested on the command line and it should be reset @@ -1031,46 +1010,46 @@ FLAG_SET_CMDLINE(uintx, MaxNewSize, 170*M); // Calculate what we expect the flag to be. flag_value = MaxHeapSize - MaxNewSize; - verify_gen1_initial(flag_value); + verify_old_initial(flag_value); } - static void verify_gen0_min(size_t expected) { + static void verify_young_min(size_t expected) { MarkSweepPolicy msp; msp.initialize_all(); - assert(msp.min_gen0_size() <= expected, err_msg("%zu > %zu", msp.min_gen0_size(), expected)); + assert(msp.min_young_size() <= expected, err_msg("%zu > %zu", msp.min_young_size(), expected)); } - static void verify_gen0_initial(size_t expected) { + static void verify_young_initial(size_t expected) { MarkSweepPolicy msp; msp.initialize_all(); - assert(msp.initial_gen0_size() == expected, err_msg("%zu != %zu", msp.initial_gen0_size(), expected)); + assert(msp.initial_young_size() == expected, err_msg("%zu != %zu", msp.initial_young_size(), expected)); } - static void verify_scaled_gen0_initial(size_t initial_heap_size) { + static void verify_scaled_young_initial(size_t initial_heap_size) { MarkSweepPolicy msp; msp.initialize_all(); size_t expected = msp.scale_by_NewRatio_aligned(initial_heap_size); - assert(msp.initial_gen0_size() == expected, err_msg("%zu != %zu", msp.initial_gen0_size(), expected)); + assert(msp.initial_young_size() == expected, err_msg("%zu != %zu", msp.initial_young_size(), expected)); assert(FLAG_IS_ERGO(NewSize) && NewSize == expected, err_msg("NewSize should have been set ergonomically to %zu, but was %zu", expected, NewSize)); } - static void verify_gen1_min(size_t expected) { + static void verify_old_min(size_t expected) { MarkSweepPolicy msp; msp.initialize_all(); - assert(msp.min_gen1_size() <= expected, err_msg("%zu > %zu", msp.min_gen1_size(), expected)); + assert(msp.min_old_size() <= expected, err_msg("%zu > %zu", msp.min_old_size(), expected)); } - static void verify_gen1_initial(size_t expected) { + static void verify_old_initial(size_t expected) { MarkSweepPolicy msp; msp.initialize_all(); - assert(msp.initial_gen1_size() == expected, err_msg("%zu != %zu", msp.initial_gen1_size(), expected)); + assert(msp.initial_old_size() == expected, err_msg("%zu != %zu", msp.initial_old_size(), expected)); } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/memory/collectorPolicy.hpp --- a/hotspot/src/share/vm/memory/collectorPolicy.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/memory/collectorPolicy.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -219,12 +219,12 @@ class GenCollectorPolicy : public CollectorPolicy { friend class TestGenCollectorPolicy; protected: - size_t _min_gen0_size; - size_t _initial_gen0_size; - size_t _max_gen0_size; - size_t _min_gen1_size; - size_t _initial_gen1_size; - size_t _max_gen1_size; + size_t _min_young_size; + size_t _initial_young_size; + size_t _max_young_size; + size_t _min_old_size; + size_t _initial_old_size; + size_t _max_old_size; // _gen_alignment and _space_alignment will have the same value most of the // time. When using large pages they can differ. @@ -260,13 +260,13 @@ GenCollectorPolicy(); // Accessors - size_t min_gen0_size() { return _min_gen0_size; } - size_t initial_gen0_size() { return _initial_gen0_size; } - size_t max_gen0_size() { return _max_gen0_size; } - size_t gen_alignment() { return _gen_alignment; } - size_t min_gen1_size() { return _min_gen1_size; } - size_t initial_gen1_size() { return _initial_gen1_size; } - size_t max_gen1_size() { return _max_gen1_size; } + size_t min_young_size() { return _min_young_size; } + size_t initial_young_size() { return _initial_young_size; } + size_t max_young_size() { return _max_young_size; } + size_t gen_alignment() { return _gen_alignment; } + size_t min_old_size() { return _min_old_size; } + size_t initial_old_size() { return _initial_old_size; } + size_t max_old_size() { return _max_old_size; } int number_of_generations() { return 2; } @@ -298,7 +298,7 @@ size_t init_survivor_size); virtual void post_heap_initialize() { - assert(_max_gen0_size == MaxNewSize, "Should be taken care of by initialize_size_info"); + assert(_max_young_size == MaxNewSize, "Should be taken care of by initialize_size_info"); } BarrierSet::Name barrier_set_name() { return BarrierSet::CardTableModRef; } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/memory/genCollectedHeap.cpp --- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -1119,10 +1119,10 @@ } void GenCollectedHeap::print_tracing_info() const { - if (TraceGen0Time) { + if (TraceYoungGenTime) { get_gen(0)->print_summary_info(); } - if (TraceGen1Time) { + if (TraceOldGenTime) { get_gen(1)->print_summary_info(); } } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/memory/tenuredGeneration.hpp --- a/hotspot/src/share/vm/memory/tenuredGeneration.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/memory/tenuredGeneration.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -67,10 +67,9 @@ // Does a "full" (forced) collection invoked on this generation collect // all younger generations as well? Note that this is a // hack to allow the collection of the younger gen first if the flag is - // set. This is better than using th policy's should_collect_gen0_first() - // since that causes us to do an extra unnecessary pair of restart-&-stop-world. + // set. virtual bool full_collects_younger_generations() const { - return !CollectGen0First; + return !ScavengeBeforeFullGC; } virtual void gc_prologue(bool full); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/oops/cpCache.cpp --- a/hotspot/src/share/vm/oops/cpCache.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/oops/cpCache.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -407,7 +407,7 @@ oop ConstantPoolCacheEntry::appendix_if_resolved(constantPoolHandle cpool) { - if (is_f1_null() || !has_appendix()) + if (!has_appendix()) return NULL; const int ref_index = f2_as_index() + _indy_resolved_references_appendix_offset; objArrayOop resolved_references = cpool->resolved_references(); @@ -416,7 +416,7 @@ oop ConstantPoolCacheEntry::method_type_if_resolved(constantPoolHandle cpool) { - if (is_f1_null() || !has_method_type()) + if (!has_method_type()) return NULL; const int ref_index = f2_as_index() + _indy_resolved_references_method_type_offset; objArrayOop resolved_references = cpool->resolved_references(); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/oops/cpCache.hpp --- a/hotspot/src/share/vm/oops/cpCache.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/oops/cpCache.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -348,8 +348,8 @@ bool is_final() const { return (_flags & (1 << is_final_shift)) != 0; } bool is_forced_virtual() const { return (_flags & (1 << is_forced_virtual_shift)) != 0; } bool is_vfinal() const { return (_flags & (1 << is_vfinal_shift)) != 0; } - bool has_appendix() const { return (_flags & (1 << has_appendix_shift)) != 0; } - bool has_method_type() const { return (_flags & (1 << has_method_type_shift)) != 0; } + bool has_appendix() const { return (!is_f1_null()) && (_flags & (1 << has_appendix_shift)) != 0; } + bool has_method_type() const { return (!is_f1_null()) && (_flags & (1 << has_method_type_shift)) != 0; } bool is_method_entry() const { return (_flags & (1 << is_field_entry_shift)) == 0; } bool is_field_entry() const { return (_flags & (1 << is_field_entry_shift)) != 0; } bool is_byte() const { return flag_state() == btos; } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/oops/methodData.hpp --- a/hotspot/src/share/vm/oops/methodData.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/oops/methodData.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -2053,7 +2053,7 @@ // Whole-method sticky bits and flags enum { - _trap_hist_limit = 20, // decoupled from Deoptimization::Reason_LIMIT + _trap_hist_limit = 21, // decoupled from Deoptimization::Reason_LIMIT _trap_hist_mask = max_jubyte, _extra_data_count = 4 // extra DataLayout headers, for trap history }; // Public flag values diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/addnode.cpp --- a/hotspot/src/share/vm/opto/addnode.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/addnode.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -254,47 +254,46 @@ const Type *t_sub1 = phase->type( in1->in(1) ); const Type *t_2 = phase->type( in2 ); if( t_sub1->singleton() && t_2->singleton() && t_sub1 != Type::TOP && t_2 != Type::TOP ) - return new (phase->C) SubINode(phase->makecon( add_ring( t_sub1, t_2 ) ), - in1->in(2) ); + return new SubINode(phase->makecon( add_ring( t_sub1, t_2 ) ), in1->in(2) ); // Convert "(a-b)+(c-d)" into "(a+c)-(b+d)" if( op2 == Op_SubI ) { // Check for dead cycle: d = (a-b)+(c-d) assert( in1->in(2) != this && in2->in(2) != this, "dead loop in AddINode::Ideal" ); - Node *sub = new (phase->C) SubINode(NULL, NULL); - sub->init_req(1, phase->transform(new (phase->C) AddINode(in1->in(1), in2->in(1) ) )); - sub->init_req(2, phase->transform(new (phase->C) AddINode(in1->in(2), in2->in(2) ) )); + Node *sub = new SubINode(NULL, NULL); + sub->init_req(1, phase->transform(new AddINode(in1->in(1), in2->in(1) ) )); + sub->init_req(2, phase->transform(new AddINode(in1->in(2), in2->in(2) ) )); return sub; } // Convert "(a-b)+(b+c)" into "(a+c)" if( op2 == Op_AddI && in1->in(2) == in2->in(1) ) { assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddINode::Ideal"); - return new (phase->C) AddINode(in1->in(1), in2->in(2)); + return new AddINode(in1->in(1), in2->in(2)); } // Convert "(a-b)+(c+b)" into "(a+c)" if( op2 == Op_AddI && in1->in(2) == in2->in(2) ) { assert(in1->in(1) != this && in2->in(1) != this,"dead loop in AddINode::Ideal"); - return new (phase->C) AddINode(in1->in(1), in2->in(1)); + return new AddINode(in1->in(1), in2->in(1)); } // Convert "(a-b)+(b-c)" into "(a-c)" if( op2 == Op_SubI && in1->in(2) == in2->in(1) ) { assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddINode::Ideal"); - return new (phase->C) SubINode(in1->in(1), in2->in(2)); + return new SubINode(in1->in(1), in2->in(2)); } // Convert "(a-b)+(c-a)" into "(c-b)" if( op2 == Op_SubI && in1->in(1) == in2->in(2) ) { assert(in1->in(2) != this && in2->in(1) != this,"dead loop in AddINode::Ideal"); - return new (phase->C) SubINode(in2->in(1), in1->in(2)); + return new SubINode(in2->in(1), in1->in(2)); } } // Convert "x+(0-y)" into "(x-y)" if( op2 == Op_SubI && phase->type(in2->in(1)) == TypeInt::ZERO ) - return new (phase->C) SubINode(in1, in2->in(2) ); + return new SubINode(in1, in2->in(2) ); // Convert "(0-y)+x" into "(x-y)" if( op1 == Op_SubI && phase->type(in1->in(1)) == TypeInt::ZERO ) - return new (phase->C) SubINode( in2, in1->in(2) ); + return new SubINode( in2, in1->in(2) ); // Convert (x>>>z)+y into (x+(y<>>z for small constant z and y. // Helps with array allocation math constant folding @@ -315,8 +314,8 @@ if( z < 5 && -5 < y && y < 0 ) { const Type *t_in11 = phase->type(in1->in(1)); if( t_in11 != Type::TOP && (t_in11->is_int()->_lo >= -(y << z)) ) { - Node *a = phase->transform( new (phase->C) AddINode( in1->in(1), phase->intcon(y<C) URShiftINode( a, in1->in(2) ); + Node *a = phase->transform( new AddINode( in1->in(1), phase->intcon(y<in(2) ); } } } @@ -387,47 +386,46 @@ const Type *t_sub1 = phase->type( in1->in(1) ); const Type *t_2 = phase->type( in2 ); if( t_sub1->singleton() && t_2->singleton() && t_sub1 != Type::TOP && t_2 != Type::TOP ) - return new (phase->C) SubLNode(phase->makecon( add_ring( t_sub1, t_2 ) ), - in1->in(2) ); + return new SubLNode(phase->makecon( add_ring( t_sub1, t_2 ) ), in1->in(2) ); // Convert "(a-b)+(c-d)" into "(a+c)-(b+d)" if( op2 == Op_SubL ) { // Check for dead cycle: d = (a-b)+(c-d) assert( in1->in(2) != this && in2->in(2) != this, "dead loop in AddLNode::Ideal" ); - Node *sub = new (phase->C) SubLNode(NULL, NULL); - sub->init_req(1, phase->transform(new (phase->C) AddLNode(in1->in(1), in2->in(1) ) )); - sub->init_req(2, phase->transform(new (phase->C) AddLNode(in1->in(2), in2->in(2) ) )); + Node *sub = new SubLNode(NULL, NULL); + sub->init_req(1, phase->transform(new AddLNode(in1->in(1), in2->in(1) ) )); + sub->init_req(2, phase->transform(new AddLNode(in1->in(2), in2->in(2) ) )); return sub; } // Convert "(a-b)+(b+c)" into "(a+c)" if( op2 == Op_AddL && in1->in(2) == in2->in(1) ) { assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddLNode::Ideal"); - return new (phase->C) AddLNode(in1->in(1), in2->in(2)); + return new AddLNode(in1->in(1), in2->in(2)); } // Convert "(a-b)+(c+b)" into "(a+c)" if( op2 == Op_AddL && in1->in(2) == in2->in(2) ) { assert(in1->in(1) != this && in2->in(1) != this,"dead loop in AddLNode::Ideal"); - return new (phase->C) AddLNode(in1->in(1), in2->in(1)); + return new AddLNode(in1->in(1), in2->in(1)); } // Convert "(a-b)+(b-c)" into "(a-c)" if( op2 == Op_SubL && in1->in(2) == in2->in(1) ) { assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddLNode::Ideal"); - return new (phase->C) SubLNode(in1->in(1), in2->in(2)); + return new SubLNode(in1->in(1), in2->in(2)); } // Convert "(a-b)+(c-a)" into "(c-b)" if( op2 == Op_SubL && in1->in(1) == in1->in(2) ) { assert(in1->in(2) != this && in2->in(1) != this,"dead loop in AddLNode::Ideal"); - return new (phase->C) SubLNode(in2->in(1), in1->in(2)); + return new SubLNode(in2->in(1), in1->in(2)); } } // Convert "x+(0-y)" into "(x-y)" if( op2 == Op_SubL && phase->type(in2->in(1)) == TypeLong::ZERO ) - return new (phase->C) SubLNode( in1, in2->in(2) ); + return new SubLNode( in1, in2->in(2) ); // Convert "(0-y)+x" into "(x-y)" if( op1 == Op_SubL && phase->type(in1->in(1)) == TypeInt::ZERO ) - return new (phase->C) SubLNode( in2, in1->in(2) ); + return new SubLNode( in2, in1->in(2) ); // Convert "X+X+X+X+X...+X+Y" into "k*X+Y" or really convert "X+(X+Y)" // into "(X<<1)+Y" and let shift-folding happen. @@ -435,8 +433,8 @@ in2->in(1) == in1 && op1 != Op_ConL && 0 ) { - Node *shift = phase->transform(new (phase->C) LShiftLNode(in1,phase->intcon(1))); - return new (phase->C) AddLNode(shift,in2->in(2)); + Node *shift = phase->transform(new LShiftLNode(in1,phase->intcon(1))); + return new AddLNode(shift,in2->in(2)); } return AddNode::Ideal(phase, can_reshape); @@ -596,7 +594,7 @@ offset = phase->MakeConX(t2->get_con() + t12->get_con()); } else { // Else move the constant to the right. ((A+con)+B) into ((A+B)+con) - address = phase->transform(new (phase->C) AddPNode(in(Base),addp->in(Address),in(Offset))); + address = phase->transform(new AddPNode(in(Base),addp->in(Address),in(Offset))); offset = addp->in(Offset); } PhaseIterGVN *igvn = phase->is_IterGVN(); @@ -616,7 +614,7 @@ // If this is a NULL+long form (from unsafe accesses), switch to a rawptr. if (phase->type(in(Address)) == TypePtr::NULL_PTR) { Node* offset = in(Offset); - return new (phase->C) CastX2PNode(offset); + return new CastX2PNode(offset); } } @@ -628,7 +626,7 @@ if( add->Opcode() == Op_AddX && add->in(1) != add ) { const Type *t22 = phase->type( add->in(2) ); if( t22->singleton() && (t22 != Type::TOP) ) { // Right input is an add of a constant? - set_req(Address, phase->transform(new (phase->C) AddPNode(in(Base),in(Address),add->in(1)))); + set_req(Address, phase->transform(new AddPNode(in(Base),in(Address),add->in(1)))); set_req(Offset, add->in(2)); PhaseIterGVN *igvn = phase->is_IterGVN(); if (add->outcnt() == 0 && igvn) { @@ -858,7 +856,7 @@ // to force a right-spline graph for the rest of MinINode::Ideal(). if( l->Opcode() == Op_MinI ) { assert( l != l->in(1), "dead loop in MinINode::Ideal" ); - r = phase->transform(new (phase->C) MinINode(l->in(2),r)); + r = phase->transform(new MinINode(l->in(2),r)); l = l->in(1); set_req(1, l); set_req(2, r); @@ -906,18 +904,18 @@ } if( x->_idx > y->_idx ) - return new (phase->C) MinINode(r->in(1),phase->transform(new (phase->C) MinINode(l,r->in(2)))); + return new MinINode(r->in(1),phase->transform(new MinINode(l,r->in(2)))); // See if covers: MIN2(x+c0,MIN2(y+c1,z)) if( !phase->eqv(x,y) ) return NULL; // If (y == x) transform MIN2(x+c0, MIN2(x+c1,z)) into // MIN2(x+c0 or x+c1 which less, z). - return new (phase->C) MinINode(phase->transform(new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off)))),r->in(2)); + return new MinINode(phase->transform(new AddINode(x,phase->intcon(MIN2(x_off,y_off)))),r->in(2)); } else { // See if covers: MIN2(x+c0,y+c1) if( !phase->eqv(x,y) ) return NULL; // If (y == x) transform MIN2(x+c0,x+c1) into x+c0 or x+c1 which less. - return new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off))); + return new AddINode(x,phase->intcon(MIN2(x_off,y_off))); } } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/block.cpp --- a/hotspot/src/share/vm/opto/block.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/block.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -373,7 +373,7 @@ // I'll need a few machine-specific GotoNodes. Make an Ideal GotoNode, // then Match it into a machine-specific Node. Then clone the machine // Node on demand. - Node *x = new (C) GotoNode(NULL); + Node *x = new GotoNode(NULL); x->init_req(0, x); _goto = matcher.match_tree(x); assert(_goto != NULL, ""); @@ -426,7 +426,7 @@ !p->is_block_start() ); // Make the block begin with one of Region or StartNode. if( !p->is_block_start() ) { - RegionNode *r = new (C) RegionNode( 2 ); + RegionNode *r = new RegionNode( 2 ); r->init_req(1, p); // Insert RegionNode in the way proj->set_req(0, r); // Insert RegionNode in the way p = r; @@ -501,7 +501,7 @@ // get ProjNode corresponding to the succ_no'th successor of the in block ProjNode* proj = in->get_node(in->number_of_nodes() - in->_num_succs + succ_no)->as_Proj(); // create region for basic block - RegionNode* region = new (C) RegionNode(2); + RegionNode* region = new RegionNode(2); region->init_req(1, proj); // setup corresponding basic block Block* block = new (_block_arena) Block(_block_arena, region); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/bytecodeInfo.cpp --- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -361,11 +361,14 @@ set_msg("not an accessor"); return false; } + + // Limit inlining depth in case inlining is forced or + // _max_inline_level was increased to compensate for lambda forms. + if (inline_level() > MaxForceInlineLevel) { + set_msg("MaxForceInlineLevel"); + return false; + } if (inline_level() > _max_inline_level) { - if (callee_method->force_inline() && inline_level() > MaxForceInlineLevel) { - set_msg("MaxForceInlineLevel"); - return false; - } if (!callee_method->force_inline() || !IncrementalInline) { set_msg("inlining too deep"); return false; diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/c2_globals.hpp --- a/hotspot/src/share/vm/opto/c2_globals.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/c2_globals.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -650,9 +650,6 @@ product(bool, UseMathExactIntrinsics, true, \ "Enables intrinsification of various java.lang.Math functions") \ \ - experimental(bool, ReplaceInParentMaps, false, \ - "Propagate type improvements in callers of inlinee if possible") \ - \ product(bool, UseTypeSpeculation, true, \ "Speculatively propagate types from profiles") \ \ diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/callGenerator.cpp --- a/hotspot/src/share/vm/opto/callGenerator.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/callGenerator.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -63,12 +63,12 @@ } virtual bool is_parse() const { return true; } - virtual JVMState* generate(JVMState* jvms, Parse* parent_parser); + virtual JVMState* generate(JVMState* jvms); int is_osr() { return _is_osr; } }; -JVMState* ParseGenerator::generate(JVMState* jvms, Parse* parent_parser) { +JVMState* ParseGenerator::generate(JVMState* jvms) { Compile* C = Compile::current(); C->print_inlining_update(this); @@ -81,7 +81,7 @@ return NULL; // bailing out of the compile; do not try to parse } - Parse parser(jvms, method(), _expected_uses, parent_parser); + Parse parser(jvms, method(), _expected_uses); // Grab signature for matching/allocation #ifdef ASSERT if (parser.tf() != (parser.depth() == 1 ? C->tf() : tf())) { @@ -120,12 +120,12 @@ _separate_io_proj(separate_io_proj) { } - virtual JVMState* generate(JVMState* jvms, Parse* parent_parser); + virtual JVMState* generate(JVMState* jvms); CallStaticJavaNode* call_node() const { return _call_node; } }; -JVMState* DirectCallGenerator::generate(JVMState* jvms, Parse* parent_parser) { +JVMState* DirectCallGenerator::generate(JVMState* jvms) { GraphKit kit(jvms); kit.C->print_inlining_update(this); bool is_static = method()->is_static(); @@ -136,7 +136,7 @@ kit.C->log()->elem("direct_call bci='%d'", jvms->bci()); } - CallStaticJavaNode *call = new (kit.C) CallStaticJavaNode(kit.C, tf(), target, method(), kit.bci()); + CallStaticJavaNode *call = new CallStaticJavaNode(kit.C, tf(), target, method(), kit.bci()); _call_node = call; // Save the call node in case we need it later if (!is_static) { // Make an explicit receiver null_check as part of this call. @@ -173,10 +173,10 @@ vtable_index >= 0, "either invalid or usable"); } virtual bool is_virtual() const { return true; } - virtual JVMState* generate(JVMState* jvms, Parse* parent_parser); + virtual JVMState* generate(JVMState* jvms); }; -JVMState* VirtualCallGenerator::generate(JVMState* jvms, Parse* parent_parser) { +JVMState* VirtualCallGenerator::generate(JVMState* jvms) { GraphKit kit(jvms); Node* receiver = kit.argument(0); @@ -225,7 +225,7 @@ "no vtable calls if +UseInlineCaches "); address target = SharedRuntime::get_resolve_virtual_call_stub(); // Normal inline cache used for call - CallDynamicJavaNode *call = new (kit.C) CallDynamicJavaNode(tf(), target, method(), _vtable_index, kit.bci()); + CallDynamicJavaNode *call = new CallDynamicJavaNode(tf(), target, method(), _vtable_index, kit.bci()); kit.set_arguments_for_java_call(call); kit.set_edges_for_java_call(call); Node* ret = kit.set_results_for_java_call(call); @@ -283,7 +283,7 @@ // Convert the CallStaticJava into an inline virtual void do_late_inline(); - virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) { + virtual JVMState* generate(JVMState* jvms) { Compile *C = Compile::current(); C->log_inline_id(this); @@ -298,7 +298,7 @@ // that the late inlining logic can distinguish between fall // through and exceptional uses of the memory and io projections // as is done for allocations and macro expansion. - return DirectCallGenerator::generate(jvms, parent_parser); + return DirectCallGenerator::generate(jvms); } virtual void print_inlining_late(const char* msg) { @@ -350,7 +350,7 @@ JVMState* old_jvms = call->jvms(); JVMState* jvms = old_jvms->clone_shallow(C); uint size = call->req(); - SafePointNode* map = new (C) SafePointNode(size, jvms); + SafePointNode* map = new SafePointNode(size, jvms); for (uint i1 = 0; i1 < size; i1++) { map->init_req(i1, call->in(i1)); } @@ -399,7 +399,7 @@ } // Now perform the inlining using the synthesized JVMState - JVMState* new_jvms = _inline_cg->generate(jvms, NULL); + JVMState* new_jvms = _inline_cg->generate(jvms); if (new_jvms == NULL) return; // no change if (C->failing()) return; @@ -417,7 +417,7 @@ C->env()->notice_inlined_method(_inline_cg->method()); C->set_inlining_progress(true); - kit.replace_call(call, result); + kit.replace_call(call, result, true); } @@ -439,8 +439,8 @@ virtual bool is_mh_late_inline() const { return true; } - virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) { - JVMState* new_jvms = LateInlineCallGenerator::generate(jvms, parent_parser); + virtual JVMState* generate(JVMState* jvms) { + JVMState* new_jvms = LateInlineCallGenerator::generate(jvms); Compile* C = Compile::current(); if (_input_not_const) { @@ -486,14 +486,14 @@ LateInlineStringCallGenerator(ciMethod* method, CallGenerator* inline_cg) : LateInlineCallGenerator(method, inline_cg) {} - virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) { + virtual JVMState* generate(JVMState* jvms) { Compile *C = Compile::current(); C->log_inline_id(this); C->add_string_late_inline(this); - JVMState* new_jvms = DirectCallGenerator::generate(jvms, parent_parser); + JVMState* new_jvms = DirectCallGenerator::generate(jvms); return new_jvms; } @@ -510,14 +510,14 @@ LateInlineBoxingCallGenerator(ciMethod* method, CallGenerator* inline_cg) : LateInlineCallGenerator(method, inline_cg) {} - virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) { + virtual JVMState* generate(JVMState* jvms) { Compile *C = Compile::current(); C->log_inline_id(this); C->add_boxing_late_inline(this); - JVMState* new_jvms = DirectCallGenerator::generate(jvms, parent_parser); + JVMState* new_jvms = DirectCallGenerator::generate(jvms); return new_jvms; } }; @@ -553,7 +553,7 @@ virtual bool is_virtual() const { return _is_virtual; } virtual bool is_deferred() const { return true; } - virtual JVMState* generate(JVMState* jvms, Parse* parent_parser); + virtual JVMState* generate(JVMState* jvms); }; @@ -563,14 +563,14 @@ return new WarmCallGenerator(ci, if_cold, if_hot); } -JVMState* WarmCallGenerator::generate(JVMState* jvms, Parse* parent_parser) { +JVMState* WarmCallGenerator::generate(JVMState* jvms) { Compile* C = Compile::current(); C->print_inlining_update(this); if (C->log() != NULL) { C->log()->elem("warm_call bci='%d'", jvms->bci()); } - jvms = _if_cold->generate(jvms, parent_parser); + jvms = _if_cold->generate(jvms); if (jvms != NULL) { Node* m = jvms->map()->control(); if (m->is_CatchProj()) m = m->in(0); else m = C->top(); @@ -631,7 +631,7 @@ virtual bool is_inline() const { return _if_hit->is_inline(); } virtual bool is_deferred() const { return _if_hit->is_deferred(); } - virtual JVMState* generate(JVMState* jvms, Parse* parent_parser); + virtual JVMState* generate(JVMState* jvms); }; @@ -643,14 +643,13 @@ } -JVMState* PredictedCallGenerator::generate(JVMState* jvms, Parse* parent_parser) { +JVMState* PredictedCallGenerator::generate(JVMState* jvms) { GraphKit kit(jvms); kit.C->print_inlining_update(this); PhaseGVN& gvn = kit.gvn(); // We need an explicit receiver null_check before checking its type. // We share a map with the caller, so his JVMS gets adjusted. Node* receiver = kit.argument(0); - CompileLog* log = kit.C->log(); if (log != NULL) { log->elem("predicted_call bci='%d' klass='%d'", @@ -662,6 +661,10 @@ return kit.transfer_exceptions_into_jvms(); } + // Make a copy of the replaced nodes in case we need to restore them + ReplacedNodes replaced_nodes = kit.map()->replaced_nodes(); + replaced_nodes.clone(); + Node* exact_receiver = receiver; // will get updated in place... Node* slow_ctl = kit.type_check_receiver(receiver, _predicted_receiver, _hit_prob, @@ -672,7 +675,7 @@ { PreserveJVMState pjvms(&kit); kit.set_control(slow_ctl); if (!kit.stopped()) { - slow_jvms = _if_missed->generate(kit.sync_jvms(), parent_parser); + slow_jvms = _if_missed->generate(kit.sync_jvms()); if (kit.failing()) return NULL; // might happen because of NodeCountInliningCutoff assert(slow_jvms != NULL, "must be"); @@ -693,12 +696,12 @@ kit.replace_in_map(receiver, exact_receiver); // Make the hot call: - JVMState* new_jvms = _if_hit->generate(kit.sync_jvms(), parent_parser); + JVMState* new_jvms = _if_hit->generate(kit.sync_jvms()); if (new_jvms == NULL) { // Inline failed, so make a direct call. assert(_if_hit->is_inline(), "must have been a failed inline"); CallGenerator* cg = CallGenerator::for_direct_call(_if_hit->method()); - new_jvms = cg->generate(kit.sync_jvms(), parent_parser); + new_jvms = cg->generate(kit.sync_jvms()); } kit.add_exception_states_from(new_jvms); kit.set_jvms(new_jvms); @@ -715,16 +718,29 @@ return kit.transfer_exceptions_into_jvms(); } + // There are 2 branches and the replaced nodes are only valid on + // one: restore the replaced nodes to what they were before the + // branch. + kit.map()->set_replaced_nodes(replaced_nodes); + // Finish the diamond. kit.C->set_has_split_ifs(true); // Has chance for split-if optimization - RegionNode* region = new (kit.C) RegionNode(3); + RegionNode* region = new RegionNode(3); region->init_req(1, kit.control()); region->init_req(2, slow_map->control()); kit.set_control(gvn.transform(region)); Node* iophi = PhiNode::make(region, kit.i_o(), Type::ABIO); iophi->set_req(2, slow_map->i_o()); kit.set_i_o(gvn.transform(iophi)); + // Merge memory kit.merge_memory(slow_map->merged_memory(), region, 2); + // Transform new memory Phis. + for (MergeMemStream mms(kit.merged_memory()); mms.next_non_empty();) { + Node* phi = mms.memory(); + if (phi->is_Phi() && phi->in(0) == region) { + mms.set_memory(gvn.transform(phi)); + } + } uint tos = kit.jvms()->stkoff() + kit.sp(); uint limit = slow_map->req(); for (uint i = TypeFunc::Parms; i < limit; i++) { @@ -825,7 +841,7 @@ const TypeOopPtr* arg_type = arg->bottom_type()->isa_oopptr(); const Type* sig_type = TypeOopPtr::make_from_klass(signature->accessing_klass()); if (arg_type != NULL && !arg_type->higher_equal(sig_type)) { - Node* cast_obj = gvn.transform(new (C) CheckCastPPNode(kit.control(), arg, sig_type)); + Node* cast_obj = gvn.transform(new CheckCastPPNode(kit.control(), arg, sig_type)); kit.set_argument(0, cast_obj); } } @@ -837,7 +853,7 @@ const TypeOopPtr* arg_type = arg->bottom_type()->isa_oopptr(); const Type* sig_type = TypeOopPtr::make_from_klass(t->as_klass()); if (arg_type != NULL && !arg_type->higher_equal(sig_type)) { - Node* cast_obj = gvn.transform(new (C) CheckCastPPNode(kit.control(), arg, sig_type)); + Node* cast_obj = gvn.transform(new CheckCastPPNode(kit.control(), arg, sig_type)); kit.set_argument(receiver_skip + i, cast_obj); } } @@ -882,15 +898,15 @@ } -//------------------------PredictedIntrinsicGenerator------------------------------ -// Internal class which handles all predicted Intrinsic calls. -class PredictedIntrinsicGenerator : public CallGenerator { +//------------------------PredicatedIntrinsicGenerator------------------------------ +// Internal class which handles all predicated Intrinsic calls. +class PredicatedIntrinsicGenerator : public CallGenerator { CallGenerator* _intrinsic; CallGenerator* _cg; public: - PredictedIntrinsicGenerator(CallGenerator* intrinsic, - CallGenerator* cg) + PredicatedIntrinsicGenerator(CallGenerator* intrinsic, + CallGenerator* cg) : CallGenerator(cg->method()) { _intrinsic = intrinsic; @@ -901,108 +917,186 @@ virtual bool is_inlined() const { return true; } virtual bool is_intrinsic() const { return true; } - virtual JVMState* generate(JVMState* jvms, Parse* parent_parser); + virtual JVMState* generate(JVMState* jvms); }; -CallGenerator* CallGenerator::for_predicted_intrinsic(CallGenerator* intrinsic, - CallGenerator* cg) { - return new PredictedIntrinsicGenerator(intrinsic, cg); +CallGenerator* CallGenerator::for_predicated_intrinsic(CallGenerator* intrinsic, + CallGenerator* cg) { + return new PredicatedIntrinsicGenerator(intrinsic, cg); } -JVMState* PredictedIntrinsicGenerator::generate(JVMState* jvms, Parse* parent_parser) { +JVMState* PredicatedIntrinsicGenerator::generate(JVMState* jvms) { + // The code we want to generate here is: + // if (receiver == NULL) + // uncommon_Trap + // if (predicate(0)) + // do_intrinsic(0) + // else + // if (predicate(1)) + // do_intrinsic(1) + // ... + // else + // do_java_comp + GraphKit kit(jvms); PhaseGVN& gvn = kit.gvn(); CompileLog* log = kit.C->log(); if (log != NULL) { - log->elem("predicted_intrinsic bci='%d' method='%d'", + log->elem("predicated_intrinsic bci='%d' method='%d'", jvms->bci(), log->identify(method())); } - Node* slow_ctl = _intrinsic->generate_predicate(kit.sync_jvms()); - if (kit.failing()) - return NULL; // might happen because of NodeCountInliningCutoff - - kit.C->print_inlining_update(this); - SafePointNode* slow_map = NULL; - JVMState* slow_jvms; - if (slow_ctl != NULL) { - PreserveJVMState pjvms(&kit); - kit.set_control(slow_ctl); - if (!kit.stopped()) { - slow_jvms = _cg->generate(kit.sync_jvms(), parent_parser); - if (kit.failing()) - return NULL; // might happen because of NodeCountInliningCutoff - assert(slow_jvms != NULL, "must be"); - kit.add_exception_states_from(slow_jvms); - kit.set_map(slow_jvms->map()); - if (!kit.stopped()) - slow_map = kit.stop(); + if (!method()->is_static()) { + // We need an explicit receiver null_check before checking its type in predicate. + // We share a map with the caller, so his JVMS gets adjusted. + Node* receiver = kit.null_check_receiver_before_call(method()); + if (kit.stopped()) { + return kit.transfer_exceptions_into_jvms(); } } - if (kit.stopped()) { - // Predicate is always false. - kit.set_jvms(slow_jvms); + int n_predicates = _intrinsic->predicates_count(); + assert(n_predicates > 0, "sanity"); + + JVMState** result_jvms = NEW_RESOURCE_ARRAY(JVMState*, (n_predicates+1)); + + // Region for normal compilation code if intrinsic failed. + Node* slow_region = new RegionNode(1); + + int results = 0; + for (int predicate = 0; (predicate < n_predicates) && !kit.stopped(); predicate++) { +#ifdef ASSERT + JVMState* old_jvms = kit.jvms(); + SafePointNode* old_map = kit.map(); + Node* old_io = old_map->i_o(); + Node* old_mem = old_map->memory(); + Node* old_exc = old_map->next_exception(); +#endif + Node* else_ctrl = _intrinsic->generate_predicate(kit.sync_jvms(), predicate); +#ifdef ASSERT + // Assert(no_new_memory && no_new_io && no_new_exceptions) after generate_predicate. + assert(old_jvms == kit.jvms(), "generate_predicate should not change jvm state"); + SafePointNode* new_map = kit.map(); + assert(old_io == new_map->i_o(), "generate_predicate should not change i_o"); + assert(old_mem == new_map->memory(), "generate_predicate should not change memory"); + assert(old_exc == new_map->next_exception(), "generate_predicate should not add exceptions"); +#endif + if (!kit.stopped()) { + PreserveJVMState pjvms(&kit); + // Generate intrinsic code: + JVMState* new_jvms = _intrinsic->generate(kit.sync_jvms()); + if (new_jvms == NULL) { + // Intrinsic failed, use normal compilation path for this predicate. + slow_region->add_req(kit.control()); + } else { + kit.add_exception_states_from(new_jvms); + kit.set_jvms(new_jvms); + if (!kit.stopped()) { + result_jvms[results++] = kit.jvms(); + } + } + } + if (else_ctrl == NULL) { + else_ctrl = kit.C->top(); + } + kit.set_control(else_ctrl); + } + if (!kit.stopped()) { + // Final 'else' after predicates. + slow_region->add_req(kit.control()); + } + if (slow_region->req() > 1) { + PreserveJVMState pjvms(&kit); + // Generate normal compilation code: + kit.set_control(gvn.transform(slow_region)); + JVMState* new_jvms = _cg->generate(kit.sync_jvms()); + if (kit.failing()) + return NULL; // might happen because of NodeCountInliningCutoff + assert(new_jvms != NULL, "must be"); + kit.add_exception_states_from(new_jvms); + kit.set_jvms(new_jvms); + if (!kit.stopped()) { + result_jvms[results++] = kit.jvms(); + } + } + + if (results == 0) { + // All paths ended in uncommon traps. + (void) kit.stop(); return kit.transfer_exceptions_into_jvms(); } - // Generate intrinsic code: - JVMState* new_jvms = _intrinsic->generate(kit.sync_jvms(), parent_parser); - if (new_jvms == NULL) { - // Intrinsic failed, so use slow code or make a direct call. - if (slow_map == NULL) { - CallGenerator* cg = CallGenerator::for_direct_call(method()); - new_jvms = cg->generate(kit.sync_jvms(), parent_parser); - } else { - kit.set_jvms(slow_jvms); - return kit.transfer_exceptions_into_jvms(); - } - } - kit.add_exception_states_from(new_jvms); - kit.set_jvms(new_jvms); - - // Need to merge slow and fast? - if (slow_map == NULL) { - // The fast path is the only path remaining. + if (results == 1) { // Only one path + kit.set_jvms(result_jvms[0]); return kit.transfer_exceptions_into_jvms(); } - if (kit.stopped()) { - // Intrinsic method threw an exception, so it's just the slow path after all. - kit.set_jvms(slow_jvms); - return kit.transfer_exceptions_into_jvms(); + // Merge all paths. + kit.C->set_has_split_ifs(true); // Has chance for split-if optimization + RegionNode* region = new RegionNode(results + 1); + Node* iophi = PhiNode::make(region, kit.i_o(), Type::ABIO); + for (int i = 0; i < results; i++) { + JVMState* jvms = result_jvms[i]; + int path = i + 1; + SafePointNode* map = jvms->map(); + region->init_req(path, map->control()); + iophi->set_req(path, map->i_o()); + if (i == 0) { + kit.set_jvms(jvms); + } else { + kit.merge_memory(map->merged_memory(), region, path); + } + } + kit.set_control(gvn.transform(region)); + kit.set_i_o(gvn.transform(iophi)); + // Transform new memory Phis. + for (MergeMemStream mms(kit.merged_memory()); mms.next_non_empty();) { + Node* phi = mms.memory(); + if (phi->is_Phi() && phi->in(0) == region) { + mms.set_memory(gvn.transform(phi)); + } } - // Finish the diamond. - kit.C->set_has_split_ifs(true); // Has chance for split-if optimization - RegionNode* region = new (kit.C) RegionNode(3); - region->init_req(1, kit.control()); - region->init_req(2, slow_map->control()); - kit.set_control(gvn.transform(region)); - Node* iophi = PhiNode::make(region, kit.i_o(), Type::ABIO); - iophi->set_req(2, slow_map->i_o()); - kit.set_i_o(gvn.transform(iophi)); - kit.merge_memory(slow_map->merged_memory(), region, 2); + // Merge debug info. + Node** ins = NEW_RESOURCE_ARRAY(Node*, results); uint tos = kit.jvms()->stkoff() + kit.sp(); - uint limit = slow_map->req(); + Node* map = kit.map(); + uint limit = map->req(); for (uint i = TypeFunc::Parms; i < limit; i++) { // Skip unused stack slots; fast forward to monoff(); if (i == tos) { i = kit.jvms()->monoff(); if( i >= limit ) break; } - Node* m = kit.map()->in(i); - Node* n = slow_map->in(i); - if (m != n) { - const Type* t = gvn.type(m)->meet_speculative(gvn.type(n)); - Node* phi = PhiNode::make(region, m, t); - phi->set_req(2, n); - kit.map()->set_req(i, gvn.transform(phi)); + Node* n = map->in(i); + ins[0] = n; + const Type* t = gvn.type(n); + bool needs_phi = false; + for (int j = 1; j < results; j++) { + JVMState* jvms = result_jvms[j]; + Node* jmap = jvms->map(); + Node* m = NULL; + if (jmap->req() > i) { + m = jmap->in(i); + if (m != n) { + needs_phi = true; + t = t->meet_speculative(gvn.type(m)); + } + } + ins[j] = m; + } + if (needs_phi) { + Node* phi = PhiNode::make(region, n, t); + for (int j = 1; j < results; j++) { + phi->set_req(j + 1, ins[j]); + } + map->set_req(i, gvn.transform(phi)); } } + return kit.transfer_exceptions_into_jvms(); } @@ -1025,7 +1119,7 @@ virtual bool is_virtual() const { ShouldNotReachHere(); return false; } virtual bool is_trap() const { return true; } - virtual JVMState* generate(JVMState* jvms, Parse* parent_parser); + virtual JVMState* generate(JVMState* jvms); }; @@ -1037,7 +1131,7 @@ } -JVMState* UncommonTrapCallGenerator::generate(JVMState* jvms, Parse* parent_parser) { +JVMState* UncommonTrapCallGenerator::generate(JVMState* jvms) { GraphKit kit(jvms); kit.C->print_inlining_update(this); // Take the trap with arguments pushed on the stack. (Cf. null_check_receiver). diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/callGenerator.hpp --- a/hotspot/src/share/vm/opto/callGenerator.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/callGenerator.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -31,8 +31,6 @@ #include "opto/type.hpp" #include "runtime/deoptimization.hpp" -class Parse; - //---------------------------CallGenerator------------------------------------- // The subclasses of this class handle generation of ideal nodes for // call sites and method entry points. @@ -63,8 +61,9 @@ virtual bool is_virtual() const { return false; } // is_deferred: The decision whether to inline or not is deferred. virtual bool is_deferred() const { return false; } - // is_predicted: Uses an explicit check against a predicted type. - virtual bool is_predicted() const { return false; } + // is_predicated: Uses an explicit check (predicate). + virtual bool is_predicated() const { return false; } + virtual int predicates_count() const { return 0; } // is_trap: Does not return to the caller. (E.g., uncommon trap.) virtual bool is_trap() const { return false; } // does_virtual_dispatch: Should try inlining as normal method first. @@ -114,7 +113,7 @@ // // If the result is NULL, it means that this CallGenerator was unable // to handle the given call, and another CallGenerator should be consulted. - virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) = 0; + virtual JVMState* generate(JVMState* jvms) = 0; // How to generate a call site that is inlined: static CallGenerator* for_inline(ciMethod* m, float expected_uses = -1); @@ -160,9 +159,9 @@ // Registry for intrinsics: static CallGenerator* for_intrinsic(ciMethod* m); static void register_intrinsic(ciMethod* m, CallGenerator* cg); - static CallGenerator* for_predicted_intrinsic(CallGenerator* intrinsic, - CallGenerator* cg); - virtual Node* generate_predicate(JVMState* jvms) { return NULL; }; + static CallGenerator* for_predicated_intrinsic(CallGenerator* intrinsic, + CallGenerator* cg); + virtual Node* generate_predicate(JVMState* jvms, int predicate) { return NULL; }; virtual void print_inlining_late(const char* msg) { ShouldNotReachHere(); } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/callnode.cpp --- a/hotspot/src/share/vm/opto/callnode.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/callnode.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -74,20 +74,20 @@ case TypeFunc::Control: case TypeFunc::I_O: case TypeFunc::Memory: - return new (match->C) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj); + return new MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj); case TypeFunc::FramePtr: - return new (match->C) MachProjNode(this,proj->_con,Matcher::c_frame_ptr_mask, Op_RegP); + return new MachProjNode(this,proj->_con,Matcher::c_frame_ptr_mask, Op_RegP); case TypeFunc::ReturnAdr: - return new (match->C) MachProjNode(this,proj->_con,match->_return_addr_mask,Op_RegP); + return new MachProjNode(this,proj->_con,match->_return_addr_mask,Op_RegP); case TypeFunc::Parms: default: { uint parm_num = proj->_con - TypeFunc::Parms; const Type *t = _domain->field_at(proj->_con); if (t->base() == Type::Half) // 2nd half of Longs and Doubles - return new (match->C) ConNode(Type::TOP); + return new ConNode(Type::TOP); uint ideal_reg = t->ideal_reg(); RegMask &rm = match->_calling_convention_mask[parm_num]; - return new (match->C) MachProjNode(this,proj->_con,rm,ideal_reg); + return new MachProjNode(this,proj->_con,rm,ideal_reg); } } return NULL; @@ -685,12 +685,12 @@ case TypeFunc::Control: case TypeFunc::I_O: case TypeFunc::Memory: - return new (match->C) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj); + return new MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj); case TypeFunc::Parms+1: // For LONG & DOUBLE returns assert(tf()->_range->field_at(TypeFunc::Parms+1) == Type::HALF, ""); // 2nd half of doubles and longs - return new (match->C) MachProjNode(this,proj->_con, RegMask::Empty, (uint)OptoReg::Bad); + return new MachProjNode(this,proj->_con, RegMask::Empty, (uint)OptoReg::Bad); case TypeFunc::Parms: { // Normal returns uint ideal_reg = tf()->range()->field_at(TypeFunc::Parms)->ideal_reg(); @@ -700,7 +700,7 @@ RegMask rm = RegMask(regs.first()); if( OptoReg::is_valid(regs.second()) ) rm.Insert( regs.second() ); - return new (match->C) MachProjNode(this,proj->_con,rm,ideal_reg); + return new MachProjNode(this,proj->_con,rm,ideal_reg); } case TypeFunc::ReturnAdr: @@ -1090,6 +1090,7 @@ #ifndef PRODUCT void SafePointNode::dump_spec(outputStream *st) const { st->print(" SafePoint "); + _replaced_nodes.dump(st); } #endif @@ -1288,10 +1289,10 @@ Node* nproj = catchproj->clone(); igvn->register_new_node_with_optimizer(nproj); - Node *frame = new (phase->C) ParmNode( phase->C->start(), TypeFunc::FramePtr ); + Node *frame = new ParmNode( phase->C->start(), TypeFunc::FramePtr ); frame = phase->transform(frame); // Halt & Catch Fire - Node *halt = new (phase->C) HaltNode( nproj, frame ); + Node *halt = new HaltNode( nproj, frame ); phase->C->root()->add_req(halt); phase->transform(halt); @@ -1333,7 +1334,7 @@ if (!allow_new_nodes) return NULL; // Create a cast which is control dependent on the initialization to // propagate the fact that the array length must be positive. - length = new (phase->C) CastIINode(length, narrow_length_type); + length = new CastIINode(length, narrow_length_type); length->set_req(0, initialization()->proj_out(0)); } } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/callnode.hpp --- a/hotspot/src/share/vm/opto/callnode.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/callnode.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -30,6 +30,7 @@ #include "opto/multnode.hpp" #include "opto/opcodes.hpp" #include "opto/phaseX.hpp" +#include "opto/replacednodes.hpp" #include "opto/type.hpp" // Portions of code courtesy of Clifford Click @@ -335,6 +336,7 @@ OopMap* _oop_map; // Array of OopMap info (8-bit char) for GC JVMState* const _jvms; // Pointer to list of JVM State objects const TypePtr* _adr_type; // What type of memory does this node produce? + ReplacedNodes _replaced_nodes; // During parsing: list of pair of nodes from calls to GraphKit::replace_in_map() // Many calls take *all* of memory as input, // but some produce a limited subset of that memory as output. @@ -426,6 +428,37 @@ void set_next_exception(SafePointNode* n); bool has_exceptions() const { return next_exception() != NULL; } + // Helper methods to operate on replaced nodes + ReplacedNodes replaced_nodes() const { + return _replaced_nodes; + } + + void set_replaced_nodes(ReplacedNodes replaced_nodes) { + _replaced_nodes = replaced_nodes; + } + + void clone_replaced_nodes() { + _replaced_nodes.clone(); + } + void record_replaced_node(Node* initial, Node* improved) { + _replaced_nodes.record(initial, improved); + } + void transfer_replaced_nodes_from(SafePointNode* sfpt, uint idx = 0) { + _replaced_nodes.transfer_from(sfpt->_replaced_nodes, idx); + } + void delete_replaced_nodes() { + _replaced_nodes.reset(); + } + void apply_replaced_nodes() { + _replaced_nodes.apply(this); + } + void merge_replaced_nodes_with(SafePointNode* sfpt) { + _replaced_nodes.merge_with(sfpt->_replaced_nodes); + } + bool has_replaced_nodes() const { + return !_replaced_nodes.is_empty(); + } + // Standard Node stuff virtual int Opcode() const; virtual bool pinned() const { return true; } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/castnode.cpp --- a/hotspot/src/share/vm/opto/castnode.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/castnode.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -228,11 +228,11 @@ Node* dispX, bool negate = false) { if (negate) { - dispX = new (phase->C) SubXNode(phase->MakeConX(0), phase->transform(dispX)); + dispX = new SubXNode(phase->MakeConX(0), phase->transform(dispX)); } - return new (phase->C) AddPNode(phase->C->top(), - phase->transform(new (phase->C) CastX2PNode(base)), - phase->transform(dispX)); + return new AddPNode(phase->C->top(), + phase->transform(new CastX2PNode(base)), + phase->transform(dispX)); } Node *CastX2PNode::Ideal(PhaseGVN *phase, bool can_reshape) { diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/cfgnode.cpp --- a/hotspot/src/share/vm/opto/cfgnode.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/cfgnode.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -662,17 +662,17 @@ convf2i->in(1) == bot_in ) { // Matched pattern, including LShiftI; RShiftI, replace with integer compares // max test - Node *cmp = gvn->register_new_node_with_optimizer(new (phase->C) CmpINode( convf2i, min )); - Node *boo = gvn->register_new_node_with_optimizer(new (phase->C) BoolNode( cmp, BoolTest::lt )); - IfNode *iff = (IfNode*)gvn->register_new_node_with_optimizer(new (phase->C) IfNode( top_if->in(0), boo, PROB_UNLIKELY_MAG(5), top_if->_fcnt )); - Node *if_min= gvn->register_new_node_with_optimizer(new (phase->C) IfTrueNode (iff)); - Node *ifF = gvn->register_new_node_with_optimizer(new (phase->C) IfFalseNode(iff)); + Node *cmp = gvn->register_new_node_with_optimizer(new CmpINode( convf2i, min )); + Node *boo = gvn->register_new_node_with_optimizer(new BoolNode( cmp, BoolTest::lt )); + IfNode *iff = (IfNode*)gvn->register_new_node_with_optimizer(new IfNode( top_if->in(0), boo, PROB_UNLIKELY_MAG(5), top_if->_fcnt )); + Node *if_min= gvn->register_new_node_with_optimizer(new IfTrueNode (iff)); + Node *ifF = gvn->register_new_node_with_optimizer(new IfFalseNode(iff)); // min test - cmp = gvn->register_new_node_with_optimizer(new (phase->C) CmpINode( convf2i, max )); - boo = gvn->register_new_node_with_optimizer(new (phase->C) BoolNode( cmp, BoolTest::gt )); - iff = (IfNode*)gvn->register_new_node_with_optimizer(new (phase->C) IfNode( ifF, boo, PROB_UNLIKELY_MAG(5), bot_if->_fcnt )); - Node *if_max= gvn->register_new_node_with_optimizer(new (phase->C) IfTrueNode (iff)); - ifF = gvn->register_new_node_with_optimizer(new (phase->C) IfFalseNode(iff)); + cmp = gvn->register_new_node_with_optimizer(new CmpINode( convf2i, max )); + boo = gvn->register_new_node_with_optimizer(new BoolNode( cmp, BoolTest::gt )); + iff = (IfNode*)gvn->register_new_node_with_optimizer(new IfNode( ifF, boo, PROB_UNLIKELY_MAG(5), bot_if->_fcnt )); + Node *if_max= gvn->register_new_node_with_optimizer(new IfTrueNode (iff)); + ifF = gvn->register_new_node_with_optimizer(new IfFalseNode(iff)); // update input edges to region node set_req_X( min_idx, if_min, gvn ); set_req_X( max_idx, if_max, gvn ); @@ -731,7 +731,7 @@ PhiNode* PhiNode::make(Node* r, Node* x, const Type *t, const TypePtr* at) { uint preds = r->req(); // Number of predecessor paths assert(t != Type::MEMORY || at == flatten_phi_adr_type(at), "flatten at"); - PhiNode* p = new (Compile::current()) PhiNode(r, t, at); + PhiNode* p = new PhiNode(r, t, at); for (uint j = 1; j < preds; j++) { // Fill in all inputs, except those which the region does not yet have if (r->in(j) != NULL) @@ -749,7 +749,7 @@ const Type* t = x->bottom_type(); const TypePtr* at = NULL; if (t == Type::MEMORY) at = flatten_phi_adr_type(x->adr_type()); - return new (Compile::current()) PhiNode(r, t, at); + return new PhiNode(r, t, at); } @@ -1258,9 +1258,9 @@ } else return NULL; // Build int->bool conversion - Node *n = new (phase->C) Conv2BNode( cmp->in(1) ); + Node *n = new Conv2BNode( cmp->in(1) ); if( flipped ) - n = new (phase->C) XorINode( phase->transform(n), phase->intcon(1) ); + n = new XorINode( phase->transform(n), phase->intcon(1) ); return n; } @@ -1320,9 +1320,9 @@ if( q->is_Con() && phase->type(q) != TypeInt::ZERO && y->is_Con() ) return NULL; - Node *cmplt = phase->transform( new (phase->C) CmpLTMaskNode(p,q) ); - Node *j_and = phase->transform( new (phase->C) AndINode(cmplt,y) ); - return new (phase->C) AddINode(j_and,x); + Node *cmplt = phase->transform( new CmpLTMaskNode(p,q) ); + Node *j_and = phase->transform( new AndINode(cmplt,y) ); + return new AddINode(j_and,x); } //------------------------------is_absolute------------------------------------ @@ -1384,17 +1384,17 @@ if( sub->Opcode() != Op_SubF || sub->in(2) != x || phase->type(sub->in(1)) != tzero ) return NULL; - x = new (phase->C) AbsFNode(x); + x = new AbsFNode(x); if (flip) { - x = new (phase->C) SubFNode(sub->in(1), phase->transform(x)); + x = new SubFNode(sub->in(1), phase->transform(x)); } } else { if( sub->Opcode() != Op_SubD || sub->in(2) != x || phase->type(sub->in(1)) != tzero ) return NULL; - x = new (phase->C) AbsDNode(x); + x = new AbsDNode(x); if (flip) { - x = new (phase->C) SubDNode(sub->in(1), phase->transform(x)); + x = new SubDNode(sub->in(1), phase->transform(x)); } } @@ -1469,7 +1469,7 @@ // Now start splitting out the flow paths that merge the same value. // Split first the RegionNode. PhaseIterGVN *igvn = phase->is_IterGVN(); - RegionNode *newr = new (phase->C) RegionNode(hit+1); + RegionNode *newr = new RegionNode(hit+1); split_once(igvn, phi, val, r, newr); // Now split all other Phis than this one @@ -1781,13 +1781,13 @@ } if (doit) { if (base == NULL) { - base = new (phase->C) PhiNode(in(0), type, NULL); + base = new PhiNode(in(0), type, NULL); for (uint i = 1; i < req(); i++) { base->init_req(i, in(i)->in(AddPNode::Base)); } phase->is_IterGVN()->register_new_node_with_optimizer(base); } - return new (phase->C) AddPNode(base, base, y); + return new AddPNode(base, base, y); } } } @@ -1864,7 +1864,7 @@ // Phi(...MergeMem(m0, m1:AT1, m2:AT2)...) into // MergeMem(Phi(...m0...), Phi:AT1(...m1...), Phi:AT2(...m2...)) PhaseIterGVN *igvn = phase->is_IterGVN(); - Node* hook = new (phase->C) Node(1); + Node* hook = new Node(1); PhiNode* new_base = (PhiNode*) clone(); // Must eagerly register phis, since they participate in loops. if (igvn) { @@ -1961,7 +1961,7 @@ } else { narrow_t = TypeNarrowKlass::make(this->bottom_type()->is_ptr()); } - PhiNode* new_phi = new (phase->C) PhiNode(r, narrow_t); + PhiNode* new_phi = new PhiNode(r, narrow_t); uint orig_cnt = req(); for (uint i=1; iC) EncodePNode(ii, narrow_t); + new_ii = new EncodePNode(ii, narrow_t); } else { - new_ii = new (phase->C) EncodePKlassNode(ii, narrow_t); + new_ii = new EncodePKlassNode(ii, narrow_t); } igvn->register_new_node_with_optimizer(new_ii); } @@ -1986,9 +1986,9 @@ } igvn->register_new_node_with_optimizer(new_phi, this); if (is_decodeN) { - progress = new (phase->C) DecodeNNode(new_phi, bottom_type()); + progress = new DecodeNNode(new_phi, bottom_type()); } else { - progress = new (phase->C) DecodeNKlassNode(new_phi, bottom_type()); + progress = new DecodeNKlassNode(new_phi, bottom_type()); } } } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/chaitin.cpp --- a/hotspot/src/share/vm/opto/chaitin.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/chaitin.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -1730,7 +1730,7 @@ // Now we see we need a base-Phi here to merge the bases const Type *t = base->bottom_type(); - base = new (C) PhiNode( derived->in(0), t ); + base = new PhiNode( derived->in(0), t ); for( i = 1; i < derived->req(); i++ ) { base->init_req(i, find_base_for_derived(derived_base_map, derived->in(i), maxlrg)); t = t->meet(base->in(i)->bottom_type()); @@ -1800,7 +1800,7 @@ Block *phi_block = _cfg.get_block_for_node(phi); if (_cfg.get_block_for_node(phi_block->pred(2)) == block) { const RegMask *mask = C->matcher()->idealreg2spillmask[Op_RegI]; - Node *spill = new (C) MachSpillCopyNode(MachSpillCopyNode::LoopPhiInput, phi, *mask, *mask); + Node *spill = new MachSpillCopyNode(MachSpillCopyNode::LoopPhiInput, phi, *mask, *mask); insert_proj( phi_block, 1, spill, maxlrg++ ); n->set_req(1,spill); must_recompute_live = true; diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/coalesce.cpp --- a/hotspot/src/share/vm/opto/coalesce.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/coalesce.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -291,7 +291,7 @@ _phc.clone_projs(pred, pred->end_idx(), m, copy, _phc._lrg_map); } else { const RegMask *rm = C->matcher()->idealreg2spillmask[m->ideal_reg()]; - copy = new (C) MachSpillCopyNode(MachSpillCopyNode::PhiInput, m, *rm, *rm); + copy = new MachSpillCopyNode(MachSpillCopyNode::PhiInput, m, *rm, *rm); // Find a good place to insert. Kinda tricky, use a subroutine insert_copy_with_overlap(pred,copy,phi_name,src_name); } @@ -325,7 +325,7 @@ l += _phc.clone_projs(b, l, m, copy, _phc._lrg_map); } else { const RegMask *rm = C->matcher()->idealreg2spillmask[m->ideal_reg()]; - copy = new (C) MachSpillCopyNode(MachSpillCopyNode::TwoAddress, m, *rm, *rm); + copy = new MachSpillCopyNode(MachSpillCopyNode::TwoAddress, m, *rm, *rm); // Insert the copy in the basic block, just before us b->insert_node(copy, l++); } @@ -372,7 +372,7 @@ continue; // Live out; do not pre-split // Split the lrg at this use const RegMask *rm = C->matcher()->idealreg2spillmask[inp->ideal_reg()]; - Node* copy = new (C) MachSpillCopyNode(MachSpillCopyNode::DebugUse, inp, *rm, *rm); + Node* copy = new MachSpillCopyNode(MachSpillCopyNode::DebugUse, inp, *rm, *rm); // Insert the copy in the use-def chain n->set_req(inpidx, copy ); // Insert the copy in the basic block, just before us diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/compile.cpp --- a/hotspot/src/share/vm/opto/compile.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/compile.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -95,7 +95,7 @@ // Constant table base node singleton. MachConstantBaseNode* Compile::mach_constant_base_node() { if (_mach_constant_base_node == NULL) { - _mach_constant_base_node = new (C) MachConstantBaseNode(); + _mach_constant_base_node = new MachConstantBaseNode(); _mach_constant_base_node->add_req(C->root()); } return _mach_constant_base_node; @@ -392,6 +392,11 @@ uint next = 0; while (next < useful.size()) { Node *n = useful.at(next++); + if (n->is_SafePoint()) { + // We're done with a parsing phase. Replaced nodes are not valid + // beyond that point. + n->as_SafePoint()->delete_replaced_nodes(); + } // Use raw traversal of out edges since this code removes out edges int max = n->outcnt(); for (int j = 0; j < max; ++j) { @@ -673,7 +678,6 @@ _print_inlining_stream(NULL), _print_inlining_idx(0), _print_inlining_output(NULL), - _preserve_jvm_state(0), _interpreter_frame_size(0) { C = this; @@ -748,14 +752,14 @@ const TypeTuple *domain = StartOSRNode::osr_domain(); const TypeTuple *range = TypeTuple::make_range(method()->signature()); init_tf(TypeFunc::make(domain, range)); - StartNode* s = new (this) StartOSRNode(root(), domain); + StartNode* s = new StartOSRNode(root(), domain); initial_gvn()->set_type_bottom(s); init_start(s); cg = CallGenerator::for_osr(method(), entry_bci()); } else { // Normal case. init_tf(TypeFunc::make(method())); - StartNode* s = new (this) StartNode(root(), tf()->domain()); + StartNode* s = new StartNode(root(), tf()->domain()); initial_gvn()->set_type_bottom(s); init_start(s); if (method()->intrinsic_id() == vmIntrinsics::_Reference_get && UseG1GC) { @@ -783,7 +787,7 @@ return; } JVMState* jvms = build_start_state(start(), tf()); - if ((jvms = cg->generate(jvms, NULL)) == NULL) { + if ((jvms = cg->generate(jvms)) == NULL) { record_method_not_compilable("method parse failed"); return; } @@ -980,7 +984,6 @@ _print_inlining_stream(NULL), _print_inlining_idx(0), _print_inlining_output(NULL), - _preserve_jvm_state(0), _allowed_reasons(0), _interpreter_frame_size(0) { C = this; @@ -1061,9 +1064,9 @@ // Globally visible Nodes // First set TOP to NULL to give safe behavior during creation of RootNode set_cached_top_node(NULL); - set_root(new (this) RootNode()); + set_root(new RootNode()); // Now that you have a Root to point to, create the real TOP - set_cached_top_node( new (this) ConNode(Type::TOP) ); + set_cached_top_node( new ConNode(Type::TOP) ); set_recent_alloc(NULL, NULL); // Create Debug Information Recorder to record scopes, oopmaps, etc. @@ -1914,6 +1917,8 @@ for_igvn()->clear(); gvn->replace_with(&igvn); + _late_inlines_pos = _late_inlines.length(); + while (_boxing_late_inlines.length() > 0) { CallGenerator* cg = _boxing_late_inlines.pop(); cg->do_late_inline(); @@ -1977,8 +1982,8 @@ if (live_nodes() > (uint)LiveNodeCountInliningCutoff) { if (low_live_nodes < (uint)LiveNodeCountInliningCutoff * 8 / 10) { // PhaseIdealLoop is expensive so we only try it once we are - // out of loop and we only try it again if the previous helped - // got the number of nodes down significantly + // out of live nodes and we only try it again if the previous + // helped got the number of nodes down significantly PhaseIdealLoop ideal_loop( igvn, false, true ); if (failing()) return; low_live_nodes = live_nodes(); @@ -2072,6 +2077,10 @@ // Inline valueOf() methods now. inline_boxing_calls(igvn); + if (AlwaysIncrementalInline) { + inline_incrementally(igvn); + } + print_method(PHASE_INCREMENTAL_BOXING_INLINE, 2); if (failing()) return; @@ -2757,9 +2766,9 @@ // Decode a narrow oop to match address // [R12 + narrow_oop_reg<<3 + offset] if (t->isa_oopptr()) { - nn = new (this) DecodeNNode(nn, t); + nn = new DecodeNNode(nn, t); } else { - nn = new (this) DecodeNKlassNode(nn, t); + nn = new DecodeNKlassNode(nn, t); } n->set_req(AddPNode::Base, nn); n->set_req(AddPNode::Address, nn); @@ -2880,7 +2889,7 @@ } } if (new_in2 != NULL) { - Node* cmpN = new (this) CmpNNode(in1->in(1), new_in2); + Node* cmpN = new CmpNNode(in1->in(1), new_in2); n->subsume_by(cmpN, this); if (in1->outcnt() == 0) { in1->disconnect_inputs(NULL, this); @@ -2979,8 +2988,8 @@ n->subsume_by(divmod->mod_proj(), this); } else { // replace a%b with a-((a/b)*b) - Node* mult = new (this) MulINode(d, d->in(2)); - Node* sub = new (this) SubINode(d->in(1), mult); + Node* mult = new MulINode(d, d->in(2)); + Node* sub = new SubINode(d->in(1), mult); n->subsume_by(sub, this); } } @@ -2999,8 +3008,8 @@ n->subsume_by(divmod->mod_proj(), this); } else { // replace a%b with a-((a/b)*b) - Node* mult = new (this) MulLNode(d, d->in(2)); - Node* sub = new (this) SubLNode(d->in(1), mult); + Node* mult = new MulLNode(d, d->in(2)); + Node* sub = new SubLNode(d->in(1), mult); n->subsume_by(sub, this); } } @@ -3049,7 +3058,7 @@ } } else { if (t == NULL || t->_lo < 0 || t->_hi > (int)mask) { - Node* shift = new (this) AndINode(in2, ConNode::make(this, TypeInt::make(mask))); + Node* shift = new AndINode(in2, ConNode::make(this, TypeInt::make(mask))); n->set_req(2, shift); } } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/compile.hpp --- a/hotspot/src/share/vm/opto/compile.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/compile.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -431,9 +431,6 @@ // Remove the speculative part of types and clean up the graph void remove_speculative_types(PhaseIterGVN &igvn); - // Are we within a PreserveJVMState block? - int _preserve_jvm_state; - void* _replay_inline_data; // Pointer to data loaded from file void print_inlining_init(); @@ -1198,21 +1195,6 @@ // Auxiliary method for randomized fuzzing/stressing static bool randomized_select(int count); - - // enter a PreserveJVMState block - void inc_preserve_jvm_state() { - _preserve_jvm_state++; - } - - // exit a PreserveJVMState block - void dec_preserve_jvm_state() { - _preserve_jvm_state--; - assert(_preserve_jvm_state >= 0, "_preserve_jvm_state shouldn't be negative"); - } - - bool has_preserve_jvm_state() const { - return _preserve_jvm_state > 0; - } }; #endif // SHARE_VM_OPTO_COMPILE_HPP diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/connode.cpp --- a/hotspot/src/share/vm/opto/connode.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/connode.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -45,17 +45,17 @@ //------------------------------make------------------------------------------- ConNode *ConNode::make( Compile* C, const Type *t ) { switch( t->basic_type() ) { - case T_INT: return new (C) ConINode( t->is_int() ); - case T_LONG: return new (C) ConLNode( t->is_long() ); - case T_FLOAT: return new (C) ConFNode( t->is_float_constant() ); - case T_DOUBLE: return new (C) ConDNode( t->is_double_constant() ); - case T_VOID: return new (C) ConNode ( Type::TOP ); - case T_OBJECT: return new (C) ConPNode( t->is_ptr() ); - case T_ARRAY: return new (C) ConPNode( t->is_aryptr() ); - case T_ADDRESS: return new (C) ConPNode( t->is_ptr() ); - case T_NARROWOOP: return new (C) ConNNode( t->is_narrowoop() ); - case T_NARROWKLASS: return new (C) ConNKlassNode( t->is_narrowklass() ); - case T_METADATA: return new (C) ConPNode( t->is_ptr() ); + case T_INT: return new ConINode( t->is_int() ); + case T_LONG: return new ConLNode( t->is_long() ); + case T_FLOAT: return new ConFNode( t->is_float_constant() ); + case T_DOUBLE: return new ConDNode( t->is_double_constant() ); + case T_VOID: return new ConNode ( Type::TOP ); + case T_OBJECT: return new ConPNode( t->is_ptr() ); + case T_ARRAY: return new ConPNode( t->is_aryptr() ); + case T_ADDRESS: return new ConPNode( t->is_ptr() ); + case T_NARROWOOP: return new ConNNode( t->is_narrowoop() ); + case T_NARROWKLASS: return new ConNKlassNode( t->is_narrowklass() ); + case T_METADATA: return new ConPNode( t->is_ptr() ); // Expected cases: TypePtr::NULL_PTR, any is_rawptr() // Also seen: AnyPtr(TopPTR *+top); from command line: // r -XX:+PrintOpto -XX:CIStart=285 -XX:+CompileTheWorld -XX:CompileTheWorldStartAt=660 diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/connode.hpp --- a/hotspot/src/share/vm/opto/connode.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/connode.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -58,7 +58,7 @@ // Factory method: static ConINode* make( Compile* C, int con ) { - return new (C) ConINode( TypeInt::make(con) ); + return new ConINode( TypeInt::make(con) ); } }; @@ -73,9 +73,9 @@ // Factory methods: static ConPNode* make( Compile *C ,address con ) { if (con == NULL) - return new (C) ConPNode( TypePtr::NULL_PTR ) ; + return new ConPNode( TypePtr::NULL_PTR ) ; else - return new (C) ConPNode( TypeRawPtr::make(con) ); + return new ConPNode( TypeRawPtr::make(con) ); } }; @@ -106,7 +106,7 @@ // Factory method: static ConLNode* make( Compile *C ,jlong con ) { - return new (C) ConLNode( TypeLong::make(con) ); + return new ConLNode( TypeLong::make(con) ); } }; @@ -120,7 +120,7 @@ // Factory method: static ConFNode* make( Compile *C, float con ) { - return new (C) ConFNode( TypeF::make(con) ); + return new ConFNode( TypeF::make(con) ); } }; @@ -134,7 +134,7 @@ // Factory method: static ConDNode* make( Compile *C, double con ) { - return new (C) ConDNode( TypeD::make(con) ); + return new ConDNode( TypeD::make(con) ); } }; diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/convertnode.cpp --- a/hotspot/src/share/vm/opto/convertnode.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/convertnode.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -374,11 +374,11 @@ ryhi = -rylo0; } - Node* cx = phase->transform( new (phase->C) ConvI2LNode(x, TypeLong::make(rxlo, rxhi, widen)) ); - Node* cy = phase->transform( new (phase->C) ConvI2LNode(y, TypeLong::make(rylo, ryhi, widen)) ); + Node* cx = phase->transform( new ConvI2LNode(x, TypeLong::make(rxlo, rxhi, widen)) ); + Node* cy = phase->transform( new ConvI2LNode(y, TypeLong::make(rylo, ryhi, widen)) ); switch (op) { - case Op_AddI: return new (phase->C) AddLNode(cx, cy); - case Op_SubI: return new (phase->C) SubLNode(cx, cy); + case Op_AddI: return new AddLNode(cx, cy); + case Op_SubI: return new SubLNode(cx, cy); default: ShouldNotReachHere(); } } @@ -452,9 +452,9 @@ assert( x != andl && y != andl, "dead loop in ConvL2INode::Ideal" ); if (phase->type(x) == Type::TOP) return NULL; if (phase->type(y) == Type::TOP) return NULL; - Node *add1 = phase->transform(new (phase->C) ConvL2INode(x)); - Node *add2 = phase->transform(new (phase->C) ConvL2INode(y)); - return new (phase->C) AddINode(add1,add2); + Node *add1 = phase->transform(new ConvL2INode(x)); + Node *add2 = phase->transform(new ConvL2INode(y)); + return new AddINode(add1,add2); } // Disable optimization: LoadL->ConvL2I ==> LoadI. diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/divnode.cpp --- a/hotspot/src/share/vm/opto/divnode.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/divnode.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -106,7 +106,7 @@ // division by +/- 1 if (!d_pos) { // Just negate the value - q = new (phase->C) SubINode(phase->intcon(0), dividend); + q = new SubINode(phase->intcon(0), dividend); } } else if ( is_power_of_2(d) ) { // division by +/- a power of 2 @@ -143,18 +143,18 @@ // (-2+3)>>2 becomes 0, etc. // Compute 0 or -1, based on sign bit - Node *sign = phase->transform(new (phase->C) RShiftINode(dividend, phase->intcon(N - 1))); + Node *sign = phase->transform(new RShiftINode(dividend, phase->intcon(N - 1))); // Mask sign bit to the low sign bits - Node *round = phase->transform(new (phase->C) URShiftINode(sign, phase->intcon(N - l))); + Node *round = phase->transform(new URShiftINode(sign, phase->intcon(N - l))); // Round up before shifting - dividend = phase->transform(new (phase->C) AddINode(dividend, round)); + dividend = phase->transform(new AddINode(dividend, round)); } // Shift for division - q = new (phase->C) RShiftINode(dividend, phase->intcon(l)); + q = new RShiftINode(dividend, phase->intcon(l)); if (!d_pos) { - q = new (phase->C) SubINode(phase->intcon(0), phase->transform(q)); + q = new SubINode(phase->intcon(0), phase->transform(q)); } } else { // Attempt the jint constant divide -> multiply transform found in @@ -166,33 +166,33 @@ jint shift_const; if (magic_int_divide_constants(d, magic_const, shift_const)) { Node *magic = phase->longcon(magic_const); - Node *dividend_long = phase->transform(new (phase->C) ConvI2LNode(dividend)); + Node *dividend_long = phase->transform(new ConvI2LNode(dividend)); // Compute the high half of the dividend x magic multiplication - Node *mul_hi = phase->transform(new (phase->C) MulLNode(dividend_long, magic)); + Node *mul_hi = phase->transform(new MulLNode(dividend_long, magic)); if (magic_const < 0) { - mul_hi = phase->transform(new (phase->C) RShiftLNode(mul_hi, phase->intcon(N))); - mul_hi = phase->transform(new (phase->C) ConvL2INode(mul_hi)); + mul_hi = phase->transform(new RShiftLNode(mul_hi, phase->intcon(N))); + mul_hi = phase->transform(new ConvL2INode(mul_hi)); // The magic multiplier is too large for a 32 bit constant. We've adjusted // it down by 2^32, but have to add 1 dividend back in after the multiplication. // This handles the "overflow" case described by Granlund and Montgomery. - mul_hi = phase->transform(new (phase->C) AddINode(dividend, mul_hi)); + mul_hi = phase->transform(new AddINode(dividend, mul_hi)); // Shift over the (adjusted) mulhi if (shift_const != 0) { - mul_hi = phase->transform(new (phase->C) RShiftINode(mul_hi, phase->intcon(shift_const))); + mul_hi = phase->transform(new RShiftINode(mul_hi, phase->intcon(shift_const))); } } else { // No add is required, we can merge the shifts together. - mul_hi = phase->transform(new (phase->C) RShiftLNode(mul_hi, phase->intcon(N + shift_const))); - mul_hi = phase->transform(new (phase->C) ConvL2INode(mul_hi)); + mul_hi = phase->transform(new RShiftLNode(mul_hi, phase->intcon(N + shift_const))); + mul_hi = phase->transform(new ConvL2INode(mul_hi)); } // Get a 0 or -1 from the sign of the dividend. Node *addend0 = mul_hi; - Node *addend1 = phase->transform(new (phase->C) RShiftINode(dividend, phase->intcon(N-1))); + Node *addend1 = phase->transform(new RShiftINode(dividend, phase->intcon(N-1))); // If the divisor is negative, swap the order of the input addends; // this has the effect of negating the quotient. @@ -202,7 +202,7 @@ // Adjust the final quotient by subtracting -1 (adding 1) // from the mul_hi. - q = new (phase->C) SubINode(addend0, addend1); + q = new SubINode(addend0, addend1); } } @@ -261,7 +261,7 @@ // no need to synthesize it in ideal nodes. if (Matcher::has_match_rule(Op_MulHiL)) { Node* v = phase->longcon(magic_const); - return new (phase->C) MulHiLNode(dividend, v); + return new MulHiLNode(dividend, v); } // Taken from Hacker's Delight, Fig. 8-2. Multiply high signed. @@ -287,11 +287,11 @@ const int N = 64; // Dummy node to keep intermediate nodes alive during construction - Node* hook = new (phase->C) Node(4); + Node* hook = new Node(4); // u0 = u & 0xFFFFFFFF; u1 = u >> 32; - Node* u0 = phase->transform(new (phase->C) AndLNode(dividend, phase->longcon(0xFFFFFFFF))); - Node* u1 = phase->transform(new (phase->C) RShiftLNode(dividend, phase->intcon(N / 2))); + Node* u0 = phase->transform(new AndLNode(dividend, phase->longcon(0xFFFFFFFF))); + Node* u1 = phase->transform(new RShiftLNode(dividend, phase->intcon(N / 2))); hook->init_req(0, u0); hook->init_req(1, u1); @@ -300,29 +300,29 @@ Node* v1 = phase->longcon(magic_const >> (N / 2)); // w0 = u0*v0; - Node* w0 = phase->transform(new (phase->C) MulLNode(u0, v0)); + Node* w0 = phase->transform(new MulLNode(u0, v0)); // t = u1*v0 + (w0 >> 32); - Node* u1v0 = phase->transform(new (phase->C) MulLNode(u1, v0)); - Node* temp = phase->transform(new (phase->C) URShiftLNode(w0, phase->intcon(N / 2))); - Node* t = phase->transform(new (phase->C) AddLNode(u1v0, temp)); + Node* u1v0 = phase->transform(new MulLNode(u1, v0)); + Node* temp = phase->transform(new URShiftLNode(w0, phase->intcon(N / 2))); + Node* t = phase->transform(new AddLNode(u1v0, temp)); hook->init_req(2, t); // w1 = t & 0xFFFFFFFF; - Node* w1 = phase->transform(new (phase->C) AndLNode(t, phase->longcon(0xFFFFFFFF))); + Node* w1 = phase->transform(new AndLNode(t, phase->longcon(0xFFFFFFFF))); hook->init_req(3, w1); // w2 = t >> 32; - Node* w2 = phase->transform(new (phase->C) RShiftLNode(t, phase->intcon(N / 2))); + Node* w2 = phase->transform(new RShiftLNode(t, phase->intcon(N / 2))); // w1 = u0*v1 + w1; - Node* u0v1 = phase->transform(new (phase->C) MulLNode(u0, v1)); - w1 = phase->transform(new (phase->C) AddLNode(u0v1, w1)); + Node* u0v1 = phase->transform(new MulLNode(u0, v1)); + w1 = phase->transform(new AddLNode(u0v1, w1)); // return u1*v1 + w2 + (w1 >> 32); - Node* u1v1 = phase->transform(new (phase->C) MulLNode(u1, v1)); - Node* temp1 = phase->transform(new (phase->C) AddLNode(u1v1, w2)); - Node* temp2 = phase->transform(new (phase->C) RShiftLNode(w1, phase->intcon(N / 2))); + Node* u1v1 = phase->transform(new MulLNode(u1, v1)); + Node* temp1 = phase->transform(new AddLNode(u1v1, w2)); + Node* temp2 = phase->transform(new RShiftLNode(w1, phase->intcon(N / 2))); // Remove the bogus extra edges used to keep things alive PhaseIterGVN* igvn = phase->is_IterGVN(); @@ -334,7 +334,7 @@ } } - return new (phase->C) AddLNode(temp1, temp2); + return new AddLNode(temp1, temp2); } @@ -357,7 +357,7 @@ // division by +/- 1 if (!d_pos) { // Just negate the value - q = new (phase->C) SubLNode(phase->longcon(0), dividend); + q = new SubLNode(phase->longcon(0), dividend); } } else if ( is_power_of_2_long(d) ) { @@ -396,18 +396,18 @@ // (-2+3)>>2 becomes 0, etc. // Compute 0 or -1, based on sign bit - Node *sign = phase->transform(new (phase->C) RShiftLNode(dividend, phase->intcon(N - 1))); + Node *sign = phase->transform(new RShiftLNode(dividend, phase->intcon(N - 1))); // Mask sign bit to the low sign bits - Node *round = phase->transform(new (phase->C) URShiftLNode(sign, phase->intcon(N - l))); + Node *round = phase->transform(new URShiftLNode(sign, phase->intcon(N - l))); // Round up before shifting - dividend = phase->transform(new (phase->C) AddLNode(dividend, round)); + dividend = phase->transform(new AddLNode(dividend, round)); } // Shift for division - q = new (phase->C) RShiftLNode(dividend, phase->intcon(l)); + q = new RShiftLNode(dividend, phase->intcon(l)); if (!d_pos) { - q = new (phase->C) SubLNode(phase->longcon(0), phase->transform(q)); + q = new SubLNode(phase->longcon(0), phase->transform(q)); } } else if ( !Matcher::use_asm_for_ldiv_by_con(d) ) { // Use hardware DIV instruction when // it is faster than code generated below. @@ -427,17 +427,17 @@ // The magic multiplier is too large for a 64 bit constant. We've adjusted // it down by 2^64, but have to add 1 dividend back in after the multiplication. // This handles the "overflow" case described by Granlund and Montgomery. - mul_hi = phase->transform(new (phase->C) AddLNode(dividend, mul_hi)); + mul_hi = phase->transform(new AddLNode(dividend, mul_hi)); } // Shift over the (adjusted) mulhi if (shift_const != 0) { - mul_hi = phase->transform(new (phase->C) RShiftLNode(mul_hi, phase->intcon(shift_const))); + mul_hi = phase->transform(new RShiftLNode(mul_hi, phase->intcon(shift_const))); } // Get a 0 or -1 from the sign of the dividend. Node *addend0 = mul_hi; - Node *addend1 = phase->transform(new (phase->C) RShiftLNode(dividend, phase->intcon(N-1))); + Node *addend1 = phase->transform(new RShiftLNode(dividend, phase->intcon(N-1))); // If the divisor is negative, swap the order of the input addends; // this has the effect of negating the quotient. @@ -447,7 +447,7 @@ // Adjust the final quotient by subtracting -1 (adding 1) // from the mul_hi. - q = new (phase->C) SubLNode(addend0, addend1); + q = new SubLNode(addend0, addend1); } } @@ -737,7 +737,7 @@ assert( frexp((double)reciprocal, &exp) == 0.5, "reciprocal should be power of 2" ); // return multiplication by the reciprocal - return (new (phase->C) MulFNode(in(1), phase->makecon(TypeF::make(reciprocal)))); + return (new MulFNode(in(1), phase->makecon(TypeF::make(reciprocal)))); } //============================================================================= @@ -831,7 +831,7 @@ assert( frexp(reciprocal, &exp) == 0.5, "reciprocal should be power of 2" ); // return multiplication by the reciprocal - return (new (phase->C) MulDNode(in(1), phase->makecon(TypeD::make(reciprocal)))); + return (new MulDNode(in(1), phase->makecon(TypeD::make(reciprocal)))); } //============================================================================= @@ -858,7 +858,7 @@ if( !ti->is_con() ) return NULL; jint con = ti->get_con(); - Node *hook = new (phase->C) Node(1); + Node *hook = new Node(1); // First, special check for modulo 2^k-1 if( con >= 0 && con < max_jint && is_power_of_2(con+1) ) { @@ -878,24 +878,24 @@ hook->init_req(0, x); // Add a use to x to prevent him from dying // Generate code to reduce X rapidly to nearly 2^k-1. for( int i = 0; i < trip_count; i++ ) { - Node *xl = phase->transform( new (phase->C) AndINode(x,divisor) ); - Node *xh = phase->transform( new (phase->C) RShiftINode(x,phase->intcon(k)) ); // Must be signed - x = phase->transform( new (phase->C) AddINode(xh,xl) ); + Node *xl = phase->transform( new AndINode(x,divisor) ); + Node *xh = phase->transform( new RShiftINode(x,phase->intcon(k)) ); // Must be signed + x = phase->transform( new AddINode(xh,xl) ); hook->set_req(0, x); } // Generate sign-fixup code. Was original value positive? // int hack_res = (i >= 0) ? divisor : 1; - Node *cmp1 = phase->transform( new (phase->C) CmpINode( in(1), phase->intcon(0) ) ); - Node *bol1 = phase->transform( new (phase->C) BoolNode( cmp1, BoolTest::ge ) ); - Node *cmov1= phase->transform( new (phase->C) CMoveINode(bol1, phase->intcon(1), divisor, TypeInt::POS) ); + Node *cmp1 = phase->transform( new CmpINode( in(1), phase->intcon(0) ) ); + Node *bol1 = phase->transform( new BoolNode( cmp1, BoolTest::ge ) ); + Node *cmov1= phase->transform( new CMoveINode(bol1, phase->intcon(1), divisor, TypeInt::POS) ); // if( x >= hack_res ) x -= divisor; - Node *sub = phase->transform( new (phase->C) SubINode( x, divisor ) ); - Node *cmp2 = phase->transform( new (phase->C) CmpINode( x, cmov1 ) ); - Node *bol2 = phase->transform( new (phase->C) BoolNode( cmp2, BoolTest::ge ) ); + Node *sub = phase->transform( new SubINode( x, divisor ) ); + Node *cmp2 = phase->transform( new CmpINode( x, cmov1 ) ); + Node *bol2 = phase->transform( new BoolNode( cmp2, BoolTest::ge ) ); // Convention is to not transform the return value of an Ideal // since Ideal is expected to return a modified 'this' or a new node. - Node *cmov2= new (phase->C) CMoveINode(bol2, x, sub, TypeInt::INT); + Node *cmov2= new CMoveINode(bol2, x, sub, TypeInt::INT); // cmov2 is now the mod // Now remove the bogus extra edges used to keep things alive @@ -918,7 +918,7 @@ jint pos_con = (con >= 0) ? con : -con; // integer Mod 1 is always 0 - if( pos_con == 1 ) return new (phase->C) ConINode(TypeInt::ZERO); + if( pos_con == 1 ) return new ConINode(TypeInt::ZERO); int log2_con = -1; @@ -931,7 +931,7 @@ // See if this can be masked, if the dividend is non-negative if( dti && dti->_lo >= 0 ) - return ( new (phase->C) AndINode( in(1), phase->intcon( pos_con-1 ) ) ); + return ( new AndINode( in(1), phase->intcon( pos_con-1 ) ) ); } // Save in(1) so that it cannot be changed or deleted @@ -946,12 +946,12 @@ Node *mult = NULL; if( log2_con >= 0 ) - mult = phase->transform( new (phase->C) LShiftINode( divide, phase->intcon( log2_con ) ) ); + mult = phase->transform( new LShiftINode( divide, phase->intcon( log2_con ) ) ); else - mult = phase->transform( new (phase->C) MulINode( divide, phase->intcon( pos_con ) ) ); + mult = phase->transform( new MulINode( divide, phase->intcon( pos_con ) ) ); // Finally, subtract the multiplied divided value from the original - result = new (phase->C) SubINode( in(1), mult ); + result = new SubINode( in(1), mult ); } // Now remove the bogus extra edges used to keep things alive @@ -1029,7 +1029,7 @@ if( !tl->is_con() ) return NULL; jlong con = tl->get_con(); - Node *hook = new (phase->C) Node(1); + Node *hook = new Node(1); // Expand mod if( con >= 0 && con < max_jlong && is_power_of_2_long(con+1) ) { @@ -1051,24 +1051,24 @@ hook->init_req(0, x); // Add a use to x to prevent him from dying // Generate code to reduce X rapidly to nearly 2^k-1. for( int i = 0; i < trip_count; i++ ) { - Node *xl = phase->transform( new (phase->C) AndLNode(x,divisor) ); - Node *xh = phase->transform( new (phase->C) RShiftLNode(x,phase->intcon(k)) ); // Must be signed - x = phase->transform( new (phase->C) AddLNode(xh,xl) ); + Node *xl = phase->transform( new AndLNode(x,divisor) ); + Node *xh = phase->transform( new RShiftLNode(x,phase->intcon(k)) ); // Must be signed + x = phase->transform( new AddLNode(xh,xl) ); hook->set_req(0, x); // Add a use to x to prevent him from dying } // Generate sign-fixup code. Was original value positive? // long hack_res = (i >= 0) ? divisor : CONST64(1); - Node *cmp1 = phase->transform( new (phase->C) CmpLNode( in(1), phase->longcon(0) ) ); - Node *bol1 = phase->transform( new (phase->C) BoolNode( cmp1, BoolTest::ge ) ); - Node *cmov1= phase->transform( new (phase->C) CMoveLNode(bol1, phase->longcon(1), divisor, TypeLong::LONG) ); + Node *cmp1 = phase->transform( new CmpLNode( in(1), phase->longcon(0) ) ); + Node *bol1 = phase->transform( new BoolNode( cmp1, BoolTest::ge ) ); + Node *cmov1= phase->transform( new CMoveLNode(bol1, phase->longcon(1), divisor, TypeLong::LONG) ); // if( x >= hack_res ) x -= divisor; - Node *sub = phase->transform( new (phase->C) SubLNode( x, divisor ) ); - Node *cmp2 = phase->transform( new (phase->C) CmpLNode( x, cmov1 ) ); - Node *bol2 = phase->transform( new (phase->C) BoolNode( cmp2, BoolTest::ge ) ); + Node *sub = phase->transform( new SubLNode( x, divisor ) ); + Node *cmp2 = phase->transform( new CmpLNode( x, cmov1 ) ); + Node *bol2 = phase->transform( new BoolNode( cmp2, BoolTest::ge ) ); // Convention is to not transform the return value of an Ideal // since Ideal is expected to return a modified 'this' or a new node. - Node *cmov2= new (phase->C) CMoveLNode(bol2, x, sub, TypeLong::LONG); + Node *cmov2= new CMoveLNode(bol2, x, sub, TypeLong::LONG); // cmov2 is now the mod // Now remove the bogus extra edges used to keep things alive @@ -1091,7 +1091,7 @@ jlong pos_con = (con >= 0) ? con : -con; // integer Mod 1 is always 0 - if( pos_con == 1 ) return new (phase->C) ConLNode(TypeLong::ZERO); + if( pos_con == 1 ) return new ConLNode(TypeLong::ZERO); int log2_con = -1; @@ -1104,7 +1104,7 @@ // See if this can be masked, if the dividend is non-negative if( dtl && dtl->_lo >= 0 ) - return ( new (phase->C) AndLNode( in(1), phase->longcon( pos_con-1 ) ) ); + return ( new AndLNode( in(1), phase->longcon( pos_con-1 ) ) ); } // Save in(1) so that it cannot be changed or deleted @@ -1119,12 +1119,12 @@ Node *mult = NULL; if( log2_con >= 0 ) - mult = phase->transform( new (phase->C) LShiftLNode( divide, phase->intcon( log2_con ) ) ); + mult = phase->transform( new LShiftLNode( divide, phase->intcon( log2_con ) ) ); else - mult = phase->transform( new (phase->C) MulLNode( divide, phase->longcon( pos_con ) ) ); + mult = phase->transform( new MulLNode( divide, phase->longcon( pos_con ) ) ); // Finally, subtract the multiplied divided value from the original - result = new (phase->C) SubLNode( in(1), mult ); + result = new SubLNode( in(1), mult ); } // Now remove the bogus extra edges used to keep things alive @@ -1279,9 +1279,9 @@ assert(n->Opcode() == Op_DivI || n->Opcode() == Op_ModI, "only div or mod input pattern accepted"); - DivModINode* divmod = new (C) DivModINode(n->in(0), n->in(1), n->in(2)); - Node* dproj = new (C) ProjNode(divmod, DivModNode::div_proj_num); - Node* mproj = new (C) ProjNode(divmod, DivModNode::mod_proj_num); + DivModINode* divmod = new DivModINode(n->in(0), n->in(1), n->in(2)); + Node* dproj = new ProjNode(divmod, DivModNode::div_proj_num); + Node* mproj = new ProjNode(divmod, DivModNode::mod_proj_num); return divmod; } @@ -1291,9 +1291,9 @@ assert(n->Opcode() == Op_DivL || n->Opcode() == Op_ModL, "only div or mod input pattern accepted"); - DivModLNode* divmod = new (C) DivModLNode(n->in(0), n->in(1), n->in(2)); - Node* dproj = new (C) ProjNode(divmod, DivModNode::div_proj_num); - Node* mproj = new (C) ProjNode(divmod, DivModNode::mod_proj_num); + DivModLNode* divmod = new DivModLNode(n->in(0), n->in(1), n->in(2)); + Node* dproj = new ProjNode(divmod, DivModNode::div_proj_num); + Node* mproj = new ProjNode(divmod, DivModNode::mod_proj_num); return divmod; } @@ -1308,7 +1308,7 @@ assert(proj->_con == mod_proj_num, "must be div or mod projection"); rm = match->modI_proj_mask(); } - return new (match->C)MachProjNode(this, proj->_con, rm, ideal_reg); + return new MachProjNode(this, proj->_con, rm, ideal_reg); } @@ -1323,5 +1323,5 @@ assert(proj->_con == mod_proj_num, "must be div or mod projection"); rm = match->modL_proj_mask(); } - return new (match->C)MachProjNode(this, proj->_con, rm, ideal_reg); + return new MachProjNode(this, proj->_con, rm, ideal_reg); } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/doCall.cpp --- a/hotspot/src/share/vm/opto/doCall.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/doCall.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -119,12 +119,12 @@ if (allow_inline && allow_intrinsics) { CallGenerator* cg = find_intrinsic(callee, call_does_dispatch); if (cg != NULL) { - if (cg->is_predicted()) { + if (cg->is_predicated()) { // Code without intrinsic but, hopefully, inlined. CallGenerator* inline_cg = this->call_generator(callee, vtable_index, call_does_dispatch, jvms, allow_inline, prof_factor, speculative_receiver_type, false); if (inline_cg != NULL) { - cg = CallGenerator::for_predicted_intrinsic(cg, inline_cg); + cg = CallGenerator::for_predicated_intrinsic(cg, inline_cg); } } @@ -525,7 +525,7 @@ // because exceptions don't return to the call site.) profile_call(receiver); - JVMState* new_jvms = cg->generate(jvms, this); + JVMState* new_jvms = cg->generate(jvms); if (new_jvms == NULL) { // When inlining attempt fails (e.g., too many arguments), // it may contaminate the current compile state, making it @@ -539,7 +539,7 @@ // intrinsic was expecting to optimize. Should always be possible to // get a normal java call that may inline in that case cg = C->call_generator(cg->method(), vtable_index, call_does_dispatch, jvms, try_inline, prof_factor(), speculative_receiver_type, /* allow_intrinsics= */ false); - new_jvms = cg->generate(jvms, this); + new_jvms = cg->generate(jvms); if (new_jvms == NULL) { guarantee(failing(), "call failed to generate: calls should work"); return; @@ -596,7 +596,7 @@ const Type* sig_type = TypeOopPtr::make_from_klass(ctype->as_klass()); if (arg_type != NULL && !arg_type->higher_equal(sig_type)) { Node* retnode = pop(); - Node* cast_obj = _gvn.transform(new (C) CheckCastPPNode(control(), retnode, sig_type)); + Node* cast_obj = _gvn.transform(new CheckCastPPNode(control(), retnode, sig_type)); push(cast_obj); } } @@ -689,7 +689,7 @@ } int len = bcis->length(); - CatchNode *cn = new (C) CatchNode(control(), i_o, len+1); + CatchNode *cn = new CatchNode(control(), i_o, len+1); Node *catch_ = _gvn.transform(cn); // now branch with the exception state to each of the (potential) @@ -700,14 +700,14 @@ // Locals are just copied from before the call. // Get control from the CatchNode. int handler_bci = bcis->at(i); - Node* ctrl = _gvn.transform( new (C) CatchProjNode(catch_, i+1,handler_bci)); + Node* ctrl = _gvn.transform( new CatchProjNode(catch_, i+1,handler_bci)); // This handler cannot happen? if (ctrl == top()) continue; set_control(ctrl); // Create exception oop const TypeInstPtr* extype = extypes->at(i)->is_instptr(); - Node *ex_oop = _gvn.transform(new (C) CreateExNode(extypes->at(i), ctrl, i_o)); + Node *ex_oop = _gvn.transform(new CreateExNode(extypes->at(i), ctrl, i_o)); // Handle unloaded exception classes. if (saw_unloaded->contains(handler_bci)) { @@ -746,7 +746,7 @@ // The first CatchProj is for the normal return. // (Note: If this is a call to rethrow_Java, this node goes dead.) - set_control(_gvn.transform( new (C) CatchProjNode(catch_, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci))); + set_control(_gvn.transform( new CatchProjNode(catch_, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci))); } @@ -797,7 +797,7 @@ // I'm loading the class from, I can replace the LoadKlass with the // klass constant for the exception oop. if( ex_node->is_Phi() ) { - ex_klass_node = new (C) PhiNode( ex_node->in(0), TypeKlassPtr::OBJECT ); + ex_klass_node = new PhiNode( ex_node->in(0), TypeKlassPtr::OBJECT ); for( uint i = 1; i < ex_node->req(); i++ ) { Node* p = basic_plus_adr( ex_node->in(i), ex_node->in(i), oopDesc::klass_offset_in_bytes() ); Node* k = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT) ); @@ -863,7 +863,7 @@ PreserveJVMState pjvms(this); const TypeInstPtr* tinst = TypeOopPtr::make_from_klass_unique(klass)->cast_to_ptr_type(TypePtr::NotNull)->is_instptr(); assert(klass->has_subklass() || tinst->klass_is_exact(), "lost exactness"); - Node* ex_oop = _gvn.transform(new (C) CheckCastPPNode(control(), ex_node, tinst)); + Node* ex_oop = _gvn.transform(new CheckCastPPNode(control(), ex_node, tinst)); push_ex_oop(ex_oop); // Push exception oop for handler #ifndef PRODUCT if (PrintOpto && WizardMode) { diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/escape.cpp --- a/hotspot/src/share/vm/opto/escape.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/escape.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -939,7 +939,13 @@ strcmp(call->as_CallLeaf()->_name, "aescrypt_encryptBlock") == 0 || strcmp(call->as_CallLeaf()->_name, "aescrypt_decryptBlock") == 0 || strcmp(call->as_CallLeaf()->_name, "cipherBlockChaining_encryptAESCrypt") == 0 || - strcmp(call->as_CallLeaf()->_name, "cipherBlockChaining_decryptAESCrypt") == 0) + strcmp(call->as_CallLeaf()->_name, "cipherBlockChaining_decryptAESCrypt") == 0 || + strcmp(call->as_CallLeaf()->_name, "sha1_implCompress") == 0 || + strcmp(call->as_CallLeaf()->_name, "sha1_implCompressMB") == 0 || + strcmp(call->as_CallLeaf()->_name, "sha256_implCompress") == 0 || + strcmp(call->as_CallLeaf()->_name, "sha256_implCompressMB") == 0 || + strcmp(call->as_CallLeaf()->_name, "sha512_implCompress") == 0 || + strcmp(call->as_CallLeaf()->_name, "sha512_implCompressMB") == 0) ))) { call->dump(); fatal(err_msg_res("EA unexpected CallLeaf %s", call->as_CallLeaf()->_name)); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/generateOptoStub.cpp --- a/hotspot/src/share/vm/opto/generateOptoStub.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/generateOptoStub.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -50,7 +50,7 @@ const TypeTuple *jrange = C->tf()->range(); // The procedure start - StartNode* start = new (C) StartNode(root(), jdomain); + StartNode* start = new StartNode(root(), jdomain); _gvn.set_type_bottom(start); // Make a map, with JVM state @@ -64,7 +64,7 @@ jvms->set_scloff(max_map); jvms->set_endoff(max_map); { - SafePointNode *map = new (C) SafePointNode( max_map, jvms ); + SafePointNode *map = new SafePointNode( max_map, jvms ); jvms->set_map(map); set_jvms(jvms); assert(map == this->map(), "kit.map is set"); @@ -73,7 +73,7 @@ // Make up the parameters uint i; for( i = 0; i < parm_cnt; i++ ) - map()->init_req(i, _gvn.transform(new (C) ParmNode(start, i))); + map()->init_req(i, _gvn.transform(new ParmNode(start, i))); for( ; ireq(); i++ ) map()->init_req(i, top()); // For nicer debugging @@ -81,7 +81,7 @@ set_all_memory(map()->memory()); // Get base of thread-local storage area - Node* thread = _gvn.transform( new (C) ThreadLocalNode() ); + Node* thread = _gvn.transform( new ThreadLocalNode() ); const int NoAlias = Compile::AliasIdxBot; @@ -166,8 +166,7 @@ //----------------------------- // Make the call node - CallRuntimeNode *call = new (C) - CallRuntimeNode(c_sig, C_function, name, TypePtr::BOTTOM); + CallRuntimeNode *call = new CallRuntimeNode(c_sig, C_function, name, TypePtr::BOTTOM); //----------------------------- // Fix-up the debug info for the call @@ -184,7 +183,7 @@ for (; i < parm_cnt; i++) { // Regular input arguments // Convert ints to longs if required. if (CCallingConventionRequiresIntsAsLongs && jdomain->field_at(i)->isa_int()) { - Node* int_as_long = _gvn.transform(new (C) ConvI2LNode(map()->in(i))); + Node* int_as_long = _gvn.transform(new ConvI2LNode(map()->in(i))); call->init_req(cnt++, int_as_long); // long call->init_req(cnt++, top()); // half } else { @@ -200,23 +199,23 @@ //----------------------------- // Now set up the return results - set_control( _gvn.transform( new (C) ProjNode(call,TypeFunc::Control)) ); - set_i_o( _gvn.transform( new (C) ProjNode(call,TypeFunc::I_O )) ); + set_control( _gvn.transform( new ProjNode(call,TypeFunc::Control)) ); + set_i_o( _gvn.transform( new ProjNode(call,TypeFunc::I_O )) ); set_all_memory_call(call); if (range->cnt() > TypeFunc::Parms) { - Node* retnode = _gvn.transform( new (C) ProjNode(call,TypeFunc::Parms) ); + Node* retnode = _gvn.transform( new ProjNode(call,TypeFunc::Parms) ); // C-land is allowed to return sub-word values. Convert to integer type. assert( retval != Type::TOP, "" ); if (retval == TypeInt::BOOL) { - retnode = _gvn.transform( new (C) AndINode(retnode, intcon(0xFF)) ); + retnode = _gvn.transform( new AndINode(retnode, intcon(0xFF)) ); } else if (retval == TypeInt::CHAR) { - retnode = _gvn.transform( new (C) AndINode(retnode, intcon(0xFFFF)) ); + retnode = _gvn.transform( new AndINode(retnode, intcon(0xFFFF)) ); } else if (retval == TypeInt::BYTE) { - retnode = _gvn.transform( new (C) LShiftINode(retnode, intcon(24)) ); - retnode = _gvn.transform( new (C) RShiftINode(retnode, intcon(24)) ); + retnode = _gvn.transform( new LShiftINode(retnode, intcon(24)) ); + retnode = _gvn.transform( new RShiftINode(retnode, intcon(24)) ); } else if (retval == TypeInt::SHORT) { - retnode = _gvn.transform( new (C) LShiftINode(retnode, intcon(16)) ); - retnode = _gvn.transform( new (C) RShiftINode(retnode, intcon(16)) ); + retnode = _gvn.transform( new LShiftINode(retnode, intcon(16)) ); + retnode = _gvn.transform( new RShiftINode(retnode, intcon(16)) ); } map()->set_req( TypeFunc::Parms, retnode ); } @@ -253,21 +252,21 @@ Node* exit_memory = reset_memory(); - Node* cmp = _gvn.transform( new (C) CmpPNode(pending, null()) ); - Node* bo = _gvn.transform( new (C) BoolNode(cmp, BoolTest::ne) ); + Node* cmp = _gvn.transform( new CmpPNode(pending, null()) ); + Node* bo = _gvn.transform( new BoolNode(cmp, BoolTest::ne) ); IfNode *iff = create_and_map_if(control(), bo, PROB_MIN, COUNT_UNKNOWN); - Node* if_null = _gvn.transform( new (C) IfFalseNode(iff) ); - Node* if_not_null = _gvn.transform( new (C) IfTrueNode(iff) ); + Node* if_null = _gvn.transform( new IfFalseNode(iff) ); + Node* if_not_null = _gvn.transform( new IfTrueNode(iff) ); assert (StubRoutines::forward_exception_entry() != NULL, "must be generated before"); Node *exc_target = makecon(TypeRawPtr::make( StubRoutines::forward_exception_entry() )); - Node *to_exc = new (C) TailCallNode(if_not_null, - i_o(), - exit_memory, - frameptr(), - returnadr(), - exc_target, null()); + Node *to_exc = new TailCallNode(if_not_null, + i_o(), + exit_memory, + frameptr(), + returnadr(), + exc_target, null()); root()->add_req(_gvn.transform(to_exc)); // bind to root to keep live C->init_start(start); @@ -277,27 +276,27 @@ switch( is_fancy_jump ) { case 0: // Make a return instruction // Return to caller, free any space for return address - ret = new (C) ReturnNode(TypeFunc::Parms, if_null, - i_o(), - exit_memory, - frameptr(), - returnadr()); + ret = new ReturnNode(TypeFunc::Parms, if_null, + i_o(), + exit_memory, + frameptr(), + returnadr()); if (C->tf()->range()->cnt() > TypeFunc::Parms) ret->add_req( map()->in(TypeFunc::Parms) ); break; case 1: // This is a fancy tail-call jump. Jump to computed address. // Jump to new callee; leave old return address alone. - ret = new (C) TailCallNode(if_null, - i_o(), - exit_memory, - frameptr(), - returnadr(), - target, map()->in(TypeFunc::Parms)); + ret = new TailCallNode(if_null, + i_o(), + exit_memory, + frameptr(), + returnadr(), + target, map()->in(TypeFunc::Parms)); break; case 2: // Pop return address & jump // Throw away old return address; jump to new computed address //assert(C_function == CAST_FROM_FN_PTR(address, OptoRuntime::rethrow_C), "fancy_jump==2 only for rethrow"); - ret = new (C) TailJumpNode(if_null, + ret = new TailJumpNode(if_null, i_o(), exit_memory, frameptr(), diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/graphKit.cpp --- a/hotspot/src/share/vm/opto/graphKit.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/graphKit.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -294,7 +294,7 @@ JVMState* jvms = new (C) JVMState(_method, NULL); jvms->set_bci(_bci); jvms->set_sp(_sp); - jvms->set_map(new (C) SafePointNode(TypeFunc::Parms, jvms)); + jvms->set_map(new SafePointNode(TypeFunc::Parms, jvms)); set_jvms(jvms); for (uint i = 0; i < map()->req(); i++) map()->init_req(i, top()); set_all_memory(top()); @@ -347,7 +347,7 @@ if (region->in(0) != hidden_merge_mark) { // The control input is not (yet) a specially-marked region in phi_map. // Make it so, and build some phis. - region = new (C) RegionNode(2); + region = new RegionNode(2); _gvn.set_type(region, Type::CONTROL); region->set_req(0, hidden_merge_mark); // marks an internal ex-state region->init_req(1, phi_map->control()); @@ -432,6 +432,7 @@ } } } + phi_map->merge_replaced_nodes_with(ex_map); } //--------------------------use_exception_state-------------------------------- @@ -496,13 +497,13 @@ // take the uncommon_trap in the BuildCutout below. // first must access the should_post_on_exceptions_flag in this thread's JavaThread - Node* jthread = _gvn.transform(new (C) ThreadLocalNode()); + Node* jthread = _gvn.transform(new ThreadLocalNode()); Node* adr = basic_plus_adr(top(), jthread, in_bytes(JavaThread::should_post_on_exceptions_flag_offset())); Node* should_post_flag = make_load(control(), adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw, MemNode::unordered); // Test the should_post_on_exceptions_flag vs. 0 - Node* chk = _gvn.transform( new (C) CmpINode(should_post_flag, intcon(0)) ); - Node* tst = _gvn.transform( new (C) BoolNode(chk, BoolTest::eq) ); + Node* chk = _gvn.transform( new CmpINode(should_post_flag, intcon(0)) ); + Node* tst = _gvn.transform( new BoolNode(chk, BoolTest::eq) ); // Branch to slow_path if should_post_on_exceptions_flag was true { BuildCutout unless(this, tst, PROB_MAX); @@ -645,7 +646,6 @@ _map = kit->map(); // preserve the map _sp = kit->sp(); kit->set_map(clone_map ? kit->clone_map() : NULL); - Compile::current()->inc_preserve_jvm_state(); #ifdef ASSERT _bci = kit->bci(); Parse* parser = kit->is_Parse(); @@ -663,7 +663,6 @@ #endif kit->set_map(_map); kit->set_sp(_sp); - Compile::current()->dec_preserve_jvm_state(); } @@ -675,8 +674,8 @@ SafePointNode* outer_map = _map; // preserved map is caller's SafePointNode* inner_map = kit->map(); IfNode* iff = kit->create_and_map_if(outer_map->control(), p, prob, cnt); - outer_map->set_control(kit->gvn().transform( new (kit->C) IfTrueNode(iff) )); - inner_map->set_control(kit->gvn().transform( new (kit->C) IfFalseNode(iff) )); + outer_map->set_control(kit->gvn().transform( new IfTrueNode(iff) )); + inner_map->set_control(kit->gvn().transform( new IfFalseNode(iff) )); } BuildCutout::~BuildCutout() { GraphKit* kit = _kit; @@ -1118,7 +1117,7 @@ Node* GraphKit::basic_plus_adr(Node* base, Node* ptr, Node* offset) { // short-circuit a common case if (offset == intcon(0)) return ptr; - return _gvn.transform( new (C) AddPNode(base, ptr, offset) ); + return _gvn.transform( new AddPNode(base, ptr, offset) ); } Node* GraphKit::ConvI2L(Node* offset) { @@ -1127,7 +1126,7 @@ if (offset_con != Type::OffsetBot) { return longcon((jlong) offset_con); } - return _gvn.transform( new (C) ConvI2LNode(offset)); + return _gvn.transform( new ConvI2LNode(offset)); } Node* GraphKit::ConvI2UL(Node* offset) { @@ -1135,9 +1134,9 @@ if (offset_con != (juint) Type::OffsetBot) { return longcon((julong) offset_con); } - Node* conv = _gvn.transform( new (C) ConvI2LNode(offset)); + Node* conv = _gvn.transform( new ConvI2LNode(offset)); Node* mask = _gvn.transform( ConLNode::make(C, (julong) max_juint) ); - return _gvn.transform( new (C) AndLNode(conv, mask) ); + return _gvn.transform( new AndLNode(conv, mask) ); } Node* GraphKit::ConvL2I(Node* offset) { @@ -1146,7 +1145,7 @@ if (offset_con != (jlong)Type::OffsetBot) { return intcon((int) offset_con); } - return _gvn.transform( new (C) ConvL2INode(offset)); + return _gvn.transform( new ConvL2INode(offset)); } //-------------------------load_object_klass----------------------------------- @@ -1165,7 +1164,7 @@ Node *alen; if (alloc == NULL) { Node *r_adr = basic_plus_adr(array, arrayOopDesc::length_offset_in_bytes()); - alen = _gvn.transform( new (C) LoadRangeNode(0, immutable_memory(), r_adr, TypeInt::POS)); + alen = _gvn.transform( new LoadRangeNode(0, immutable_memory(), r_adr, TypeInt::POS)); } else { alen = alloc->Ideal_length(); Node* ccast = alloc->make_ideal_length(_gvn.type(array)->is_oopptr(), &_gvn); @@ -1199,8 +1198,8 @@ // Construct NULL check Node *chk = NULL; switch(type) { - case T_LONG : chk = new (C) CmpLNode(value, _gvn.zerocon(T_LONG)); break; - case T_INT : chk = new (C) CmpINode(value, _gvn.intcon(0)); break; + case T_LONG : chk = new CmpLNode(value, _gvn.zerocon(T_LONG)); break; + case T_INT : chk = new CmpINode(value, _gvn.intcon(0)); break; case T_ARRAY : // fall through type = T_OBJECT; // simplify further tests case T_OBJECT : { @@ -1247,7 +1246,7 @@ return value; // Elided null check quickly! } } - chk = new (C) CmpPNode( value, null() ); + chk = new CmpPNode( value, null() ); break; } @@ -1258,7 +1257,7 @@ chk = _gvn.transform(chk); BoolTest::mask btest = assert_null ? BoolTest::eq : BoolTest::ne; - BoolNode *btst = new (C) BoolNode( chk, btest); + BoolNode *btst = new BoolNode( chk, btest); Node *tst = _gvn.transform( btst ); //----------- @@ -1325,8 +1324,8 @@ if (null_control != NULL) { IfNode* iff = create_and_map_if(control(), tst, ok_prob, COUNT_UNKNOWN); - Node* null_true = _gvn.transform( new (C) IfFalseNode(iff)); - set_control( _gvn.transform( new (C) IfTrueNode(iff))); + Node* null_true = _gvn.transform( new IfFalseNode(iff)); + set_control( _gvn.transform( new IfTrueNode(iff))); if (null_true == top()) explicit_null_checks_elided++; (*null_control) = null_true; @@ -1378,7 +1377,7 @@ // Object is already not-null? if( t == t_not_null ) return obj; - Node *cast = new (C) CastPPNode(obj,t_not_null); + Node *cast = new CastPPNode(obj,t_not_null); cast->init_req(0, control()); cast = _gvn.transform( cast ); @@ -1403,60 +1402,17 @@ // on the map. This includes locals, stack, and monitors // of the current (innermost) JVM state. - if (!ReplaceInParentMaps) { - return; - } - - // PreserveJVMState doesn't do a deep copy so we can't modify - // parents - if (Compile::current()->has_preserve_jvm_state()) { + // don't let inconsistent types from profiling escape this + // method + + const Type* told = _gvn.type(old); + const Type* tnew = _gvn.type(neww); + + if (!tnew->higher_equal(told)) { return; } - Parse* parser = is_Parse(); - bool progress = true; - Node* ctrl = map()->in(0); - // Follow the chain of parsers and see whether the update can be - // done in the map of callers. We can do the replace for a caller if - // the current control post dominates the control of a caller. - while (parser != NULL && parser->caller() != NULL && progress) { - progress = false; - Node* parent_map = parser->caller()->map(); - assert(parser->exits().map()->jvms()->depth() == parser->caller()->depth(), "map mismatch"); - - Node* parent_ctrl = parent_map->in(0); - - while (parent_ctrl->is_Region()) { - Node* n = parent_ctrl->as_Region()->is_copy(); - if (n == NULL) { - break; - } - parent_ctrl = n; - } - - for (;;) { - if (ctrl == parent_ctrl) { - // update the map of the exits which is the one that will be - // used when compilation resume after inlining - parser->exits().map()->replace_edge(old, neww); - progress = true; - break; - } - if (ctrl->is_Proj() && ctrl->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none)) { - ctrl = ctrl->in(0)->in(0); - } else if (ctrl->is_Region()) { - Node* n = ctrl->as_Region()->is_copy(); - if (n == NULL) { - break; - } - ctrl = n; - } else { - break; - } - } - - parser = parser->parent_parser(); - } + map()->record_replaced_node(old, neww); } @@ -1486,7 +1442,7 @@ //------------------------------set_all_memory_call---------------------------- void GraphKit::set_all_memory_call(Node* call, bool separate_io_proj) { - Node* newmem = _gvn.transform( new (C) ProjNode(call, TypeFunc::Memory, separate_io_proj) ); + Node* newmem = _gvn.transform( new ProjNode(call, TypeFunc::Memory, separate_io_proj) ); set_all_memory(newmem); } @@ -1721,9 +1677,9 @@ int index_max = max_jint - 1; // array size is max_jint, index is one less if (sizetype != NULL) index_max = sizetype->_hi - 1; const TypeLong* lidxtype = TypeLong::make(CONST64(0), index_max, Type::WidenMax); - idx = _gvn.transform( new (C) ConvI2LNode(idx, lidxtype) ); + idx = _gvn.transform( new ConvI2LNode(idx, lidxtype) ); #endif - Node* scale = _gvn.transform( new (C) LShiftXNode(idx, intcon(shift)) ); + Node* scale = _gvn.transform( new LShiftXNode(idx, intcon(shift)) ); return basic_plus_adr(ary, base, scale); } @@ -1771,8 +1727,8 @@ // Re-use the current map to produce the result. - set_control(_gvn.transform(new (C) ProjNode(call, TypeFunc::Control))); - set_i_o( _gvn.transform(new (C) ProjNode(call, TypeFunc::I_O , separate_io_proj))); + set_control(_gvn.transform(new ProjNode(call, TypeFunc::Control))); + set_i_o( _gvn.transform(new ProjNode(call, TypeFunc::I_O , separate_io_proj))); set_all_memory_call(xcall, separate_io_proj); //return xcall; // no need, caller already has it @@ -1786,7 +1742,7 @@ if (call->method() == NULL || call->method()->return_type()->basic_type() == T_VOID) ret = top(); - else ret = _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms)); + else ret = _gvn.transform(new ProjNode(call, TypeFunc::Parms)); // Note: Since any out-of-line call can produce an exception, // we always insert an I_O projection from the call into the result. @@ -1797,8 +1753,8 @@ // The caller requested separate projections be used by the fall // through and exceptional paths, so replace the projections for // the fall through path. - set_i_o(_gvn.transform( new (C) ProjNode(call, TypeFunc::I_O) )); - set_all_memory(_gvn.transform( new (C) ProjNode(call, TypeFunc::Memory) )); + set_i_o(_gvn.transform( new ProjNode(call, TypeFunc::I_O) )); + set_all_memory(_gvn.transform( new ProjNode(call, TypeFunc::Memory) )); } return ret; } @@ -1838,13 +1794,13 @@ Node* keep_mem, const TypePtr* hook_mem) { // no i/o - set_control(_gvn.transform( new (C) ProjNode(call,TypeFunc::Control) )); + set_control(_gvn.transform( new ProjNode(call,TypeFunc::Control) )); if (keep_mem) { // First clone the existing memory state set_all_memory(keep_mem); if (hook_mem != NULL) { // Make memory for the call - Node* mem = _gvn.transform( new (C) ProjNode(call, TypeFunc::Memory) ); + Node* mem = _gvn.transform( new ProjNode(call, TypeFunc::Memory) ); // Set the RawPtr memory state only. This covers all the heap top/GC stuff // We also use hook_mem to extract specific effects from arraycopy stubs. set_memory(mem, hook_mem); @@ -1864,12 +1820,16 @@ // Replace the call with the current state of the kit. -void GraphKit::replace_call(CallNode* call, Node* result) { +void GraphKit::replace_call(CallNode* call, Node* result, bool do_replaced_nodes) { JVMState* ejvms = NULL; if (has_exceptions()) { ejvms = transfer_exceptions_into_jvms(); } + ReplacedNodes replaced_nodes = map()->replaced_nodes(); + ReplacedNodes replaced_nodes_exception; + Node* ex_ctl = top(); + SafePointNode* final_state = stop(); // Find all the needed outputs of this call @@ -1886,6 +1846,10 @@ C->gvn_replace_by(callprojs.fallthrough_catchproj, final_ctl); } if (callprojs.fallthrough_memproj != NULL) { + if (final_mem->is_MergeMem()) { + // Parser's exits MergeMem was not transformed but may be optimized + final_mem = _gvn.transform(final_mem); + } C->gvn_replace_by(callprojs.fallthrough_memproj, final_mem); } if (callprojs.fallthrough_ioproj != NULL) { @@ -1917,10 +1881,13 @@ // Load my combined exception state into the kit, with all phis transformed: SafePointNode* ex_map = ekit.combine_and_pop_all_exception_states(); + replaced_nodes_exception = ex_map->replaced_nodes(); Node* ex_oop = ekit.use_exception_state(ex_map); + if (callprojs.catchall_catchproj != NULL) { C->gvn_replace_by(callprojs.catchall_catchproj, ekit.control()); + ex_ctl = ekit.control(); } if (callprojs.catchall_memproj != NULL) { C->gvn_replace_by(callprojs.catchall_memproj, ekit.reset_memory()); @@ -1953,6 +1920,13 @@ _gvn.transform(wl.pop()); } } + + if (callprojs.fallthrough_catchproj != NULL && !final_ctl->is_top() && do_replaced_nodes) { + replaced_nodes.apply(C, final_ctl); + } + if (!ex_ctl->is_top() && do_replaced_nodes) { + replaced_nodes_exception.apply(C, ex_ctl); + } } @@ -1968,7 +1942,7 @@ int adr_type = Compile::AliasIdxRaw; Node* ctrl = control(); Node* cnt = make_load(ctrl, counter_addr, TypeInt::INT, T_INT, adr_type, MemNode::unordered); - Node* incr = _gvn.transform(new (C) AddINode(cnt, _gvn.intcon(1))); + Node* incr = _gvn.transform(new AddINode(cnt, _gvn.intcon(1))); store_to_memory(ctrl, counter_addr, incr, T_INT, adr_type, MemNode::unordered); } @@ -2087,7 +2061,7 @@ // The debug info is the only real input to this call. // Halt-and-catch fire here. The above call should never return! - HaltNode* halt = new(C) HaltNode(control(), frameptr()); + HaltNode* halt = new HaltNode(control(), frameptr()); _gvn.set_type_bottom(halt); root()->add_req(halt); @@ -2169,7 +2143,7 @@ // the new type. The new type depends on the control: what // profiling tells us is only valid from here as far as we can // tell. - Node* cast = new(C) CheckCastPPNode(control(), n, current_type->remove_speculative()->join_speculative(spec_type)); + Node* cast = new CheckCastPPNode(control(), n, current_type->remove_speculative()->join_speculative(spec_type)); cast = _gvn.transform(cast); replace_in_map(n, cast); n = cast; @@ -2287,7 +2261,7 @@ Node* GraphKit::precision_rounding(Node* n) { return UseStrictFP && _method->flags().is_strict() && UseSSE == 0 && Matcher::strict_fp_requires_explicit_rounding - ? _gvn.transform( new (C) RoundFloatNode(0, n) ) + ? _gvn.transform( new RoundFloatNode(0, n) ) : n; } @@ -2295,7 +2269,7 @@ Node* GraphKit::dprecision_rounding(Node *n) { return UseStrictFP && _method->flags().is_strict() && UseSSE <= 1 && Matcher::strict_fp_requires_explicit_rounding - ? _gvn.transform( new (C) RoundDoubleNode(0, n) ) + ? _gvn.transform( new RoundDoubleNode(0, n) ) : n; } @@ -2303,7 +2277,7 @@ Node* GraphKit::dstore_rounding(Node* n) { return Matcher::strict_fp_requires_explicit_rounding && UseSSE <= 1 - ? _gvn.transform( new (C) RoundDoubleNode(0, n) ) + ? _gvn.transform( new RoundDoubleNode(0, n) ) : n; } @@ -2382,11 +2356,11 @@ IfNode *opt_iff = _gvn.transform(iff)->as_If(); // Fast path taken; set region slot 2 - Node *fast_taken = _gvn.transform( new (C) IfFalseNode(opt_iff) ); + Node *fast_taken = _gvn.transform( new IfFalseNode(opt_iff) ); region->init_req(2,fast_taken); // Capture fast-control // Fast path not-taken, i.e. slow path - Node *slow_taken = _gvn.transform( new (C) IfTrueNode(opt_iff) ); + Node *slow_taken = _gvn.transform( new IfTrueNode(opt_iff) ); return slow_taken; } @@ -2410,12 +2384,12 @@ } CallNode* call; if (!is_leaf) { - call = new(C) CallStaticJavaNode(call_type, call_addr, call_name, + call = new CallStaticJavaNode(call_type, call_addr, call_name, bci(), adr_type); } else if (flags & RC_NO_FP) { - call = new(C) CallLeafNoFPNode(call_type, call_addr, call_name, adr_type); + call = new CallLeafNoFPNode(call_type, call_addr, call_name, adr_type); } else { - call = new(C) CallLeafNode(call_type, call_addr, call_name, adr_type); + call = new CallLeafNode(call_type, call_addr, call_name, adr_type); } // The following is similar to set_edges_for_java_call, @@ -2476,7 +2450,7 @@ } if (has_io) { - set_i_o(_gvn.transform(new (C) ProjNode(call, TypeFunc::I_O))); + set_i_o(_gvn.transform(new ProjNode(call, TypeFunc::I_O))); } return call; @@ -2490,48 +2464,55 @@ Node* new_slice = mms.memory2(); if (old_slice != new_slice) { PhiNode* phi; - if (new_slice->is_Phi() && new_slice->as_Phi()->region() == region) { - phi = new_slice->as_Phi(); - #ifdef ASSERT - if (old_slice->is_Phi() && old_slice->as_Phi()->region() == region) - old_slice = old_slice->in(new_path); - // Caller is responsible for ensuring that any pre-existing - // phis are already aware of old memory. - int old_path = (new_path > 1) ? 1 : 2; // choose old_path != new_path - assert(phi->in(old_path) == old_slice, "pre-existing phis OK"); - #endif - mms.set_memory(phi); + if (old_slice->is_Phi() && old_slice->as_Phi()->region() == region) { + if (mms.is_empty()) { + // clone base memory Phi's inputs for this memory slice + assert(old_slice == mms.base_memory(), "sanity"); + phi = PhiNode::make(region, NULL, Type::MEMORY, mms.adr_type(C)); + _gvn.set_type(phi, Type::MEMORY); + for (uint i = 1; i < phi->req(); i++) { + phi->init_req(i, old_slice->in(i)); + } + } else { + phi = old_slice->as_Phi(); // Phi was generated already + } } else { phi = PhiNode::make(region, old_slice, Type::MEMORY, mms.adr_type(C)); _gvn.set_type(phi, Type::MEMORY); - phi->set_req(new_path, new_slice); - mms.set_memory(_gvn.transform(phi)); // assume it is complete } + phi->set_req(new_path, new_slice); + mms.set_memory(phi); } } } //------------------------------make_slow_call_ex------------------------------ // Make the exception handler hookups for the slow call -void GraphKit::make_slow_call_ex(Node* call, ciInstanceKlass* ex_klass, bool separate_io_proj) { +void GraphKit::make_slow_call_ex(Node* call, ciInstanceKlass* ex_klass, bool separate_io_proj, bool deoptimize) { if (stopped()) return; // Make a catch node with just two handlers: fall-through and catch-all - Node* i_o = _gvn.transform( new (C) ProjNode(call, TypeFunc::I_O, separate_io_proj) ); - Node* catc = _gvn.transform( new (C) CatchNode(control(), i_o, 2) ); - Node* norm = _gvn.transform( new (C) CatchProjNode(catc, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci) ); - Node* excp = _gvn.transform( new (C) CatchProjNode(catc, CatchProjNode::catch_all_index, CatchProjNode::no_handler_bci) ); + Node* i_o = _gvn.transform( new ProjNode(call, TypeFunc::I_O, separate_io_proj) ); + Node* catc = _gvn.transform( new CatchNode(control(), i_o, 2) ); + Node* norm = _gvn.transform( new CatchProjNode(catc, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci) ); + Node* excp = _gvn.transform( new CatchProjNode(catc, CatchProjNode::catch_all_index, CatchProjNode::no_handler_bci) ); { PreserveJVMState pjvms(this); set_control(excp); set_i_o(i_o); if (excp != top()) { - // Create an exception state also. - // Use an exact type if the caller has specified a specific exception. - const Type* ex_type = TypeOopPtr::make_from_klass_unique(ex_klass)->cast_to_ptr_type(TypePtr::NotNull); - Node* ex_oop = new (C) CreateExNode(ex_type, control(), i_o); - add_exception_state(make_exception_state(_gvn.transform(ex_oop))); + if (deoptimize) { + // Deoptimize if an exception is caught. Don't construct exception state in this case. + uncommon_trap(Deoptimization::Reason_unhandled, + Deoptimization::Action_none); + } else { + // Create an exception state also. + // Use an exact type if the caller has specified a specific exception. + const Type* ex_type = TypeOopPtr::make_from_klass_unique(ex_klass)->cast_to_ptr_type(TypePtr::NotNull); + Node* ex_oop = new CreateExNode(ex_type, control(), i_o); + add_exception_state(make_exception_state(_gvn.transform(ex_oop))); + } } } @@ -2580,11 +2561,11 @@ case SSC_easy_test: { // Just do a direct pointer compare and be done. - Node* cmp = _gvn.transform( new(C) CmpPNode(subklass, superklass) ); - Node* bol = _gvn.transform( new(C) BoolNode(cmp, BoolTest::eq) ); + Node* cmp = _gvn.transform( new CmpPNode(subklass, superklass) ); + Node* bol = _gvn.transform( new BoolNode(cmp, BoolTest::eq) ); IfNode* iff = create_and_xform_if(control(), bol, PROB_STATIC_FREQUENT, COUNT_UNKNOWN); - set_control( _gvn.transform( new(C) IfTrueNode (iff) ) ); - return _gvn.transform( new(C) IfFalseNode(iff) ); + set_control( _gvn.transform( new IfTrueNode (iff) ) ); + return _gvn.transform( new IfFalseNode(iff) ); } case SSC_full_test: break; @@ -2599,7 +2580,7 @@ // First load the super-klass's check-offset Node *p1 = basic_plus_adr( superklass, superklass, in_bytes(Klass::super_check_offset_offset()) ); - Node *chk_off = _gvn.transform(new (C) LoadINode(NULL, memory(p1), p1, _gvn.type(p1)->is_ptr(), + Node *chk_off = _gvn.transform(new LoadINode(NULL, memory(p1), p1, _gvn.type(p1)->is_ptr(), TypeInt::INT, MemNode::unordered)); int cacheoff_con = in_bytes(Klass::secondary_super_cache_offset()); bool might_be_cache = (find_int_con(chk_off, cacheoff_con) == cacheoff_con); @@ -2611,7 +2592,7 @@ // Worst-case type is a little odd: NULL is allowed as a result (usually // klass loads can never produce a NULL). Node *chk_off_X = ConvI2X(chk_off); - Node *p2 = _gvn.transform( new (C) AddPNode(subklass,subklass,chk_off_X) ); + Node *p2 = _gvn.transform( new AddPNode(subklass,subklass,chk_off_X) ); // For some types like interfaces the following loadKlass is from a 1-word // cache which is mutable so can't use immutable memory. Other // types load from the super-class display table which is immutable. @@ -2625,11 +2606,11 @@ // See if we get an immediate positive hit. Happens roughly 83% of the // time. Test to see if the value loaded just previously from the subklass // is exactly the superklass. - Node *cmp1 = _gvn.transform( new (C) CmpPNode( superklass, nkls ) ); - Node *bol1 = _gvn.transform( new (C) BoolNode( cmp1, BoolTest::eq ) ); + Node *cmp1 = _gvn.transform( new CmpPNode( superklass, nkls ) ); + Node *bol1 = _gvn.transform( new BoolNode( cmp1, BoolTest::eq ) ); IfNode *iff1 = create_and_xform_if( control(), bol1, PROB_LIKELY(0.83f), COUNT_UNKNOWN ); - Node *iftrue1 = _gvn.transform( new (C) IfTrueNode ( iff1 ) ); - set_control( _gvn.transform( new (C) IfFalseNode( iff1 ) ) ); + Node *iftrue1 = _gvn.transform( new IfTrueNode ( iff1 ) ); + set_control( _gvn.transform( new IfFalseNode( iff1 ) ) ); // Compile speed common case: Check for being deterministic right now. If // chk_off is a constant and not equal to cacheoff then we are NOT a @@ -2642,9 +2623,9 @@ } // Gather the various success & failures here - RegionNode *r_ok_subtype = new (C) RegionNode(4); + RegionNode *r_ok_subtype = new RegionNode(4); record_for_igvn(r_ok_subtype); - RegionNode *r_not_subtype = new (C) RegionNode(3); + RegionNode *r_not_subtype = new RegionNode(3); record_for_igvn(r_not_subtype); r_ok_subtype->init_req(1, iftrue1); @@ -2655,20 +2636,20 @@ // cache. If it points to the display (and NOT the cache) and the display // missed then it's not a subtype. Node *cacheoff = _gvn.intcon(cacheoff_con); - Node *cmp2 = _gvn.transform( new (C) CmpINode( chk_off, cacheoff ) ); - Node *bol2 = _gvn.transform( new (C) BoolNode( cmp2, BoolTest::ne ) ); + Node *cmp2 = _gvn.transform( new CmpINode( chk_off, cacheoff ) ); + Node *bol2 = _gvn.transform( new BoolNode( cmp2, BoolTest::ne ) ); IfNode *iff2 = create_and_xform_if( control(), bol2, PROB_LIKELY(0.63f), COUNT_UNKNOWN ); - r_not_subtype->init_req(1, _gvn.transform( new (C) IfTrueNode (iff2) ) ); - set_control( _gvn.transform( new (C) IfFalseNode(iff2) ) ); + r_not_subtype->init_req(1, _gvn.transform( new IfTrueNode (iff2) ) ); + set_control( _gvn.transform( new IfFalseNode(iff2) ) ); // Check for self. Very rare to get here, but it is taken 1/3 the time. // No performance impact (too rare) but allows sharing of secondary arrays // which has some footprint reduction. - Node *cmp3 = _gvn.transform( new (C) CmpPNode( subklass, superklass ) ); - Node *bol3 = _gvn.transform( new (C) BoolNode( cmp3, BoolTest::eq ) ); + Node *cmp3 = _gvn.transform( new CmpPNode( subklass, superklass ) ); + Node *bol3 = _gvn.transform( new BoolNode( cmp3, BoolTest::eq ) ); IfNode *iff3 = create_and_xform_if( control(), bol3, PROB_LIKELY(0.36f), COUNT_UNKNOWN ); - r_ok_subtype->init_req(2, _gvn.transform( new (C) IfTrueNode ( iff3 ) ) ); - set_control( _gvn.transform( new (C) IfFalseNode( iff3 ) ) ); + r_ok_subtype->init_req(2, _gvn.transform( new IfTrueNode ( iff3 ) ) ); + set_control( _gvn.transform( new IfFalseNode( iff3 ) ) ); // -- Roads not taken here: -- // We could also have chosen to perform the self-check at the beginning @@ -2692,13 +2673,13 @@ // The decision to inline or out-of-line this final check is platform // dependent, and is found in the AD file definition of PartialSubtypeCheck. Node* psc = _gvn.transform( - new (C) PartialSubtypeCheckNode(control(), subklass, superklass) ); - - Node *cmp4 = _gvn.transform( new (C) CmpPNode( psc, null() ) ); - Node *bol4 = _gvn.transform( new (C) BoolNode( cmp4, BoolTest::ne ) ); + new PartialSubtypeCheckNode(control(), subklass, superklass) ); + + Node *cmp4 = _gvn.transform( new CmpPNode( psc, null() ) ); + Node *bol4 = _gvn.transform( new BoolNode( cmp4, BoolTest::ne ) ); IfNode *iff4 = create_and_xform_if( control(), bol4, PROB_FAIR, COUNT_UNKNOWN ); - r_not_subtype->init_req(2, _gvn.transform( new (C) IfTrueNode (iff4) ) ); - r_ok_subtype ->init_req(3, _gvn.transform( new (C) IfFalseNode(iff4) ) ); + r_not_subtype->init_req(2, _gvn.transform( new IfTrueNode (iff4) ) ); + r_ok_subtype ->init_req(3, _gvn.transform( new IfFalseNode(iff4) ) ); // Return false path; set default control to true path. set_control( _gvn.transform(r_ok_subtype) ); @@ -2762,18 +2743,18 @@ const TypeKlassPtr* tklass = TypeKlassPtr::make(klass); Node* recv_klass = load_object_klass(receiver); Node* want_klass = makecon(tklass); - Node* cmp = _gvn.transform( new(C) CmpPNode(recv_klass, want_klass) ); - Node* bol = _gvn.transform( new(C) BoolNode(cmp, BoolTest::eq) ); + Node* cmp = _gvn.transform( new CmpPNode(recv_klass, want_klass) ); + Node* bol = _gvn.transform( new BoolNode(cmp, BoolTest::eq) ); IfNode* iff = create_and_xform_if(control(), bol, prob, COUNT_UNKNOWN); - set_control( _gvn.transform( new(C) IfTrueNode (iff) )); - Node* fail = _gvn.transform( new(C) IfFalseNode(iff) ); + set_control( _gvn.transform( new IfTrueNode (iff) )); + Node* fail = _gvn.transform( new IfFalseNode(iff) ); const TypeOopPtr* recv_xtype = tklass->as_instance_type(); assert(recv_xtype->klass_is_exact(), ""); // Subsume downstream occurrences of receiver with a cast to // recv_xtype, since now we know what the type will be. - Node* cast = new(C) CheckCastPPNode(control(), receiver, recv_xtype); + Node* cast = new CheckCastPPNode(control(), receiver, recv_xtype); (*casted_receiver) = _gvn.transform(cast); // (User must make the replace_in_map call.) @@ -2920,8 +2901,8 @@ // Make the merge point enum { _obj_path = 1, _fail_path, _null_path, PATH_LIMIT }; - RegionNode* region = new(C) RegionNode(PATH_LIMIT); - Node* phi = new(C) PhiNode(region, TypeInt::BOOL); + RegionNode* region = new RegionNode(PATH_LIMIT); + Node* phi = new PhiNode(region, TypeInt::BOOL); C->set_has_split_ifs(true); // Has chance for split-if optimization ciProfileData* data = NULL; @@ -3052,8 +3033,8 @@ // Make the merge point enum { _obj_path = 1, _null_path, PATH_LIMIT }; - RegionNode* region = new (C) RegionNode(PATH_LIMIT); - Node* phi = new (C) PhiNode(region, toop); + RegionNode* region = new RegionNode(PATH_LIMIT); + Node* phi = new PhiNode(region, toop); C->set_has_split_ifs(true); // Has chance for split-if optimization // Use null-cast information if it is available @@ -3114,8 +3095,7 @@ Node* not_subtype_ctrl = gen_subtype_check( obj_klass, superklass ); // Plug in success path into the merge - cast_obj = _gvn.transform(new (C) CheckCastPPNode(control(), - not_null_obj, toop)); + cast_obj = _gvn.transform(new CheckCastPPNode(control(), not_null_obj, toop)); // Failure path ends in uncommon trap (or may be dead - failure impossible) if (failure_control == NULL) { if (not_subtype_ctrl != top()) { // If failure is possible @@ -3168,7 +3148,7 @@ mb->init_req(TypeFunc::Control, control()); mb->init_req(TypeFunc::Memory, reset_memory()); Node* membar = _gvn.transform(mb); - set_control(_gvn.transform(new (C) ProjNode(membar, TypeFunc::Control))); + set_control(_gvn.transform(new ProjNode(membar, TypeFunc::Control))); set_all_memory_call(membar); return membar; } @@ -3197,11 +3177,11 @@ mb->set_req(TypeFunc::Memory, memory(alias_idx)); } Node* membar = _gvn.transform(mb); - set_control(_gvn.transform(new (C) ProjNode(membar, TypeFunc::Control))); + set_control(_gvn.transform(new ProjNode(membar, TypeFunc::Control))); if (alias_idx == Compile::AliasIdxBot) { - merged_memory()->set_base_memory(_gvn.transform(new (C) ProjNode(membar, TypeFunc::Memory))); + merged_memory()->set_base_memory(_gvn.transform(new ProjNode(membar, TypeFunc::Memory))); } else { - set_memory(_gvn.transform(new (C) ProjNode(membar, TypeFunc::Memory)),alias_idx); + set_memory(_gvn.transform(new ProjNode(membar, TypeFunc::Memory)),alias_idx); } return membar; } @@ -3221,10 +3201,10 @@ assert(dead_locals_are_killed(), "should kill locals before sync. point"); // Box the stack location - Node* box = _gvn.transform(new (C) BoxLockNode(next_monitor())); + Node* box = _gvn.transform(new BoxLockNode(next_monitor())); Node* mem = reset_memory(); - FastLockNode * flock = _gvn.transform(new (C) FastLockNode(0, obj, box) )->as_FastLock(); + FastLockNode * flock = _gvn.transform(new FastLockNode(0, obj, box) )->as_FastLock(); if (UseBiasedLocking && PrintPreciseBiasedLockingStatistics) { // Create the counters for this fast lock. flock->create_lock_counter(sync_jvms()); // sync_jvms used to get current bci @@ -3238,7 +3218,7 @@ map()->push_monitor( flock ); const TypeFunc *tf = LockNode::lock_type(); - LockNode *lock = new (C) LockNode(C, tf); + LockNode *lock = new LockNode(C, tf); lock->init_req( TypeFunc::Control, control() ); lock->init_req( TypeFunc::Memory , mem ); @@ -3292,7 +3272,7 @@ insert_mem_bar(Op_MemBarReleaseLock); const TypeFunc *tf = OptoRuntime::complete_monitor_exit_Type(); - UnlockNode *unlock = new (C) UnlockNode(C, tf); + UnlockNode *unlock = new UnlockNode(C, tf); uint raw_idx = Compile::AliasIdxRaw; unlock->init_req( TypeFunc::Control, control() ); unlock->init_req( TypeFunc::Memory , memory(raw_idx) ); @@ -3353,24 +3333,25 @@ //---------------------------set_output_for_allocation------------------------- Node* GraphKit::set_output_for_allocation(AllocateNode* alloc, - const TypeOopPtr* oop_type) { + const TypeOopPtr* oop_type, + bool deoptimize_on_exception) { int rawidx = Compile::AliasIdxRaw; alloc->set_req( TypeFunc::FramePtr, frameptr() ); add_safepoint_edges(alloc); Node* allocx = _gvn.transform(alloc); - set_control( _gvn.transform(new (C) ProjNode(allocx, TypeFunc::Control) ) ); + set_control( _gvn.transform(new ProjNode(allocx, TypeFunc::Control) ) ); // create memory projection for i_o - set_memory ( _gvn.transform( new (C) ProjNode(allocx, TypeFunc::Memory, true) ), rawidx ); - make_slow_call_ex(allocx, env()->Throwable_klass(), true); + set_memory ( _gvn.transform( new ProjNode(allocx, TypeFunc::Memory, true) ), rawidx ); + make_slow_call_ex(allocx, env()->Throwable_klass(), true, deoptimize_on_exception); // create a memory projection as for the normal control path - Node* malloc = _gvn.transform(new (C) ProjNode(allocx, TypeFunc::Memory)); + Node* malloc = _gvn.transform(new ProjNode(allocx, TypeFunc::Memory)); set_memory(malloc, rawidx); // a normal slow-call doesn't change i_o, but an allocation does // we create a separate i_o projection for the normal control path - set_i_o(_gvn.transform( new (C) ProjNode(allocx, TypeFunc::I_O, false) ) ); - Node* rawoop = _gvn.transform( new (C) ProjNode(allocx, TypeFunc::Parms) ); + set_i_o(_gvn.transform( new ProjNode(allocx, TypeFunc::I_O, false) ) ); + Node* rawoop = _gvn.transform( new ProjNode(allocx, TypeFunc::Parms) ); // put in an initialization barrier InitializeNode* init = insert_mem_bar_volatile(Op_Initialize, rawidx, @@ -3406,7 +3387,7 @@ } // Cast raw oop to the real thing... - Node* javaoop = new (C) CheckCastPPNode(control(), rawoop, oop_type); + Node* javaoop = new CheckCastPPNode(control(), rawoop, oop_type); javaoop = _gvn.transform(javaoop); C->set_recent_alloc(control(), javaoop); assert(just_allocated_object(control()) == javaoop, "just allocated"); @@ -3439,9 +3420,11 @@ // The optional arguments are for specialized use by intrinsics: // - If 'extra_slow_test' if not null is an extra condition for the slow-path. // - If 'return_size_val', report the the total object size to the caller. +// - deoptimize_on_exception controls how Java exceptions are handled (rethrow vs deoptimize) Node* GraphKit::new_instance(Node* klass_node, Node* extra_slow_test, - Node* *return_size_val) { + Node* *return_size_val, + bool deoptimize_on_exception) { // Compute size in doublewords // The size is always an integral number of doublewords, represented // as a positive bytewise size stored in the klass's layout_helper. @@ -3465,9 +3448,9 @@ // (It may be stress-tested by specifying StressReflectiveCode.) // Basically, we want to get into the VM is there's an illegal argument. Node* bit = intcon(Klass::_lh_instance_slow_path_bit); - initial_slow_test = _gvn.transform( new (C) AndINode(layout_val, bit) ); + initial_slow_test = _gvn.transform( new AndINode(layout_val, bit) ); if (extra_slow_test != intcon(0)) { - initial_slow_test = _gvn.transform( new (C) OrINode(initial_slow_test, extra_slow_test) ); + initial_slow_test = _gvn.transform( new OrINode(initial_slow_test, extra_slow_test) ); } // (Macro-expander will further convert this to a Bool, if necessary.) } @@ -3484,7 +3467,7 @@ // Clear the low bits to extract layout_helper_size_in_bytes: assert((int)Klass::_lh_instance_slow_path_bit < BytesPerLong, "clear bit"); Node* mask = MakeConX(~ (intptr_t)right_n_bits(LogBytesPerLong)); - size = _gvn.transform( new (C) AndXNode(size, mask) ); + size = _gvn.transform( new AndXNode(size, mask) ); } if (return_size_val != NULL) { (*return_size_val) = size; @@ -3504,13 +3487,12 @@ Node *mem = reset_memory(); set_all_memory(mem); // Create new memory state - AllocateNode* alloc - = new (C) AllocateNode(C, AllocateNode::alloc_type(Type::TOP), - control(), mem, i_o(), - size, klass_node, - initial_slow_test); - - return set_output_for_allocation(alloc, oop_type); + AllocateNode* alloc = new AllocateNode(C, AllocateNode::alloc_type(Type::TOP), + control(), mem, i_o(), + size, klass_node, + initial_slow_test); + + return set_output_for_allocation(alloc, oop_type, deoptimize_on_exception); } //-------------------------------new_array------------------------------------- @@ -3520,7 +3502,8 @@ Node* GraphKit::new_array(Node* klass_node, // array klass (maybe variable) Node* length, // number of array elements int nargs, // number of arguments to push back for uncommon trap - Node* *return_size_val) { + Node* *return_size_val, + bool deoptimize_on_exception) { jint layout_con = Klass::_lh_neutral_value; Node* layout_val = get_layout_helper(klass_node, layout_con); int layout_is_con = (layout_val == NULL); @@ -3531,8 +3514,8 @@ // Optimistically assume that it is a subtype of Object[], // so that we can fold up all the address arithmetic. layout_con = Klass::array_layout_helper(T_OBJECT); - Node* cmp_lh = _gvn.transform( new(C) CmpINode(layout_val, intcon(layout_con)) ); - Node* bol_lh = _gvn.transform( new(C) BoolNode(cmp_lh, BoolTest::eq) ); + Node* cmp_lh = _gvn.transform( new CmpINode(layout_val, intcon(layout_con)) ); + Node* bol_lh = _gvn.transform( new BoolNode(cmp_lh, BoolTest::eq) ); { BuildCutout unless(this, bol_lh, PROB_MAX); inc_sp(nargs); uncommon_trap(Deoptimization::Reason_class_check, @@ -3556,8 +3539,8 @@ fast_size_limit <<= (LogBytesPerLong - log2_esize); } - Node* initial_slow_cmp = _gvn.transform( new (C) CmpUNode( length, intcon( fast_size_limit ) ) ); - Node* initial_slow_test = _gvn.transform( new (C) BoolNode( initial_slow_cmp, BoolTest::gt ) ); + Node* initial_slow_cmp = _gvn.transform( new CmpUNode( length, intcon( fast_size_limit ) ) ); + Node* initial_slow_test = _gvn.transform( new BoolNode( initial_slow_cmp, BoolTest::gt ) ); if (initial_slow_test->is_Bool()) { // Hide it behind a CMoveI, or else PhaseIdealLoop::split_up will get sick. initial_slow_test = initial_slow_test->as_Bool()->as_int_value(&_gvn); @@ -3585,10 +3568,10 @@ } else { Node* hss = intcon(Klass::_lh_header_size_shift); Node* hsm = intcon(Klass::_lh_header_size_mask); - Node* hsize = _gvn.transform( new(C) URShiftINode(layout_val, hss) ); - hsize = _gvn.transform( new(C) AndINode(hsize, hsm) ); + Node* hsize = _gvn.transform( new URShiftINode(layout_val, hss) ); + hsize = _gvn.transform( new AndINode(hsize, hsm) ); Node* mask = intcon(round_mask); - header_size = _gvn.transform( new(C) AddINode(hsize, mask) ); + header_size = _gvn.transform( new AddINode(hsize, mask) ); } Node* elem_shift = NULL; @@ -3613,7 +3596,7 @@ jlong size_max = arrayOopDesc::max_array_length(T_BYTE); if (size_max > tllen->_hi) size_max = tllen->_hi; const TypeLong* tlcon = TypeLong::make(CONST64(0), size_max, Type::WidenMin); - lengthx = _gvn.transform( new (C) ConvI2LNode(length, tlcon)); + lengthx = _gvn.transform( new ConvI2LNode(length, tlcon)); } } #endif @@ -3624,11 +3607,11 @@ // after a successful allocation. Node* abody = lengthx; if (elem_shift != NULL) - abody = _gvn.transform( new(C) LShiftXNode(lengthx, elem_shift) ); - Node* size = _gvn.transform( new(C) AddXNode(headerx, abody) ); + abody = _gvn.transform( new LShiftXNode(lengthx, elem_shift) ); + Node* size = _gvn.transform( new AddXNode(headerx, abody) ); if (round_mask != 0) { Node* mask = MakeConX(~round_mask); - size = _gvn.transform( new(C) AndXNode(size, mask) ); + size = _gvn.transform( new AndXNode(size, mask) ); } // else if round_mask == 0, the size computation is self-rounding @@ -3646,11 +3629,11 @@ // Create the AllocateArrayNode and its result projections AllocateArrayNode* alloc - = new (C) AllocateArrayNode(C, AllocateArrayNode::alloc_type(TypeInt::INT), - control(), mem, i_o(), - size, klass_node, - initial_slow_test, - length); + = new AllocateArrayNode(C, AllocateArrayNode::alloc_type(TypeInt::INT), + control(), mem, i_o(), + size, klass_node, + initial_slow_test, + length); // Cast to correct type. Note that the klass_node may be constant or not, // and in the latter case the actual array type will be inexact also. @@ -3663,7 +3646,7 @@ ary_type = ary_type->is_aryptr()->cast_to_size(length_type); } - Node* javaoop = set_output_for_allocation(alloc, ary_type); + Node* javaoop = set_output_for_allocation(alloc, ary_type, deoptimize_on_exception); // Cast length on remaining path to be as narrow as possible if (map()->find_edge(length) >= 0) { @@ -3760,10 +3743,10 @@ } Node *cont = _gvn.intcon(1); - Node* opq = _gvn.transform(new (C) Opaque1Node(C, cont)); - Node *bol = _gvn.transform(new (C) Conv2BNode(opq)); + Node* opq = _gvn.transform(new Opaque1Node(C, cont)); + Node *bol = _gvn.transform(new Conv2BNode(opq)); IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN); - Node* iffalse = _gvn.transform(new (C) IfFalseNode(iff)); + Node* iffalse = _gvn.transform(new IfFalseNode(iff)); C->add_predicate_opaq(opq); { PreserveJVMState pjvms(this); @@ -3771,7 +3754,7 @@ inc_sp(nargs); uncommon_trap(reason, Deoptimization::Action_maybe_recompile); } - Node* iftrue = _gvn.transform(new (C) IfTrueNode(iff)); + Node* iftrue = _gvn.transform(new IfTrueNode(iff)); set_control(iftrue); } @@ -3963,7 +3946,7 @@ __ if_then(index, BoolTest::ne, zeroX, likely); { // decrement the index - Node* next_index = _gvn.transform(new (C) SubXNode(index, __ ConX(sizeof(intptr_t)))); + Node* next_index = _gvn.transform(new SubXNode(index, __ ConX(sizeof(intptr_t)))); // Now get the buffer location we will log the previous value into and store it Node *log_addr = __ AddP(no_base, buffer, next_index); @@ -4006,7 +3989,7 @@ // Now do the queue work __ if_then(index, BoolTest::ne, zeroX); { - Node* next_index = _gvn.transform(new (C) SubXNode(index, __ ConX(sizeof(intptr_t)))); + Node* next_index = _gvn.transform(new SubXNode(index, __ ConX(sizeof(intptr_t)))); Node* log_addr = __ AddP(no_base, buffer, next_index); // Order, see storeCM. @@ -4213,5 +4196,5 @@ Node* GraphKit::cast_array_to_stable(Node* ary, const TypeAryPtr* ary_type) { // Reify the property as a CastPP node in Ideal graph to comply with monotonicity // assumption of CCP analysis. - return _gvn.transform(new(C) CastPPNode(ary, ary_type->cast_to_stable(true))); + return _gvn.transform(new CastPPNode(ary, ary_type->cast_to_stable(true))); } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/graphKit.hpp --- a/hotspot/src/share/vm/opto/graphKit.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/graphKit.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -309,31 +309,31 @@ // Some convenient shortcuts for common nodes - Node* IfTrue(IfNode* iff) { return _gvn.transform(new (C) IfTrueNode(iff)); } - Node* IfFalse(IfNode* iff) { return _gvn.transform(new (C) IfFalseNode(iff)); } + Node* IfTrue(IfNode* iff) { return _gvn.transform(new IfTrueNode(iff)); } + Node* IfFalse(IfNode* iff) { return _gvn.transform(new IfFalseNode(iff)); } - Node* AddI(Node* l, Node* r) { return _gvn.transform(new (C) AddINode(l, r)); } - Node* SubI(Node* l, Node* r) { return _gvn.transform(new (C) SubINode(l, r)); } - Node* MulI(Node* l, Node* r) { return _gvn.transform(new (C) MulINode(l, r)); } - Node* DivI(Node* ctl, Node* l, Node* r) { return _gvn.transform(new (C) DivINode(ctl, l, r)); } + Node* AddI(Node* l, Node* r) { return _gvn.transform(new AddINode(l, r)); } + Node* SubI(Node* l, Node* r) { return _gvn.transform(new SubINode(l, r)); } + Node* MulI(Node* l, Node* r) { return _gvn.transform(new MulINode(l, r)); } + Node* DivI(Node* ctl, Node* l, Node* r) { return _gvn.transform(new DivINode(ctl, l, r)); } - Node* AndI(Node* l, Node* r) { return _gvn.transform(new (C) AndINode(l, r)); } - Node* OrI(Node* l, Node* r) { return _gvn.transform(new (C) OrINode(l, r)); } - Node* XorI(Node* l, Node* r) { return _gvn.transform(new (C) XorINode(l, r)); } + Node* AndI(Node* l, Node* r) { return _gvn.transform(new AndINode(l, r)); } + Node* OrI(Node* l, Node* r) { return _gvn.transform(new OrINode(l, r)); } + Node* XorI(Node* l, Node* r) { return _gvn.transform(new XorINode(l, r)); } - Node* MaxI(Node* l, Node* r) { return _gvn.transform(new (C) MaxINode(l, r)); } - Node* MinI(Node* l, Node* r) { return _gvn.transform(new (C) MinINode(l, r)); } + Node* MaxI(Node* l, Node* r) { return _gvn.transform(new MaxINode(l, r)); } + Node* MinI(Node* l, Node* r) { return _gvn.transform(new MinINode(l, r)); } - Node* LShiftI(Node* l, Node* r) { return _gvn.transform(new (C) LShiftINode(l, r)); } - Node* RShiftI(Node* l, Node* r) { return _gvn.transform(new (C) RShiftINode(l, r)); } - Node* URShiftI(Node* l, Node* r) { return _gvn.transform(new (C) URShiftINode(l, r)); } + Node* LShiftI(Node* l, Node* r) { return _gvn.transform(new LShiftINode(l, r)); } + Node* RShiftI(Node* l, Node* r) { return _gvn.transform(new RShiftINode(l, r)); } + Node* URShiftI(Node* l, Node* r) { return _gvn.transform(new URShiftINode(l, r)); } - Node* CmpI(Node* l, Node* r) { return _gvn.transform(new (C) CmpINode(l, r)); } - Node* CmpL(Node* l, Node* r) { return _gvn.transform(new (C) CmpLNode(l, r)); } - Node* CmpP(Node* l, Node* r) { return _gvn.transform(new (C) CmpPNode(l, r)); } - Node* Bool(Node* cmp, BoolTest::mask relop) { return _gvn.transform(new (C) BoolNode(cmp, relop)); } + Node* CmpI(Node* l, Node* r) { return _gvn.transform(new CmpINode(l, r)); } + Node* CmpL(Node* l, Node* r) { return _gvn.transform(new CmpLNode(l, r)); } + Node* CmpP(Node* l, Node* r) { return _gvn.transform(new CmpPNode(l, r)); } + Node* Bool(Node* cmp, BoolTest::mask relop) { return _gvn.transform(new BoolNode(cmp, relop)); } - Node* AddP(Node* b, Node* a, Node* o) { return _gvn.transform(new (C) AddPNode(b, a, o)); } + Node* AddP(Node* b, Node* a, Node* o) { return _gvn.transform(new AddPNode(b, a, o)); } // Convert between int and long, and size_t. // (See macros ConvI2X, etc., in type.hpp for ConvI2X, etc.) @@ -690,7 +690,7 @@ // Replace the call with the current state of the kit. Requires // that the call was generated with separate io_projs so that // exceptional control flow can be handled properly. - void replace_call(CallNode* call, Node* result); + void replace_call(CallNode* call, Node* result, bool do_replaced_nodes = false); // helper functions for statistics void increment_counter(address counter_addr); // increment a debug counter @@ -807,7 +807,7 @@ // merge in all memory slices from new_mem, along the given path void merge_memory(Node* new_mem, Node* region, int new_path); - void make_slow_call_ex(Node* call, ciInstanceKlass* ex_klass, bool separate_io_proj); + void make_slow_call_ex(Node* call, ciInstanceKlass* ex_klass, bool separate_io_proj, bool deoptimize = false); // Helper functions to build synchronizations int next_monitor(); @@ -849,13 +849,16 @@ // implementation of object creation Node* set_output_for_allocation(AllocateNode* alloc, - const TypeOopPtr* oop_type); + const TypeOopPtr* oop_type, + bool deoptimize_on_exception=false); Node* get_layout_helper(Node* klass_node, jint& constant_value); Node* new_instance(Node* klass_node, Node* slow_test = NULL, - Node* *return_size_val = NULL); + Node* *return_size_val = NULL, + bool deoptimize_on_exception = false); Node* new_array(Node* klass_node, Node* count_val, int nargs, - Node* *return_size_val = NULL); + Node* *return_size_val = NULL, + bool deoptimize_on_exception = false); // java.lang.String helpers Node* load_String_offset(Node* ctrl, Node* str); @@ -867,7 +870,7 @@ // Handy for making control flow IfNode* create_and_map_if(Node* ctrl, Node* tst, float prob, float cnt) { - IfNode* iff = new (C) IfNode(ctrl, tst, prob, cnt);// New IfNode's + IfNode* iff = new IfNode(ctrl, tst, prob, cnt);// New IfNode's _gvn.set_type(iff, iff->Value(&_gvn)); // Value may be known at parse-time // Place 'if' on worklist if it will be in graph if (!tst->is_Con()) record_for_igvn(iff); // Range-check and Null-check removal is later @@ -875,7 +878,7 @@ } IfNode* create_and_xform_if(Node* ctrl, Node* tst, float prob, float cnt) { - IfNode* iff = new (C) IfNode(ctrl, tst, prob, cnt);// New IfNode's + IfNode* iff = new IfNode(ctrl, tst, prob, cnt);// New IfNode's _gvn.transform(iff); // Value may be known at parse-time // Place 'if' on worklist if it will be in graph if (!tst->is_Con()) record_for_igvn(iff); // Range-check and Null-check removal is later diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/idealKit.cpp --- a/hotspot/src/share/vm/opto/idealKit.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/idealKit.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -86,7 +86,7 @@ } // Delay gvn.tranform on if-nodes until construction is finished // to prevent a constant bool input from discarding a control output. - IfNode* iff = delay_transform(new (C) IfNode(ctrl(), bol, prob, cnt))->as_If(); + IfNode* iff = delay_transform(new IfNode(ctrl(), bol, prob, cnt))->as_If(); Node* then = IfTrue(iff); Node* elsen = IfFalse(iff); Node* else_cvstate = copy_cvstate(); @@ -205,7 +205,7 @@ assert(_cvstate != NULL, "must declare variables before labels"); Node* lab = new_cvstate(); int sz = 1 + goto_ct + 1 /* fall thru */; - Node* reg = delay_transform(new (C) RegionNode(sz)); + Node* reg = delay_transform(new RegionNode(sz)); lab->init_req(TypeFunc::Control, reg); return lab; } @@ -312,7 +312,7 @@ //-----------------------------new_cvstate----------------------------------- Node* IdealKit::new_cvstate() { uint sz = _var_ct + first_var; - return new (C) Node(sz); + return new Node(sz); } //-----------------------------copy_cvstate----------------------------------- @@ -397,7 +397,7 @@ // Add required edge to oop_store, optimizer does not support precedence edges. // Convert required edge to precedence edge before allocation. - Node* st = new (C) StoreCMNode(ctl, mem, adr, adr_type, val, oop_store, oop_adr_idx); + Node* st = new StoreCMNode(ctl, mem, adr, adr_type, val, oop_store, oop_adr_idx); st = transform(st); set_memory(st, adr_idx); @@ -497,7 +497,7 @@ uint adr_idx = C->get_alias_index(adr_type); // Slow-path leaf call - CallNode *call = (CallNode*)new (C) CallLeafNode( slow_call_type, slow_call, leaf_name, adr_type); + CallNode *call = (CallNode*)new CallLeafNode( slow_call_type, slow_call, leaf_name, adr_type); // Set fixed predefined input arguments call->init_req( TypeFunc::Control, ctrl() ); @@ -518,10 +518,10 @@ // Slow leaf call has no side-effects, sets few values - set_ctrl(transform( new (C) ProjNode(call,TypeFunc::Control) )); + set_ctrl(transform( new ProjNode(call,TypeFunc::Control) )); // Make memory for the call - Node* mem = _gvn.transform( new (C) ProjNode(call, TypeFunc::Memory) ); + Node* mem = _gvn.transform( new ProjNode(call, TypeFunc::Memory) ); // Set the RawPtr memory state only. set_memory(mem, adr_idx); @@ -544,7 +544,7 @@ uint adr_idx = C->get_alias_index(adr_type); // Slow-path leaf call - CallNode *call = (CallNode*)new (C) CallLeafNoFPNode( slow_call_type, slow_call, leaf_name, adr_type); + CallNode *call = (CallNode*)new CallLeafNoFPNode( slow_call_type, slow_call, leaf_name, adr_type); // Set fixed predefined input arguments call->init_req( TypeFunc::Control, ctrl() ); @@ -565,10 +565,10 @@ // Slow leaf call has no side-effects, sets few values - set_ctrl(transform( new (C) ProjNode(call,TypeFunc::Control) )); + set_ctrl(transform( new ProjNode(call,TypeFunc::Control) )); // Make memory for the call - Node* mem = _gvn.transform( new (C) ProjNode(call, TypeFunc::Memory) ); + Node* mem = _gvn.transform( new ProjNode(call, TypeFunc::Memory) ); // Set the RawPtr memory state only. set_memory(mem, adr_idx); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/idealKit.hpp --- a/hotspot/src/share/vm/opto/idealKit.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/idealKit.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -173,43 +173,43 @@ void goto_(Node* lab, bool bind = false); void declarations_done(); - Node* IfTrue(IfNode* iff) { return transform(new (C) IfTrueNode(iff)); } - Node* IfFalse(IfNode* iff) { return transform(new (C) IfFalseNode(iff)); } + Node* IfTrue(IfNode* iff) { return transform(new IfTrueNode(iff)); } + Node* IfFalse(IfNode* iff) { return transform(new IfFalseNode(iff)); } // Data Node* ConI(jint k) { return (Node*)gvn().intcon(k); } Node* makecon(const Type *t) const { return _gvn.makecon(t); } - Node* AddI(Node* l, Node* r) { return transform(new (C) AddINode(l, r)); } - Node* SubI(Node* l, Node* r) { return transform(new (C) SubINode(l, r)); } - Node* AndI(Node* l, Node* r) { return transform(new (C) AndINode(l, r)); } - Node* MaxI(Node* l, Node* r) { return transform(new (C) MaxINode(l, r)); } - Node* LShiftI(Node* l, Node* r) { return transform(new (C) LShiftINode(l, r)); } - Node* CmpI(Node* l, Node* r) { return transform(new (C) CmpINode(l, r)); } - Node* Bool(Node* cmp, BoolTest::mask relop) { return transform(new (C) BoolNode(cmp, relop)); } + Node* AddI(Node* l, Node* r) { return transform(new AddINode(l, r)); } + Node* SubI(Node* l, Node* r) { return transform(new SubINode(l, r)); } + Node* AndI(Node* l, Node* r) { return transform(new AndINode(l, r)); } + Node* MaxI(Node* l, Node* r) { return transform(new MaxINode(l, r)); } + Node* LShiftI(Node* l, Node* r) { return transform(new LShiftINode(l, r)); } + Node* CmpI(Node* l, Node* r) { return transform(new CmpINode(l, r)); } + Node* Bool(Node* cmp, BoolTest::mask relop) { return transform(new BoolNode(cmp, relop)); } void increment(IdealVariable& v, Node* j) { set(v, AddI(value(v), j)); } void decrement(IdealVariable& v, Node* j) { set(v, SubI(value(v), j)); } - Node* CmpL(Node* l, Node* r) { return transform(new (C) CmpLNode(l, r)); } + Node* CmpL(Node* l, Node* r) { return transform(new CmpLNode(l, r)); } // TLS - Node* thread() { return gvn().transform(new (C) ThreadLocalNode()); } + Node* thread() { return gvn().transform(new ThreadLocalNode()); } // Pointers // Raw address should be transformed regardless 'delay_transform' flag // to produce canonical form CastX2P(offset). - Node* AddP(Node *base, Node *ptr, Node *off) { return _gvn.transform(new (C) AddPNode(base, ptr, off)); } + Node* AddP(Node *base, Node *ptr, Node *off) { return _gvn.transform(new AddPNode(base, ptr, off)); } - Node* CmpP(Node* l, Node* r) { return transform(new (C) CmpPNode(l, r)); } + Node* CmpP(Node* l, Node* r) { return transform(new CmpPNode(l, r)); } #ifdef _LP64 - Node* XorX(Node* l, Node* r) { return transform(new (C) XorLNode(l, r)); } + Node* XorX(Node* l, Node* r) { return transform(new XorLNode(l, r)); } #else // _LP64 - Node* XorX(Node* l, Node* r) { return transform(new (C) XorINode(l, r)); } + Node* XorX(Node* l, Node* r) { return transform(new XorINode(l, r)); } #endif // _LP64 - Node* URShiftX(Node* l, Node* r) { return transform(new (C) URShiftXNode(l, r)); } + Node* URShiftX(Node* l, Node* r) { return transform(new URShiftXNode(l, r)); } Node* ConX(jint k) { return (Node*)gvn().MakeConX(k); } - Node* CastPX(Node* ctl, Node* p) { return transform(new (C) CastP2XNode(ctl, p)); } + Node* CastPX(Node* ctl, Node* p) { return transform(new CastP2XNode(ctl, p)); } // Memory operations diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/ifnode.cpp --- a/hotspot/src/share/vm/opto/ifnode.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/ifnode.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -238,10 +238,10 @@ Node* predicate_x = NULL; bool counted_loop = r->is_CountedLoop(); - Node *region_c = new (igvn->C) RegionNode(req_c + 1); + Node *region_c = new RegionNode(req_c + 1); Node *phi_c = con1; uint len = r->req(); - Node *region_x = new (igvn->C) RegionNode(len - req_c); + Node *region_x = new RegionNode(len - req_c); Node *phi_x = PhiNode::make_blank(region_x, phi); for (uint i = 1, i_c = 1, i_x = 1; i < len; i++) { if (phi->in(i) == con1) { @@ -272,7 +272,7 @@ // Prevent the untimely death of phi_x. Currently he has no uses. He is // about to get one. If this only use goes away, then phi_x will look dead. // However, he will be picking up some more uses down below. - Node *hook = new (igvn->C) Node(4); + Node *hook = new Node(4); hook->init_req(0, phi_x); hook->init_req(1, phi_c); phi_x = phase->transform( phi_x ); @@ -284,30 +284,30 @@ cmp_x->set_req(2,con2); cmp_x = phase->transform(cmp_x); // Make the bool - Node *b_c = phase->transform(new (igvn->C) BoolNode(cmp_c,b->_test._test)); - Node *b_x = phase->transform(new (igvn->C) BoolNode(cmp_x,b->_test._test)); + Node *b_c = phase->transform(new BoolNode(cmp_c,b->_test._test)); + Node *b_x = phase->transform(new BoolNode(cmp_x,b->_test._test)); // Make the IfNode - IfNode *iff_c = new (igvn->C) IfNode(region_c,b_c,iff->_prob,iff->_fcnt); + IfNode *iff_c = new IfNode(region_c,b_c,iff->_prob,iff->_fcnt); igvn->set_type_bottom(iff_c); igvn->_worklist.push(iff_c); hook->init_req(2, iff_c); - IfNode *iff_x = new (igvn->C) IfNode(region_x,b_x,iff->_prob, iff->_fcnt); + IfNode *iff_x = new IfNode(region_x,b_x,iff->_prob, iff->_fcnt); igvn->set_type_bottom(iff_x); igvn->_worklist.push(iff_x); hook->init_req(3, iff_x); // Make the true/false arms - Node *iff_c_t = phase->transform(new (igvn->C) IfTrueNode (iff_c)); - Node *iff_c_f = phase->transform(new (igvn->C) IfFalseNode(iff_c)); + Node *iff_c_t = phase->transform(new IfTrueNode (iff_c)); + Node *iff_c_f = phase->transform(new IfFalseNode(iff_c)); if (predicate_c != NULL) { assert(predicate_x == NULL, "only one predicate entry expected"); // Clone loop predicates to each path iff_c_t = igvn->clone_loop_predicates(predicate_c, iff_c_t, !counted_loop); iff_c_f = igvn->clone_loop_predicates(predicate_c, iff_c_f, !counted_loop); } - Node *iff_x_t = phase->transform(new (igvn->C) IfTrueNode (iff_x)); - Node *iff_x_f = phase->transform(new (igvn->C) IfFalseNode(iff_x)); + Node *iff_x_t = phase->transform(new IfTrueNode (iff_x)); + Node *iff_x_f = phase->transform(new IfFalseNode(iff_x)); if (predicate_x != NULL) { assert(predicate_c == NULL, "only one predicate entry expected"); // Clone loop predicates to each path @@ -316,14 +316,14 @@ } // Merge the TRUE paths - Node *region_s = new (igvn->C) RegionNode(3); + Node *region_s = new RegionNode(3); igvn->_worklist.push(region_s); region_s->init_req(1, iff_c_t); region_s->init_req(2, iff_x_t); igvn->register_new_node_with_optimizer( region_s ); // Merge the FALSE paths - Node *region_f = new (igvn->C) RegionNode(3); + Node *region_f = new RegionNode(3); igvn->_worklist.push(region_f); region_f->init_req(1, iff_c_f); region_f->init_req(2, iff_x_f); @@ -438,7 +438,7 @@ // Must return either the original node (now dead) or a new node // (Do not return a top here, since that would break the uniqueness of top.) - return new (igvn->C) ConINode(TypeInt::ZERO); + return new ConINode(TypeInt::ZERO); } //------------------------------is_range_check--------------------------------- @@ -541,16 +541,16 @@ // Compute a new check Node *new_add = gvn->intcon(off_lo); if( index ) { - new_add = off_lo ? gvn->transform(new (gvn->C) AddINode( index, new_add )) : index; + new_add = off_lo ? gvn->transform(new AddINode( index, new_add )) : index; } Node *new_cmp = (flip == 1) - ? new (gvn->C) CmpUNode( new_add, range ) - : new (gvn->C) CmpUNode( range, new_add ); + ? new CmpUNode( new_add, range ) + : new CmpUNode( range, new_add ); new_cmp = gvn->transform(new_cmp); // See if no need to adjust the existing check if( new_cmp == cmp ) return; // Else, adjust existing check - Node *new_bol = gvn->transform( new (gvn->C) BoolNode( new_cmp, bol->as_Bool()->_test._test ) ); + Node *new_bol = gvn->transform( new BoolNode( new_cmp, bol->as_Bool()->_test._test ) ); igvn->rehash_node_delayed( iff ); iff->set_req_X( 1, new_bol, igvn ); } @@ -728,9 +728,9 @@ if (failtype->_hi != max_jint && failtype->_lo != min_jint && bound > 1) { // Merge the two compares into a single unsigned compare by building (CmpU (n - lo) hi) BoolTest::mask cond = fail->as_Proj()->_con ? BoolTest::lt : BoolTest::ge; - Node* adjusted = phase->transform(new (phase->C) SubINode(n, phase->intcon(failtype->_lo))); - Node* newcmp = phase->transform(new (phase->C) CmpUNode(adjusted, phase->intcon(bound))); - Node* newbool = phase->transform(new (phase->C) BoolNode(newcmp, cond)); + Node* adjusted = phase->transform(new SubINode(n, phase->intcon(failtype->_lo))); + Node* newcmp = phase->transform(new CmpUNode(adjusted, phase->intcon(bound))); + Node* newbool = phase->transform(new BoolNode(newcmp, cond)); phase->is_IterGVN()->replace_input_of(dom_iff, 1, phase->intcon(ctrl->as_Proj()->_con)); phase->hash_delete(this); set_req(1, newbool); @@ -1003,7 +1003,7 @@ // Must return either the original node (now dead) or a new node // (Do not return a top here, since that would break the uniqueness of top.) - return new (phase->C) ConINode(TypeInt::ZERO); + return new ConINode(TypeInt::ZERO); } //------------------------------dominated_by----------------------------------- @@ -1099,7 +1099,7 @@ // Flip test to be canonical. Requires flipping the IfFalse/IfTrue and // cloning the IfNode. - Node* new_b = phase->transform( new (phase->C) BoolNode(b->in(1), bt.negate()) ); + Node* new_b = phase->transform( new BoolNode(b->in(1), bt.negate()) ); if( !new_b->is_Bool() ) return NULL; b = new_b->as_Bool(); @@ -1107,7 +1107,7 @@ assert( igvn, "Test is not canonical in parser?" ); // The IF node never really changes, but it needs to be cloned - iff = new (phase->C) IfNode( iff->in(0), b, 1.0-iff->_prob, iff->_fcnt); + iff = new IfNode( iff->in(0), b, 1.0-iff->_prob, iff->_fcnt); Node *prior = igvn->hash_find_insert(iff); if( prior ) { @@ -1120,8 +1120,8 @@ igvn->_worklist.push(iff); // Now handle projections. Cloning not required. - Node* new_if_f = (Node*)(new (phase->C) IfFalseNode( iff )); - Node* new_if_t = (Node*)(new (phase->C) IfTrueNode ( iff )); + Node* new_if_f = (Node*)(new IfFalseNode( iff )); + Node* new_if_t = (Node*)(new IfTrueNode ( iff )); igvn->register_new_node_with_optimizer(new_if_f); igvn->register_new_node_with_optimizer(new_if_t); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/lcm.cpp --- a/hotspot/src/share/vm/opto/lcm.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/lcm.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -419,7 +419,7 @@ Node *tmp2 = block->get_node(block->end_idx()+2); block->map_node(tmp2, block->end_idx()+1); block->map_node(tmp1, block->end_idx()+2); - Node *tmp = new (C) Node(C->top()); // Use not NULL input + Node *tmp = new Node(C->top()); // Use not NULL input tmp1->replace_by(tmp); tmp2->replace_by(tmp1); tmp->replace_by(tmp2); @@ -430,7 +430,7 @@ // Since schedule-local needs precise def-use info, we need to correct // it as well. Node *old_tst = proj->in(0); - MachNode *nul_chk = new (C) MachNullCheckNode(old_tst->in(0),best,bidx); + MachNode *nul_chk = new MachNullCheckNode(old_tst->in(0),best,bidx); block->map_node(nul_chk, block->end_idx()); map_node_to_block(nul_chk, block); // Redirect users of old_test to nul_chk @@ -671,7 +671,7 @@ // Set all registers killed and not already defined by the call. uint r_cnt = mcall->tf()->range()->cnt(); int op = mcall->ideal_Opcode(); - MachProjNode *proj = new (C) MachProjNode( mcall, r_cnt+1, RegMask::Empty, MachProjNode::fat_proj ); + MachProjNode *proj = new MachProjNode( mcall, r_cnt+1, RegMask::Empty, MachProjNode::fat_proj ); map_node_to_block(proj, block); block->insert_node(proj, node_cnt++); @@ -900,7 +900,7 @@ regs.Insert(_matcher.c_frame_pointer()); regs.OR(n->out_RegMask()); - MachProjNode *proj = new (C) MachProjNode( n, 1, RegMask::Empty, MachProjNode::fat_proj ); + MachProjNode *proj = new MachProjNode( n, 1, RegMask::Empty, MachProjNode::fat_proj ); map_node_to_block(proj, block); block->insert_node(proj, phi_cnt++); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/library_call.cpp --- a/hotspot/src/share/vm/opto/library_call.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/library_call.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -52,25 +52,28 @@ public: private: bool _is_virtual; - bool _is_predicted; bool _does_virtual_dispatch; + int8_t _predicates_count; // Intrinsic is predicated by several conditions + int8_t _last_predicate; // Last generated predicate vmIntrinsics::ID _intrinsic_id; public: - LibraryIntrinsic(ciMethod* m, bool is_virtual, bool is_predicted, bool does_virtual_dispatch, vmIntrinsics::ID id) + LibraryIntrinsic(ciMethod* m, bool is_virtual, int predicates_count, bool does_virtual_dispatch, vmIntrinsics::ID id) : InlineCallGenerator(m), _is_virtual(is_virtual), - _is_predicted(is_predicted), _does_virtual_dispatch(does_virtual_dispatch), + _predicates_count((int8_t)predicates_count), + _last_predicate((int8_t)-1), _intrinsic_id(id) { } virtual bool is_intrinsic() const { return true; } virtual bool is_virtual() const { return _is_virtual; } - virtual bool is_predicted() const { return _is_predicted; } + virtual bool is_predicated() const { return _predicates_count > 0; } + virtual int predicates_count() const { return _predicates_count; } virtual bool does_virtual_dispatch() const { return _does_virtual_dispatch; } - virtual JVMState* generate(JVMState* jvms, Parse* parent_parser); - virtual Node* generate_predicate(JVMState* jvms); + virtual JVMState* generate(JVMState* jvms); + virtual Node* generate_predicate(JVMState* jvms, int predicate); vmIntrinsics::ID intrinsic_id() const { return _intrinsic_id; } }; @@ -113,8 +116,8 @@ vmIntrinsics::ID intrinsic_id() const { return _intrinsic->intrinsic_id(); } ciMethod* callee() const { return _intrinsic->method(); } - bool try_to_inline(); - Node* try_to_predicate(); + bool try_to_inline(int predicate); + Node* try_to_predicate(int predicate); void push_result() { // Push the result onto the stack. @@ -313,6 +316,14 @@ Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting); Node* get_key_start_from_aescrypt_object(Node* aescrypt_object); Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object); + bool inline_sha_implCompress(vmIntrinsics::ID id); + bool inline_digestBase_implCompressMB(int predicate); + bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA, + bool long_state, address stubAddr, const char *stubName, + Node* src_start, Node* ofs, Node* limit); + Node* get_state_from_sha_object(Node *sha_object); + Node* get_state_from_sha5_object(Node *sha_object); + Node* inline_digestBase_implCompressMB_predicate(int predicate); bool inline_encodeISOArray(); bool inline_updateCRC32(); bool inline_updateBytesCRC32(); @@ -373,7 +384,7 @@ } } - bool is_predicted = false; + int predicates = 0; bool does_virtual_dispatch = false; switch (id) { @@ -513,7 +524,24 @@ case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt: if (!UseAESIntrinsics) return NULL; // these two require the predicated logic - is_predicted = true; + predicates = 1; + break; + + case vmIntrinsics::_sha_implCompress: + if (!UseSHA1Intrinsics) return NULL; + break; + + case vmIntrinsics::_sha2_implCompress: + if (!UseSHA256Intrinsics) return NULL; + break; + + case vmIntrinsics::_sha5_implCompress: + if (!UseSHA512Intrinsics) return NULL; + break; + + case vmIntrinsics::_digestBase_implCompressMB: + if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) return NULL; + predicates = 3; break; case vmIntrinsics::_updateCRC32: @@ -582,7 +610,7 @@ if (!InlineUnsafeOps) return NULL; } - return new LibraryIntrinsic(m, is_virtual, is_predicted, does_virtual_dispatch, (vmIntrinsics::ID) id); + return new LibraryIntrinsic(m, is_virtual, predicates, does_virtual_dispatch, (vmIntrinsics::ID) id); } //----------------------register_library_intrinsics----------------------- @@ -591,7 +619,7 @@ // Nothing to do here. } -JVMState* LibraryIntrinsic::generate(JVMState* jvms, Parse* parent_parser) { +JVMState* LibraryIntrinsic::generate(JVMState* jvms) { LibraryCallKit kit(jvms, this); Compile* C = kit.C; int nodes = C->unique(); @@ -606,7 +634,7 @@ const int bci = kit.bci(); // Try to inline the intrinsic. - if (kit.try_to_inline()) { + if (kit.try_to_inline(_last_predicate)) { if (C->print_intrinsics() || C->print_inlining()) { C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)"); } @@ -641,12 +669,13 @@ return NULL; } -Node* LibraryIntrinsic::generate_predicate(JVMState* jvms) { +Node* LibraryIntrinsic::generate_predicate(JVMState* jvms, int predicate) { LibraryCallKit kit(jvms, this); Compile* C = kit.C; int nodes = C->unique(); + _last_predicate = predicate; #ifndef PRODUCT - assert(is_predicted(), "sanity"); + assert(is_predicated() && predicate < predicates_count(), "sanity"); if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { char buf[1000]; const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf)); @@ -656,10 +685,10 @@ ciMethod* callee = kit.callee(); const int bci = kit.bci(); - Node* slow_ctl = kit.try_to_predicate(); + Node* slow_ctl = kit.try_to_predicate(predicate); if (!kit.failing()) { if (C->print_intrinsics() || C->print_inlining()) { - C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)"); + C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual, predicate)" : "(intrinsic, predicate)"); } C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked); if (C->log()) { @@ -688,7 +717,7 @@ return NULL; } -bool LibraryCallKit::try_to_inline() { +bool LibraryCallKit::try_to_inline(int predicate) { // Handle symbolic names for otherwise undistinguished boolean switches: const bool is_store = true; const bool is_native_ptr = true; @@ -882,6 +911,14 @@ case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt: return inline_cipherBlockChaining_AESCrypt(intrinsic_id()); + case vmIntrinsics::_sha_implCompress: + case vmIntrinsics::_sha2_implCompress: + case vmIntrinsics::_sha5_implCompress: + return inline_sha_implCompress(intrinsic_id()); + + case vmIntrinsics::_digestBase_implCompressMB: + return inline_digestBase_implCompressMB(predicate); + case vmIntrinsics::_encodeISOArray: return inline_encodeISOArray(); @@ -905,7 +942,7 @@ } } -Node* LibraryCallKit::try_to_predicate() { +Node* LibraryCallKit::try_to_predicate(int predicate) { if (!jvms()->has_method()) { // Root JVMState has a null method. assert(map()->memory()->Opcode() == Op_Parm, ""); @@ -919,6 +956,8 @@ return inline_cipherBlockChaining_AESCrypt_predicate(false); case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt: return inline_cipherBlockChaining_AESCrypt_predicate(true); + case vmIntrinsics::_digestBase_implCompressMB: + return inline_digestBase_implCompressMB_predicate(predicate); default: // If you get here, it may be that someone has added a new intrinsic @@ -969,7 +1008,7 @@ IfNode* iff = create_and_map_if(control(), test, true_prob, COUNT_UNKNOWN); - Node* if_slow = _gvn.transform(new (C) IfTrueNode(iff)); + Node* if_slow = _gvn.transform(new IfTrueNode(iff)); if (if_slow == top()) { // The slow branch is never taken. No need to build this guard. return NULL; @@ -978,7 +1017,7 @@ if (region != NULL) region->add_req(if_slow); - Node* if_fast = _gvn.transform(new (C) IfFalseNode(iff)); + Node* if_fast = _gvn.transform(new IfFalseNode(iff)); set_control(if_fast); return if_slow; @@ -997,12 +1036,12 @@ return NULL; // already stopped if (_gvn.type(index)->higher_equal(TypeInt::POS)) // [0,maxint] return NULL; // index is already adequately typed - Node* cmp_lt = _gvn.transform(new (C) CmpINode(index, intcon(0))); - Node* bol_lt = _gvn.transform(new (C) BoolNode(cmp_lt, BoolTest::lt)); + Node* cmp_lt = _gvn.transform(new CmpINode(index, intcon(0))); + Node* bol_lt = _gvn.transform(new BoolNode(cmp_lt, BoolTest::lt)); Node* is_neg = generate_guard(bol_lt, region, PROB_MIN); if (is_neg != NULL && pos_index != NULL) { // Emulate effect of Parse::adjust_map_after_if. - Node* ccast = new (C) CastIINode(index, TypeInt::POS); + Node* ccast = new CastIINode(index, TypeInt::POS); ccast->set_req(0, control()); (*pos_index) = _gvn.transform(ccast); } @@ -1015,13 +1054,13 @@ return NULL; // already stopped if (_gvn.type(index)->higher_equal(TypeInt::POS1)) // [1,maxint] return NULL; // index is already adequately typed - Node* cmp_le = _gvn.transform(new (C) CmpINode(index, intcon(0))); + Node* cmp_le = _gvn.transform(new CmpINode(index, intcon(0))); BoolTest::mask le_or_eq = (never_negative ? BoolTest::eq : BoolTest::le); - Node* bol_le = _gvn.transform(new (C) BoolNode(cmp_le, le_or_eq)); + Node* bol_le = _gvn.transform(new BoolNode(cmp_le, le_or_eq)); Node* is_notp = generate_guard(bol_le, NULL, PROB_MIN); if (is_notp != NULL && pos_index != NULL) { // Emulate effect of Parse::adjust_map_after_if. - Node* ccast = new (C) CastIINode(index, TypeInt::POS1); + Node* ccast = new CastIINode(index, TypeInt::POS1); ccast->set_req(0, control()); (*pos_index) = _gvn.transform(ccast); } @@ -1053,9 +1092,9 @@ return NULL; // common case of whole-array copy Node* last = subseq_length; if (!zero_offset) // last += offset - last = _gvn.transform(new (C) AddINode(last, offset)); - Node* cmp_lt = _gvn.transform(new (C) CmpUNode(array_length, last)); - Node* bol_lt = _gvn.transform(new (C) BoolNode(cmp_lt, BoolTest::lt)); + last = _gvn.transform(new AddINode(last, offset)); + Node* cmp_lt = _gvn.transform(new CmpUNode(array_length, last)); + Node* bol_lt = _gvn.transform(new BoolNode(cmp_lt, BoolTest::lt)); Node* is_over = generate_guard(bol_lt, region, PROB_MIN); return is_over; } @@ -1065,7 +1104,7 @@ Node* LibraryCallKit::generate_current_thread(Node* &tls_output) { ciKlass* thread_klass = env()->Thread_klass(); const Type* thread_type = TypeOopPtr::make_from_klass(thread_klass)->cast_to_ptr_type(TypePtr::NotNull); - Node* thread = _gvn.transform(new (C) ThreadLocalNode()); + Node* thread = _gvn.transform(new ThreadLocalNode()); Node* p = basic_plus_adr(top()/*!oop*/, thread, in_bytes(JavaThread::threadObj_offset())); Node* threadObj = make_load(NULL, p, thread_type, T_OBJECT, MemNode::unordered); tls_output = thread; @@ -1100,18 +1139,18 @@ // Get length of string 2 str2_len = load_String_length(no_ctrl, str2); - result = new (C) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS), - str1_start, str1_len, str2_start, str2_len); + result = new StrIndexOfNode(control(), memory(TypeAryPtr::CHARS), + str1_start, str1_len, str2_start, str2_len); break; case Op_StrComp: // Get length of string 2 str2_len = load_String_length(no_ctrl, str2); - result = new (C) StrCompNode(control(), memory(TypeAryPtr::CHARS), - str1_start, str1_len, str2_start, str2_len); + result = new StrCompNode(control(), memory(TypeAryPtr::CHARS), + str1_start, str1_len, str2_start, str2_len); break; case Op_StrEquals: - result = new (C) StrEqualsNode(control(), memory(TypeAryPtr::CHARS), + result = new StrEqualsNode(control(), memory(TypeAryPtr::CHARS), str1_start, str2_start, str1_len); break; default: @@ -1133,16 +1172,16 @@ Node* result = NULL; switch (opcode) { case Op_StrIndexOf: - result = new (C) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS), - str1_start, cnt1, str2_start, cnt2); + result = new StrIndexOfNode(control(), memory(TypeAryPtr::CHARS), + str1_start, cnt1, str2_start, cnt2); break; case Op_StrComp: - result = new (C) StrCompNode(control(), memory(TypeAryPtr::CHARS), - str1_start, cnt1, str2_start, cnt2); + result = new StrCompNode(control(), memory(TypeAryPtr::CHARS), + str1_start, cnt1, str2_start, cnt2); break; case Op_StrEquals: - result = new (C) StrEqualsNode(control(), memory(TypeAryPtr::CHARS), - str1_start, str2_start, cnt1); + result = new StrEqualsNode(control(), memory(TypeAryPtr::CHARS), + str1_start, str2_start, cnt1); break; default: ShouldNotReachHere(); @@ -1178,12 +1217,12 @@ } // paths (plus control) merge - RegionNode* region = new (C) RegionNode(5); - Node* phi = new (C) PhiNode(region, TypeInt::BOOL); + RegionNode* region = new RegionNode(5); + Node* phi = new PhiNode(region, TypeInt::BOOL); // does source == target string? - Node* cmp = _gvn.transform(new (C) CmpPNode(receiver, argument)); - Node* bol = _gvn.transform(new (C) BoolNode(cmp, BoolTest::eq)); + Node* cmp = _gvn.transform(new CmpPNode(receiver, argument)); + Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::eq)); Node* if_eq = generate_slow_guard(bol, NULL); if (if_eq != NULL) { @@ -1197,8 +1236,8 @@ if (!stopped()) { Node* inst = gen_instanceof(argument, makecon(TypeKlassPtr::make(klass))); - Node* cmp = _gvn.transform(new (C) CmpINode(inst, intcon(1))); - Node* bol = _gvn.transform(new (C) BoolNode(cmp, BoolTest::ne)); + Node* cmp = _gvn.transform(new CmpINode(inst, intcon(1))); + Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::ne)); Node* inst_false = generate_guard(bol, NULL, PROB_MIN); //instanceOf == true, fallthrough @@ -1213,7 +1252,7 @@ const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass); // Properly cast the argument to String - argument = _gvn.transform(new (C) CheckCastPPNode(control(), argument, string_type)); + argument = _gvn.transform(new CheckCastPPNode(control(), argument, string_type)); // This path is taken only when argument's type is String:NotNull. argument = cast_not_null(argument, false); @@ -1236,8 +1275,8 @@ Node* argument_cnt = load_String_length(no_ctrl, argument); // Check for receiver count != argument count - Node* cmp = _gvn.transform(new(C) CmpINode(receiver_cnt, argument_cnt)); - Node* bol = _gvn.transform(new(C) BoolNode(cmp, BoolTest::ne)); + Node* cmp = _gvn.transform(new CmpINode(receiver_cnt, argument_cnt)); + Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::ne)); Node* if_ne = generate_slow_guard(bol, NULL); if (if_ne != NULL) { phi->init_req(4, intcon(0)); @@ -1265,7 +1304,7 @@ bool LibraryCallKit::inline_array_equals() { Node* arg1 = argument(0); Node* arg2 = argument(1); - set_result(_gvn.transform(new (C) AryEqNode(control(), memory(TypeAryPtr::CHARS), arg1, arg2))); + set_result(_gvn.transform(new AryEqNode(control(), memory(TypeAryPtr::CHARS), arg1, arg2))); return true; } @@ -1434,8 +1473,8 @@ const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(str_klass); // Make the merge point - RegionNode* result_rgn = new (C) RegionNode(4); - Node* result_phi = new (C) PhiNode(result_rgn, TypeInt::INT); + RegionNode* result_rgn = new RegionNode(4); + Node* result_phi = new PhiNode(result_rgn, TypeInt::INT); Node* no_ctrl = NULL; // Get start addr of source string @@ -1455,8 +1494,8 @@ Node* substr_cnt = load_String_length(no_ctrl, arg); // Check for substr count > string count - Node* cmp = _gvn.transform(new(C) CmpINode(substr_cnt, source_cnt)); - Node* bol = _gvn.transform(new(C) BoolNode(cmp, BoolTest::gt)); + Node* cmp = _gvn.transform(new CmpINode(substr_cnt, source_cnt)); + Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::gt)); Node* if_gt = generate_slow_guard(bol, NULL); if (if_gt != NULL) { result_phi->init_req(2, intcon(-1)); @@ -1465,8 +1504,8 @@ if (!stopped()) { // Check for substr count == 0 - cmp = _gvn.transform(new(C) CmpINode(substr_cnt, intcon(0))); - bol = _gvn.transform(new(C) BoolNode(cmp, BoolTest::eq)); + cmp = _gvn.transform(new CmpINode(substr_cnt, intcon(0))); + bol = _gvn.transform(new BoolNode(cmp, BoolTest::eq)); Node* if_zero = generate_slow_guard(bol, NULL); if (if_zero != NULL) { result_phi->init_req(3, intcon(0)); @@ -1558,7 +1597,7 @@ // Round a double node if necessary. Node* LibraryCallKit::round_double_node(Node* n) { if (Matcher::strict_fp_requires_explicit_rounding && UseSSE <= 1) - n = _gvn.transform(new (C) RoundDoubleNode(0, n)); + n = _gvn.transform(new RoundDoubleNode(0, n)); return n; } @@ -1571,10 +1610,10 @@ Node* arg = round_double_node(argument(0)); Node* n; switch (id) { - case vmIntrinsics::_dabs: n = new (C) AbsDNode( arg); break; - case vmIntrinsics::_dsqrt: n = new (C) SqrtDNode(C, control(), arg); break; - case vmIntrinsics::_dlog: n = new (C) LogDNode(C, control(), arg); break; - case vmIntrinsics::_dlog10: n = new (C) Log10DNode(C, control(), arg); break; + case vmIntrinsics::_dabs: n = new AbsDNode( arg); break; + case vmIntrinsics::_dsqrt: n = new SqrtDNode(C, control(), arg); break; + case vmIntrinsics::_dlog: n = new LogDNode(C, control(), arg); break; + case vmIntrinsics::_dlog10: n = new Log10DNode(C, control(), arg); break; default: fatal_unexpected_iid(id); break; } set_result(_gvn.transform(n)); @@ -1589,9 +1628,9 @@ Node* n = NULL; switch (id) { - case vmIntrinsics::_dsin: n = new (C) SinDNode(C, control(), arg); break; - case vmIntrinsics::_dcos: n = new (C) CosDNode(C, control(), arg); break; - case vmIntrinsics::_dtan: n = new (C) TanDNode(C, control(), arg); break; + case vmIntrinsics::_dsin: n = new SinDNode(C, control(), arg); break; + case vmIntrinsics::_dcos: n = new CosDNode(C, control(), arg); break; + case vmIntrinsics::_dtan: n = new TanDNode(C, control(), arg); break; default: fatal_unexpected_iid(id); break; } n = _gvn.transform(n); @@ -1632,17 +1671,17 @@ // probably do the math inside the SIN encoding. // Make the merge point - RegionNode* r = new (C) RegionNode(3); - Node* phi = new (C) PhiNode(r, Type::DOUBLE); + RegionNode* r = new RegionNode(3); + Node* phi = new PhiNode(r, Type::DOUBLE); // Flatten arg so we need only 1 test - Node *abs = _gvn.transform(new (C) AbsDNode(arg)); + Node *abs = _gvn.transform(new AbsDNode(arg)); // Node for PI/4 constant Node *pi4 = makecon(TypeD::make(pi_4)); // Check PI/4 : abs(arg) - Node *cmp = _gvn.transform(new (C) CmpDNode(pi4,abs)); + Node *cmp = _gvn.transform(new CmpDNode(pi4,abs)); // Check: If PI/4 < abs(arg) then go slow - Node *bol = _gvn.transform(new (C) BoolNode( cmp, BoolTest::lt )); + Node *bol = _gvn.transform(new BoolNode( cmp, BoolTest::lt )); // Branch either way IfNode *iff = create_and_xform_if(control(),bol, PROB_STATIC_FREQUENT, COUNT_UNKNOWN); set_control(opt_iff(r,iff)); @@ -1670,7 +1709,7 @@ break; } assert(control()->in(0) == call, ""); - Node* slow_result = _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms)); + Node* slow_result = _gvn.transform(new ProjNode(call, TypeFunc::Parms)); r->init_req(1, control()); phi->init_req(1, slow_result); @@ -1690,9 +1729,9 @@ //result=(result.isNaN())? funcAddr():result; // Check: If isNaN() by checking result!=result? then either trap // or go to runtime - Node* cmpisnan = _gvn.transform(new (C) CmpDNode(result, result)); + Node* cmpisnan = _gvn.transform(new CmpDNode(result, result)); // Build the boolean node - Node* bolisnum = _gvn.transform(new (C) BoolNode(cmpisnan, BoolTest::eq)); + Node* bolisnum = _gvn.transform(new BoolNode(cmpisnan, BoolTest::eq)); if (!too_many_traps(Deoptimization::Reason_intrinsic)) { { BuildCutout unless(this, bolisnum, PROB_STATIC_FREQUENT); @@ -1707,12 +1746,12 @@ // to the runtime to properly handle corner cases IfNode* iff = create_and_xform_if(control(), bolisnum, PROB_STATIC_FREQUENT, COUNT_UNKNOWN); - Node* if_slow = _gvn.transform(new (C) IfFalseNode(iff)); - Node* if_fast = _gvn.transform(new (C) IfTrueNode(iff)); + Node* if_slow = _gvn.transform(new IfFalseNode(iff)); + Node* if_fast = _gvn.transform(new IfTrueNode(iff)); if (!if_slow->is_top()) { - RegionNode* result_region = new (C) RegionNode(3); - PhiNode* result_val = new (C) PhiNode(result_region, Type::DOUBLE); + RegionNode* result_region = new RegionNode(3); + PhiNode* result_val = new PhiNode(result_region, Type::DOUBLE); result_region->init_req(1, if_fast); result_val->init_req(1, result); @@ -1723,9 +1762,9 @@ Node* rt = make_runtime_call(RC_LEAF, call_type, funcAddr, funcName, no_memory_effects, x, top(), y, y ? top() : NULL); - Node* value = _gvn.transform(new (C) ProjNode(rt, TypeFunc::Parms+0)); + Node* value = _gvn.transform(new ProjNode(rt, TypeFunc::Parms+0)); #ifdef ASSERT - Node* value_top = _gvn.transform(new (C) ProjNode(rt, TypeFunc::Parms+1)); + Node* value_top = _gvn.transform(new ProjNode(rt, TypeFunc::Parms+1)); assert(value_top == top(), "second value must be top"); #endif @@ -1744,7 +1783,7 @@ // really odd corner cases (+/- Infinity). Just uncommon-trap them. bool LibraryCallKit::inline_exp() { Node* arg = round_double_node(argument(0)); - Node* n = _gvn.transform(new (C) ExpDNode(C, control(), arg)); + Node* n = _gvn.transform(new ExpDNode(C, control(), arg)); n = finish_pow_exp(n, arg, NULL, OptoRuntime::Math_D_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dexp), "EXP"); set_result(n); @@ -1783,76 +1822,76 @@ Node* result = NULL; Node* const_two_node = makecon(TypeD::make(2.0)); - Node* cmp_node = _gvn.transform(new (C) CmpDNode(y, const_two_node)); - Node* bool_node = _gvn.transform(new (C) BoolNode(cmp_node, BoolTest::eq)); + Node* cmp_node = _gvn.transform(new CmpDNode(y, const_two_node)); + Node* bool_node = _gvn.transform(new BoolNode(cmp_node, BoolTest::eq)); IfNode* if_node = create_and_xform_if(control(), bool_node, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN); - Node* if_true = _gvn.transform(new (C) IfTrueNode(if_node)); - Node* if_false = _gvn.transform(new (C) IfFalseNode(if_node)); - - RegionNode* region_node = new (C) RegionNode(3); + Node* if_true = _gvn.transform(new IfTrueNode(if_node)); + Node* if_false = _gvn.transform(new IfFalseNode(if_node)); + + RegionNode* region_node = new RegionNode(3); region_node->init_req(1, if_true); - Node* phi_node = new (C) PhiNode(region_node, Type::DOUBLE); + Node* phi_node = new PhiNode(region_node, Type::DOUBLE); // special case for x^y where y == 2, we can convert it to x * x - phi_node->init_req(1, _gvn.transform(new (C) MulDNode(x, x))); + phi_node->init_req(1, _gvn.transform(new MulDNode(x, x))); // set control to if_false since we will now process the false branch set_control(if_false); if (!too_many_traps(Deoptimization::Reason_intrinsic)) { // Short form: skip the fancy tests and just check for NaN result. - result = _gvn.transform(new (C) PowDNode(C, control(), x, y)); + result = _gvn.transform(new PowDNode(C, control(), x, y)); } else { // If this inlining ever returned NaN in the past, include all // checks + call to the runtime. // Set the merge point for If node with condition of (x <= 0.0) // There are four possible paths to region node and phi node - RegionNode *r = new (C) RegionNode(4); - Node *phi = new (C) PhiNode(r, Type::DOUBLE); + RegionNode *r = new RegionNode(4); + Node *phi = new PhiNode(r, Type::DOUBLE); // Build the first if node: if (x <= 0.0) // Node for 0 constant Node *zeronode = makecon(TypeD::ZERO); // Check x:0 - Node *cmp = _gvn.transform(new (C) CmpDNode(x, zeronode)); + Node *cmp = _gvn.transform(new CmpDNode(x, zeronode)); // Check: If (x<=0) then go complex path - Node *bol1 = _gvn.transform(new (C) BoolNode( cmp, BoolTest::le )); + Node *bol1 = _gvn.transform(new BoolNode( cmp, BoolTest::le )); // Branch either way IfNode *if1 = create_and_xform_if(control(),bol1, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN); // Fast path taken; set region slot 3 - Node *fast_taken = _gvn.transform(new (C) IfFalseNode(if1)); + Node *fast_taken = _gvn.transform(new IfFalseNode(if1)); r->init_req(3,fast_taken); // Capture fast-control // Fast path not-taken, i.e. slow path - Node *complex_path = _gvn.transform(new (C) IfTrueNode(if1)); + Node *complex_path = _gvn.transform(new IfTrueNode(if1)); // Set fast path result - Node *fast_result = _gvn.transform(new (C) PowDNode(C, control(), x, y)); + Node *fast_result = _gvn.transform(new PowDNode(C, control(), x, y)); phi->init_req(3, fast_result); // Complex path // Build the second if node (if y is long) // Node for (long)y - Node *longy = _gvn.transform(new (C) ConvD2LNode(y)); + Node *longy = _gvn.transform(new ConvD2LNode(y)); // Node for (double)((long) y) - Node *doublelongy= _gvn.transform(new (C) ConvL2DNode(longy)); + Node *doublelongy= _gvn.transform(new ConvL2DNode(longy)); // Check (double)((long) y) : y - Node *cmplongy= _gvn.transform(new (C) CmpDNode(doublelongy, y)); + Node *cmplongy= _gvn.transform(new CmpDNode(doublelongy, y)); // Check if (y isn't long) then go to slow path - Node *bol2 = _gvn.transform(new (C) BoolNode( cmplongy, BoolTest::ne )); + Node *bol2 = _gvn.transform(new BoolNode( cmplongy, BoolTest::ne )); // Branch either way IfNode *if2 = create_and_xform_if(complex_path,bol2, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN); - Node* ylong_path = _gvn.transform(new (C) IfFalseNode(if2)); - - Node *slow_path = _gvn.transform(new (C) IfTrueNode(if2)); + Node* ylong_path = _gvn.transform(new IfFalseNode(if2)); + + Node *slow_path = _gvn.transform(new IfTrueNode(if2)); // Calculate DPow(abs(x), y)*(1 & (long)y) // Node for constant 1 Node *conone = longcon(1); // 1& (long)y - Node *signnode= _gvn.transform(new (C) AndLNode(conone, longy)); + Node *signnode= _gvn.transform(new AndLNode(conone, longy)); // A huge number is always even. Detect a huge number by checking // if y + 1 == y and set integer to be tested for parity to 0. @@ -1860,18 +1899,18 @@ // (long)9.223372036854776E18 = max_jlong // (double)(long)9.223372036854776E18 = 9.223372036854776E18 // max_jlong is odd but 9.223372036854776E18 is even - Node* yplus1 = _gvn.transform(new (C) AddDNode(y, makecon(TypeD::make(1)))); - Node *cmpyplus1= _gvn.transform(new (C) CmpDNode(yplus1, y)); - Node *bolyplus1 = _gvn.transform(new (C) BoolNode( cmpyplus1, BoolTest::eq )); + Node* yplus1 = _gvn.transform(new AddDNode(y, makecon(TypeD::make(1)))); + Node *cmpyplus1= _gvn.transform(new CmpDNode(yplus1, y)); + Node *bolyplus1 = _gvn.transform(new BoolNode( cmpyplus1, BoolTest::eq )); Node* correctedsign = NULL; if (ConditionalMoveLimit != 0) { correctedsign = _gvn.transform( CMoveNode::make(C, NULL, bolyplus1, signnode, longcon(0), TypeLong::LONG)); } else { IfNode *ifyplus1 = create_and_xform_if(ylong_path,bolyplus1, PROB_FAIR, COUNT_UNKNOWN); - RegionNode *r = new (C) RegionNode(3); - Node *phi = new (C) PhiNode(r, TypeLong::LONG); - r->init_req(1, _gvn.transform(new (C) IfFalseNode(ifyplus1))); - r->init_req(2, _gvn.transform(new (C) IfTrueNode(ifyplus1))); + RegionNode *r = new RegionNode(3); + Node *phi = new PhiNode(r, TypeLong::LONG); + r->init_req(1, _gvn.transform(new IfFalseNode(ifyplus1))); + r->init_req(2, _gvn.transform(new IfTrueNode(ifyplus1))); phi->init_req(1, signnode); phi->init_req(2, longcon(0)); correctedsign = _gvn.transform(phi); @@ -1882,25 +1921,25 @@ // zero node Node *conzero = longcon(0); // Check (1&(long)y)==0? - Node *cmpeq1 = _gvn.transform(new (C) CmpLNode(correctedsign, conzero)); + Node *cmpeq1 = _gvn.transform(new CmpLNode(correctedsign, conzero)); // Check if (1&(long)y)!=0?, if so the result is negative - Node *bol3 = _gvn.transform(new (C) BoolNode( cmpeq1, BoolTest::ne )); + Node *bol3 = _gvn.transform(new BoolNode( cmpeq1, BoolTest::ne )); // abs(x) - Node *absx=_gvn.transform(new (C) AbsDNode(x)); + Node *absx=_gvn.transform(new AbsDNode(x)); // abs(x)^y - Node *absxpowy = _gvn.transform(new (C) PowDNode(C, control(), absx, y)); + Node *absxpowy = _gvn.transform(new PowDNode(C, control(), absx, y)); // -abs(x)^y - Node *negabsxpowy = _gvn.transform(new (C) NegDNode (absxpowy)); + Node *negabsxpowy = _gvn.transform(new NegDNode (absxpowy)); // (1&(long)y)==1?-DPow(abs(x), y):DPow(abs(x), y) Node *signresult = NULL; if (ConditionalMoveLimit != 0) { signresult = _gvn.transform( CMoveNode::make(C, NULL, bol3, absxpowy, negabsxpowy, Type::DOUBLE)); } else { IfNode *ifyeven = create_and_xform_if(ylong_path,bol3, PROB_FAIR, COUNT_UNKNOWN); - RegionNode *r = new (C) RegionNode(3); - Node *phi = new (C) PhiNode(r, Type::DOUBLE); - r->init_req(1, _gvn.transform(new (C) IfFalseNode(ifyeven))); - r->init_req(2, _gvn.transform(new (C) IfTrueNode(ifyeven))); + RegionNode *r = new RegionNode(3); + Node *phi = new PhiNode(r, Type::DOUBLE); + r->init_req(1, _gvn.transform(new IfFalseNode(ifyeven))); + r->init_req(2, _gvn.transform(new IfTrueNode(ifyeven))); phi->init_req(1, absxpowy); phi->init_req(2, negabsxpowy); signresult = _gvn.transform(phi); @@ -1949,9 +1988,9 @@ Node* trig = make_runtime_call(RC_LEAF, call_type, funcAddr, funcName, no_memory_effects, a, top(), b, b ? top() : NULL); - Node* value = _gvn.transform(new (C) ProjNode(trig, TypeFunc::Parms+0)); + Node* value = _gvn.transform(new ProjNode(trig, TypeFunc::Parms+0)); #ifdef ASSERT - Node* value_top = _gvn.transform(new (C) ProjNode(trig, TypeFunc::Parms+1)); + Node* value_top = _gvn.transform(new ProjNode(trig, TypeFunc::Parms+1)); assert(value_top == top(), "second value must be top"); #endif @@ -2011,10 +2050,10 @@ } void LibraryCallKit::inline_math_mathExact(Node* math, Node *test) { - Node* bol = _gvn.transform( new (C) BoolNode(test, BoolTest::overflow) ); + Node* bol = _gvn.transform( new BoolNode(test, BoolTest::overflow) ); IfNode* check = create_and_map_if(control(), bol, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN); - Node* fast_path = _gvn.transform( new (C) IfFalseNode(check)); - Node* slow_path = _gvn.transform( new (C) IfTrueNode(check) ); + Node* fast_path = _gvn.transform( new IfFalseNode(check)); + Node* slow_path = _gvn.transform( new IfTrueNode(check) ); { PreserveJVMState pjvms(this); @@ -2036,9 +2075,9 @@ bool LibraryCallKit::inline_math_overflow(Node* arg1, Node* arg2) { typedef typename OverflowOp::MathOp MathOp; - MathOp* mathOp = new(C) MathOp(arg1, arg2); + MathOp* mathOp = new MathOp(arg1, arg2); Node* operation = _gvn.transform( mathOp ); - Node* ofcheck = _gvn.transform( new(C) OverflowOp(arg1, arg2) ); + Node* ofcheck = _gvn.transform( new OverflowOp(arg1, arg2) ); inline_math_mathExact(operation, ofcheck); return true; } @@ -2106,7 +2145,7 @@ int cmp_op = Op_CmpI; Node* xkey = xvalue; Node* ykey = yvalue; - Node* ideal_cmpxy = _gvn.transform(new(C) CmpINode(xkey, ykey)); + Node* ideal_cmpxy = _gvn.transform(new CmpINode(xkey, ykey)); if (ideal_cmpxy->is_Cmp()) { // E.g., if we have CmpI(length - offset, count), // it might idealize to CmpI(length, count + offset) @@ -2199,7 +2238,7 @@ default: if (cmpxy == NULL) cmpxy = ideal_cmpxy; - best_bol = _gvn.transform(new(C) BoolNode(cmpxy, BoolTest::lt)); + best_bol = _gvn.transform(new BoolNode(cmpxy, BoolTest::lt)); // and fall through: case BoolTest::lt: // x < y case BoolTest::le: // x <= y @@ -2259,7 +2298,7 @@ return Type::AnyPtr; } else if (base_type == TypePtr::NULL_PTR) { // Since this is a NULL+long form, we have to switch to a rawptr. - base = _gvn.transform(new (C) CastX2PNode(offset)); + base = _gvn.transform(new CastX2PNode(offset)); offset = MakeConX(0); return Type::RawPtr; } else if (base_type->base() == Type::RawPtr) { @@ -2312,16 +2351,16 @@ Node* arg = argument(0); Node* n; switch (id) { - case vmIntrinsics::_numberOfLeadingZeros_i: n = new (C) CountLeadingZerosINode( arg); break; - case vmIntrinsics::_numberOfLeadingZeros_l: n = new (C) CountLeadingZerosLNode( arg); break; - case vmIntrinsics::_numberOfTrailingZeros_i: n = new (C) CountTrailingZerosINode(arg); break; - case vmIntrinsics::_numberOfTrailingZeros_l: n = new (C) CountTrailingZerosLNode(arg); break; - case vmIntrinsics::_bitCount_i: n = new (C) PopCountINode( arg); break; - case vmIntrinsics::_bitCount_l: n = new (C) PopCountLNode( arg); break; - case vmIntrinsics::_reverseBytes_c: n = new (C) ReverseBytesUSNode(0, arg); break; - case vmIntrinsics::_reverseBytes_s: n = new (C) ReverseBytesSNode( 0, arg); break; - case vmIntrinsics::_reverseBytes_i: n = new (C) ReverseBytesINode( 0, arg); break; - case vmIntrinsics::_reverseBytes_l: n = new (C) ReverseBytesLNode( 0, arg); break; + case vmIntrinsics::_numberOfLeadingZeros_i: n = new CountLeadingZerosINode( arg); break; + case vmIntrinsics::_numberOfLeadingZeros_l: n = new CountLeadingZerosLNode( arg); break; + case vmIntrinsics::_numberOfTrailingZeros_i: n = new CountTrailingZerosINode(arg); break; + case vmIntrinsics::_numberOfTrailingZeros_l: n = new CountTrailingZerosLNode(arg); break; + case vmIntrinsics::_bitCount_i: n = new PopCountINode( arg); break; + case vmIntrinsics::_bitCount_l: n = new PopCountLNode( arg); break; + case vmIntrinsics::_reverseBytes_c: n = new ReverseBytesUSNode(0, arg); break; + case vmIntrinsics::_reverseBytes_s: n = new ReverseBytesSNode( 0, arg); break; + case vmIntrinsics::_reverseBytes_i: n = new ReverseBytesINode( 0, arg); break; + case vmIntrinsics::_reverseBytes_l: n = new ReverseBytesLNode( 0, arg); break; default: fatal_unexpected_iid(id); break; } set_result(_gvn.transform(n)); @@ -2637,7 +2676,7 @@ break; case T_ADDRESS: // Cast to an int type. - p = _gvn.transform(new (C) CastP2XNode(NULL, p)); + p = _gvn.transform(new CastP2XNode(NULL, p)); p = ConvX2UL(p); break; default: @@ -2658,7 +2697,7 @@ case T_ADDRESS: // Repackage the long as a pointer. val = ConvL2X(val); - val = _gvn.transform(new (C) CastX2PNode(val)); + val = _gvn.transform(new CastX2PNode(val)); break; } @@ -2766,9 +2805,9 @@ // Generate the read or write prefetch Node *prefetch; if (is_store) { - prefetch = new (C) PrefetchWriteNode(i_o(), adr); + prefetch = new PrefetchWriteNode(i_o(), adr); } else { - prefetch = new (C) PrefetchReadNode(i_o(), adr); + prefetch = new PrefetchReadNode(i_o(), adr); } prefetch->init_req(0, control()); set_i_o(_gvn.transform(prefetch)); @@ -2906,22 +2945,22 @@ switch(type) { case T_INT: if (kind == LS_xadd) { - load_store = _gvn.transform(new (C) GetAndAddINode(control(), mem, adr, newval, adr_type)); + load_store = _gvn.transform(new GetAndAddINode(control(), mem, adr, newval, adr_type)); } else if (kind == LS_xchg) { - load_store = _gvn.transform(new (C) GetAndSetINode(control(), mem, adr, newval, adr_type)); + load_store = _gvn.transform(new GetAndSetINode(control(), mem, adr, newval, adr_type)); } else if (kind == LS_cmpxchg) { - load_store = _gvn.transform(new (C) CompareAndSwapINode(control(), mem, adr, newval, oldval)); + load_store = _gvn.transform(new CompareAndSwapINode(control(), mem, adr, newval, oldval)); } else { ShouldNotReachHere(); } break; case T_LONG: if (kind == LS_xadd) { - load_store = _gvn.transform(new (C) GetAndAddLNode(control(), mem, adr, newval, adr_type)); + load_store = _gvn.transform(new GetAndAddLNode(control(), mem, adr, newval, adr_type)); } else if (kind == LS_xchg) { - load_store = _gvn.transform(new (C) GetAndSetLNode(control(), mem, adr, newval, adr_type)); + load_store = _gvn.transform(new GetAndSetLNode(control(), mem, adr, newval, adr_type)); } else if (kind == LS_cmpxchg) { - load_store = _gvn.transform(new (C) CompareAndSwapLNode(control(), mem, adr, newval, oldval)); + load_store = _gvn.transform(new CompareAndSwapLNode(control(), mem, adr, newval, oldval)); } else { ShouldNotReachHere(); } @@ -2958,24 +2997,24 @@ #ifdef _LP64 if (adr->bottom_type()->is_ptr_to_narrowoop()) { - Node *newval_enc = _gvn.transform(new (C) EncodePNode(newval, newval->bottom_type()->make_narrowoop())); + Node *newval_enc = _gvn.transform(new EncodePNode(newval, newval->bottom_type()->make_narrowoop())); if (kind == LS_xchg) { - load_store = _gvn.transform(new (C) GetAndSetNNode(control(), mem, adr, - newval_enc, adr_type, value_type->make_narrowoop())); + load_store = _gvn.transform(new GetAndSetNNode(control(), mem, adr, + newval_enc, adr_type, value_type->make_narrowoop())); } else { assert(kind == LS_cmpxchg, "wrong LoadStore operation"); - Node *oldval_enc = _gvn.transform(new (C) EncodePNode(oldval, oldval->bottom_type()->make_narrowoop())); - load_store = _gvn.transform(new (C) CompareAndSwapNNode(control(), mem, adr, + Node *oldval_enc = _gvn.transform(new EncodePNode(oldval, oldval->bottom_type()->make_narrowoop())); + load_store = _gvn.transform(new CompareAndSwapNNode(control(), mem, adr, newval_enc, oldval_enc)); } } else #endif { if (kind == LS_xchg) { - load_store = _gvn.transform(new (C) GetAndSetPNode(control(), mem, adr, newval, adr_type, value_type->is_oopptr())); + load_store = _gvn.transform(new GetAndSetPNode(control(), mem, adr, newval, adr_type, value_type->is_oopptr())); } else { assert(kind == LS_cmpxchg, "wrong LoadStore operation"); - load_store = _gvn.transform(new (C) CompareAndSwapPNode(control(), mem, adr, newval, oldval)); + load_store = _gvn.transform(new CompareAndSwapPNode(control(), mem, adr, newval, oldval)); } } post_barrier(control(), load_store, base, adr, alias_idx, newval, T_OBJECT, true); @@ -2988,13 +3027,13 @@ // SCMemProjNodes represent the memory state of a LoadStore. Their // main role is to prevent LoadStore nodes from being optimized away // when their results aren't used. - Node* proj = _gvn.transform(new (C) SCMemProjNode(load_store)); + Node* proj = _gvn.transform(new SCMemProjNode(load_store)); set_memory(proj, alias_idx); if (type == T_OBJECT && kind == LS_xchg) { #ifdef _LP64 if (adr->bottom_type()->is_ptr_to_narrowoop()) { - load_store = _gvn.transform(new (C) DecodeNNode(load_store, load_store->get_ptr_type())); + load_store = _gvn.transform(new DecodeNNode(load_store, load_store->get_ptr_type())); } #endif if (can_move_pre_barrier()) { @@ -3136,7 +3175,7 @@ // can generate code to load it as unsigned byte. Node* inst = make_load(NULL, insp, TypeInt::UBYTE, T_BOOLEAN, MemNode::unordered); Node* bits = intcon(InstanceKlass::fully_initialized); - test = _gvn.transform(new (C) SubINode(inst, bits)); + test = _gvn.transform(new SubINode(inst, bits)); // The 'test' is non-zero if we need to take a slow path. } @@ -3160,9 +3199,9 @@ Node* insp = basic_plus_adr(kls, in_bytes(offset)); Node* tvalue = make_load(NULL, insp, TypeLong::LONG, T_LONG, MemNode::unordered); Node* bits = longcon(~0x03l); // ignore bit 0 & 1 - Node* andl = _gvn.transform(new (C) AndLNode(tvalue, bits)); + Node* andl = _gvn.transform(new AndLNode(tvalue, bits)); Node* clsused = longcon(0x01l); // set the class bit - Node* orl = _gvn.transform(new (C) OrLNode(tvalue, clsused)); + Node* orl = _gvn.transform(new OrLNode(tvalue, clsused)); const TypePtr *adr_type = _gvn.type(insp)->isa_ptr(); store_to_memory(control(), insp, orl, T_LONG, adr_type, MemNode::unordered); @@ -3198,9 +3237,9 @@ const TypeFunc* tf = OptoRuntime::void_long_Type(); const TypePtr* no_memory_effects = NULL; Node* time = make_runtime_call(RC_LEAF, tf, funcAddr, funcName, no_memory_effects); - Node* value = _gvn.transform(new (C) ProjNode(time, TypeFunc::Parms+0)); + Node* value = _gvn.transform(new ProjNode(time, TypeFunc::Parms+0)); #ifdef ASSERT - Node* value_top = _gvn.transform(new (C) ProjNode(time, TypeFunc::Parms+1)); + Node* value_top = _gvn.transform(new ProjNode(time, TypeFunc::Parms+1)); assert(value_top == top(), "second value must be top"); #endif set_result(value); @@ -3241,18 +3280,18 @@ // out of the function. insert_mem_bar(Op_MemBarCPUOrder); - RegionNode* result_rgn = new (C) RegionNode(PATH_LIMIT); - PhiNode* result_val = new (C) PhiNode(result_rgn, TypeInt::BOOL); - - RegionNode* slow_region = new (C) RegionNode(1); + RegionNode* result_rgn = new RegionNode(PATH_LIMIT); + PhiNode* result_val = new PhiNode(result_rgn, TypeInt::BOOL); + + RegionNode* slow_region = new RegionNode(1); record_for_igvn(slow_region); // (a) Receiving thread must be the current thread. Node* rec_thr = argument(0); Node* tls_ptr = NULL; Node* cur_thr = generate_current_thread(tls_ptr); - Node* cmp_thr = _gvn.transform(new (C) CmpPNode(cur_thr, rec_thr)); - Node* bol_thr = _gvn.transform(new (C) BoolNode(cmp_thr, BoolTest::ne)); + Node* cmp_thr = _gvn.transform(new CmpPNode(cur_thr, rec_thr)); + Node* bol_thr = _gvn.transform(new BoolNode(cmp_thr, BoolTest::ne)); generate_slow_guard(bol_thr, slow_region); @@ -3263,33 +3302,33 @@ // Set the control input on the field _interrupted read to prevent it floating up. Node* int_bit = make_load(control(), p, TypeInt::BOOL, T_INT, MemNode::unordered); - Node* cmp_bit = _gvn.transform(new (C) CmpINode(int_bit, intcon(0))); - Node* bol_bit = _gvn.transform(new (C) BoolNode(cmp_bit, BoolTest::ne)); + Node* cmp_bit = _gvn.transform(new CmpINode(int_bit, intcon(0))); + Node* bol_bit = _gvn.transform(new BoolNode(cmp_bit, BoolTest::ne)); IfNode* iff_bit = create_and_map_if(control(), bol_bit, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN); // First fast path: if (!TLS._interrupted) return false; - Node* false_bit = _gvn.transform(new (C) IfFalseNode(iff_bit)); + Node* false_bit = _gvn.transform(new IfFalseNode(iff_bit)); result_rgn->init_req(no_int_result_path, false_bit); result_val->init_req(no_int_result_path, intcon(0)); // drop through to next case - set_control( _gvn.transform(new (C) IfTrueNode(iff_bit))); + set_control( _gvn.transform(new IfTrueNode(iff_bit))); #ifndef TARGET_OS_FAMILY_windows // (c) Or, if interrupt bit is set and clear_int is false, use 2nd fast path. Node* clr_arg = argument(1); - Node* cmp_arg = _gvn.transform(new (C) CmpINode(clr_arg, intcon(0))); - Node* bol_arg = _gvn.transform(new (C) BoolNode(cmp_arg, BoolTest::ne)); + Node* cmp_arg = _gvn.transform(new CmpINode(clr_arg, intcon(0))); + Node* bol_arg = _gvn.transform(new BoolNode(cmp_arg, BoolTest::ne)); IfNode* iff_arg = create_and_map_if(control(), bol_arg, PROB_FAIR, COUNT_UNKNOWN); // Second fast path: ... else if (!clear_int) return true; - Node* false_arg = _gvn.transform(new (C) IfFalseNode(iff_arg)); + Node* false_arg = _gvn.transform(new IfFalseNode(iff_arg)); result_rgn->init_req(no_clear_result_path, false_arg); result_val->init_req(no_clear_result_path, intcon(1)); // drop through to next case - set_control( _gvn.transform(new (C) IfTrueNode(iff_arg))); + set_control( _gvn.transform(new IfTrueNode(iff_arg))); #else // To return true on Windows you must read the _interrupted field // and check the the event state i.e. take the slow path. @@ -3375,9 +3414,9 @@ Node* mods = make_load(NULL, modp, TypeInt::INT, T_INT, MemNode::unordered); Node* mask = intcon(modifier_mask); Node* bits = intcon(modifier_bits); - Node* mbit = _gvn.transform(new (C) AndINode(mods, mask)); - Node* cmp = _gvn.transform(new (C) CmpINode(mbit, bits)); - Node* bol = _gvn.transform(new (C) BoolNode(cmp, BoolTest::ne)); + Node* mbit = _gvn.transform(new AndINode(mods, mask)); + Node* cmp = _gvn.transform(new CmpINode(mbit, bits)); + Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::ne)); return generate_fair_guard(bol, region); } Node* LibraryCallKit::generate_interface_guard(Node* kls, RegionNode* region) { @@ -3450,9 +3489,9 @@ #endif // Null-check the mirror, and the mirror's klass ptr (in case it is a primitive). - RegionNode* region = new (C) RegionNode(PATH_LIMIT); + RegionNode* region = new RegionNode(PATH_LIMIT); record_for_igvn(region); - PhiNode* phi = new (C) PhiNode(region, return_type); + PhiNode* phi = new PhiNode(region, return_type); // The mirror will never be null of Reflection.getClassAccessFlags, however // it may be null for Class.isInstance or Class.getModifiers. Throw a NPE @@ -3594,8 +3633,8 @@ PATH_LIMIT }; - RegionNode* region = new (C) RegionNode(PATH_LIMIT); - Node* phi = new (C) PhiNode(region, TypeInt::BOOL); + RegionNode* region = new RegionNode(PATH_LIMIT); + Node* phi = new PhiNode(region, TypeInt::BOOL); record_for_igvn(region); const TypePtr* adr_type = TypeRawPtr::BOTTOM; // memory type of loads @@ -3642,8 +3681,8 @@ set_control(region->in(_prim_0_path)); // go back to first null check if (!stopped()) { // Since superc is primitive, make a guard for the superc==subc case. - Node* cmp_eq = _gvn.transform(new (C) CmpPNode(args[0], args[1])); - Node* bol_eq = _gvn.transform(new (C) BoolNode(cmp_eq, BoolTest::eq)); + Node* cmp_eq = _gvn.transform(new CmpPNode(args[0], args[1])); + Node* bol_eq = _gvn.transform(new BoolNode(cmp_eq, BoolTest::eq)); generate_guard(bol_eq, region, PROB_FAIR); if (region->req() == PATH_LIMIT+1) { // A guard was added. If the added guard is taken, superc==subc. @@ -3708,11 +3747,11 @@ ? ((jint)Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift) : Klass::_lh_neutral_value); - Node* cmp = _gvn.transform(new(C) CmpINode(layout_val, intcon(nval))); + Node* cmp = _gvn.transform(new CmpINode(layout_val, intcon(nval))); BoolTest::mask btest = BoolTest::lt; // correct for testing is_[obj]array // invert the test if we are looking for a non-array if (not_array) btest = BoolTest(btest).negate(); - Node* bol = _gvn.transform(new(C) BoolNode(cmp, btest)); + Node* bol = _gvn.transform(new BoolNode(cmp, btest)); return generate_fair_guard(bol, region); } @@ -3728,12 +3767,10 @@ if (stopped()) return true; enum { _normal_path = 1, _slow_path = 2, PATH_LIMIT }; - RegionNode* result_reg = new(C) RegionNode(PATH_LIMIT); - PhiNode* result_val = new(C) PhiNode(result_reg, - TypeInstPtr::NOTNULL); - PhiNode* result_io = new(C) PhiNode(result_reg, Type::ABIO); - PhiNode* result_mem = new(C) PhiNode(result_reg, Type::MEMORY, - TypePtr::BOTTOM); + RegionNode* result_reg = new RegionNode(PATH_LIMIT); + PhiNode* result_val = new PhiNode(result_reg, TypeInstPtr::NOTNULL); + PhiNode* result_io = new PhiNode(result_reg, Type::ABIO); + PhiNode* result_mem = new PhiNode(result_reg, Type::MEMORY, TypePtr::BOTTOM); bool never_see_null = !too_many_traps(Deoptimization::Reason_null_check); Node* klass_node = load_array_klass_from_mirror(mirror, never_see_null, @@ -3840,7 +3877,7 @@ Node* klass_node = load_klass_from_mirror(array_type_mirror, false, NULL, 0); klass_node = null_check(klass_node); - RegionNode* bailout = new (C) RegionNode(1); + RegionNode* bailout = new RegionNode(1); record_for_igvn(bailout); // Despite the generic type of Arrays.copyOf, the mirror might be int, int[], etc. @@ -3850,7 +3887,7 @@ // Improve the klass node's type from the new optimistic assumption: ciKlass* ak = ciArrayKlass::make(env()->Object_klass()); const Type* akls = TypeKlassPtr::make(TypePtr::NotNull, ak, 0/*offset*/); - Node* cast = new (C) CastPPNode(klass_node, akls); + Node* cast = new CastPPNode(klass_node, akls); cast->init_req(0, control()); klass_node = _gvn.transform(cast); } @@ -3861,7 +3898,7 @@ Node* length = end; if (_gvn.type(start) != TypeInt::ZERO) { - length = _gvn.transform(new (C) SubINode(end, start)); + length = _gvn.transform(new SubINode(end, start)); } // Bail out if length is negative. @@ -3880,7 +3917,7 @@ if (!stopped()) { // How many elements will we copy from the original? // The answer is MinI(orig_length - start, length). - Node* orig_tail = _gvn.transform(new (C) SubINode(orig_length, start)); + Node* orig_tail = _gvn.transform(new SubINode(orig_length, start)); Node* moved = generate_min_max(vmIntrinsics::_min, orig_tail, length); newcopy = new_array(klass_node, length, 0); // no argments to push @@ -3927,8 +3964,8 @@ const TypePtr* native_call_addr = TypeMetadataPtr::make(method); Node* native_call = makecon(native_call_addr); - Node* chk_native = _gvn.transform(new(C) CmpPNode(target_call, native_call)); - Node* test_native = _gvn.transform(new(C) BoolNode(chk_native, BoolTest::ne)); + Node* chk_native = _gvn.transform(new CmpPNode(target_call, native_call)); + Node* test_native = _gvn.transform(new BoolNode(chk_native, BoolTest::ne)); return generate_slow_guard(test_native, slow_region); } @@ -3953,7 +3990,7 @@ CallJavaNode* slow_call; if (is_static) { assert(!is_virtual, ""); - slow_call = new(C) CallStaticJavaNode(C, tf, + slow_call = new CallStaticJavaNode(C, tf, SharedRuntime::get_resolve_static_call_stub(), method, bci()); } else if (is_virtual) { @@ -3969,12 +4006,12 @@ assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index, err_msg_res("bad index %d", vtable_index)); } - slow_call = new(C) CallDynamicJavaNode(tf, + slow_call = new CallDynamicJavaNode(tf, SharedRuntime::get_resolve_virtual_call_stub(), method, vtable_index, bci()); } else { // neither virtual nor static: opt_virtual null_check_receiver(); - slow_call = new(C) CallStaticJavaNode(C, tf, + slow_call = new CallStaticJavaNode(C, tf, SharedRuntime::get_resolve_opt_virtual_call_stub(), method, bci()); slow_call->set_optimized_virtual(true); @@ -3985,20 +4022,21 @@ } -//------------------------------inline_native_hashcode-------------------- -// Build special case code for calls to hashCode on an object. +/** + * Build special case code for calls to hashCode on an object. This call may + * be virtual (invokevirtual) or bound (invokespecial). For each case we generate + * slightly different code. + */ bool LibraryCallKit::inline_native_hashcode(bool is_virtual, bool is_static) { assert(is_static == callee()->is_static(), "correct intrinsic selection"); assert(!(is_virtual && is_static), "either virtual, special, or static"); enum { _slow_path = 1, _fast_path, _null_path, PATH_LIMIT }; - RegionNode* result_reg = new(C) RegionNode(PATH_LIMIT); - PhiNode* result_val = new(C) PhiNode(result_reg, - TypeInt::INT); - PhiNode* result_io = new(C) PhiNode(result_reg, Type::ABIO); - PhiNode* result_mem = new(C) PhiNode(result_reg, Type::MEMORY, - TypePtr::BOTTOM); + RegionNode* result_reg = new RegionNode(PATH_LIMIT); + PhiNode* result_val = new PhiNode(result_reg, TypeInt::INT); + PhiNode* result_io = new PhiNode(result_reg, Type::ABIO); + PhiNode* result_mem = new PhiNode(result_reg, Type::MEMORY, TypePtr::BOTTOM); Node* obj = NULL; if (!is_static) { // Check for hashing null object @@ -4024,15 +4062,9 @@ return true; } - // After null check, get the object's klass. - Node* obj_klass = load_object_klass(obj); - - // This call may be virtual (invokevirtual) or bound (invokespecial). - // For each case we generate slightly different code. - // We only go to the fast case code if we pass a number of guards. The // paths which do not pass are accumulated in the slow_region. - RegionNode* slow_region = new (C) RegionNode(1); + RegionNode* slow_region = new RegionNode(1); record_for_igvn(slow_region); // If this is a virtual call, we generate a funny guard. We pull out @@ -4042,19 +4074,24 @@ // guard for non-virtual calls -- the caller is known to be the native // Object hashCode(). if (is_virtual) { + // After null check, get the object's klass. + Node* obj_klass = load_object_klass(obj); generate_virtual_guard(obj_klass, slow_region); } // Get the header out of the object, use LoadMarkNode when available Node* header_addr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes()); - Node* header = make_load(control(), header_addr, TypeX_X, TypeX_X->basic_type(), MemNode::unordered); + // The control of the load must be NULL. Otherwise, the load can move before + // the null check after castPP removal. + Node* no_ctrl = NULL; + Node* header = make_load(no_ctrl, header_addr, TypeX_X, TypeX_X->basic_type(), MemNode::unordered); // Test the header to see if it is unlocked. Node *lock_mask = _gvn.MakeConX(markOopDesc::biased_lock_mask_in_place); - Node *lmasked_header = _gvn.transform(new (C) AndXNode(header, lock_mask)); + Node *lmasked_header = _gvn.transform(new AndXNode(header, lock_mask)); Node *unlocked_val = _gvn.MakeConX(markOopDesc::unlocked_value); - Node *chk_unlocked = _gvn.transform(new (C) CmpXNode( lmasked_header, unlocked_val)); - Node *test_unlocked = _gvn.transform(new (C) BoolNode( chk_unlocked, BoolTest::ne)); + Node *chk_unlocked = _gvn.transform(new CmpXNode( lmasked_header, unlocked_val)); + Node *test_unlocked = _gvn.transform(new BoolNode( chk_unlocked, BoolTest::ne)); generate_slow_guard(test_unlocked, slow_region); @@ -4064,17 +4101,17 @@ // vm: see markOop.hpp. Node *hash_mask = _gvn.intcon(markOopDesc::hash_mask); Node *hash_shift = _gvn.intcon(markOopDesc::hash_shift); - Node *hshifted_header= _gvn.transform(new (C) URShiftXNode(header, hash_shift)); + Node *hshifted_header= _gvn.transform(new URShiftXNode(header, hash_shift)); // This hack lets the hash bits live anywhere in the mark object now, as long // as the shift drops the relevant bits into the low 32 bits. Note that // Java spec says that HashCode is an int so there's no point in capturing // an 'X'-sized hashcode (32 in 32-bit build or 64 in 64-bit build). hshifted_header = ConvX2I(hshifted_header); - Node *hash_val = _gvn.transform(new (C) AndINode(hshifted_header, hash_mask)); + Node *hash_val = _gvn.transform(new AndINode(hshifted_header, hash_mask)); Node *no_hash_val = _gvn.intcon(markOopDesc::no_hash); - Node *chk_assigned = _gvn.transform(new (C) CmpINode( hash_val, no_hash_val)); - Node *test_assigned = _gvn.transform(new (C) BoolNode( chk_assigned, BoolTest::eq)); + Node *chk_assigned = _gvn.transform(new CmpINode( hash_val, no_hash_val)); + Node *test_assigned = _gvn.transform(new BoolNode( chk_assigned, BoolTest::eq)); generate_slow_guard(test_assigned, slow_region); @@ -4213,19 +4250,19 @@ Node* result; switch (id) { - case vmIntrinsics::_floatToRawIntBits: result = new (C) MoveF2INode(arg); break; - case vmIntrinsics::_intBitsToFloat: result = new (C) MoveI2FNode(arg); break; - case vmIntrinsics::_doubleToRawLongBits: result = new (C) MoveD2LNode(arg); break; - case vmIntrinsics::_longBitsToDouble: result = new (C) MoveL2DNode(arg); break; + case vmIntrinsics::_floatToRawIntBits: result = new MoveF2INode(arg); break; + case vmIntrinsics::_intBitsToFloat: result = new MoveI2FNode(arg); break; + case vmIntrinsics::_doubleToRawLongBits: result = new MoveD2LNode(arg); break; + case vmIntrinsics::_longBitsToDouble: result = new MoveL2DNode(arg); break; case vmIntrinsics::_doubleToLongBits: { // two paths (plus control) merge in a wood - RegionNode *r = new (C) RegionNode(3); - Node *phi = new (C) PhiNode(r, TypeLong::LONG); - - Node *cmpisnan = _gvn.transform(new (C) CmpDNode(arg, arg)); + RegionNode *r = new RegionNode(3); + Node *phi = new PhiNode(r, TypeLong::LONG); + + Node *cmpisnan = _gvn.transform(new CmpDNode(arg, arg)); // Build the boolean node - Node *bolisnan = _gvn.transform(new (C) BoolNode(cmpisnan, BoolTest::ne)); + Node *bolisnan = _gvn.transform(new BoolNode(cmpisnan, BoolTest::ne)); // Branch either way. // NaN case is less traveled, which makes all the difference. @@ -4233,7 +4270,7 @@ Node *opt_isnan = _gvn.transform(ifisnan); assert( opt_isnan->is_If(), "Expect an IfNode"); IfNode *opt_ifisnan = (IfNode*)opt_isnan; - Node *iftrue = _gvn.transform(new (C) IfTrueNode(opt_ifisnan)); + Node *iftrue = _gvn.transform(new IfTrueNode(opt_ifisnan)); set_control(iftrue); @@ -4243,10 +4280,10 @@ r->init_req(1, iftrue); // Else fall through - Node *iffalse = _gvn.transform(new (C) IfFalseNode(opt_ifisnan)); + Node *iffalse = _gvn.transform(new IfFalseNode(opt_ifisnan)); set_control(iffalse); - phi->init_req(2, _gvn.transform(new (C) MoveD2LNode(arg))); + phi->init_req(2, _gvn.transform(new MoveD2LNode(arg))); r->init_req(2, iffalse); // Post merge @@ -4261,12 +4298,12 @@ case vmIntrinsics::_floatToIntBits: { // two paths (plus control) merge in a wood - RegionNode *r = new (C) RegionNode(3); - Node *phi = new (C) PhiNode(r, TypeInt::INT); - - Node *cmpisnan = _gvn.transform(new (C) CmpFNode(arg, arg)); + RegionNode *r = new RegionNode(3); + Node *phi = new PhiNode(r, TypeInt::INT); + + Node *cmpisnan = _gvn.transform(new CmpFNode(arg, arg)); // Build the boolean node - Node *bolisnan = _gvn.transform(new (C) BoolNode(cmpisnan, BoolTest::ne)); + Node *bolisnan = _gvn.transform(new BoolNode(cmpisnan, BoolTest::ne)); // Branch either way. // NaN case is less traveled, which makes all the difference. @@ -4274,7 +4311,7 @@ Node *opt_isnan = _gvn.transform(ifisnan); assert( opt_isnan->is_If(), "Expect an IfNode"); IfNode *opt_ifisnan = (IfNode*)opt_isnan; - Node *iftrue = _gvn.transform(new (C) IfTrueNode(opt_ifisnan)); + Node *iftrue = _gvn.transform(new IfTrueNode(opt_ifisnan)); set_control(iftrue); @@ -4284,10 +4321,10 @@ r->init_req(1, iftrue); // Else fall through - Node *iffalse = _gvn.transform(new (C) IfFalseNode(opt_ifisnan)); + Node *iffalse = _gvn.transform(new IfFalseNode(opt_ifisnan)); set_control(iffalse); - phi->init_req(2, _gvn.transform(new (C) MoveF2INode(arg))); + phi->init_req(2, _gvn.transform(new MoveF2INode(arg))); r->init_req(2, iffalse); // Post merge @@ -4403,8 +4440,8 @@ // Compute the length also, if needed: Node* countx = size; - countx = _gvn.transform(new (C) SubXNode(countx, MakeConX(base_off))); - countx = _gvn.transform(new (C) URShiftXNode(countx, intcon(LogBytesPerLong) )); + countx = _gvn.transform(new SubXNode(countx, MakeConX(base_off))); + countx = _gvn.transform(new URShiftXNode(countx, intcon(LogBytesPerLong) )); const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; bool disjoint_bases = true; @@ -4493,12 +4530,10 @@ _instance_path, // plain instance allocation, plus arrayof_long_arraycopy PATH_LIMIT }; - RegionNode* result_reg = new(C) RegionNode(PATH_LIMIT); - result_val = new(C) PhiNode(result_reg, - TypeInstPtr::NOTNULL); - PhiNode* result_i_o = new(C) PhiNode(result_reg, Type::ABIO); - PhiNode* result_mem = new(C) PhiNode(result_reg, Type::MEMORY, - TypePtr::BOTTOM); + RegionNode* result_reg = new RegionNode(PATH_LIMIT); + result_val = new PhiNode(result_reg, TypeInstPtr::NOTNULL); + PhiNode* result_i_o = new PhiNode(result_reg, Type::ABIO); + PhiNode* result_mem = new PhiNode(result_reg, Type::MEMORY, TypePtr::BOTTOM); record_for_igvn(result_reg); const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; @@ -4554,7 +4589,7 @@ // We only go to the instance fast case code if we pass a number of guards. // The paths which do not pass are accumulated in the slow_region. - RegionNode* slow_region = new (C) RegionNode(1); + RegionNode* slow_region = new RegionNode(1); record_for_igvn(slow_region); if (!stopped()) { // It's an instance (we did array above). Make the slow-path tests. @@ -4583,7 +4618,10 @@ // It's an instance, and it passed the slow-path tests. PreserveJVMState pjvms(this); Node* obj_size = NULL; - Node* alloc_obj = new_instance(obj_klass, NULL, &obj_size); + // Need to deoptimize on exception from allocation since Object.clone intrinsic + // is reexecuted if deoptimization occurs and there could be problems when merging + // exception state between multiple Object.clone versions (reexecute=true vs reexecute=false). + Node* alloc_obj = new_instance(obj_klass, NULL, &obj_size, /*deoptimize_on_exception=*/true); copy_to_clone(obj, alloc_obj, obj_size, false, !use_ReduceInitialCardMarks()); @@ -4811,7 +4849,7 @@ // (8) dest_offset + length must not exceed length of dest. // (9) each element of an oop array must be assignable - RegionNode* slow_region = new (C) RegionNode(1); + RegionNode* slow_region = new RegionNode(1); record_for_igvn(slow_region); // (3) operands must not be null @@ -4899,7 +4937,7 @@ RegionNode* slow_region) { if (slow_region == NULL) { - slow_region = new(C) RegionNode(1); + slow_region = new RegionNode(1); record_for_igvn(slow_region); } @@ -4947,9 +4985,9 @@ bcopy_path = 5, // copy primitive array by 64-bit blocks PATH_LIMIT = 6 }; - RegionNode* result_region = new(C) RegionNode(PATH_LIMIT); - PhiNode* result_i_o = new(C) PhiNode(result_region, Type::ABIO); - PhiNode* result_memory = new(C) PhiNode(result_region, Type::MEMORY, adr_type); + RegionNode* result_region = new RegionNode(PATH_LIMIT); + PhiNode* result_i_o = new PhiNode(result_region, Type::ABIO); + PhiNode* result_memory = new PhiNode(result_region, Type::MEMORY, adr_type); record_for_igvn(result_region); _gvn.set_type_bottom(result_i_o); _gvn.set_type_bottom(result_memory); @@ -5023,8 +5061,7 @@ // are dest_head = dest[0..off] and dest_tail = dest[off+len..dest.length]. Node* dest_size = alloc->in(AllocateNode::AllocSize); Node* dest_length = alloc->in(AllocateNode::ALength); - Node* dest_tail = _gvn.transform(new(C) AddINode(dest_offset, - copy_length)); + Node* dest_tail = _gvn.transform(new AddINode(dest_offset, copy_length)); // If there is a head section that needs zeroing, do it now. if (find_int_con(dest_offset, -1) != 0) { @@ -5040,8 +5077,8 @@ // the copy to a more hardware-friendly word size of 64 bits. Node* tail_ctl = NULL; if (!stopped() && !dest_tail->eqv_uncast(dest_length)) { - Node* cmp_lt = _gvn.transform(new(C) CmpINode(dest_tail, dest_length)); - Node* bol_lt = _gvn.transform(new(C) BoolNode(cmp_lt, BoolTest::lt)); + Node* cmp_lt = _gvn.transform(new CmpINode(dest_tail, dest_length)); + Node* bol_lt = _gvn.transform(new BoolNode(cmp_lt, BoolTest::lt)); tail_ctl = generate_slow_guard(bol_lt, NULL); assert(tail_ctl != NULL || !stopped(), "must be an outcome"); } @@ -5075,8 +5112,8 @@ dest_size); } else { // Make a local merge. - Node* done_ctl = new(C) RegionNode(3); - Node* done_mem = new(C) PhiNode(done_ctl, Type::MEMORY, adr_type); + Node* done_ctl = new RegionNode(3); + Node* done_mem = new PhiNode(done_ctl, Type::MEMORY, adr_type); done_ctl->init_req(1, notail_ctl); done_mem->init_req(1, memory(adr_type)); generate_clear_array(adr_type, dest, basic_elem_type, @@ -5171,21 +5208,21 @@ // Clean up after the checked call. // The returned value is either 0 or -1^K, // where K = number of partially transferred array elements. - Node* cmp = _gvn.transform(new(C) CmpINode(checked_value, intcon(0))); - Node* bol = _gvn.transform(new(C) BoolNode(cmp, BoolTest::eq)); + Node* cmp = _gvn.transform(new CmpINode(checked_value, intcon(0))); + Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::eq)); IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN); // If it is 0, we are done, so transfer to the end. - Node* checks_done = _gvn.transform(new(C) IfTrueNode(iff)); + Node* checks_done = _gvn.transform(new IfTrueNode(iff)); result_region->init_req(checked_path, checks_done); result_i_o ->init_req(checked_path, checked_i_o); result_memory->init_req(checked_path, checked_mem); // If it is not zero, merge into the slow call. - set_control( _gvn.transform(new(C) IfFalseNode(iff) )); - RegionNode* slow_reg2 = new(C) RegionNode(3); - PhiNode* slow_i_o2 = new(C) PhiNode(slow_reg2, Type::ABIO); - PhiNode* slow_mem2 = new(C) PhiNode(slow_reg2, Type::MEMORY, adr_type); + set_control( _gvn.transform(new IfFalseNode(iff) )); + RegionNode* slow_reg2 = new RegionNode(3); + PhiNode* slow_i_o2 = new PhiNode(slow_reg2, Type::ABIO); + PhiNode* slow_mem2 = new PhiNode(slow_reg2, Type::MEMORY, adr_type); record_for_igvn(slow_reg2); slow_reg2 ->init_req(1, slow_control); slow_i_o2 ->init_req(1, slow_i_o); @@ -5205,16 +5242,16 @@ } else { // We must continue the copy exactly where it failed, or else // another thread might see the wrong number of writes to dest. - Node* checked_offset = _gvn.transform(new(C) XorINode(checked_value, intcon(-1))); - Node* slow_offset = new(C) PhiNode(slow_reg2, TypeInt::INT); + Node* checked_offset = _gvn.transform(new XorINode(checked_value, intcon(-1))); + Node* slow_offset = new PhiNode(slow_reg2, TypeInt::INT); slow_offset->init_req(1, intcon(0)); slow_offset->init_req(2, checked_offset); slow_offset = _gvn.transform(slow_offset); // Adjust the arguments by the conditionally incoming offset. - Node* src_off_plus = _gvn.transform(new(C) AddINode(src_offset, slow_offset)); - Node* dest_off_plus = _gvn.transform(new(C) AddINode(dest_offset, slow_offset)); - Node* length_minus = _gvn.transform(new(C) SubINode(copy_length, slow_offset)); + Node* src_off_plus = _gvn.transform(new AddINode(src_offset, slow_offset)); + Node* dest_off_plus = _gvn.transform(new AddINode(dest_offset, slow_offset)); + Node* length_minus = _gvn.transform(new SubINode(copy_length, slow_offset)); // Tweak the node variables to adjust the code produced below: src_offset = src_off_plus; @@ -5435,10 +5472,10 @@ int end_round = (-1 << scale) & (BytesPerLong - 1); Node* end = ConvI2X(slice_len); if (scale != 0) - end = _gvn.transform(new(C) LShiftXNode(end, intcon(scale) )); + end = _gvn.transform(new LShiftXNode(end, intcon(scale) )); end_base += end_round; - end = _gvn.transform(new(C) AddXNode(end, MakeConX(end_base))); - end = _gvn.transform(new(C) AndXNode(end, MakeConX(~end_round))); + end = _gvn.transform(new AddXNode(end, MakeConX(end_base))); + end = _gvn.transform(new AndXNode(end, MakeConX(~end_round))); mem = ClearArrayNode::clear_memory(control(), mem, dest, start_con, end, &_gvn); } else if (start_con < 0 && dest_size != top()) { @@ -5447,8 +5484,8 @@ Node* start = slice_idx; start = ConvI2X(start); if (scale != 0) - start = _gvn.transform(new(C) LShiftXNode( start, intcon(scale) )); - start = _gvn.transform(new(C) AddXNode(start, MakeConX(abase))); + start = _gvn.transform(new LShiftXNode( start, intcon(scale) )); + start = _gvn.transform(new AddXNode(start, MakeConX(abase))); if ((bump_bit | clear_low) != 0) { int to_clear = (bump_bit | clear_low); // Align up mod 8, then store a jint zero unconditionally @@ -5459,14 +5496,14 @@ assert((abase & to_clear) == 0, "array base must be long-aligned"); } else { // Bump 'start' up to (or past) the next jint boundary: - start = _gvn.transform(new(C) AddXNode(start, MakeConX(bump_bit))); + start = _gvn.transform(new AddXNode(start, MakeConX(bump_bit))); assert((abase & clear_low) == 0, "array base must be int-aligned"); } // Round bumped 'start' down to jlong boundary in body of array. - start = _gvn.transform(new(C) AndXNode(start, MakeConX(~to_clear))); + start = _gvn.transform(new AndXNode(start, MakeConX(~to_clear))); if (bump_bit != 0) { // Store a zero to the immediately preceding jint: - Node* x1 = _gvn.transform(new(C) AddXNode(start, MakeConX(-bump_bit))); + Node* x1 = _gvn.transform(new AddXNode(start, MakeConX(-bump_bit))); Node* p1 = basic_plus_adr(dest, x1); mem = StoreNode::make(_gvn, control(), mem, p1, adr_type, intcon(0), T_INT, MemNode::unordered); mem = _gvn.transform(mem); @@ -5533,8 +5570,8 @@ Node* sptr = basic_plus_adr(src, src_off); Node* dptr = basic_plus_adr(dest, dest_off); Node* countx = dest_size; - countx = _gvn.transform(new (C) SubXNode(countx, MakeConX(dest_off))); - countx = _gvn.transform(new (C) URShiftXNode(countx, intcon(LogBytesPerLong))); + countx = _gvn.transform(new SubXNode(countx, MakeConX(dest_off))); + countx = _gvn.transform(new URShiftXNode(countx, intcon(LogBytesPerLong))); bool disjoint_bases = true; // since alloc != NULL generate_unchecked_arraycopy(adr_type, T_LONG, disjoint_bases, @@ -5584,7 +5621,7 @@ // super_check_offset, for the desired klass. int sco_offset = in_bytes(Klass::super_check_offset_offset()); Node* p3 = basic_plus_adr(dest_elem_klass, sco_offset); - Node* n3 = new(C) LoadINode(NULL, memory(p3), p3, _gvn.type(p3)->is_ptr(), TypeInt::INT, MemNode::unordered); + Node* n3 = new LoadINode(NULL, memory(p3), p3, _gvn.type(p3)->is_ptr(), TypeInt::INT, MemNode::unordered); Node* check_offset = ConvI2X(_gvn.transform(n3)); Node* check_value = dest_elem_klass; @@ -5602,7 +5639,7 @@ check_offset XTOP, check_value); - return _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms)); + return _gvn.transform(new ProjNode(call, TypeFunc::Parms)); } @@ -5624,7 +5661,7 @@ copyfunc_addr, "generic_arraycopy", adr_type, src, src_offset, dest, dest_offset, copy_length); - return _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms)); + return _gvn.transform(new ProjNode(call, TypeFunc::Parms)); } // Helper function; generates the fast out-of-line call to an arraycopy stub. @@ -5691,9 +5728,9 @@ // 'dst_start' points to dst array + scaled offset const TypeAryPtr* mtype = TypeAryPtr::BYTES; - Node* enc = new (C) EncodeISOArrayNode(control(), memory(mtype), src_start, dst_start, length); + Node* enc = new EncodeISOArrayNode(control(), memory(mtype), src_start, dst_start, length); enc = _gvn.transform(enc); - Node* res_mem = _gvn.transform(new (C) SCMemProjNode(enc)); + Node* res_mem = _gvn.transform(new SCMemProjNode(enc)); set_memory(res_mem, mtype); set_result(enc); return true; @@ -5718,18 +5755,18 @@ */ Node* M1 = intcon(-1); - crc = _gvn.transform(new (C) XorINode(crc, M1)); - Node* result = _gvn.transform(new (C) XorINode(crc, b)); - result = _gvn.transform(new (C) AndINode(result, intcon(0xFF))); + crc = _gvn.transform(new XorINode(crc, M1)); + Node* result = _gvn.transform(new XorINode(crc, b)); + result = _gvn.transform(new AndINode(result, intcon(0xFF))); Node* base = makecon(TypeRawPtr::make(StubRoutines::crc_table_addr())); - Node* offset = _gvn.transform(new (C) LShiftINode(result, intcon(0x2))); + Node* offset = _gvn.transform(new LShiftINode(result, intcon(0x2))); Node* adr = basic_plus_adr(top(), base, ConvI2X(offset)); result = make_load(control(), adr, TypeInt::INT, T_INT, MemNode::unordered); - crc = _gvn.transform(new (C) URShiftINode(crc, intcon(8))); - result = _gvn.transform(new (C) XorINode(crc, result)); - result = _gvn.transform(new (C) XorINode(result, M1)); + crc = _gvn.transform(new URShiftINode(crc, intcon(8))); + result = _gvn.transform(new XorINode(crc, result)); + result = _gvn.transform(new XorINode(result, M1)); set_result(result); return true; } @@ -5773,7 +5810,7 @@ Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::updateBytesCRC32_Type(), stubAddr, stubName, TypePtr::BOTTOM, crc, src_start, length); - Node* result = _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms)); + Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms)); set_result(result); return true; } @@ -5792,7 +5829,7 @@ Node* length = argument(4); // type: int src = ConvL2X(src); // adjust Java long to machine word - Node* base = _gvn.transform(new (C) CastX2PNode(src)); + Node* base = _gvn.transform(new CastX2PNode(src)); offset = ConvI2X(offset); // 'src_start' points to src array + scaled offset @@ -5805,7 +5842,7 @@ Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::updateBytesCRC32_Type(), stubAddr, stubName, TypePtr::BOTTOM, crc, src_start, length); - Node* result = _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms)); + Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms)); set_result(result); return true; } @@ -5870,7 +5907,12 @@ BasicType bt = field->layout_type(); // Build the resultant type of the load - const Type *type = TypeOopPtr::make_from_klass(field_klass->as_klass()); + const Type *type; + if (bt == T_OBJECT) { + type = TypeOopPtr::make_from_klass(field_klass->as_klass()); + } else { + type = Type::get_const_basic_type(bt); + } // Build the load. Node* loadedField = make_load(NULL, adr, type, bt, adr_type, MemNode::unordered, is_vol); @@ -6000,12 +6042,12 @@ assert(tinst != NULL, "CBC obj is null"); assert(tinst->klass()->is_loaded(), "CBC obj is not loaded"); ciKlass* klass_AESCrypt = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make("com/sun/crypto/provider/AESCrypt")); - if (!klass_AESCrypt->is_loaded()) return false; + assert(klass_AESCrypt->is_loaded(), "predicate checks that this class is loaded"); ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass(); const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_AESCrypt); const TypeOopPtr* xtype = aklass->as_instance_type(); - Node* aescrypt_object = new(C) CheckCastPPNode(control(), embeddedCipherObj, xtype); + Node* aescrypt_object = new CheckCastPPNode(control(), embeddedCipherObj, xtype); aescrypt_object = _gvn.transform(aescrypt_object); // we need to get the start of the aescrypt_object's expanded key array @@ -6038,7 +6080,7 @@ } // return cipher length (int) - Node* retvalue = _gvn.transform(new (C) ProjNode(cbcCrypt, TypeFunc::Parms)); + Node* retvalue = _gvn.transform(new ProjNode(cbcCrypt, TypeFunc::Parms)); set_result(retvalue); return true; } @@ -6075,11 +6117,8 @@ // note cipher==plain is more conservative than the original java code but that's OK // Node* LibraryCallKit::inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting) { - // First, check receiver for NULL since it is virtual method. + // The receiver was checked for NULL already. Node* objCBC = argument(0); - objCBC = null_check(objCBC); - - if (stopped()) return NULL; // Always NULL // Load embeddedCipher field of CipherBlockChaining object. Node* embeddedCipherObj = load_field_from_object(objCBC, "embeddedCipher", "Lcom/sun/crypto/provider/SymmetricCipher;", /*is_exact*/ false); @@ -6102,8 +6141,8 @@ ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass(); Node* instof = gen_instanceof(embeddedCipherObj, makecon(TypeKlassPtr::make(instklass_AESCrypt))); - Node* cmp_instof = _gvn.transform(new (C) CmpINode(instof, intcon(1))); - Node* bool_instof = _gvn.transform(new (C) BoolNode(cmp_instof, BoolTest::ne)); + Node* cmp_instof = _gvn.transform(new CmpINode(instof, intcon(1))); + Node* bool_instof = _gvn.transform(new BoolNode(cmp_instof, BoolTest::ne)); Node* instof_false = generate_guard(bool_instof, NULL, PROB_MIN); @@ -6114,15 +6153,270 @@ // for decryption, we need to add a further check to avoid // taking the intrinsic path when cipher and plain are the same // see the original java code for why. - RegionNode* region = new(C) RegionNode(3); + RegionNode* region = new RegionNode(3); region->init_req(1, instof_false); Node* src = argument(1); Node* dest = argument(4); - Node* cmp_src_dest = _gvn.transform(new (C) CmpPNode(src, dest)); - Node* bool_src_dest = _gvn.transform(new (C) BoolNode(cmp_src_dest, BoolTest::eq)); + Node* cmp_src_dest = _gvn.transform(new CmpPNode(src, dest)); + Node* bool_src_dest = _gvn.transform(new BoolNode(cmp_src_dest, BoolTest::eq)); Node* src_dest_conjoint = generate_guard(bool_src_dest, NULL, PROB_MIN); region->init_req(2, src_dest_conjoint); record_for_igvn(region); return _gvn.transform(region); } + +//------------------------------inline_sha_implCompress----------------------- +// +// Calculate SHA (i.e., SHA-1) for single-block byte[] array. +// void com.sun.security.provider.SHA.implCompress(byte[] buf, int ofs) +// +// Calculate SHA2 (i.e., SHA-244 or SHA-256) for single-block byte[] array. +// void com.sun.security.provider.SHA2.implCompress(byte[] buf, int ofs) +// +// Calculate SHA5 (i.e., SHA-384 or SHA-512) for single-block byte[] array. +// void com.sun.security.provider.SHA5.implCompress(byte[] buf, int ofs) +// +bool LibraryCallKit::inline_sha_implCompress(vmIntrinsics::ID id) { + assert(callee()->signature()->size() == 2, "sha_implCompress has 2 parameters"); + + Node* sha_obj = argument(0); + Node* src = argument(1); // type oop + Node* ofs = argument(2); // type int + + const Type* src_type = src->Value(&_gvn); + const TypeAryPtr* top_src = src_type->isa_aryptr(); + if (top_src == NULL || top_src->klass() == NULL) { + // failed array check + return false; + } + // Figure out the size and type of the elements we will be copying. + BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + if (src_elem != T_BYTE) { + return false; + } + // 'src_start' points to src array + offset + Node* src_start = array_element_address(src, ofs, src_elem); + Node* state = NULL; + address stubAddr; + const char *stubName; + + switch(id) { + case vmIntrinsics::_sha_implCompress: + assert(UseSHA1Intrinsics, "need SHA1 instruction support"); + state = get_state_from_sha_object(sha_obj); + stubAddr = StubRoutines::sha1_implCompress(); + stubName = "sha1_implCompress"; + break; + case vmIntrinsics::_sha2_implCompress: + assert(UseSHA256Intrinsics, "need SHA256 instruction support"); + state = get_state_from_sha_object(sha_obj); + stubAddr = StubRoutines::sha256_implCompress(); + stubName = "sha256_implCompress"; + break; + case vmIntrinsics::_sha5_implCompress: + assert(UseSHA512Intrinsics, "need SHA512 instruction support"); + state = get_state_from_sha5_object(sha_obj); + stubAddr = StubRoutines::sha512_implCompress(); + stubName = "sha512_implCompress"; + break; + default: + fatal_unexpected_iid(id); + return false; + } + if (state == NULL) return false; + + // Call the stub. + Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::sha_implCompress_Type(), + stubAddr, stubName, TypePtr::BOTTOM, + src_start, state); + + return true; +} + +//------------------------------inline_digestBase_implCompressMB----------------------- +// +// Calculate SHA/SHA2/SHA5 for multi-block byte[] array. +// int com.sun.security.provider.DigestBase.implCompressMultiBlock(byte[] b, int ofs, int limit) +// +bool LibraryCallKit::inline_digestBase_implCompressMB(int predicate) { + assert(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics, + "need SHA1/SHA256/SHA512 instruction support"); + assert((uint)predicate < 3, "sanity"); + assert(callee()->signature()->size() == 3, "digestBase_implCompressMB has 3 parameters"); + + Node* digestBase_obj = argument(0); // The receiver was checked for NULL already. + Node* src = argument(1); // byte[] array + Node* ofs = argument(2); // type int + Node* limit = argument(3); // type int + + const Type* src_type = src->Value(&_gvn); + const TypeAryPtr* top_src = src_type->isa_aryptr(); + if (top_src == NULL || top_src->klass() == NULL) { + // failed array check + return false; + } + // Figure out the size and type of the elements we will be copying. + BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + if (src_elem != T_BYTE) { + return false; + } + // 'src_start' points to src array + offset + Node* src_start = array_element_address(src, ofs, src_elem); + + const char* klass_SHA_name = NULL; + const char* stub_name = NULL; + address stub_addr = NULL; + bool long_state = false; + + switch (predicate) { + case 0: + if (UseSHA1Intrinsics) { + klass_SHA_name = "sun/security/provider/SHA"; + stub_name = "sha1_implCompressMB"; + stub_addr = StubRoutines::sha1_implCompressMB(); + } + break; + case 1: + if (UseSHA256Intrinsics) { + klass_SHA_name = "sun/security/provider/SHA2"; + stub_name = "sha256_implCompressMB"; + stub_addr = StubRoutines::sha256_implCompressMB(); + } + break; + case 2: + if (UseSHA512Intrinsics) { + klass_SHA_name = "sun/security/provider/SHA5"; + stub_name = "sha512_implCompressMB"; + stub_addr = StubRoutines::sha512_implCompressMB(); + long_state = true; + } + break; + default: + fatal(err_msg_res("unknown SHA intrinsic predicate: %d", predicate)); + } + if (klass_SHA_name != NULL) { + // get DigestBase klass to lookup for SHA klass + const TypeInstPtr* tinst = _gvn.type(digestBase_obj)->isa_instptr(); + assert(tinst != NULL, "digestBase_obj is not instance???"); + assert(tinst->klass()->is_loaded(), "DigestBase is not loaded"); + + ciKlass* klass_SHA = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make(klass_SHA_name)); + assert(klass_SHA->is_loaded(), "predicate checks that this class is loaded"); + ciInstanceKlass* instklass_SHA = klass_SHA->as_instance_klass(); + return inline_sha_implCompressMB(digestBase_obj, instklass_SHA, long_state, stub_addr, stub_name, src_start, ofs, limit); + } + return false; +} +//------------------------------inline_sha_implCompressMB----------------------- +bool LibraryCallKit::inline_sha_implCompressMB(Node* digestBase_obj, ciInstanceKlass* instklass_SHA, + bool long_state, address stubAddr, const char *stubName, + Node* src_start, Node* ofs, Node* limit) { + const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_SHA); + const TypeOopPtr* xtype = aklass->as_instance_type(); + Node* sha_obj = new CheckCastPPNode(control(), digestBase_obj, xtype); + sha_obj = _gvn.transform(sha_obj); + + Node* state; + if (long_state) { + state = get_state_from_sha5_object(sha_obj); + } else { + state = get_state_from_sha_object(sha_obj); + } + if (state == NULL) return false; + + // Call the stub. + Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, + OptoRuntime::digestBase_implCompressMB_Type(), + stubAddr, stubName, TypePtr::BOTTOM, + src_start, state, ofs, limit); + // return ofs (int) + Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms)); + set_result(result); + + return true; +} + +//------------------------------get_state_from_sha_object----------------------- +Node * LibraryCallKit::get_state_from_sha_object(Node *sha_object) { + Node* sha_state = load_field_from_object(sha_object, "state", "[I", /*is_exact*/ false); + assert (sha_state != NULL, "wrong version of sun.security.provider.SHA/SHA2"); + if (sha_state == NULL) return (Node *) NULL; + + // now have the array, need to get the start address of the state array + Node* state = array_element_address(sha_state, intcon(0), T_INT); + return state; +} + +//------------------------------get_state_from_sha5_object----------------------- +Node * LibraryCallKit::get_state_from_sha5_object(Node *sha_object) { + Node* sha_state = load_field_from_object(sha_object, "state", "[J", /*is_exact*/ false); + assert (sha_state != NULL, "wrong version of sun.security.provider.SHA5"); + if (sha_state == NULL) return (Node *) NULL; + + // now have the array, need to get the start address of the state array + Node* state = array_element_address(sha_state, intcon(0), T_LONG); + return state; +} + +//----------------------------inline_digestBase_implCompressMB_predicate---------------------------- +// Return node representing slow path of predicate check. +// the pseudo code we want to emulate with this predicate is: +// if (digestBaseObj instanceof SHA/SHA2/SHA5) do_intrinsic, else do_javapath +// +Node* LibraryCallKit::inline_digestBase_implCompressMB_predicate(int predicate) { + assert(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics, + "need SHA1/SHA256/SHA512 instruction support"); + assert((uint)predicate < 3, "sanity"); + + // The receiver was checked for NULL already. + Node* digestBaseObj = argument(0); + + // get DigestBase klass for instanceOf check + const TypeInstPtr* tinst = _gvn.type(digestBaseObj)->isa_instptr(); + assert(tinst != NULL, "digestBaseObj is null"); + assert(tinst->klass()->is_loaded(), "DigestBase is not loaded"); + + const char* klass_SHA_name = NULL; + switch (predicate) { + case 0: + if (UseSHA1Intrinsics) { + // we want to do an instanceof comparison against the SHA class + klass_SHA_name = "sun/security/provider/SHA"; + } + break; + case 1: + if (UseSHA256Intrinsics) { + // we want to do an instanceof comparison against the SHA2 class + klass_SHA_name = "sun/security/provider/SHA2"; + } + break; + case 2: + if (UseSHA512Intrinsics) { + // we want to do an instanceof comparison against the SHA5 class + klass_SHA_name = "sun/security/provider/SHA5"; + } + break; + default: + fatal(err_msg_res("unknown SHA intrinsic predicate: %d", predicate)); + } + + ciKlass* klass_SHA = NULL; + if (klass_SHA_name != NULL) { + klass_SHA = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make(klass_SHA_name)); + } + if ((klass_SHA == NULL) || !klass_SHA->is_loaded()) { + // if none of SHA/SHA2/SHA5 is loaded, we never take the intrinsic fast path + Node* ctrl = control(); + set_control(top()); // no intrinsic path + return ctrl; + } + ciInstanceKlass* instklass_SHA = klass_SHA->as_instance_klass(); + + Node* instofSHA = gen_instanceof(digestBaseObj, makecon(TypeKlassPtr::make(instklass_SHA))); + Node* cmp_instof = _gvn.transform(new CmpINode(instofSHA, intcon(1))); + Node* bool_instof = _gvn.transform(new BoolNode(cmp_instof, BoolTest::ne)); + Node* instof_false = generate_guard(bool_instof, NULL, PROB_MIN); + + return instof_false; // even if it is NULL +} diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/loopPredicate.cpp --- a/hotspot/src/share/vm/opto/loopPredicate.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/loopPredicate.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -104,7 +104,7 @@ assert(rgn->is_Call(), "must be call uct"); CallNode* call = rgn->as_Call(); IdealLoopTree* loop = get_loop(call); - rgn = new (C) RegionNode(1); + rgn = new RegionNode(1); rgn->add_req(uncommon_proj); register_control(rgn, loop, uncommon_proj); _igvn.hash_delete(call); @@ -130,8 +130,8 @@ IfNode *new_iff = iff->clone()->as_If(); new_iff->set_req(0, entry); register_control(new_iff, lp, entry); - Node *if_cont = new (C) IfTrueNode(new_iff); - Node *if_uct = new (C) IfFalseNode(new_iff); + Node *if_cont = new IfTrueNode(new_iff); + Node *if_uct = new IfFalseNode(new_iff); if (cont_proj->is_IfFalse()) { // Swap Node* tmp = if_uct; if_uct = if_cont; if_cont = tmp; @@ -191,7 +191,7 @@ if (!rgn->is_Region()) { // create a region to guard the call assert(rgn->is_Call(), "must be call uct"); CallNode* call = rgn->as_Call(); - rgn = new (C) RegionNode(1); + rgn = new RegionNode(1); register_new_node_with_optimizer(rgn); rgn->add_req(uncommon_proj); hash_delete(call); @@ -208,8 +208,8 @@ new_iff->set_req(0, new_entry); register_new_node_with_optimizer(new_iff); - Node *if_cont = new (C) IfTrueNode(new_iff); - Node *if_uct = new (C) IfFalseNode(new_iff); + Node *if_cont = new IfTrueNode(new_iff); + Node *if_uct = new IfFalseNode(new_iff); if (cont_proj->is_IfFalse()) { // Swap Node* tmp = if_uct; if_uct = if_cont; if_cont = tmp; @@ -254,10 +254,10 @@ // Match original condition since predicate's projections could be swapped. assert(predicate_proj->in(0)->in(1)->in(1)->Opcode()==Op_Opaque1, "must be"); - Node* opq = new (igvn->C) Opaque1Node(igvn->C, predicate_proj->in(0)->in(1)->in(1)->in(1)); + Node* opq = new Opaque1Node(igvn->C, predicate_proj->in(0)->in(1)->in(1)->in(1)); igvn->C->add_predicate_opaq(opq); - Node* bol = new (igvn->C) Conv2BNode(opq); + Node* bol = new Conv2BNode(opq); if (loop_phase != NULL) { loop_phase->register_new_node(opq, ctrl); loop_phase->register_new_node(bol, ctrl); @@ -605,11 +605,11 @@ // Calculate exact limit here. // Note, counted loop's test is '<' or '>'. limit = exact_limit(loop); - max_idx_expr = new (C) SubINode(limit, stride); + max_idx_expr = new SubINode(limit, stride); register_new_node(max_idx_expr, ctrl); if (TraceLoopPredicate) predString->print("(limit - stride) "); } else { - max_idx_expr = new (C) SubINode(limit, stride); + max_idx_expr = new SubINode(limit, stride); register_new_node(max_idx_expr, ctrl); if (TraceLoopPredicate) predString->print("(limit - stride) "); } @@ -619,22 +619,22 @@ if (scale != 1) { ConNode* con_scale = _igvn.intcon(scale); - max_idx_expr = new (C) MulINode(max_idx_expr, con_scale); + max_idx_expr = new MulINode(max_idx_expr, con_scale); register_new_node(max_idx_expr, ctrl); if (TraceLoopPredicate) predString->print("* %d ", scale); } if (offset && (!offset->is_Con() || offset->get_int() != 0)){ - max_idx_expr = new (C) AddINode(max_idx_expr, offset); + max_idx_expr = new AddINode(max_idx_expr, offset); register_new_node(max_idx_expr, ctrl); if (TraceLoopPredicate) if (offset->is_Con()) predString->print("+ %d ", offset->get_int()); else predString->print("+ offset "); } - CmpUNode* cmp = new (C) CmpUNode(max_idx_expr, range); + CmpUNode* cmp = new CmpUNode(max_idx_expr, range); register_new_node(cmp, ctrl); - BoolNode* bol = new (C) BoolNode(cmp, BoolTest::lt); + BoolNode* bol = new BoolNode(cmp, BoolTest::lt); register_new_node(bol, ctrl); if (TraceLoopPredicate) { @@ -750,7 +750,7 @@ // Negate test if necessary bool negated = false; if (proj->_con != predicate_proj->_con) { - new_predicate_bol = new (C) BoolNode(new_predicate_bol->in(1), new_predicate_bol->_test.negate()); + new_predicate_bol = new BoolNode(new_predicate_bol->in(1), new_predicate_bol->_test.negate()); register_new_node(new_predicate_bol, ctrl); negated = true; } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/loopTransform.cpp --- a/hotspot/src/share/vm/opto/loopTransform.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/loopTransform.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -227,24 +227,24 @@ if (neg_inv1) { Node *zero = phase->_igvn.intcon(0); phase->set_ctrl(zero, phase->C->root()); - n_inv1 = new (phase->C) SubINode(zero, inv1); + n_inv1 = new SubINode(zero, inv1); phase->register_new_node(n_inv1, inv1_c); } else { n_inv1 = inv1; } Node* inv; if (neg_inv2) { - inv = new (phase->C) SubINode(n_inv1, inv2); + inv = new SubINode(n_inv1, inv2); } else { - inv = new (phase->C) AddINode(n_inv1, inv2); + inv = new AddINode(n_inv1, inv2); } phase->register_new_node(inv, phase->get_early_ctrl(inv)); Node* addx; if (neg_x) { - addx = new (phase->C) SubINode(inv, x); + addx = new SubINode(inv, x); } else { - addx = new (phase->C) AddINode(x, inv); + addx = new AddINode(x, inv); } phase->register_new_node(addx, phase->get_ctrl(x)); phase->_igvn.replace_node(n1, addx); @@ -953,7 +953,7 @@ post_end->_prob = PROB_FAIR; // Build the main-loop normal exit. - IfFalseNode *new_main_exit = new (C) IfFalseNode(main_end); + IfFalseNode *new_main_exit = new IfFalseNode(main_end); _igvn.register_new_node_with_optimizer( new_main_exit ); set_idom(new_main_exit, main_end, dd_main_exit ); set_loop(new_main_exit, loop->_parent); @@ -963,15 +963,15 @@ // (the main-loop trip-counter exit value) because we will be changing // the exit value (via unrolling) so we cannot constant-fold away the zero // trip guard until all unrolling is done. - Node *zer_opaq = new (C) Opaque1Node(C, incr); - Node *zer_cmp = new (C) CmpINode( zer_opaq, limit ); - Node *zer_bol = new (C) BoolNode( zer_cmp, b_test ); + Node *zer_opaq = new Opaque1Node(C, incr); + Node *zer_cmp = new CmpINode( zer_opaq, limit ); + Node *zer_bol = new BoolNode( zer_cmp, b_test ); register_new_node( zer_opaq, new_main_exit ); register_new_node( zer_cmp , new_main_exit ); register_new_node( zer_bol , new_main_exit ); // Build the IfNode - IfNode *zer_iff = new (C) IfNode( new_main_exit, zer_bol, PROB_FAIR, COUNT_UNKNOWN ); + IfNode *zer_iff = new IfNode( new_main_exit, zer_bol, PROB_FAIR, COUNT_UNKNOWN ); _igvn.register_new_node_with_optimizer( zer_iff ); set_idom(zer_iff, new_main_exit, dd_main_exit); set_loop(zer_iff, loop->_parent); @@ -981,7 +981,7 @@ set_idom(main_exit, zer_iff, dd_main_exit); set_idom(main_exit->unique_out(), zer_iff, dd_main_exit); // Make the true-path, must enter the post loop - Node *zer_taken = new (C) IfTrueNode( zer_iff ); + Node *zer_taken = new IfTrueNode( zer_iff ); _igvn.register_new_node_with_optimizer( zer_taken ); set_idom(zer_taken, zer_iff, dd_main_exit); set_loop(zer_taken, loop->_parent); @@ -1029,7 +1029,7 @@ // Find the pre-loop normal exit. Node* pre_exit = pre_end->proj_out(false); assert( pre_exit->Opcode() == Op_IfFalse, "" ); - IfFalseNode *new_pre_exit = new (C) IfFalseNode(pre_end); + IfFalseNode *new_pre_exit = new IfFalseNode(pre_end); _igvn.register_new_node_with_optimizer( new_pre_exit ); set_idom(new_pre_exit, pre_end, dd_main_head); set_loop(new_pre_exit, loop->_parent); @@ -1038,15 +1038,15 @@ // pre-loop, the main-loop may not execute at all. Later in life this // zero-trip guard will become the minimum-trip guard when we unroll // the main-loop. - Node *min_opaq = new (C) Opaque1Node(C, limit); - Node *min_cmp = new (C) CmpINode( pre_incr, min_opaq ); - Node *min_bol = new (C) BoolNode( min_cmp, b_test ); + Node *min_opaq = new Opaque1Node(C, limit); + Node *min_cmp = new CmpINode( pre_incr, min_opaq ); + Node *min_bol = new BoolNode( min_cmp, b_test ); register_new_node( min_opaq, new_pre_exit ); register_new_node( min_cmp , new_pre_exit ); register_new_node( min_bol , new_pre_exit ); // Build the IfNode (assume the main-loop is executed always). - IfNode *min_iff = new (C) IfNode( new_pre_exit, min_bol, PROB_ALWAYS, COUNT_UNKNOWN ); + IfNode *min_iff = new IfNode( new_pre_exit, min_bol, PROB_ALWAYS, COUNT_UNKNOWN ); _igvn.register_new_node_with_optimizer( min_iff ); set_idom(min_iff, new_pre_exit, dd_main_head); set_loop(min_iff, loop->_parent); @@ -1057,7 +1057,7 @@ set_idom(pre_exit, min_iff, dd_main_head); set_idom(pre_exit->unique_out(), min_iff, dd_main_head); // Make the true-path, must enter the main loop - Node *min_taken = new (C) IfTrueNode( min_iff ); + Node *min_taken = new IfTrueNode( min_iff ); _igvn.register_new_node_with_optimizer( min_taken ); set_idom(min_taken, min_iff, dd_main_head); set_loop(min_taken, loop->_parent); @@ -1087,11 +1087,11 @@ // RCE and alignment may change this later. Node *cmp_end = pre_end->cmp_node(); assert( cmp_end->in(2) == limit, "" ); - Node *pre_limit = new (C) AddINode( init, stride ); + Node *pre_limit = new AddINode( init, stride ); // Save the original loop limit in this Opaque1 node for // use by range check elimination. - Node *pre_opaq = new (C) Opaque1Node(C, pre_limit, limit); + Node *pre_opaq = new Opaque1Node(C, pre_limit, limit); register_new_node( pre_limit, pre_head->in(0) ); register_new_node( pre_opaq , pre_head->in(0) ); @@ -1116,19 +1116,19 @@ BoolTest::mask new_test = (main_end->stride_con() > 0) ? BoolTest::lt : BoolTest::gt; // Modify pre loop end condition Node* pre_bol = pre_end->in(CountedLoopEndNode::TestValue)->as_Bool(); - BoolNode* new_bol0 = new (C) BoolNode(pre_bol->in(1), new_test); + BoolNode* new_bol0 = new BoolNode(pre_bol->in(1), new_test); register_new_node( new_bol0, pre_head->in(0) ); _igvn.hash_delete(pre_end); pre_end->set_req(CountedLoopEndNode::TestValue, new_bol0); // Modify main loop guard condition assert(min_iff->in(CountedLoopEndNode::TestValue) == min_bol, "guard okay"); - BoolNode* new_bol1 = new (C) BoolNode(min_bol->in(1), new_test); + BoolNode* new_bol1 = new BoolNode(min_bol->in(1), new_test); register_new_node( new_bol1, new_pre_exit ); _igvn.hash_delete(min_iff); min_iff->set_req(CountedLoopEndNode::TestValue, new_bol1); // Modify main loop end condition BoolNode* main_bol = main_end->in(CountedLoopEndNode::TestValue)->as_Bool(); - BoolNode* new_bol2 = new (C) BoolNode(main_bol->in(1), new_test); + BoolNode* new_bol2 = new BoolNode(main_bol->in(1), new_test); register_new_node( new_bol2, main_end->in(CountedLoopEndNode::TestControl) ); _igvn.hash_delete(main_end); main_end->set_req(CountedLoopEndNode::TestValue, new_bol2); @@ -1279,13 +1279,13 @@ // zero trip guard limit will be different from loop limit. assert(has_ctrl(opaq), "should have it"); Node* opaq_ctrl = get_ctrl(opaq); - limit = new (C) Opaque2Node( C, limit ); + limit = new Opaque2Node( C, limit ); register_new_node( limit, opaq_ctrl ); } if (stride_con > 0 && ((limit_type->_lo - stride_con) < limit_type->_lo) || stride_con < 0 && ((limit_type->_hi - stride_con) > limit_type->_hi)) { // No underflow. - new_limit = new (C) SubINode(limit, stride); + new_limit = new SubINode(limit, stride); } else { // (limit - stride) may underflow. // Clamp the adjustment value with MININT or MAXINT: @@ -1315,18 +1315,18 @@ old_limit = bol->in(1)->in(1); // Adjust previous adjusted limit. adj_limit = limit->in(CMoveNode::IfFalse); - adj_limit = new (C) SubINode(adj_limit, stride); + adj_limit = new SubINode(adj_limit, stride); } else { old_limit = limit; - adj_limit = new (C) SubINode(limit, stride); + adj_limit = new SubINode(limit, stride); } assert(old_limit != NULL && adj_limit != NULL, ""); register_new_node( adj_limit, ctrl ); // adjust amount - Node* adj_cmp = new (C) CmpINode(old_limit, adj_limit); + Node* adj_cmp = new CmpINode(old_limit, adj_limit); register_new_node( adj_cmp, ctrl ); - Node* adj_bool = new (C) BoolNode(adj_cmp, bt); + Node* adj_bool = new BoolNode(adj_cmp, bt); register_new_node( adj_bool, ctrl ); - new_limit = new (C) CMoveINode(adj_bool, adj_limit, adj_max, TypeInt::INT); + new_limit = new CMoveINode(adj_bool, adj_limit, adj_max, TypeInt::INT); } register_new_node(new_limit, ctrl); } @@ -1388,24 +1388,24 @@ // CountedLoop this is exact (stride divides limit-init exactly). // We are going to double the loop body, so we want to knock off any // odd iteration: (trip_cnt & ~1). Then back compute a new limit. - Node *span = new (C) SubINode( limit, init ); + Node *span = new SubINode( limit, init ); register_new_node( span, ctrl ); - Node *trip = new (C) DivINode( 0, span, stride ); + Node *trip = new DivINode( 0, span, stride ); register_new_node( trip, ctrl ); Node *mtwo = _igvn.intcon(-2); set_ctrl(mtwo, C->root()); - Node *rond = new (C) AndINode( trip, mtwo ); + Node *rond = new AndINode( trip, mtwo ); register_new_node( rond, ctrl ); - Node *spn2 = new (C) MulINode( rond, stride ); + Node *spn2 = new MulINode( rond, stride ); register_new_node( spn2, ctrl ); - new_limit = new (C) AddINode( spn2, init ); + new_limit = new AddINode( spn2, init ); register_new_node( new_limit, ctrl ); // Hammer in the new limit Node *ctrl2 = loop_end->in(0); - Node *cmp2 = new (C) CmpINode( loop_head->incr(), new_limit ); + Node *cmp2 = new CmpINode( loop_head->incr(), new_limit ); register_new_node( cmp2, ctrl2 ); - Node *bol2 = new (C) BoolNode( cmp2, loop_end->test_trip() ); + Node *bol2 = new BoolNode( cmp2, loop_end->test_trip() ); register_new_node( bol2, ctrl2 ); _igvn.hash_delete(loop_end); loop_end->set_req(CountedLoopEndNode::TestValue, bol2); @@ -1511,15 +1511,15 @@ // Helper function for add_constraint(). Node* PhaseIdealLoop::adjust_limit(int stride_con, Node * scale, Node *offset, Node *rc_limit, Node *loop_limit, Node *pre_ctrl) { // Compute "I :: (limit-offset)/scale" - Node *con = new (C) SubINode(rc_limit, offset); + Node *con = new SubINode(rc_limit, offset); register_new_node(con, pre_ctrl); - Node *X = new (C) DivINode(0, con, scale); + Node *X = new DivINode(0, con, scale); register_new_node(X, pre_ctrl); // Adjust loop limit loop_limit = (stride_con > 0) - ? (Node*)(new (C) MinINode(loop_limit, X)) - : (Node*)(new (C) MaxINode(loop_limit, X)); + ? (Node*)(new MinINode(loop_limit, X)) + : (Node*)(new MaxINode(loop_limit, X)); register_new_node(loop_limit, pre_ctrl); return loop_limit; } @@ -1580,9 +1580,9 @@ // to avoid problem with scale == -1 (min_int/(-1) == min_int). Node* shift = _igvn.intcon(31); set_ctrl(shift, C->root()); - Node* sign = new (C) RShiftINode(offset, shift); + Node* sign = new RShiftINode(offset, shift); register_new_node(sign, pre_ctrl); - offset = new (C) AndINode(offset, sign); + offset = new AndINode(offset, sign); register_new_node(offset, pre_ctrl); } else { assert(low_limit->get_int() == 0, "wrong low limit for range check"); @@ -1615,7 +1615,7 @@ Node *one = _igvn.intcon(1); set_ctrl(one, C->root()); - Node *plus_one = new (C) AddINode(offset, one); + Node *plus_one = new AddINode(offset, one); register_new_node( plus_one, pre_ctrl ); // Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond); *pre_limit = adjust_limit((-stride_con), scale, plus_one, upper_limit, *pre_limit, pre_ctrl); @@ -1633,9 +1633,9 @@ // to avoid problem with scale == -1 (min_int/(-1) == min_int). Node* shift = _igvn.intcon(31); set_ctrl(shift, C->root()); - Node* sign = new (C) RShiftINode(plus_one, shift); + Node* sign = new RShiftINode(plus_one, shift); register_new_node(sign, pre_ctrl); - plus_one = new (C) AndINode(plus_one, sign); + plus_one = new AndINode(plus_one, sign); register_new_node(plus_one, pre_ctrl); } else { assert(low_limit->get_int() == 0, "wrong low limit for range check"); @@ -1718,7 +1718,7 @@ p_offset != NULL ? &offset2 : NULL, depth+1)) { if (p_offset != NULL) { Node *ctrl_off2 = get_ctrl(offset2); - Node* offset = new (C) AddINode(offset2, exp->in(2)); + Node* offset = new AddINode(offset2, exp->in(2)); register_new_node(offset, ctrl_off2); *p_offset = offset; } @@ -1731,7 +1731,7 @@ Node *zero = _igvn.intcon(0); set_ctrl(zero, C->root()); Node *ctrl_off = get_ctrl(exp->in(2)); - Node* offset = new (C) SubINode(zero, exp->in(2)); + Node* offset = new SubINode(zero, exp->in(2)); register_new_node(offset, ctrl_off); *p_offset = offset; } @@ -1934,15 +1934,15 @@ case BoolTest::ge: // Convert (I*scale+offset) >= Limit to (I*(-scale)+(-offset)) <= -Limit scale_con = -scale_con; - offset = new (C) SubINode( zero, offset ); + offset = new SubINode( zero, offset ); register_new_node( offset, pre_ctrl ); - limit = new (C) SubINode( zero, limit ); + limit = new SubINode( zero, limit ); register_new_node( limit, pre_ctrl ); // Fall into LE case case BoolTest::le: if (b_test._test != BoolTest::gt) { // Convert X <= Y to X < Y+1 - limit = new (C) AddINode( limit, one ); + limit = new AddINode( limit, one ); register_new_node( limit, pre_ctrl ); } // Fall into LT case @@ -1993,8 +1993,8 @@ // Update loop limits if (conditional_rc) { - pre_limit = (stride_con > 0) ? (Node*)new (C) MinINode(pre_limit, orig_limit) - : (Node*)new (C) MaxINode(pre_limit, orig_limit); + pre_limit = (stride_con > 0) ? (Node*)new MinINode(pre_limit, orig_limit) + : (Node*)new MaxINode(pre_limit, orig_limit); register_new_node(pre_limit, pre_ctrl); } _igvn.hash_delete(pre_opaq); @@ -2009,16 +2009,16 @@ Node *ctrl = get_ctrl(main_limit); Node *stride = cl->stride(); Node *init = cl->init_trip(); - Node *span = new (C) SubINode(main_limit,init); + Node *span = new SubINode(main_limit,init); register_new_node(span,ctrl); Node *rndup = _igvn.intcon(stride_con + ((stride_con>0)?-1:1)); - Node *add = new (C) AddINode(span,rndup); + Node *add = new AddINode(span,rndup); register_new_node(add,ctrl); - Node *div = new (C) DivINode(0,add,stride); + Node *div = new DivINode(0,add,stride); register_new_node(div,ctrl); - Node *mul = new (C) MulINode(div,stride); + Node *mul = new MulINode(div,stride); register_new_node(mul,ctrl); - Node *newlim = new (C) AddINode(mul,init); + Node *newlim = new AddINode(mul,init); register_new_node(newlim,ctrl); main_limit = newlim; } @@ -2189,7 +2189,7 @@ } // Note: the final value after increment should not overflow since // counted loop has limit check predicate. - Node *final = new (phase->C) SubINode( exact_limit, cl->stride() ); + Node *final = new SubINode( exact_limit, cl->stride() ); phase->register_new_node(final,cl->in(LoopNode::EntryControl)); phase->_igvn.replace_node(phi,final); phase->C->set_major_progress(); @@ -2676,20 +2676,20 @@ // Build an expression for the beginning of the copy region Node* index = head->init_trip(); #ifdef _LP64 - index = new (C) ConvI2LNode(index); + index = new ConvI2LNode(index); _igvn.register_new_node_with_optimizer(index); #endif if (shift != NULL) { // byte arrays don't require a shift but others do. - index = new (C) LShiftXNode(index, shift->in(2)); + index = new LShiftXNode(index, shift->in(2)); _igvn.register_new_node_with_optimizer(index); } - index = new (C) AddPNode(base, base, index); + index = new AddPNode(base, base, index); _igvn.register_new_node_with_optimizer(index); - Node* from = new (C) AddPNode(base, index, offset); + Node* from = new AddPNode(base, index, offset); _igvn.register_new_node_with_optimizer(from); // Compute the number of elements to copy - Node* len = new (C) SubINode(head->limit(), head->init_trip()); + Node* len = new SubINode(head->limit(), head->init_trip()); _igvn.register_new_node_with_optimizer(len); BasicType t = store->as_Mem()->memory_type(); @@ -2706,17 +2706,17 @@ // Convert float/double to int/long for fill routines if (t == T_FLOAT) { - store_value = new (C) MoveF2INode(store_value); + store_value = new MoveF2INode(store_value); _igvn.register_new_node_with_optimizer(store_value); } else if (t == T_DOUBLE) { - store_value = new (C) MoveD2LNode(store_value); + store_value = new MoveD2LNode(store_value); _igvn.register_new_node_with_optimizer(store_value); } if (CCallingConventionRequiresIntsAsLongs && // See StubRoutines::select_fill_function for types. FLOAT has been converted to INT. (t == T_FLOAT || t == T_INT || is_subword_type(t))) { - store_value = new (C) ConvI2LNode(store_value); + store_value = new ConvI2LNode(store_value); _igvn.register_new_node_with_optimizer(store_value); } @@ -2724,8 +2724,8 @@ Node* result_ctrl; Node* result_mem; const TypeFunc* call_type = OptoRuntime::array_fill_Type(); - CallLeafNode *call = new (C) CallLeafNoFPNode(call_type, fill, - fill_name, TypeAryPtr::get_array_body_type(t)); + CallLeafNode *call = new CallLeafNoFPNode(call_type, fill, + fill_name, TypeAryPtr::get_array_body_type(t)); uint cnt = 0; call->init_req(TypeFunc::Parms + cnt++, from); call->init_req(TypeFunc::Parms + cnt++, store_value); @@ -2733,7 +2733,7 @@ call->init_req(TypeFunc::Parms + cnt++, C->top()); } #ifdef _LP64 - len = new (C) ConvI2LNode(len); + len = new ConvI2LNode(len); _igvn.register_new_node_with_optimizer(len); #endif call->init_req(TypeFunc::Parms + cnt++, len); @@ -2746,9 +2746,9 @@ call->init_req(TypeFunc::ReturnAdr, C->start()->proj_out(TypeFunc::ReturnAdr)); call->init_req(TypeFunc::FramePtr, C->start()->proj_out(TypeFunc::FramePtr)); _igvn.register_new_node_with_optimizer(call); - result_ctrl = new (C) ProjNode(call,TypeFunc::Control); + result_ctrl = new ProjNode(call,TypeFunc::Control); _igvn.register_new_node_with_optimizer(result_ctrl); - result_mem = new (C) ProjNode(call,TypeFunc::Memory); + result_mem = new ProjNode(call,TypeFunc::Memory); _igvn.register_new_node_with_optimizer(result_mem); /* Disable following optimization until proper fix (add missing checks). diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/loopUnswitch.cpp --- a/hotspot/src/share/vm/opto/loopUnswitch.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/loopUnswitch.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -225,15 +225,15 @@ Node *cont = _igvn.intcon(1); set_ctrl(cont, C->root()); - Node* opq = new (C) Opaque1Node(C, cont); + Node* opq = new Opaque1Node(C, cont); register_node(opq, outer_loop, entry, dom_depth(entry)); - Node *bol = new (C) Conv2BNode(opq); + Node *bol = new Conv2BNode(opq); register_node(bol, outer_loop, entry, dom_depth(entry)); - IfNode* iff = new (C) IfNode(entry, bol, PROB_MAX, COUNT_UNKNOWN); + IfNode* iff = new IfNode(entry, bol, PROB_MAX, COUNT_UNKNOWN); register_node(iff, outer_loop, entry, dom_depth(entry)); - ProjNode* iffast = new (C) IfTrueNode(iff); + ProjNode* iffast = new IfTrueNode(iff); register_node(iffast, outer_loop, iff, dom_depth(iff)); - ProjNode* ifslow = new (C) IfFalseNode(iff); + ProjNode* ifslow = new IfFalseNode(iff); register_node(ifslow, outer_loop, iff, dom_depth(iff)); // Clone the loop body. The clone becomes the fast loop. The diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/loopnode.cpp --- a/hotspot/src/share/vm/opto/loopnode.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/loopnode.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -443,7 +443,7 @@ assert(x->Opcode() == Op_Loop, "regular loops only"); C->print_method(PHASE_BEFORE_CLOOPS, 3); - Node *hook = new (C) Node(6); + Node *hook = new Node(6); if (LoopLimitCheck) { @@ -506,11 +506,11 @@ Node* bol; if (stride_con > 0) { - cmp_limit = new (C) CmpINode(limit, _igvn.intcon(max_jint - stride_m)); - bol = new (C) BoolNode(cmp_limit, BoolTest::le); + cmp_limit = new CmpINode(limit, _igvn.intcon(max_jint - stride_m)); + bol = new BoolNode(cmp_limit, BoolTest::le); } else { - cmp_limit = new (C) CmpINode(limit, _igvn.intcon(min_jint - stride_m)); - bol = new (C) BoolNode(cmp_limit, BoolTest::ge); + cmp_limit = new CmpINode(limit, _igvn.intcon(min_jint - stride_m)); + bol = new BoolNode(cmp_limit, BoolTest::ge); } cmp_limit = _igvn.register_new_node_with_optimizer(cmp_limit); bol = _igvn.register_new_node_with_optimizer(bol); @@ -547,7 +547,7 @@ // is converted to // i = init; do {} while(++i < limit+1); // - limit = gvn->transform(new (C) AddINode(limit, stride)); + limit = gvn->transform(new AddINode(limit, stride)); } // Now we need to canonicalize loop condition. @@ -566,7 +566,7 @@ // we can convert 'i <= limit' to 'i < limit+1' since stride != 0. // Node* one = (stride_con > 0) ? gvn->intcon( 1) : gvn->intcon(-1); - limit = gvn->transform(new (C) AddINode(limit, one)); + limit = gvn->transform(new AddINode(limit, one)); if (bt == BoolTest::le) bt = BoolTest::lt; else if (bt == BoolTest::ge) @@ -582,7 +582,7 @@ // can directly point to the phi; in this case adjust the compare so that // it points to the incr by adjusting the limit. if (cmp->in(1) == phi || cmp->in(2) == phi) - limit = gvn->transform(new (C) AddINode(limit,stride)); + limit = gvn->transform(new AddINode(limit,stride)); // trip-count for +-tive stride should be: (limit - init_trip + stride - 1)/stride. // Final value for iterator should be: trip_count * stride + init_trip. @@ -595,16 +595,16 @@ ShouldNotReachHere(); case BoolTest::ne: // Ahh, the case we desire if (stride_con == 1) - trip_count = gvn->transform(new (C) SubINode(limit,init_trip)); + trip_count = gvn->transform(new SubINode(limit,init_trip)); else if (stride_con == -1) - trip_count = gvn->transform(new (C) SubINode(init_trip,limit)); + trip_count = gvn->transform(new SubINode(init_trip,limit)); else ShouldNotReachHere(); set_subtree_ctrl(trip_count); //_loop.map(trip_count->_idx,loop(limit)); break; case BoolTest::le: // Maybe convert to '<' case - limit = gvn->transform(new (C) AddINode(limit,one_p)); + limit = gvn->transform(new AddINode(limit,one_p)); set_subtree_ctrl( limit ); hook->init_req(4, limit); @@ -615,26 +615,26 @@ case BoolTest::lt: { // Maybe convert to '!=' case if (stride_con < 0) // Count down loop rolls through MAXINT ShouldNotReachHere(); - Node *range = gvn->transform(new (C) SubINode(limit,init_trip)); + Node *range = gvn->transform(new SubINode(limit,init_trip)); set_subtree_ctrl( range ); hook->init_req(0, range); - Node *bias = gvn->transform(new (C) AddINode(range,stride)); + Node *bias = gvn->transform(new AddINode(range,stride)); set_subtree_ctrl( bias ); hook->init_req(1, bias); - Node *bias1 = gvn->transform(new (C) AddINode(bias,one_m)); + Node *bias1 = gvn->transform(new AddINode(bias,one_m)); set_subtree_ctrl( bias1 ); hook->init_req(2, bias1); - trip_count = gvn->transform(new (C) DivINode(0,bias1,stride)); + trip_count = gvn->transform(new DivINode(0,bias1,stride)); set_subtree_ctrl( trip_count ); hook->init_req(3, trip_count); break; } case BoolTest::ge: // Maybe convert to '>' case - limit = gvn->transform(new (C) AddINode(limit,one_m)); + limit = gvn->transform(new AddINode(limit,one_m)); set_subtree_ctrl( limit ); hook->init_req(4 ,limit); @@ -645,30 +645,30 @@ case BoolTest::gt: { // Maybe convert to '!=' case if (stride_con > 0) // count up loop rolls through MININT ShouldNotReachHere(); - Node *range = gvn->transform(new (C) SubINode(limit,init_trip)); + Node *range = gvn->transform(new SubINode(limit,init_trip)); set_subtree_ctrl( range ); hook->init_req(0, range); - Node *bias = gvn->transform(new (C) AddINode(range,stride)); + Node *bias = gvn->transform(new AddINode(range,stride)); set_subtree_ctrl( bias ); hook->init_req(1, bias); - Node *bias1 = gvn->transform(new (C) AddINode(bias,one_p)); + Node *bias1 = gvn->transform(new AddINode(bias,one_p)); set_subtree_ctrl( bias1 ); hook->init_req(2, bias1); - trip_count = gvn->transform(new (C) DivINode(0,bias1,stride)); + trip_count = gvn->transform(new DivINode(0,bias1,stride)); set_subtree_ctrl( trip_count ); hook->init_req(3, trip_count); break; } } // switch( bt ) - Node *span = gvn->transform(new (C) MulINode(trip_count,stride)); + Node *span = gvn->transform(new MulINode(trip_count,stride)); set_subtree_ctrl( span ); hook->init_req(5, span); - limit = gvn->transform(new (C) AddINode(span,init_trip)); + limit = gvn->transform(new AddINode(span,init_trip)); set_subtree_ctrl( limit ); } // LoopLimitCheck @@ -717,7 +717,7 @@ set_ctrl(test, iff->in(0)); // Replace the old IfNode with a new LoopEndNode - Node *lex = _igvn.register_new_node_with_optimizer(new (C) CountedLoopEndNode( iff->in(0), test, cl_prob, iff->as_If()->_fcnt )); + Node *lex = _igvn.register_new_node_with_optimizer(new CountedLoopEndNode( iff->in(0), test, cl_prob, iff->as_If()->_fcnt )); IfNode *le = lex->as_If(); uint dd = dom_depth(iff); set_idom(le, le->in(0), dd); // Update dominance for loop exit @@ -728,8 +728,8 @@ // Need to swap loop-exit and loop-back control? if (iftrue_op == Op_IfFalse) { - Node *ift2=_igvn.register_new_node_with_optimizer(new (C) IfTrueNode (le)); - Node *iff2=_igvn.register_new_node_with_optimizer(new (C) IfFalseNode(le)); + Node *ift2=_igvn.register_new_node_with_optimizer(new IfTrueNode (le)); + Node *iff2=_igvn.register_new_node_with_optimizer(new IfFalseNode(le)); loop->_tail = back_control = ift2; set_loop(ift2, loop); @@ -755,7 +755,7 @@ lazy_replace( iff, le ); // fix 'get_ctrl' // Now setup a new CountedLoopNode to replace the existing LoopNode - CountedLoopNode *l = new (C) CountedLoopNode(init_control, back_control); + CountedLoopNode *l = new CountedLoopNode(init_control, back_control); l->set_unswitch_count(x->as_Loop()->unswitch_count()); // Preserve // The following assert is approximately true, and defines the intention // of can_be_counted_loop. It fails, however, because phase->type @@ -829,7 +829,7 @@ limit = _igvn.intcon(final_int); } else { // Create new LoopLimit node to get exact limit (final iv value). - limit = new (C) LoopLimitNode(C, cl->init_trip(), cl->limit(), cl->stride()); + limit = new LoopLimitNode(C, cl->init_trip(), cl->limit(), cl->stride()); register_new_node(limit, cl->in(LoopNode::EntryControl)); } assert(limit != NULL, "sanity"); @@ -946,11 +946,11 @@ if (range <= max) { // Convert to integer expression if it is not overflow. Node* stride_m = phase->intcon(stride_con - (stride_con > 0 ? 1 : -1)); - Node *range = phase->transform(new (phase->C) SubINode(in(Limit), in(Init))); - Node *bias = phase->transform(new (phase->C) AddINode(range, stride_m)); - Node *trip = phase->transform(new (phase->C) DivINode(0, bias, in(Stride))); - Node *span = phase->transform(new (phase->C) MulINode(trip, in(Stride))); - return new (phase->C) AddINode(span, in(Init)); // exact limit + Node *range = phase->transform(new SubINode(in(Limit), in(Init))); + Node *bias = phase->transform(new AddINode(range, stride_m)); + Node *trip = phase->transform(new DivINode(0, bias, in(Stride))); + Node *span = phase->transform(new MulINode(trip, in(Stride))); + return new AddINode(span, in(Init)); // exact limit } if (is_power_of_2(stride_p) || // divisor is 2^n @@ -958,13 +958,13 @@ // Convert to long expression to avoid integer overflow // and let igvn optimizer convert this division. // - Node* init = phase->transform( new (phase->C) ConvI2LNode(in(Init))); - Node* limit = phase->transform( new (phase->C) ConvI2LNode(in(Limit))); + Node* init = phase->transform( new ConvI2LNode(in(Init))); + Node* limit = phase->transform( new ConvI2LNode(in(Limit))); Node* stride = phase->longcon(stride_con); Node* stride_m = phase->longcon(stride_con - (stride_con > 0 ? 1 : -1)); - Node *range = phase->transform(new (phase->C) SubLNode(limit, init)); - Node *bias = phase->transform(new (phase->C) AddLNode(range, stride_m)); + Node *range = phase->transform(new SubLNode(limit, init)); + Node *bias = phase->transform(new AddLNode(range, stride_m)); Node *span; if (stride_con > 0 && is_power_of_2(stride_p)) { // bias >= 0 if stride >0, so if stride is 2^n we can use &(-stride) @@ -975,14 +975,14 @@ // only RCE predicate where exact limit is used and the predicate // will simply fail forcing recompilation. Node* neg_stride = phase->longcon(-stride_con); - span = phase->transform(new (phase->C) AndLNode(bias, neg_stride)); + span = phase->transform(new AndLNode(bias, neg_stride)); } else { - Node *trip = phase->transform(new (phase->C) DivLNode(0, bias, stride)); - span = phase->transform(new (phase->C) MulLNode(trip, stride)); + Node *trip = phase->transform(new DivLNode(0, bias, stride)); + span = phase->transform(new MulLNode(trip, stride)); } // Convert back to int - Node *span_int = phase->transform(new (phase->C) ConvL2INode(span)); - return new (phase->C) AddINode(span_int, in(Init)); // exact limit + Node *span_int = phase->transform(new ConvL2INode(span)); + return new AddINode(span_int, in(Init)); // exact limit } return NULL; // No progress @@ -1188,7 +1188,7 @@ uint i; // Make a new RegionNode to be the landing pad. - Node *landing_pad = new (phase->C) RegionNode( fall_in_cnt+1 ); + Node *landing_pad = new RegionNode( fall_in_cnt+1 ); phase->set_loop(landing_pad,_parent); // Gather all the fall-in control paths into the landing pad uint icnt = fall_in_cnt; @@ -1274,7 +1274,7 @@ // Make a LoopNode for the outermost loop. Node *ctl = _head->in(LoopNode::EntryControl); - Node *outer = new (phase->C) LoopNode( ctl, _head->in(outer_idx) ); + Node *outer = new LoopNode( ctl, _head->in(outer_idx) ); outer = igvn.register_new_node_with_optimizer(outer, _head); phase->set_created_loop_node(); @@ -1388,7 +1388,7 @@ Node *hot_tail = NULL; // Make a Region for the merge point - Node *r = new (phase->C) RegionNode(1); + Node *r = new RegionNode(1); for( i = 2; i < _head->req(); i++ ) { if( i != hot_idx ) r->add_req( _head->in(i) ); @@ -1407,7 +1407,7 @@ PhiNode* n = out->as_Phi(); igvn.hash_delete(n); // Delete from hash before hacking edges Node *hot_phi = NULL; - Node *phi = new (phase->C) PhiNode(r, n->type(), n->adr_type()); + Node *phi = new PhiNode(r, n->type(), n->adr_type()); // Check all inputs for the ones to peel out uint j = 1; for( uint i = 2; i < n->req(); i++ ) { @@ -1529,7 +1529,7 @@ } else if (!_head->is_Loop() && !_irreducible) { // Make a new LoopNode to replace the old loop head - Node *l = new (phase->C) LoopNode( _head->in(1), _head->in(2) ); + Node *l = new LoopNode( _head->in(1), _head->in(2) ); l = igvn.register_new_node_with_optimizer(l, _head); phase->set_created_loop_node(); // Go ahead and replace _head @@ -1771,16 +1771,16 @@ // It is scaled by the 'ratio_con'. Node* ratio = _igvn.intcon(ratio_con); set_ctrl(ratio, C->root()); - Node* ratio_init = new (C) MulINode(init, ratio); + Node* ratio_init = new MulINode(init, ratio); _igvn.register_new_node_with_optimizer(ratio_init, init); set_early_ctrl(ratio_init); - Node* diff = new (C) SubINode(init2, ratio_init); + Node* diff = new SubINode(init2, ratio_init); _igvn.register_new_node_with_optimizer(diff, init2); set_early_ctrl(diff); - Node* ratio_idx = new (C) MulINode(phi, ratio); + Node* ratio_idx = new MulINode(phi, ratio); _igvn.register_new_node_with_optimizer(ratio_idx, phi); set_ctrl(ratio_idx, cl); - Node* add = new (C) AddINode(ratio_idx, diff); + Node* add = new AddINode(ratio_idx, diff); _igvn.register_new_node_with_optimizer(add); set_ctrl(add, cl); _igvn.replace_node( phi2, add ); @@ -2888,10 +2888,10 @@ if (!_verify_only) { // Insert the NeverBranch between 'm' and it's control user. - NeverBranchNode *iff = new (C) NeverBranchNode( m ); + NeverBranchNode *iff = new NeverBranchNode( m ); _igvn.register_new_node_with_optimizer(iff); set_loop(iff, l); - Node *if_t = new (C) CProjNode( iff, 0 ); + Node *if_t = new CProjNode( iff, 0 ); _igvn.register_new_node_with_optimizer(if_t); set_loop(if_t, l); @@ -2907,16 +2907,16 @@ cfg->set_req( k, if_t ); // Now point to NeverBranch // Now create the never-taken loop exit - Node *if_f = new (C) CProjNode( iff, 1 ); + Node *if_f = new CProjNode( iff, 1 ); _igvn.register_new_node_with_optimizer(if_f); set_loop(if_f, l); // Find frame ptr for Halt. Relies on the optimizer // V-N'ing. Easier and quicker than searching through // the program structure. - Node *frame = new (C) ParmNode( C->start(), TypeFunc::FramePtr ); + Node *frame = new ParmNode( C->start(), TypeFunc::FramePtr ); _igvn.register_new_node_with_optimizer(frame); // Halt & Catch Fire - Node *halt = new (C) HaltNode( if_f, frame ); + Node *halt = new HaltNode( if_f, frame ); _igvn.register_new_node_with_optimizer(halt); set_loop(halt, l); C->root()->add_req(halt); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/loopopts.cpp --- a/hotspot/src/share/vm/opto/loopopts.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/loopopts.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -56,7 +56,7 @@ int iid = t_oop->instance_id(); int index = C->get_alias_index(t_oop); int offset = t_oop->offset(); - phi = new (C) PhiNode(region, type, NULL, iid, index, offset); + phi = new PhiNode(region, type, NULL, iid, index, offset); } else { phi = PhiNode::make_blank(region, n); } @@ -363,9 +363,9 @@ _igvn.type( add->in(1) ) != TypeInt::ZERO ) { Node *zero = _igvn.intcon(0); set_ctrl(zero, C->root()); - Node *neg = new (C) SubINode( _igvn.intcon(0), add->in(2) ); + Node *neg = new SubINode( _igvn.intcon(0), add->in(2) ); register_new_node( neg, get_ctrl(add->in(2) ) ); - add = new (C) AddINode( add->in(1), neg ); + add = new AddINode( add->in(1), neg ); register_new_node( add, add_ctrl ); } if( add->Opcode() != Op_AddI ) return NULL; @@ -391,14 +391,14 @@ return NULL; // No invariant part of the add? // Yes! Reshape address expression! - Node *inv_scale = new (C) LShiftINode( add_invar, scale ); + Node *inv_scale = new LShiftINode( add_invar, scale ); Node *inv_scale_ctrl = dom_depth(add_invar_ctrl) > dom_depth(scale_ctrl) ? add_invar_ctrl : scale_ctrl; register_new_node( inv_scale, inv_scale_ctrl ); - Node *var_scale = new (C) LShiftINode( add_var, scale ); + Node *var_scale = new LShiftINode( add_var, scale ); register_new_node( var_scale, n_ctrl ); - Node *var_add = new (C) AddINode( var_scale, inv_scale ); + Node *var_add = new AddINode( var_scale, inv_scale ); register_new_node( var_add, n_ctrl ); _igvn.replace_node( n, var_add ); return var_add; @@ -430,10 +430,10 @@ IdealLoopTree *n23_loop = get_loop( n23_ctrl ); if( n22loop != n_loop && n22loop->is_member(n_loop) && n23_loop == n_loop ) { - Node *add1 = new (C) AddPNode( n->in(1), n->in(2)->in(2), n->in(3) ); + Node *add1 = new AddPNode( n->in(1), n->in(2)->in(2), n->in(3) ); // Stuff new AddP in the loop preheader register_new_node( add1, n_loop->_head->in(LoopNode::EntryControl) ); - Node *add2 = new (C) AddPNode( n->in(1), add1, n->in(2)->in(3) ); + Node *add2 = new AddPNode( n->in(1), add1, n->in(2)->in(3) ); register_new_node( add2, n_ctrl ); _igvn.replace_node( n, add2 ); return add2; @@ -451,10 +451,10 @@ Node *tmp = V; V = I; I = tmp; } if( !is_member(n_loop,get_ctrl(I)) ) { - Node *add1 = new (C) AddPNode( n->in(1), n->in(2), I ); + Node *add1 = new AddPNode( n->in(1), n->in(2), I ); // Stuff new AddP in the loop preheader register_new_node( add1, n_loop->_head->in(LoopNode::EntryControl) ); - Node *add2 = new (C) AddPNode( n->in(1), add1, V ); + Node *add2 = new AddPNode( n->in(1), add1, V ); register_new_node( add2, n_ctrl ); _igvn.replace_node( n, add2 ); return add2; @@ -1104,8 +1104,8 @@ Node *sample_cmp = sample_bool->in(1); // Make Phis to merge the Cmp's inputs. - PhiNode *phi1 = new (C) PhiNode( phi->in(0), Type::TOP ); - PhiNode *phi2 = new (C) PhiNode( phi->in(0), Type::TOP ); + PhiNode *phi1 = new PhiNode( phi->in(0), Type::TOP ); + PhiNode *phi2 = new PhiNode( phi->in(0), Type::TOP ); for( i = 1; i < phi->req(); i++ ) { Node *n1 = phi->in(i)->in(1)->in(1); Node *n2 = phi->in(i)->in(1)->in(2); @@ -1172,8 +1172,8 @@ Node *sample_cmp = phi->in(1); // Make Phis to merge the Cmp's inputs. - PhiNode *phi1 = new (C) PhiNode( phi->in(0), Type::TOP ); - PhiNode *phi2 = new (C) PhiNode( phi->in(0), Type::TOP ); + PhiNode *phi1 = new PhiNode( phi->in(0), Type::TOP ); + PhiNode *phi2 = new PhiNode( phi->in(0), Type::TOP ); for( uint j = 1; j < phi->req(); j++ ) { Node *cmp_top = phi->in(j); // Inputs are all Cmp or TOP Node *n1, *n2; @@ -1337,7 +1337,7 @@ // We need a Region to merge the exit from the peeled body and the // exit from the old loop body. - RegionNode *r = new (C) RegionNode(3); + RegionNode *r = new RegionNode(3); // Map the old use to the new merge point old_new.map( use->_idx, r ); uint dd_r = MIN2(dom_depth(newuse),dom_depth(use)); @@ -1403,7 +1403,8 @@ // loop. Happens if people set a loop-exit flag; then test the flag // in the loop to break the loop, then test is again outside of the // loop to determine which way the loop exited. - if( use->is_If() || use->is_CMove() ) { + // Loop predicate If node connects to Bool node through Opaque1 node. + if (use->is_If() || use->is_CMove() || C->is_predicate_opaq(use)) { // Since this code is highly unlikely, we lazily build the worklist // of such Nodes to go split. if( !split_if_set ) @@ -1684,13 +1685,13 @@ ProjNode* proj2 = proj_clone(proj, iff); register_node(proj2, loop, iff, ddepth); - Node* cmp = Signed ? (Node*) new (C)CmpINode(left, right) : (Node*) new (C)CmpUNode(left, right); + Node* cmp = Signed ? (Node*) new CmpINode(left, right) : (Node*) new CmpUNode(left, right); register_node(cmp, loop, proj2, ddepth); - BoolNode* bol = new (C)BoolNode(cmp, relop); + BoolNode* bol = new BoolNode(cmp, relop); register_node(bol, loop, proj2, ddepth); - IfNode* new_if = new (C)IfNode(proj2, bol, iff->_prob, iff->_fcnt); + IfNode* new_if = new IfNode(proj2, bol, iff->_prob, iff->_fcnt); register_node(new_if, loop, proj2, ddepth); proj->set_req(0, new_if); // reattach @@ -1742,11 +1743,11 @@ ProjNode* proj2 = proj_clone(proj, iff); register_node(proj2, loop, iff, ddepth); - RegionNode* reg = new (C)RegionNode(2); + RegionNode* reg = new RegionNode(2); reg->set_req(1, proj2); register_node(reg, loop, iff, ddepth); - IfNode* dum_if = new (C)IfNode(reg, short_circuit_if(NULL, proj), iff->_prob, iff->_fcnt); + IfNode* dum_if = new IfNode(reg, short_circuit_if(NULL, proj), iff->_prob, iff->_fcnt); register_node(dum_if, loop, reg, ddepth); proj->set_req(0, dum_if); // reattach @@ -2569,7 +2570,7 @@ // Create new loop head for new phis and to hang // the nodes being moved (sinked) from the peel region. - LoopNode* new_head = new (C) LoopNode(last_peel, last_peel); + LoopNode* new_head = new LoopNode(last_peel, last_peel); new_head->set_unswitch_count(head->unswitch_count()); // Preserve _igvn.register_new_node_with_optimizer(new_head); assert(first_not_peeled->in(0) == last_peel, "last_peel <- first_not_peeled"); @@ -2769,12 +2770,12 @@ if (dom_lca(exit, u_ctrl) != exit) continue; // Hit! Refactor use to use the post-incremented tripcounter. // Compute a post-increment tripcounter. - Node *opaq = new (C) Opaque2Node( C, cle->incr() ); - register_new_node( opaq, u_ctrl ); + Node *opaq = new Opaque2Node( C, cle->incr() ); + register_new_node(opaq, exit); Node *neg_stride = _igvn.intcon(-cle->stride_con()); set_ctrl(neg_stride, C->root()); - Node *post = new (C) AddINode( opaq, neg_stride); - register_new_node( post, u_ctrl ); + Node *post = new AddINode( opaq, neg_stride); + register_new_node(post, exit); _igvn.rehash_node_delayed(use); for (uint j = 1; j < use->req(); j++) { if (use->in(j) == phi) diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/machnode.hpp --- a/hotspot/src/share/vm/opto/machnode.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/machnode.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -60,7 +60,10 @@ class MachOper : public ResourceObj { public: // Allocate right next to the MachNodes in the same arena - void *operator new( size_t x, Compile* C ) throw() { return C->node_arena()->Amalloc_D(x); } + void *operator new(size_t x) throw() { + Compile* C = Compile::current(); + return C->node_arena()->Amalloc_D(x); + } // Opcode virtual uint opcode() const = 0; diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/macro.cpp --- a/hotspot/src/share/vm/opto/macro.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/macro.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -108,20 +108,20 @@ Node* PhaseMacroExpand::opt_bits_test(Node* ctrl, Node* region, int edge, Node* word, int mask, int bits, bool return_fast_path) { Node* cmp; if (mask != 0) { - Node* and_node = transform_later(new (C) AndXNode(word, MakeConX(mask))); - cmp = transform_later(new (C) CmpXNode(and_node, MakeConX(bits))); + Node* and_node = transform_later(new AndXNode(word, MakeConX(mask))); + cmp = transform_later(new CmpXNode(and_node, MakeConX(bits))); } else { cmp = word; } - Node* bol = transform_later(new (C) BoolNode(cmp, BoolTest::ne)); - IfNode* iff = new (C) IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN ); + Node* bol = transform_later(new BoolNode(cmp, BoolTest::ne)); + IfNode* iff = new IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN ); transform_later(iff); // Fast path taken. - Node *fast_taken = transform_later( new (C) IfFalseNode(iff) ); + Node *fast_taken = transform_later(new IfFalseNode(iff)); // Fast path not-taken, i.e. slow path - Node *slow_taken = transform_later( new (C) IfTrueNode(iff) ); + Node *slow_taken = transform_later(new IfTrueNode(iff)); if (return_fast_path) { region->init_req(edge, slow_taken); // Capture slow-control @@ -147,8 +147,8 @@ // Slow-path call CallNode *call = leaf_name - ? (CallNode*)new (C) CallLeafNode ( slow_call_type, slow_call, leaf_name, TypeRawPtr::BOTTOM ) - : (CallNode*)new (C) CallStaticJavaNode( slow_call_type, slow_call, OptoRuntime::stub_name(slow_call), oldcall->jvms()->bci(), TypeRawPtr::BOTTOM ); + ? (CallNode*)new CallLeafNode ( slow_call_type, slow_call, leaf_name, TypeRawPtr::BOTTOM ) + : (CallNode*)new CallStaticJavaNode( slow_call_type, slow_call, OptoRuntime::stub_name(slow_call), oldcall->jvms()->bci(), TypeRawPtr::BOTTOM ); // Slow path call has no side-effects, uses few values copy_predefined_input_for_runtime_call(slow_path, oldcall, call ); @@ -423,7 +423,7 @@ GrowableArray values(length, length, NULL, false); // create a new Phi for the value - PhiNode *phi = new (C) PhiNode(mem->in(0), phi_type, NULL, instance_id, alias_idx, offset); + PhiNode *phi = new PhiNode(mem->in(0), phi_type, NULL, instance_id, alias_idx, offset); transform_later(phi); value_phis->push(phi, mem->_idx); @@ -735,7 +735,7 @@ // of regular debuginfo at the last (youngest) JVMS. // Record relative start index. uint first_ind = (sfpt->req() - sfpt->jvms()->scloff()); - SafePointScalarObjectNode* sobj = new (C) SafePointScalarObjectNode(res_type, + SafePointScalarObjectNode* sobj = new SafePointScalarObjectNode(res_type, #ifdef ASSERT alloc, #endif @@ -843,7 +843,7 @@ if (field_val->is_EncodeP()) { field_val = field_val->in(1); } else { - field_val = transform_later(new (C) DecodeNNode(field_val, field_val->get_ptr_type())); + field_val = transform_later(new DecodeNNode(field_val, field_val->get_ptr_type())); } } sfpt->add_req(field_val); @@ -1069,7 +1069,7 @@ //---------------------------set_eden_pointers------------------------- void PhaseMacroExpand::set_eden_pointers(Node* &eden_top_adr, Node* &eden_end_adr) { if (UseTLAB) { // Private allocation: load from TLS - Node* thread = transform_later(new (C) ThreadLocalNode()); + Node* thread = transform_later(new ThreadLocalNode()); int tlab_top_offset = in_bytes(JavaThread::tlab_top_offset()); int tlab_end_offset = in_bytes(JavaThread::tlab_end_offset()); eden_top_adr = basic_plus_adr(top()/*not oop*/, thread, tlab_top_offset); @@ -1205,18 +1205,18 @@ assert (initial_slow_test == NULL || !always_slow, "arguments must be consistent"); // generate the initial test if necessary if (initial_slow_test != NULL ) { - slow_region = new (C) RegionNode(3); + slow_region = new RegionNode(3); // Now make the initial failure test. Usually a too-big test but // might be a TRUE for finalizers or a fancy class check for // newInstance0. - IfNode *toobig_iff = new (C) IfNode(ctrl, initial_slow_test, PROB_MIN, COUNT_UNKNOWN); + IfNode *toobig_iff = new IfNode(ctrl, initial_slow_test, PROB_MIN, COUNT_UNKNOWN); transform_later(toobig_iff); // Plug the failing-too-big test into the slow-path region - Node *toobig_true = new (C) IfTrueNode( toobig_iff ); + Node *toobig_true = new IfTrueNode( toobig_iff ); transform_later(toobig_true); slow_region ->init_req( too_big_or_final_path, toobig_true ); - toobig_false = new (C) IfFalseNode( toobig_iff ); + toobig_false = new IfFalseNode( toobig_iff ); transform_later(toobig_false); } else { // No initial test, just fall into next case toobig_false = ctrl; @@ -1249,10 +1249,10 @@ Node *eden_end = make_load(ctrl, mem, eden_end_adr, 0, TypeRawPtr::BOTTOM, T_ADDRESS); // allocate the Region and Phi nodes for the result - result_region = new (C) RegionNode(3); - result_phi_rawmem = new (C) PhiNode(result_region, Type::MEMORY, TypeRawPtr::BOTTOM); - result_phi_rawoop = new (C) PhiNode(result_region, TypeRawPtr::BOTTOM); - result_phi_i_o = new (C) PhiNode(result_region, Type::ABIO); // I/O is used for Prefetch + result_region = new RegionNode(3); + result_phi_rawmem = new PhiNode(result_region, Type::MEMORY, TypeRawPtr::BOTTOM); + result_phi_rawoop = new PhiNode(result_region, TypeRawPtr::BOTTOM); + result_phi_i_o = new PhiNode(result_region, Type::ABIO); // I/O is used for Prefetch // We need a Region for the loop-back contended case. enum { fall_in_path = 1, contended_loopback_path = 2 }; @@ -1262,8 +1262,8 @@ contended_region = toobig_false; contended_phi_rawmem = mem; } else { - contended_region = new (C) RegionNode(3); - contended_phi_rawmem = new (C) PhiNode(contended_region, Type::MEMORY, TypeRawPtr::BOTTOM); + contended_region = new RegionNode(3); + contended_phi_rawmem = new PhiNode(contended_region, Type::MEMORY, TypeRawPtr::BOTTOM); // Now handle the passing-too-big test. We fall into the contended // loop-back merge point. contended_region ->init_req(fall_in_path, toobig_false); @@ -1275,23 +1275,23 @@ // Load(-locked) the heap top. // See note above concerning the control input when using a TLAB Node *old_eden_top = UseTLAB - ? new (C) LoadPNode (ctrl, contended_phi_rawmem, eden_top_adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM, MemNode::unordered) - : new (C) LoadPLockedNode(contended_region, contended_phi_rawmem, eden_top_adr, MemNode::acquire); + ? new LoadPNode (ctrl, contended_phi_rawmem, eden_top_adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM, MemNode::unordered) + : new LoadPLockedNode(contended_region, contended_phi_rawmem, eden_top_adr, MemNode::acquire); transform_later(old_eden_top); // Add to heap top to get a new heap top - Node *new_eden_top = new (C) AddPNode(top(), old_eden_top, size_in_bytes); + Node *new_eden_top = new AddPNode(top(), old_eden_top, size_in_bytes); transform_later(new_eden_top); // Check for needing a GC; compare against heap end - Node *needgc_cmp = new (C) CmpPNode(new_eden_top, eden_end); + Node *needgc_cmp = new CmpPNode(new_eden_top, eden_end); transform_later(needgc_cmp); - Node *needgc_bol = new (C) BoolNode(needgc_cmp, BoolTest::ge); + Node *needgc_bol = new BoolNode(needgc_cmp, BoolTest::ge); transform_later(needgc_bol); - IfNode *needgc_iff = new (C) IfNode(contended_region, needgc_bol, PROB_UNLIKELY_MAG(4), COUNT_UNKNOWN); + IfNode *needgc_iff = new IfNode(contended_region, needgc_bol, PROB_UNLIKELY_MAG(4), COUNT_UNKNOWN); transform_later(needgc_iff); // Plug the failing-heap-space-need-gc test into the slow-path region - Node *needgc_true = new (C) IfTrueNode(needgc_iff); + Node *needgc_true = new IfTrueNode(needgc_iff); transform_later(needgc_true); if (initial_slow_test) { slow_region->init_req(need_gc_path, needgc_true); @@ -1302,7 +1302,7 @@ slow_region = needgc_true; } // No need for a GC. Setup for the Store-Conditional - Node *needgc_false = new (C) IfFalseNode(needgc_iff); + Node *needgc_false = new IfFalseNode(needgc_iff); transform_later(needgc_false); // Grab regular I/O before optional prefetch may change it. @@ -1322,37 +1322,37 @@ // memory state. if (UseTLAB) { Node* store_eden_top = - new (C) StorePNode(needgc_false, contended_phi_rawmem, eden_top_adr, + new StorePNode(needgc_false, contended_phi_rawmem, eden_top_adr, TypeRawPtr::BOTTOM, new_eden_top, MemNode::unordered); transform_later(store_eden_top); fast_oop_ctrl = needgc_false; // No contention, so this is the fast path fast_oop_rawmem = store_eden_top; } else { Node* store_eden_top = - new (C) StorePConditionalNode(needgc_false, contended_phi_rawmem, eden_top_adr, + new StorePConditionalNode(needgc_false, contended_phi_rawmem, eden_top_adr, new_eden_top, fast_oop/*old_eden_top*/); transform_later(store_eden_top); - Node *contention_check = new (C) BoolNode(store_eden_top, BoolTest::ne); + Node *contention_check = new BoolNode(store_eden_top, BoolTest::ne); transform_later(contention_check); - store_eden_top = new (C) SCMemProjNode(store_eden_top); + store_eden_top = new SCMemProjNode(store_eden_top); transform_later(store_eden_top); // If not using TLABs, check to see if there was contention. - IfNode *contention_iff = new (C) IfNode (needgc_false, contention_check, PROB_MIN, COUNT_UNKNOWN); + IfNode *contention_iff = new IfNode (needgc_false, contention_check, PROB_MIN, COUNT_UNKNOWN); transform_later(contention_iff); - Node *contention_true = new (C) IfTrueNode(contention_iff); + Node *contention_true = new IfTrueNode(contention_iff); transform_later(contention_true); // If contention, loopback and try again. contended_region->init_req(contended_loopback_path, contention_true); contended_phi_rawmem->init_req(contended_loopback_path, store_eden_top); // Fast-path succeeded with no contention! - Node *contention_false = new (C) IfFalseNode(contention_iff); + Node *contention_false = new IfFalseNode(contention_iff); transform_later(contention_false); fast_oop_ctrl = contention_false; // Bump total allocated bytes for this thread - Node* thread = new (C) ThreadLocalNode(); + Node* thread = new ThreadLocalNode(); transform_later(thread); Node* alloc_bytes_adr = basic_plus_adr(top()/*not oop*/, thread, in_bytes(JavaThread::allocated_bytes_offset())); @@ -1361,10 +1361,10 @@ #ifdef _LP64 Node* alloc_size = size_in_bytes; #else - Node* alloc_size = new (C) ConvI2LNode(size_in_bytes); + Node* alloc_size = new ConvI2LNode(size_in_bytes); transform_later(alloc_size); #endif - Node* new_alloc_bytes = new (C) AddLNode(alloc_bytes, alloc_size); + Node* new_alloc_bytes = new AddLNode(alloc_bytes, alloc_size); transform_later(new_alloc_bytes); fast_oop_rawmem = make_store(fast_oop_ctrl, store_eden_top, alloc_bytes_adr, 0, new_alloc_bytes, T_LONG); @@ -1391,9 +1391,9 @@ mb->init_req(TypeFunc::Memory, fast_oop_rawmem); mb->init_req(TypeFunc::Control, fast_oop_ctrl); - fast_oop_ctrl = new (C) ProjNode(mb,TypeFunc::Control); + fast_oop_ctrl = new ProjNode(mb,TypeFunc::Control); transform_later(fast_oop_ctrl); - fast_oop_rawmem = new (C) ProjNode(mb,TypeFunc::Memory); + fast_oop_rawmem = new ProjNode(mb,TypeFunc::Memory); transform_later(fast_oop_rawmem); } else { // Add the MemBarStoreStore after the InitializeNode so that @@ -1407,9 +1407,9 @@ MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot); transform_later(mb); - Node* ctrl = new (C) ProjNode(init,TypeFunc::Control); + Node* ctrl = new ProjNode(init,TypeFunc::Control); transform_later(ctrl); - Node* mem = new (C) ProjNode(init,TypeFunc::Memory); + Node* mem = new ProjNode(init,TypeFunc::Memory); transform_later(mem); // The MemBarStoreStore depends on control and memory coming @@ -1417,9 +1417,9 @@ mb->init_req(TypeFunc::Memory, mem); mb->init_req(TypeFunc::Control, ctrl); - ctrl = new (C) ProjNode(mb,TypeFunc::Control); + ctrl = new ProjNode(mb,TypeFunc::Control); transform_later(ctrl); - mem = new (C) ProjNode(mb,TypeFunc::Memory); + mem = new ProjNode(mb,TypeFunc::Memory); transform_later(mem); // All nodes that depended on the InitializeNode for control @@ -1433,13 +1433,13 @@ if (C->env()->dtrace_extended_probes()) { // Slow-path call int size = TypeFunc::Parms + 2; - CallLeafNode *call = new (C) CallLeafNode(OptoRuntime::dtrace_object_alloc_Type(), - CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc_base), - "dtrace_object_alloc", - TypeRawPtr::BOTTOM); + CallLeafNode *call = new CallLeafNode(OptoRuntime::dtrace_object_alloc_Type(), + CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc_base), + "dtrace_object_alloc", + TypeRawPtr::BOTTOM); // Get base of thread-local storage area - Node* thread = new (C) ThreadLocalNode(); + Node* thread = new ThreadLocalNode(); transform_later(thread); call->init_req(TypeFunc::Parms+0, thread); @@ -1450,9 +1450,9 @@ call->init_req(TypeFunc::ReturnAdr, alloc->in(TypeFunc::ReturnAdr)); call->init_req(TypeFunc::FramePtr, alloc->in(TypeFunc::FramePtr)); transform_later(call); - fast_oop_ctrl = new (C) ProjNode(call,TypeFunc::Control); + fast_oop_ctrl = new ProjNode(call,TypeFunc::Control); transform_later(fast_oop_ctrl); - fast_oop_rawmem = new (C) ProjNode(call,TypeFunc::Memory); + fast_oop_rawmem = new ProjNode(call,TypeFunc::Memory); transform_later(fast_oop_rawmem); } @@ -1467,7 +1467,7 @@ } // Generate slow-path call - CallNode *call = new (C) CallStaticJavaNode(slow_call_type, slow_call_address, + CallNode *call = new CallStaticJavaNode(slow_call_type, slow_call_address, OptoRuntime::stub_name(slow_call_address), alloc->jvms()->bci(), TypePtr::BOTTOM); @@ -1524,7 +1524,7 @@ // _memproj_catchall so we end up with a call that has only 1 memory projection. if (_memproj_catchall != NULL ) { if (_memproj_fallthrough == NULL) { - _memproj_fallthrough = new (C) ProjNode(call, TypeFunc::Memory); + _memproj_fallthrough = new ProjNode(call, TypeFunc::Memory); transform_later(_memproj_fallthrough); } for (DUIterator_Fast imax, i = _memproj_catchall->fast_outs(imax); i < imax; i++) { @@ -1556,7 +1556,7 @@ // _ioproj_catchall so we end up with a call that has only 1 i_o projection. if (_ioproj_catchall != NULL ) { if (_ioproj_fallthrough == NULL) { - _ioproj_fallthrough = new (C) ProjNode(call, TypeFunc::I_O); + _ioproj_fallthrough = new ProjNode(call, TypeFunc::I_O); transform_later(_ioproj_fallthrough); } for (DUIterator_Fast imax, i = _ioproj_catchall->fast_outs(imax); i < imax; i++) { @@ -1690,47 +1690,47 @@ // As an allocation hits the watermark, we will prefetch starting // at a "distance" away from watermark. - Node *pf_region = new (C) RegionNode(3); - Node *pf_phi_rawmem = new (C) PhiNode( pf_region, Type::MEMORY, + Node *pf_region = new RegionNode(3); + Node *pf_phi_rawmem = new PhiNode( pf_region, Type::MEMORY, TypeRawPtr::BOTTOM ); // I/O is used for Prefetch - Node *pf_phi_abio = new (C) PhiNode( pf_region, Type::ABIO ); + Node *pf_phi_abio = new PhiNode( pf_region, Type::ABIO ); - Node *thread = new (C) ThreadLocalNode(); + Node *thread = new ThreadLocalNode(); transform_later(thread); - Node *eden_pf_adr = new (C) AddPNode( top()/*not oop*/, thread, + Node *eden_pf_adr = new AddPNode( top()/*not oop*/, thread, _igvn.MakeConX(in_bytes(JavaThread::tlab_pf_top_offset())) ); transform_later(eden_pf_adr); - Node *old_pf_wm = new (C) LoadPNode(needgc_false, + Node *old_pf_wm = new LoadPNode(needgc_false, contended_phi_rawmem, eden_pf_adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM, MemNode::unordered); transform_later(old_pf_wm); // check against new_eden_top - Node *need_pf_cmp = new (C) CmpPNode( new_eden_top, old_pf_wm ); + Node *need_pf_cmp = new CmpPNode( new_eden_top, old_pf_wm ); transform_later(need_pf_cmp); - Node *need_pf_bol = new (C) BoolNode( need_pf_cmp, BoolTest::ge ); + Node *need_pf_bol = new BoolNode( need_pf_cmp, BoolTest::ge ); transform_later(need_pf_bol); - IfNode *need_pf_iff = new (C) IfNode( needgc_false, need_pf_bol, + IfNode *need_pf_iff = new IfNode( needgc_false, need_pf_bol, PROB_UNLIKELY_MAG(4), COUNT_UNKNOWN ); transform_later(need_pf_iff); // true node, add prefetchdistance - Node *need_pf_true = new (C) IfTrueNode( need_pf_iff ); + Node *need_pf_true = new IfTrueNode( need_pf_iff ); transform_later(need_pf_true); - Node *need_pf_false = new (C) IfFalseNode( need_pf_iff ); + Node *need_pf_false = new IfFalseNode( need_pf_iff ); transform_later(need_pf_false); - Node *new_pf_wmt = new (C) AddPNode( top(), old_pf_wm, + Node *new_pf_wmt = new AddPNode( top(), old_pf_wm, _igvn.MakeConX(AllocatePrefetchDistance) ); transform_later(new_pf_wmt ); new_pf_wmt->set_req(0, need_pf_true); - Node *store_new_wmt = new (C) StorePNode(need_pf_true, + Node *store_new_wmt = new StorePNode(need_pf_true, contended_phi_rawmem, eden_pf_adr, TypeRawPtr::BOTTOM, new_pf_wmt, MemNode::unordered); @@ -1746,10 +1746,10 @@ uint distance = 0; for ( uint i = 0; i < lines; i++ ) { - prefetch_adr = new (C) AddPNode( old_pf_wm, new_pf_wmt, + prefetch_adr = new AddPNode( old_pf_wm, new_pf_wmt, _igvn.MakeConX(distance) ); transform_later(prefetch_adr); - prefetch = new (C) PrefetchAllocationNode( i_o, prefetch_adr ); + prefetch = new PrefetchAllocationNode( i_o, prefetch_adr ); transform_later(prefetch); distance += step_size; i_o = prefetch; @@ -1772,8 +1772,8 @@ } else if( UseTLAB && AllocatePrefetchStyle == 3 ) { // Insert a prefetch for each allocation. // This code is used for Sparc with BIS. - Node *pf_region = new (C) RegionNode(3); - Node *pf_phi_rawmem = new (C) PhiNode( pf_region, Type::MEMORY, + Node *pf_region = new RegionNode(3); + Node *pf_phi_rawmem = new PhiNode( pf_region, Type::MEMORY, TypeRawPtr::BOTTOM ); // Generate several prefetch instructions. @@ -1782,29 +1782,29 @@ uint distance = AllocatePrefetchDistance; // Next cache address. - Node *cache_adr = new (C) AddPNode(old_eden_top, old_eden_top, + Node *cache_adr = new AddPNode(old_eden_top, old_eden_top, _igvn.MakeConX(distance)); transform_later(cache_adr); - cache_adr = new (C) CastP2XNode(needgc_false, cache_adr); + cache_adr = new CastP2XNode(needgc_false, cache_adr); transform_later(cache_adr); Node* mask = _igvn.MakeConX(~(intptr_t)(step_size-1)); - cache_adr = new (C) AndXNode(cache_adr, mask); + cache_adr = new AndXNode(cache_adr, mask); transform_later(cache_adr); - cache_adr = new (C) CastX2PNode(cache_adr); + cache_adr = new CastX2PNode(cache_adr); transform_later(cache_adr); // Prefetch - Node *prefetch = new (C) PrefetchAllocationNode( contended_phi_rawmem, cache_adr ); + Node *prefetch = new PrefetchAllocationNode( contended_phi_rawmem, cache_adr ); prefetch->set_req(0, needgc_false); transform_later(prefetch); contended_phi_rawmem = prefetch; Node *prefetch_adr; distance = step_size; for ( uint i = 1; i < lines; i++ ) { - prefetch_adr = new (C) AddPNode( cache_adr, cache_adr, + prefetch_adr = new AddPNode( cache_adr, cache_adr, _igvn.MakeConX(distance) ); transform_later(prefetch_adr); - prefetch = new (C) PrefetchAllocationNode( contended_phi_rawmem, prefetch_adr ); + prefetch = new PrefetchAllocationNode( contended_phi_rawmem, prefetch_adr ); transform_later(prefetch); distance += step_size; contended_phi_rawmem = prefetch; @@ -1818,10 +1818,10 @@ uint step_size = AllocatePrefetchStepSize; uint distance = AllocatePrefetchDistance; for ( uint i = 0; i < lines; i++ ) { - prefetch_adr = new (C) AddPNode( old_eden_top, new_eden_top, + prefetch_adr = new AddPNode( old_eden_top, new_eden_top, _igvn.MakeConX(distance) ); transform_later(prefetch_adr); - prefetch = new (C) PrefetchAllocationNode( i_o, prefetch_adr ); + prefetch = new PrefetchAllocationNode( i_o, prefetch_adr ); // Do not let it float too high, since if eden_top == eden_end, // both might be null. if( i == 0 ) { // Set control for first prefetch, next follows it @@ -2170,12 +2170,12 @@ * } */ - region = new (C) RegionNode(5); + region = new RegionNode(5); // create a Phi for the memory state - mem_phi = new (C) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); + mem_phi = new PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); - Node* fast_lock_region = new (C) RegionNode(3); - Node* fast_lock_mem_phi = new (C) PhiNode( fast_lock_region, Type::MEMORY, TypeRawPtr::BOTTOM); + Node* fast_lock_region = new RegionNode(3); + Node* fast_lock_mem_phi = new PhiNode( fast_lock_region, Type::MEMORY, TypeRawPtr::BOTTOM); // First, check mark word for the biased lock pattern. Node* mark_node = make_load(ctrl, mem, obj, oopDesc::mark_offset_in_bytes(), TypeX_X, TypeX_X->basic_type()); @@ -2205,10 +2205,10 @@ } Node *proto_node = make_load(ctrl, mem, klass_node, in_bytes(Klass::prototype_header_offset()), TypeX_X, TypeX_X->basic_type()); - Node* thread = transform_later(new (C) ThreadLocalNode()); - Node* cast_thread = transform_later(new (C) CastP2XNode(ctrl, thread)); - Node* o_node = transform_later(new (C) OrXNode(cast_thread, proto_node)); - Node* x_node = transform_later(new (C) XorXNode(o_node, mark_node)); + Node* thread = transform_later(new ThreadLocalNode()); + Node* cast_thread = transform_later(new CastP2XNode(ctrl, thread)); + Node* o_node = transform_later(new OrXNode(cast_thread, proto_node)); + Node* x_node = transform_later(new XorXNode(o_node, mark_node)); // Get slow path - mark word does NOT match the value. Node* not_biased_ctrl = opt_bits_test(ctrl, region, 3, x_node, @@ -2231,17 +2231,17 @@ // We are going to try to reset the mark of this object to the prototype // value and fall through to the CAS-based locking scheme. Node* adr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes()); - Node* cas = new (C) StoreXConditionalNode(not_biased_ctrl, mem, adr, - proto_node, mark_node); + Node* cas = new StoreXConditionalNode(not_biased_ctrl, mem, adr, + proto_node, mark_node); transform_later(cas); - Node* proj = transform_later( new (C) SCMemProjNode(cas)); + Node* proj = transform_later(new SCMemProjNode(cas)); fast_lock_mem_phi->init_req(2, proj); // Second, check epoch bits. - Node* rebiased_region = new (C) RegionNode(3); - Node* old_phi = new (C) PhiNode( rebiased_region, TypeX_X); - Node* new_phi = new (C) PhiNode( rebiased_region, TypeX_X); + Node* rebiased_region = new RegionNode(3); + Node* old_phi = new PhiNode( rebiased_region, TypeX_X); + Node* new_phi = new PhiNode( rebiased_region, TypeX_X); // Get slow path - mark word does NOT match epoch bits. Node* epoch_ctrl = opt_bits_test(ctrl, rebiased_region, 1, x_node, @@ -2258,9 +2258,9 @@ Node* cmask = MakeConX(markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place); - Node* old = transform_later(new (C) AndXNode(mark_node, cmask)); - cast_thread = transform_later(new (C) CastP2XNode(ctrl, thread)); - Node* new_mark = transform_later(new (C) OrXNode(cast_thread, old)); + Node* old = transform_later(new AndXNode(mark_node, cmask)); + cast_thread = transform_later(new CastP2XNode(ctrl, thread)); + Node* new_mark = transform_later(new OrXNode(cast_thread, old)); old_phi->init_req(1, old); new_phi->init_req(1, new_mark); @@ -2270,10 +2270,9 @@ // Try to acquire the bias of the object using an atomic operation. // If this fails we will go in to the runtime to revoke the object's bias. - cas = new (C) StoreXConditionalNode(rebiased_region, mem, adr, - new_phi, old_phi); + cas = new StoreXConditionalNode(rebiased_region, mem, adr, new_phi, old_phi); transform_later(cas); - proj = transform_later( new (C) SCMemProjNode(cas)); + proj = transform_later(new SCMemProjNode(cas)); // Get slow path - Failed to CAS. not_biased_ctrl = opt_bits_test(rebiased_region, region, 4, cas, 0, 0); @@ -2281,8 +2280,8 @@ // region->in(4) is set to fast path - the object is rebiased to the current thread. // Failed to CAS. - slow_path = new (C) RegionNode(3); - Node *slow_mem = new (C) PhiNode( slow_path, Type::MEMORY, TypeRawPtr::BOTTOM); + slow_path = new RegionNode(3); + Node *slow_mem = new PhiNode( slow_path, Type::MEMORY, TypeRawPtr::BOTTOM); slow_path->init_req(1, not_biased_ctrl); // Capture slow-control slow_mem->init_req(1, proj); @@ -2306,9 +2305,9 @@ lock->set_req(TypeFunc::Memory, slow_mem); } else { - region = new (C) RegionNode(3); + region = new RegionNode(3); // create a Phi for the memory state - mem_phi = new (C) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); + mem_phi = new PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); // Optimize test; set region slot 2 slow_path = opt_bits_test(ctrl, region, 2, flock, 0, 0); @@ -2339,7 +2338,7 @@ transform_later(region); _igvn.replace_node(_fallthroughproj, region); - Node *memproj = transform_later( new(C) ProjNode(call, TypeFunc::Memory) ); + Node *memproj = transform_later(new ProjNode(call, TypeFunc::Memory)); mem_phi->init_req(1, memproj ); transform_later(mem_phi); _igvn.replace_node(_memproj_fallthrough, mem_phi); @@ -2364,9 +2363,9 @@ if (UseOptoBiasInlining) { // Check for biased locking unlock case, which is a no-op. // See the full description in MacroAssembler::biased_locking_exit(). - region = new (C) RegionNode(4); + region = new RegionNode(4); // create a Phi for the memory state - mem_phi = new (C) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); + mem_phi = new PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); mem_phi->init_req(3, mem); Node* mark_node = make_load(ctrl, mem, obj, oopDesc::mark_offset_in_bytes(), TypeX_X, TypeX_X->basic_type()); @@ -2374,12 +2373,12 @@ markOopDesc::biased_lock_mask_in_place, markOopDesc::biased_lock_pattern); } else { - region = new (C) RegionNode(3); + region = new RegionNode(3); // create a Phi for the memory state - mem_phi = new (C) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); + mem_phi = new PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); } - FastUnlockNode *funlock = new (C) FastUnlockNode( ctrl, obj, box ); + FastUnlockNode *funlock = new FastUnlockNode( ctrl, obj, box ); funlock = transform_later( funlock )->as_FastUnlock(); // Optimize test; set region slot 2 Node *slow_path = opt_bits_test(ctrl, region, 2, funlock, 0, 0); @@ -2404,7 +2403,7 @@ transform_later(region); _igvn.replace_node(_fallthroughproj, region); - Node *memproj = transform_later( new(C) ProjNode(call, TypeFunc::Memory) ); + Node *memproj = transform_later(new ProjNode(call, TypeFunc::Memory) ); mem_phi->init_req(1, memproj ); mem_phi->init_req(2, mem); transform_later(mem_phi); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/macro.hpp --- a/hotspot/src/share/vm/opto/macro.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/macro.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -52,7 +52,7 @@ return basic_plus_adr(base, base, offset); } Node* basic_plus_adr(Node* base, Node* ptr, Node* offset) { - Node* adr = new (C) AddPNode(base, ptr, offset); + Node* adr = new AddPNode(base, ptr, offset); return transform_later(adr); } Node* transform_later(Node* n) { diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/matcher.cpp --- a/hotspot/src/share/vm/opto/matcher.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/matcher.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -751,7 +751,7 @@ tail_call_rms[tail_call_edge_cnt].Insert(OptoReg::Name(i+1)); tail_jump_rms[tail_jump_edge_cnt].Insert(OptoReg::Name(i+1)); halt_rms [ halt_edge_cnt].Insert(OptoReg::Name(i+1)); - mproj = new (C) MachProjNode( start, proj_cnt, ret_rms[ret_edge_cnt], Op_RegD ); + mproj = new MachProjNode( start, proj_cnt, ret_rms[ret_edge_cnt], Op_RegD ); proj_cnt += 2; // Skip 2 for doubles } else if( (i&1) == 1 && // Else check for high half of double @@ -777,7 +777,7 @@ tail_call_rms[tail_call_edge_cnt].Insert(OptoReg::Name(i+1)); tail_jump_rms[tail_jump_edge_cnt].Insert(OptoReg::Name(i+1)); halt_rms [ halt_edge_cnt].Insert(OptoReg::Name(i+1)); - mproj = new (C) MachProjNode( start, proj_cnt, ret_rms[ret_edge_cnt], Op_RegL ); + mproj = new MachProjNode( start, proj_cnt, ret_rms[ret_edge_cnt], Op_RegL ); proj_cnt += 2; // Skip 2 for longs } else if( (i&1) == 1 && // Else check for high half of long @@ -792,7 +792,7 @@ mproj = C->top(); } else { // Make a projection for it off the Start - mproj = new (C) MachProjNode( start, proj_cnt++, ret_rms[ret_edge_cnt], _register_save_type[i] ); + mproj = new MachProjNode( start, proj_cnt++, ret_rms[ret_edge_cnt], _register_save_type[i] ); } ret_edge_cnt ++; @@ -845,13 +845,13 @@ // Compute generic short-offset Loads #ifdef _LP64 - MachNode *spillCP = match_tree(new (C) LoadNNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM,MemNode::unordered)); + MachNode *spillCP = match_tree(new LoadNNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM,MemNode::unordered)); #endif - MachNode *spillI = match_tree(new (C) LoadINode(NULL,mem,fp,atp,TypeInt::INT,MemNode::unordered)); - MachNode *spillL = match_tree(new (C) LoadLNode(NULL,mem,fp,atp,TypeLong::LONG,MemNode::unordered,false)); - MachNode *spillF = match_tree(new (C) LoadFNode(NULL,mem,fp,atp,Type::FLOAT,MemNode::unordered)); - MachNode *spillD = match_tree(new (C) LoadDNode(NULL,mem,fp,atp,Type::DOUBLE,MemNode::unordered)); - MachNode *spillP = match_tree(new (C) LoadPNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM,MemNode::unordered)); + MachNode *spillI = match_tree(new LoadINode(NULL,mem,fp,atp,TypeInt::INT,MemNode::unordered)); + MachNode *spillL = match_tree(new LoadLNode(NULL,mem,fp,atp,TypeLong::LONG,MemNode::unordered,false)); + MachNode *spillF = match_tree(new LoadFNode(NULL,mem,fp,atp,Type::FLOAT,MemNode::unordered)); + MachNode *spillD = match_tree(new LoadDNode(NULL,mem,fp,atp,Type::DOUBLE,MemNode::unordered)); + MachNode *spillP = match_tree(new LoadPNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM,MemNode::unordered)); assert(spillI != NULL && spillL != NULL && spillF != NULL && spillD != NULL && spillP != NULL, ""); // Get the ADLC notion of the right regmask, for each basic type. @@ -867,19 +867,19 @@ // Vector regmasks. if (Matcher::vector_size_supported(T_BYTE,4)) { TypeVect::VECTS = TypeVect::make(T_BYTE, 4); - MachNode *spillVectS = match_tree(new (C) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTS)); + MachNode *spillVectS = match_tree(new LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTS)); idealreg2regmask[Op_VecS] = &spillVectS->out_RegMask(); } if (Matcher::vector_size_supported(T_FLOAT,2)) { - MachNode *spillVectD = match_tree(new (C) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTD)); + MachNode *spillVectD = match_tree(new LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTD)); idealreg2regmask[Op_VecD] = &spillVectD->out_RegMask(); } if (Matcher::vector_size_supported(T_FLOAT,4)) { - MachNode *spillVectX = match_tree(new (C) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTX)); + MachNode *spillVectX = match_tree(new LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTX)); idealreg2regmask[Op_VecX] = &spillVectX->out_RegMask(); } if (Matcher::vector_size_supported(T_FLOAT,8)) { - MachNode *spillVectY = match_tree(new (C) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTY)); + MachNode *spillVectY = match_tree(new LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTY)); idealreg2regmask[Op_VecY] = &spillVectY->out_RegMask(); } } @@ -1319,7 +1319,7 @@ // is excluded on the max-per-method basis, debug info cannot land in // this killed area. uint r_cnt = mcall->tf()->range()->cnt(); - MachProjNode *proj = new (C) MachProjNode( mcall, r_cnt+10000, RegMask::Empty, MachProjNode::fat_proj ); + MachProjNode *proj = new MachProjNode( mcall, r_cnt+10000, RegMask::Empty, MachProjNode::fat_proj ); if (!RegMask::can_represent_arg(OptoReg::Name(out_arg_limit_per_call-1))) { C->record_method_not_compilable_all_tiers("unsupported outgoing calling sequence"); } else { @@ -2274,7 +2274,7 @@ case Op_CompareAndSwapN: { // Convert trinary to binary-tree Node *newval = n->in(MemNode::ValueIn ); Node *oldval = n->in(LoadStoreConditionalNode::ExpectedIn); - Node *pair = new (C) BinaryNode( oldval, newval ); + Node *pair = new BinaryNode( oldval, newval ); n->set_req(MemNode::ValueIn,pair); n->del_req(LoadStoreConditionalNode::ExpectedIn); break; @@ -2289,22 +2289,22 @@ // we could move this code up next to the graph reshaping for IfNodes // or vice-versa, but I do not want to debug this for Ladybird. // 10/2/2000 CNC. - Node *pair1 = new (C) BinaryNode(n->in(1),n->in(1)->in(1)); + Node *pair1 = new BinaryNode(n->in(1),n->in(1)->in(1)); n->set_req(1,pair1); - Node *pair2 = new (C) BinaryNode(n->in(2),n->in(3)); + Node *pair2 = new BinaryNode(n->in(2),n->in(3)); n->set_req(2,pair2); n->del_req(3); break; } case Op_LoopLimit: { - Node *pair1 = new (C) BinaryNode(n->in(1),n->in(2)); + Node *pair1 = new BinaryNode(n->in(1),n->in(2)); n->set_req(1,pair1); n->set_req(2,n->in(3)); n->del_req(3); break; } case Op_StrEquals: { - Node *pair1 = new (C) BinaryNode(n->in(2),n->in(3)); + Node *pair1 = new BinaryNode(n->in(2),n->in(3)); n->set_req(2,pair1); n->set_req(3,n->in(4)); n->del_req(4); @@ -2312,9 +2312,9 @@ } case Op_StrComp: case Op_StrIndexOf: { - Node *pair1 = new (C) BinaryNode(n->in(2),n->in(3)); + Node *pair1 = new BinaryNode(n->in(2),n->in(3)); n->set_req(2,pair1); - Node *pair2 = new (C) BinaryNode(n->in(4),n->in(5)); + Node *pair2 = new BinaryNode(n->in(4),n->in(5)); n->set_req(3,pair2); n->del_req(5); n->del_req(4); @@ -2322,7 +2322,7 @@ } case Op_EncodeISOArray: { // Restructure into a binary tree for Matching. - Node* pair = new (C) BinaryNode(n->in(3), n->in(4)); + Node* pair = new BinaryNode(n->in(3), n->in(4)); n->set_req(3, pair); n->del_req(4); break; diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/memnode.cpp --- a/hotspot/src/share/vm/opto/memnode.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/memnode.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -908,25 +908,25 @@ rt->isa_oopptr() || is_immutable_value(adr), "raw memory operations should have control edge"); switch (bt) { - case T_BOOLEAN: return new (C) LoadUBNode(ctl, mem, adr, adr_type, rt->is_int(), mo); - case T_BYTE: return new (C) LoadBNode (ctl, mem, adr, adr_type, rt->is_int(), mo); - case T_INT: return new (C) LoadINode (ctl, mem, adr, adr_type, rt->is_int(), mo); - case T_CHAR: return new (C) LoadUSNode(ctl, mem, adr, adr_type, rt->is_int(), mo); - case T_SHORT: return new (C) LoadSNode (ctl, mem, adr, adr_type, rt->is_int(), mo); - case T_LONG: return new (C) LoadLNode (ctl, mem, adr, adr_type, rt->is_long(), mo); - case T_FLOAT: return new (C) LoadFNode (ctl, mem, adr, adr_type, rt, mo); - case T_DOUBLE: return new (C) LoadDNode (ctl, mem, adr, adr_type, rt, mo); - case T_ADDRESS: return new (C) LoadPNode (ctl, mem, adr, adr_type, rt->is_ptr(), mo); + case T_BOOLEAN: return new LoadUBNode(ctl, mem, adr, adr_type, rt->is_int(), mo); + case T_BYTE: return new LoadBNode (ctl, mem, adr, adr_type, rt->is_int(), mo); + case T_INT: return new LoadINode (ctl, mem, adr, adr_type, rt->is_int(), mo); + case T_CHAR: return new LoadUSNode(ctl, mem, adr, adr_type, rt->is_int(), mo); + case T_SHORT: return new LoadSNode (ctl, mem, adr, adr_type, rt->is_int(), mo); + case T_LONG: return new LoadLNode (ctl, mem, adr, adr_type, rt->is_long(), mo); + case T_FLOAT: return new LoadFNode (ctl, mem, adr, adr_type, rt, mo); + case T_DOUBLE: return new LoadDNode (ctl, mem, adr, adr_type, rt, mo); + case T_ADDRESS: return new LoadPNode (ctl, mem, adr, adr_type, rt->is_ptr(), mo); case T_OBJECT: #ifdef _LP64 if (adr->bottom_type()->is_ptr_to_narrowoop()) { - Node* load = gvn.transform(new (C) LoadNNode(ctl, mem, adr, adr_type, rt->make_narrowoop(), mo)); - return new (C) DecodeNNode(load, load->bottom_type()->make_ptr()); + Node* load = gvn.transform(new LoadNNode(ctl, mem, adr, adr_type, rt->make_narrowoop(), mo)); + return new DecodeNNode(load, load->bottom_type()->make_ptr()); } else #endif { assert(!adr->bottom_type()->is_ptr_to_narrowoop() && !adr->bottom_type()->is_ptr_to_narrowklass(), "should have got back a narrow oop"); - return new (C) LoadPNode(ctl, mem, adr, adr_type, rt->is_oopptr(), mo); + return new LoadPNode(ctl, mem, adr, adr_type, rt->is_oopptr(), mo); } } ShouldNotReachHere(); @@ -935,12 +935,12 @@ LoadLNode* LoadLNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt, MemOrd mo) { bool require_atomic = true; - return new (C) LoadLNode(ctl, mem, adr, adr_type, rt->is_long(), mo, require_atomic); + return new LoadLNode(ctl, mem, adr, adr_type, rt->is_long(), mo, require_atomic); } LoadDNode* LoadDNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt, MemOrd mo) { bool require_atomic = true; - return new (C) LoadDNode(ctl, mem, adr, adr_type, rt, mo, require_atomic); + return new LoadDNode(ctl, mem, adr, adr_type, rt, mo, require_atomic); } @@ -1228,33 +1228,33 @@ // Add up all the offsets making of the address of the load Node* result = elements[0]; for (int i = 1; i < count; i++) { - result = phase->transform(new (phase->C) AddXNode(result, elements[i])); + result = phase->transform(new AddXNode(result, elements[i])); } // Remove the constant offset from the address and then - result = phase->transform(new (phase->C) AddXNode(result, phase->MakeConX(-(int)offset))); + result = phase->transform(new AddXNode(result, phase->MakeConX(-(int)offset))); // remove the scaling of the offset to recover the original index. if (result->Opcode() == Op_LShiftX && result->in(2) == phase->intcon(shift)) { // Peel the shift off directly but wrap it in a dummy node // since Ideal can't return existing nodes - result = new (phase->C) RShiftXNode(result->in(1), phase->intcon(0)); + result = new RShiftXNode(result->in(1), phase->intcon(0)); } else if (result->is_Add() && result->in(2)->is_Con() && result->in(1)->Opcode() == Op_LShiftX && result->in(1)->in(2) == phase->intcon(shift)) { // We can't do general optimization: ((X<> Z ==> X + (Y>>Z) // but for boxing cache access we know that X<C) RShiftXNode(result->in(2), phase->intcon(shift)); - result = new (phase->C) AddXNode(result->in(1)->in(1), phase->transform(add_con)); + Node* add_con = new RShiftXNode(result->in(2), phase->intcon(shift)); + result = new AddXNode(result->in(1)->in(1), phase->transform(add_con)); } else { - result = new (phase->C) RShiftXNode(result, phase->intcon(shift)); + result = new RShiftXNode(result, phase->intcon(shift)); } #ifdef _LP64 if (bt != T_LONG) { - result = new (phase->C) ConvL2INode(phase->transform(result)); + result = new ConvL2INode(phase->transform(result)); } #else if (bt == T_LONG) { - result = new (phase->C) ConvI2LNode(phase->transform(result)); + result = new ConvI2LNode(phase->transform(result)); } #endif return result; @@ -1385,7 +1385,7 @@ this_iid = base->_idx; } PhaseIterGVN* igvn = phase->is_IterGVN(); - Node* phi = new (C) PhiNode(region, this_type, NULL, this_iid, this_index, this_offset); + Node* phi = new PhiNode(region, this_type, NULL, this_iid, this_index, this_offset); for (uint i = 1; i < region->req(); i++) { Node* x; Node* the_clone = NULL; @@ -1408,7 +1408,7 @@ } if (base_is_phi && (base->in(0) == region)) { Node* base_x = base->in(i); // Clone address for loads from boxed objects. - Node* adr_x = phase->transform(new (C) AddPNode(base_x,base_x,address->in(AddPNode::Offset))); + Node* adr_x = phase->transform(new AddPNode(base_x,base_x,address->in(AddPNode::Offset))); x->set_req(Address, adr_x); } } @@ -1897,8 +1897,8 @@ Node* mem = in(MemNode::Memory); Node* value = can_see_stored_value(mem,phase); if( value && !phase->type(value)->higher_equal( _type ) ) { - Node *result = phase->transform( new (phase->C) LShiftINode(value, phase->intcon(24)) ); - return new (phase->C) RShiftINode(result, phase->intcon(24)); + Node *result = phase->transform( new LShiftINode(value, phase->intcon(24)) ); + return new RShiftINode(result, phase->intcon(24)); } // Identity call will handle the case where truncation is not needed. return LoadNode::Ideal(phase, can_reshape); @@ -1929,7 +1929,7 @@ Node* mem = in(MemNode::Memory); Node* value = can_see_stored_value(mem, phase); if (value && !phase->type(value)->higher_equal(_type)) - return new (phase->C) AndINode(value, phase->intcon(0xFF)); + return new AndINode(value, phase->intcon(0xFF)); // Identity call will handle the case where truncation is not needed. return LoadNode::Ideal(phase, can_reshape); } @@ -1959,7 +1959,7 @@ Node* mem = in(MemNode::Memory); Node* value = can_see_stored_value(mem,phase); if( value && !phase->type(value)->higher_equal( _type ) ) - return new (phase->C) AndINode(value,phase->intcon(0xFFFF)); + return new AndINode(value,phase->intcon(0xFFFF)); // Identity call will handle the case where truncation is not needed. return LoadNode::Ideal(phase, can_reshape); } @@ -1989,8 +1989,8 @@ Node* mem = in(MemNode::Memory); Node* value = can_see_stored_value(mem,phase); if( value && !phase->type(value)->higher_equal( _type ) ) { - Node *result = phase->transform( new (phase->C) LShiftINode(value, phase->intcon(16)) ); - return new (phase->C) RShiftINode(result, phase->intcon(16)); + Node *result = phase->transform( new LShiftINode(value, phase->intcon(16)) ); + return new RShiftINode(result, phase->intcon(16)); } // Identity call will handle the case where truncation is not needed. return LoadNode::Ideal(phase, can_reshape); @@ -2022,12 +2022,12 @@ #ifdef _LP64 if (adr_type->is_ptr_to_narrowklass()) { assert(UseCompressedClassPointers, "no compressed klasses"); - Node* load_klass = gvn.transform(new (C) LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowklass(), MemNode::unordered)); - return new (C) DecodeNKlassNode(load_klass, load_klass->bottom_type()->make_ptr()); + Node* load_klass = gvn.transform(new LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowklass(), MemNode::unordered)); + return new DecodeNKlassNode(load_klass, load_klass->bottom_type()->make_ptr()); } #endif assert(!adr_type->is_ptr_to_narrowklass() && !adr_type->is_ptr_to_narrowoop(), "should have got back a narrow oop"); - return new (C) LoadKlassNode(ctl, mem, adr, at, tk, MemNode::unordered); + return new LoadKlassNode(ctl, mem, adr, at, tk, MemNode::unordered); } //------------------------------Value------------------------------------------ @@ -2255,7 +2255,7 @@ if( t->isa_narrowklass()) return x; assert (!t->isa_narrowoop(), "no narrow oop here"); - return phase->transform(new (phase->C) EncodePKlassNode(x, t->make_narrowklass())); + return phase->transform(new EncodePKlassNode(x, t->make_narrowklass())); } //------------------------------Value----------------------------------------- @@ -2350,29 +2350,29 @@ switch (bt) { case T_BOOLEAN: - case T_BYTE: return new (C) StoreBNode(ctl, mem, adr, adr_type, val, mo); - case T_INT: return new (C) StoreINode(ctl, mem, adr, adr_type, val, mo); + case T_BYTE: return new StoreBNode(ctl, mem, adr, adr_type, val, mo); + case T_INT: return new StoreINode(ctl, mem, adr, adr_type, val, mo); case T_CHAR: - case T_SHORT: return new (C) StoreCNode(ctl, mem, adr, adr_type, val, mo); - case T_LONG: return new (C) StoreLNode(ctl, mem, adr, adr_type, val, mo); - case T_FLOAT: return new (C) StoreFNode(ctl, mem, adr, adr_type, val, mo); - case T_DOUBLE: return new (C) StoreDNode(ctl, mem, adr, adr_type, val, mo); + case T_SHORT: return new StoreCNode(ctl, mem, adr, adr_type, val, mo); + case T_LONG: return new StoreLNode(ctl, mem, adr, adr_type, val, mo); + case T_FLOAT: return new StoreFNode(ctl, mem, adr, adr_type, val, mo); + case T_DOUBLE: return new StoreDNode(ctl, mem, adr, adr_type, val, mo); case T_METADATA: case T_ADDRESS: case T_OBJECT: #ifdef _LP64 if (adr->bottom_type()->is_ptr_to_narrowoop()) { - val = gvn.transform(new (C) EncodePNode(val, val->bottom_type()->make_narrowoop())); - return new (C) StoreNNode(ctl, mem, adr, adr_type, val, mo); + val = gvn.transform(new EncodePNode(val, val->bottom_type()->make_narrowoop())); + return new StoreNNode(ctl, mem, adr, adr_type, val, mo); } else if (adr->bottom_type()->is_ptr_to_narrowklass() || (UseCompressedClassPointers && val->bottom_type()->isa_klassptr() && adr->bottom_type()->isa_rawptr())) { - val = gvn.transform(new (C) EncodePKlassNode(val, val->bottom_type()->make_narrowklass())); - return new (C) StoreNKlassNode(ctl, mem, adr, adr_type, val, mo); + val = gvn.transform(new EncodePKlassNode(val, val->bottom_type()->make_narrowklass())); + return new StoreNKlassNode(ctl, mem, adr, adr_type, val, mo); } #endif { - return new (C) StorePNode(ctl, mem, adr, adr_type, val, mo); + return new StorePNode(ctl, mem, adr, adr_type, val, mo); } } ShouldNotReachHere(); @@ -2381,12 +2381,12 @@ StoreLNode* StoreLNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, MemOrd mo) { bool require_atomic = true; - return new (C) StoreLNode(ctl, mem, adr, adr_type, val, mo, require_atomic); + return new StoreLNode(ctl, mem, adr, adr_type, val, mo, require_atomic); } StoreDNode* StoreDNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, MemOrd mo) { bool require_atomic = true; - return new (C) StoreDNode(ctl, mem, adr, adr_type, val, mo, require_atomic); + return new StoreDNode(ctl, mem, adr, adr_type, val, mo, require_atomic); } @@ -2779,12 +2779,12 @@ Node *zero = phase->makecon(TypeLong::ZERO); Node *off = phase->MakeConX(BytesPerLong); - mem = new (phase->C) StoreLNode(in(0),mem,adr,atp,zero,MemNode::unordered,false); + mem = new StoreLNode(in(0),mem,adr,atp,zero,MemNode::unordered,false); count--; while( count-- ) { mem = phase->transform(mem); - adr = phase->transform(new (phase->C) AddPNode(base,adr,off)); - mem = new (phase->C) StoreLNode(in(0),mem,adr,atp,zero,MemNode::unordered,false); + adr = phase->transform(new AddPNode(base,adr,off)); + mem = new StoreLNode(in(0),mem,adr,atp,zero,MemNode::unordered,false); } return mem; } @@ -2825,7 +2825,7 @@ int unit = BytesPerLong; if ((offset % unit) != 0) { - Node* adr = new (C) AddPNode(dest, dest, phase->MakeConX(offset)); + Node* adr = new AddPNode(dest, dest, phase->MakeConX(offset)); adr = phase->transform(adr); const TypePtr* atp = TypeRawPtr::BOTTOM; mem = StoreNode::make(*phase, ctl, mem, adr, atp, phase->zerocon(T_INT), T_INT, MemNode::unordered); @@ -2855,14 +2855,14 @@ // Scale to the unit required by the CPU: if (!Matcher::init_array_count_is_in_bytes) { Node* shift = phase->intcon(exact_log2(unit)); - zbase = phase->transform( new(C) URShiftXNode(zbase, shift) ); - zend = phase->transform( new(C) URShiftXNode(zend, shift) ); + zbase = phase->transform(new URShiftXNode(zbase, shift) ); + zend = phase->transform(new URShiftXNode(zend, shift) ); } // Bulk clear double-words - Node* zsize = phase->transform( new(C) SubXNode(zend, zbase) ); - Node* adr = phase->transform( new(C) AddPNode(dest, dest, start_offset) ); - mem = new (C) ClearArrayNode(ctl, mem, zsize, adr); + Node* zsize = phase->transform(new SubXNode(zend, zbase) ); + Node* adr = phase->transform(new AddPNode(dest, dest, start_offset) ); + mem = new ClearArrayNode(ctl, mem, zsize, adr); return phase->transform(mem); } @@ -2886,7 +2886,7 @@ start_offset, phase->MakeConX(done_offset), phase); } if (done_offset < end_offset) { // emit the final 32-bit store - Node* adr = new (C) AddPNode(dest, dest, phase->MakeConX(done_offset)); + Node* adr = new AddPNode(dest, dest, phase->MakeConX(done_offset)); adr = phase->transform(adr); const TypePtr* atp = TypeRawPtr::BOTTOM; mem = StoreNode::make(*phase, ctl, mem, adr, atp, phase->zerocon(T_INT), T_INT, MemNode::unordered); @@ -2920,16 +2920,16 @@ //------------------------------make------------------------------------------- MemBarNode* MemBarNode::make(Compile* C, int opcode, int atp, Node* pn) { switch (opcode) { - case Op_MemBarAcquire: return new(C) MemBarAcquireNode(C, atp, pn); - case Op_LoadFence: return new(C) LoadFenceNode(C, atp, pn); - case Op_MemBarRelease: return new(C) MemBarReleaseNode(C, atp, pn); - case Op_StoreFence: return new(C) StoreFenceNode(C, atp, pn); - case Op_MemBarAcquireLock: return new(C) MemBarAcquireLockNode(C, atp, pn); - case Op_MemBarReleaseLock: return new(C) MemBarReleaseLockNode(C, atp, pn); - case Op_MemBarVolatile: return new(C) MemBarVolatileNode(C, atp, pn); - case Op_MemBarCPUOrder: return new(C) MemBarCPUOrderNode(C, atp, pn); - case Op_Initialize: return new(C) InitializeNode(C, atp, pn); - case Op_MemBarStoreStore: return new(C) MemBarStoreStoreNode(C, atp, pn); + case Op_MemBarAcquire: return new MemBarAcquireNode(C, atp, pn); + case Op_LoadFence: return new LoadFenceNode(C, atp, pn); + case Op_MemBarRelease: return new MemBarReleaseNode(C, atp, pn); + case Op_StoreFence: return new StoreFenceNode(C, atp, pn); + case Op_MemBarAcquireLock: return new MemBarAcquireLockNode(C, atp, pn); + case Op_MemBarReleaseLock: return new MemBarReleaseLockNode(C, atp, pn); + case Op_MemBarVolatile: return new MemBarVolatileNode(C, atp, pn); + case Op_MemBarCPUOrder: return new MemBarCPUOrderNode(C, atp, pn); + case Op_Initialize: return new InitializeNode(C, atp, pn); + case Op_MemBarStoreStore: return new MemBarStoreStoreNode(C, atp, pn); default: ShouldNotReachHere(); return NULL; } } @@ -2992,7 +2992,7 @@ igvn->replace_node(proj_out(TypeFunc::Control), in(TypeFunc::Control)); // Must return either the original node (now dead) or a new node // (Do not return a top here, since that would break the uniqueness of top.) - return new (phase->C) ConINode(TypeInt::ZERO); + return new ConINode(TypeInt::ZERO); } } return NULL; @@ -3012,7 +3012,7 @@ switch (proj->_con) { case TypeFunc::Control: case TypeFunc::Memory: - return new (m->C) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj); + return new MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj); } ShouldNotReachHere(); return NULL; @@ -3438,7 +3438,7 @@ Node* addr = in(RawAddress); if (offset != 0) { Compile* C = phase->C; - addr = phase->transform( new (C) AddPNode(C->top(), addr, + addr = phase->transform( new AddPNode(C->top(), addr, phase->MakeConX(offset)) ); } return addr; @@ -4127,7 +4127,7 @@ // Make a new, untransformed MergeMem with the same base as 'mem'. // If mem is itself a MergeMem, populate the result with the same edges. MergeMemNode* MergeMemNode::make(Compile* C, Node* mem) { - return new(C) MergeMemNode(mem); + return new MergeMemNode(mem); } //------------------------------cmp-------------------------------------------- diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/movenode.cpp --- a/hotspot/src/share/vm/opto/movenode.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/movenode.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -160,13 +160,13 @@ // from the inputs we do not need to specify it here. CMoveNode *CMoveNode::make( Compile *C, Node *c, Node *bol, Node *left, Node *right, const Type *t ) { switch( t->basic_type() ) { - case T_INT: return new (C) CMoveINode( bol, left, right, t->is_int() ); - case T_FLOAT: return new (C) CMoveFNode( bol, left, right, t ); - case T_DOUBLE: return new (C) CMoveDNode( bol, left, right, t ); - case T_LONG: return new (C) CMoveLNode( bol, left, right, t->is_long() ); - case T_OBJECT: return new (C) CMovePNode( c, bol, left, right, t->is_oopptr() ); - case T_ADDRESS: return new (C) CMovePNode( c, bol, left, right, t->is_ptr() ); - case T_NARROWOOP: return new (C) CMoveNNode( c, bol, left, right, t ); + case T_INT: return new CMoveINode( bol, left, right, t->is_int() ); + case T_FLOAT: return new CMoveFNode( bol, left, right, t ); + case T_DOUBLE: return new CMoveDNode( bol, left, right, t ); + case T_LONG: return new CMoveLNode( bol, left, right, t->is_long() ); + case T_OBJECT: return new CMovePNode( c, bol, left, right, t->is_oopptr() ); + case T_ADDRESS: return new CMovePNode( c, bol, left, right, t->is_ptr() ); + case T_NARROWOOP: return new CMoveNNode( c, bol, left, right, t ); default: ShouldNotReachHere(); return NULL; @@ -233,9 +233,9 @@ #ifndef PRODUCT if( PrintOpto ) tty->print_cr("CMOV to I2B"); #endif - Node *n = new (phase->C) Conv2BNode( cmp->in(1) ); + Node *n = new Conv2BNode( cmp->in(1) ); if( flip ) - n = new (phase->C) XorINode( phase->transform(n), phase->intcon(1) ); + n = new XorINode( phase->transform(n), phase->intcon(1) ); return n; } @@ -289,9 +289,9 @@ sub->in(2) != X || phase->type(sub->in(1)) != TypeF::ZERO ) return NULL; - Node *abs = new (phase->C) AbsFNode( X ); + Node *abs = new AbsFNode( X ); if( flip ) - abs = new (phase->C) SubFNode(sub->in(1), phase->transform(abs)); + abs = new SubFNode(sub->in(1), phase->transform(abs)); return abs; } @@ -345,9 +345,9 @@ sub->in(2) != X || phase->type(sub->in(1)) != TypeD::ZERO ) return NULL; - Node *abs = new (phase->C) AbsDNode( X ); + Node *abs = new AbsDNode( X ); if( flip ) - abs = new (phase->C) SubDNode(sub->in(1), phase->transform(abs)); + abs = new SubDNode(sub->in(1), phase->transform(abs)); return abs; } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/mulnode.cpp --- a/hotspot/src/share/vm/opto/mulnode.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/mulnode.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -199,22 +199,22 @@ Node *res = NULL; jint bit1 = con & -con; // Extract low bit if( bit1 == con ) { // Found a power of 2? - res = new (phase->C) LShiftINode( in(1), phase->intcon(log2_intptr(bit1)) ); + res = new LShiftINode( in(1), phase->intcon(log2_intptr(bit1)) ); } else { // Check for constant with 2 bits set jint bit2 = con-bit1; bit2 = bit2 & -bit2; // Extract 2nd bit if( bit2 + bit1 == con ) { // Found all bits in con? - Node *n1 = phase->transform( new (phase->C) LShiftINode( in(1), phase->intcon(log2_intptr(bit1)) ) ); - Node *n2 = phase->transform( new (phase->C) LShiftINode( in(1), phase->intcon(log2_intptr(bit2)) ) ); - res = new (phase->C) AddINode( n2, n1 ); + Node *n1 = phase->transform( new LShiftINode( in(1), phase->intcon(log2_intptr(bit1)) ) ); + Node *n2 = phase->transform( new LShiftINode( in(1), phase->intcon(log2_intptr(bit2)) ) ); + res = new AddINode( n2, n1 ); } else if (is_power_of_2(con+1)) { // Sleezy: power-of-2 -1. Next time be generic. jint temp = (jint) (con + 1); - Node *n1 = phase->transform( new (phase->C) LShiftINode( in(1), phase->intcon(log2_intptr(temp)) ) ); - res = new (phase->C) SubINode( n1, in(1) ); + Node *n1 = phase->transform( new LShiftINode( in(1), phase->intcon(log2_intptr(temp)) ) ); + res = new SubINode( n1, in(1) ); } else { return MulNode::Ideal(phase, can_reshape); } @@ -222,7 +222,7 @@ if( sign_flip ) { // Need to negate result? res = phase->transform(res);// Transform, before making the zero con - res = new (phase->C) SubINode(phase->intcon(0),res); + res = new SubINode(phase->intcon(0),res); } return res; // Return final result @@ -295,22 +295,22 @@ Node *res = NULL; jlong bit1 = con & -con; // Extract low bit if( bit1 == con ) { // Found a power of 2? - res = new (phase->C) LShiftLNode( in(1), phase->intcon(log2_long(bit1)) ); + res = new LShiftLNode( in(1), phase->intcon(log2_long(bit1)) ); } else { // Check for constant with 2 bits set jlong bit2 = con-bit1; bit2 = bit2 & -bit2; // Extract 2nd bit if( bit2 + bit1 == con ) { // Found all bits in con? - Node *n1 = phase->transform( new (phase->C) LShiftLNode( in(1), phase->intcon(log2_long(bit1)) ) ); - Node *n2 = phase->transform( new (phase->C) LShiftLNode( in(1), phase->intcon(log2_long(bit2)) ) ); - res = new (phase->C) AddLNode( n2, n1 ); + Node *n1 = phase->transform( new LShiftLNode( in(1), phase->intcon(log2_long(bit1)) ) ); + Node *n2 = phase->transform( new LShiftLNode( in(1), phase->intcon(log2_long(bit2)) ) ); + res = new AddLNode( n2, n1 ); } else if (is_power_of_2_long(con+1)) { // Sleezy: power-of-2 -1. Next time be generic. jlong temp = (jlong) (con + 1); - Node *n1 = phase->transform( new (phase->C) LShiftLNode( in(1), phase->intcon(log2_long(temp)) ) ); - res = new (phase->C) SubLNode( n1, in(1) ); + Node *n1 = phase->transform( new LShiftLNode( in(1), phase->intcon(log2_long(temp)) ) ); + res = new SubLNode( n1, in(1) ); } else { return MulNode::Ideal(phase, can_reshape); } @@ -318,7 +318,7 @@ if( sign_flip ) { // Need to negate result? res = phase->transform(res);// Transform, before making the zero con - res = new (phase->C) SubLNode(phase->longcon(0),res); + res = new SubLNode(phase->longcon(0),res); } return res; // Return final result @@ -477,31 +477,31 @@ // Masking bits off of a Character? Hi bits are already zero. if( lop == Op_LoadUS && (mask & 0xFFFF0000) ) // Can we make a smaller mask? - return new (phase->C) AndINode(load,phase->intcon(mask&0xFFFF)); + return new AndINode(load,phase->intcon(mask&0xFFFF)); // Masking bits off of a Short? Loading a Character does some masking if (can_reshape && load->outcnt() == 1 && load->unique_out() == this) { if (lop == Op_LoadS && (mask & 0xFFFF0000) == 0 ) { - Node *ldus = new (phase->C) LoadUSNode(load->in(MemNode::Control), - load->in(MemNode::Memory), - load->in(MemNode::Address), - load->adr_type(), - TypeInt::CHAR, MemNode::unordered); + Node *ldus = new LoadUSNode(load->in(MemNode::Control), + load->in(MemNode::Memory), + load->in(MemNode::Address), + load->adr_type(), + TypeInt::CHAR, MemNode::unordered); ldus = phase->transform(ldus); - return new (phase->C) AndINode(ldus, phase->intcon(mask & 0xFFFF)); + return new AndINode(ldus, phase->intcon(mask & 0xFFFF)); } // Masking sign bits off of a Byte? Do an unsigned byte load plus // an and. if (lop == Op_LoadB && (mask & 0xFFFFFF00) == 0) { - Node* ldub = new (phase->C) LoadUBNode(load->in(MemNode::Control), - load->in(MemNode::Memory), - load->in(MemNode::Address), - load->adr_type(), - TypeInt::UBYTE, MemNode::unordered); + Node* ldub = new LoadUBNode(load->in(MemNode::Control), + load->in(MemNode::Memory), + load->in(MemNode::Address), + load->adr_type(), + TypeInt::UBYTE, MemNode::unordered); ldub = phase->transform(ldub); - return new (phase->C) AndINode(ldub, phase->intcon(mask)); + return new AndINode(ldub, phase->intcon(mask)); } } @@ -516,8 +516,8 @@ // bits survive. NO sign-extension bits survive the maskings. if( (sign_bits_mask & mask) == 0 ) { // Use zero-fill shift instead - Node *zshift = phase->transform(new (phase->C) URShiftINode(load->in(1),load->in(2))); - return new (phase->C) AndINode( zshift, in(2) ); + Node *zshift = phase->transform(new URShiftINode(load->in(1),load->in(2))); + return new AndINode( zshift, in(2) ); } } } @@ -527,7 +527,7 @@ // plus 1) and the mask is of the low order bit. Skip the negate. if( lop == Op_SubI && mask == 1 && load->in(1) && phase->type(load->in(1)) == TypeInt::ZERO ) - return new (phase->C) AndINode( load->in(2), in(2) ); + return new AndINode( load->in(2), in(2) ); return MulNode::Ideal(phase, can_reshape); } @@ -611,9 +611,9 @@ // value. This check includes UI2L masks (0x00000000FFFFFFFF) which // would be optimized away later in Identity. if (op == Op_ConvI2L && (mask & CONST64(0xFFFFFFFF80000000)) == 0) { - Node* andi = new (phase->C) AndINode(in1->in(1), phase->intcon(mask)); + Node* andi = new AndINode(in1->in(1), phase->intcon(mask)); andi = phase->transform(andi); - return new (phase->C) ConvI2LNode(andi); + return new ConvI2LNode(andi); } // Masking off sign bits? Dont make them! @@ -627,8 +627,8 @@ // bits survive. NO sign-extension bits survive the maskings. if( (sign_bits_mask & mask) == 0 ) { // Use zero-fill shift instead - Node *zshift = phase->transform(new (phase->C) URShiftLNode(in1->in(1), in1->in(2))); - return new (phase->C) AndLNode(zshift, in(2)); + Node *zshift = phase->transform(new URShiftLNode(in1->in(1), in1->in(2))); + return new AndLNode(zshift, in(2)); } } } @@ -666,9 +666,9 @@ // and 'i2b' patterns which typically fold into 'StoreC/StoreB'. if( con < 16 ) { // Compute X << con0 - Node *lsh = phase->transform( new (phase->C) LShiftINode( add1->in(1), in(2) ) ); + Node *lsh = phase->transform( new LShiftINode( add1->in(1), in(2) ) ); // Compute X<C) AddINode( lsh, phase->intcon(t12->get_con() << con)); + return new AddINode( lsh, phase->intcon(t12->get_con() << con)); } } } @@ -677,7 +677,7 @@ if( (add1_op == Op_RShiftI || add1_op == Op_URShiftI ) && add1->in(2) == in(2) ) // Convert to "(x & -(1<C) AndINode(add1->in(1),phase->intcon( -(1<in(1),phase->intcon( -(1<>c0) & Y)<in(2) == in(2) ) { // Convert to "(x & (Y<transform( new (phase->C) LShiftINode( add1->in(2), in(2) ) ); - return new (phase->C) AndINode( add2->in(1), y_sh ); + Node *y_sh = phase->transform( new LShiftINode( add1->in(2), in(2) ) ); + return new AndINode( add2->in(1), y_sh ); } } @@ -696,7 +696,7 @@ const jint bits_mask = right_n_bits(BitsPerJavaInteger-con); if( add1_op == Op_AndI && phase->type(add1->in(2)) == TypeInt::make( bits_mask ) ) - return new (phase->C) LShiftINode( add1->in(1), in(2) ); + return new LShiftINode( add1->in(1), in(2) ); return NULL; } @@ -776,9 +776,9 @@ const TypeLong *t12 = phase->type(add1->in(2))->isa_long(); if( t12 && t12->is_con() ){ // Left input is an add of a con? // Compute X << con0 - Node *lsh = phase->transform( new (phase->C) LShiftLNode( add1->in(1), in(2) ) ); + Node *lsh = phase->transform( new LShiftLNode( add1->in(1), in(2) ) ); // Compute X<C) AddLNode( lsh, phase->longcon(t12->get_con() << con)); + return new AddLNode( lsh, phase->longcon(t12->get_con() << con)); } } @@ -786,7 +786,7 @@ if( (add1_op == Op_RShiftL || add1_op == Op_URShiftL ) && add1->in(2) == in(2) ) // Convert to "(x & -(1<C) AndLNode(add1->in(1),phase->longcon( -(CONST64(1)<in(1),phase->longcon( -(CONST64(1)<>c0) & Y)<in(2) == in(2) ) { // Convert to "(x & (Y<transform( new (phase->C) LShiftLNode( add1->in(2), in(2) ) ); - return new (phase->C) AndLNode( add2->in(1), y_sh ); + Node *y_sh = phase->transform( new LShiftLNode( add1->in(2), in(2) ) ); + return new AndLNode( add2->in(1), y_sh ); } } @@ -805,7 +805,7 @@ const jlong bits_mask = ((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - con)) - CONST64(1); if( add1_op == Op_AndL && phase->type(add1->in(2)) == TypeLong::make( bits_mask ) ) - return new (phase->C) LShiftLNode( add1->in(1), in(2) ); + return new LShiftLNode( add1->in(1), in(2) ); return NULL; } @@ -907,8 +907,8 @@ Node *x = mask->in(1); jint maskbits = t3->get_con(); // Convert to "(x >> shift) & (mask >> shift)" - Node *shr_nomask = phase->transform( new (phase->C) RShiftINode(mask->in(1), in(2)) ); - return new (phase->C) AndINode(shr_nomask, phase->intcon( maskbits >> shift)); + Node *shr_nomask = phase->transform( new RShiftINode(mask->in(1), in(2)) ); + return new AndINode(shr_nomask, phase->intcon( maskbits >> shift)); } // Check for "(short[i] <<16)>>16" which simply sign-extends @@ -933,11 +933,11 @@ ld->Opcode() == Op_LoadUS && ld->outcnt() == 1 && ld->unique_out() == shl) // Replace zero-extension-load with sign-extension-load - return new (phase->C) LoadSNode( ld->in(MemNode::Control), - ld->in(MemNode::Memory), - ld->in(MemNode::Address), - ld->adr_type(), TypeInt::SHORT, - MemNode::unordered); + return new LoadSNode( ld->in(MemNode::Control), + ld->in(MemNode::Memory), + ld->in(MemNode::Address), + ld->adr_type(), TypeInt::SHORT, + MemNode::unordered); } // Check for "(byte[i] <<24)>>24" which simply sign-extends @@ -1119,7 +1119,7 @@ const int con2 = t12->get_con() & 31; // Shift count is always masked const int con3 = con+con2; if( con3 < 32 ) // Only merge shifts if total is < 32 - return new (phase->C) URShiftINode( in(1)->in(1), phase->intcon(con3) ); + return new URShiftINode( in(1)->in(1), phase->intcon(con3) ); } } @@ -1132,9 +1132,9 @@ Node *lshl = add->in(1); if( lshl->Opcode() == Op_LShiftI && phase->type(lshl->in(2)) == t2 ) { - Node *y_z = phase->transform( new (phase->C) URShiftINode(add->in(2),in(2)) ); - Node *sum = phase->transform( new (phase->C) AddINode( lshl->in(1), y_z ) ); - return new (phase->C) AndINode( sum, phase->intcon(mask) ); + Node *y_z = phase->transform( new URShiftINode(add->in(2),in(2)) ); + Node *sum = phase->transform( new AddINode( lshl->in(1), y_z ) ); + return new AndINode( sum, phase->intcon(mask) ); } } @@ -1147,8 +1147,8 @@ if( t3 && t3->is_con() ) { // Right input is a constant jint mask2 = t3->get_con(); mask2 >>= con; // *signed* shift downward (high-order zeroes do not help) - Node *newshr = phase->transform( new (phase->C) URShiftINode(andi->in(1), in(2)) ); - return new (phase->C) AndINode(newshr, phase->intcon(mask2)); + Node *newshr = phase->transform( new URShiftINode(andi->in(1), in(2)) ); + return new AndINode(newshr, phase->intcon(mask2)); // The negative values are easier to materialize than positive ones. // A typical case from address arithmetic is ((x & ~15) >> 4). // It's better to change that to ((x >> 4) & ~0) versus @@ -1160,7 +1160,7 @@ Node *shl = in(1); if( in1_op == Op_LShiftI && phase->type(shl->in(2)) == t2 ) - return new (phase->C) AndINode( shl->in(1), phase->intcon(mask) ); + return new AndINode( shl->in(1), phase->intcon(mask) ); return NULL; } @@ -1265,9 +1265,9 @@ Node *lshl = add->in(1); if( lshl->Opcode() == Op_LShiftL && phase->type(lshl->in(2)) == t2 ) { - Node *y_z = phase->transform( new (phase->C) URShiftLNode(add->in(2),in(2)) ); - Node *sum = phase->transform( new (phase->C) AddLNode( lshl->in(1), y_z ) ); - return new (phase->C) AndLNode( sum, phase->longcon(mask) ); + Node *y_z = phase->transform( new URShiftLNode(add->in(2),in(2)) ); + Node *sum = phase->transform( new AddLNode( lshl->in(1), y_z ) ); + return new AndLNode( sum, phase->longcon(mask) ); } } @@ -1280,8 +1280,8 @@ if( t3 && t3->is_con() ) { // Right input is a constant jlong mask2 = t3->get_con(); mask2 >>= con; // *signed* shift downward (high-order zeroes do not help) - Node *newshr = phase->transform( new (phase->C) URShiftLNode(andi->in(1), in(2)) ); - return new (phase->C) AndLNode(newshr, phase->longcon(mask2)); + Node *newshr = phase->transform( new URShiftLNode(andi->in(1), in(2)) ); + return new AndLNode(newshr, phase->longcon(mask2)); } } @@ -1289,7 +1289,7 @@ Node *shl = in(1); if( shl->Opcode() == Op_LShiftL && phase->type(shl->in(2)) == t2 ) - return new (phase->C) AndLNode( shl->in(1), phase->longcon(mask) ); + return new AndLNode( shl->in(1), phase->longcon(mask) ); return NULL; } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/node.cpp --- a/hotspot/src/share/vm/opto/node.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/node.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -274,23 +274,6 @@ // The value NULL is reserved for the top node only. #define NO_OUT_ARRAY ((Node**)-1) -// This funny expression handshakes with Node::operator new -// to pull Compile::current out of the new node's _out field, -// and then calls a subroutine which manages most field -// initializations. The only one which is tricky is the -// _idx field, which is const, and so must be initialized -// by a return value, not an assignment. -// -// (Aren't you thankful that Java finals don't require so many tricks?) -#define IDX_INIT(req) this->Init((req), (Compile*) this->_out) -#ifdef _MSC_VER // the IDX_INIT hack falls foul of warning C4355 -#pragma warning( disable:4355 ) // 'this' : used in base member initializer list -#endif -#ifdef __clang__ -#pragma clang diagnostic push -#pragma GCC diagnostic ignored "-Wuninitialized" -#endif - // Out-of-line code from node constructors. // Executed only when extra debug info. is being passed around. static void init_node_notes(Compile* C, int idx, Node_Notes* nn) { @@ -298,8 +281,8 @@ } // Shared initialization code. -inline int Node::Init(int req, Compile* C) { - assert(Compile::current() == C, "must use operator new(Compile*)"); +inline int Node::Init(int req) { + Compile* C = Compile::current(); int idx = C->next_unique(); // Allocate memory for the necessary number of edges. @@ -328,7 +311,7 @@ //------------------------------Node------------------------------------------- // Create a Node, with a given number of required edges. Node::Node(uint req) - : _idx(IDX_INIT(req)) + : _idx(Init(req)) { assert( req < (uint)(MaxNodeLimit - NodeLimitFudgeFactor), "Input limit exceeded" ); debug_only( verify_construction() ); @@ -347,7 +330,7 @@ //------------------------------Node------------------------------------------- Node::Node(Node *n0) - : _idx(IDX_INIT(1)) + : _idx(Init(1)) { debug_only( verify_construction() ); NOT_PRODUCT(nodes_created++); @@ -359,7 +342,7 @@ //------------------------------Node------------------------------------------- Node::Node(Node *n0, Node *n1) - : _idx(IDX_INIT(2)) + : _idx(Init(2)) { debug_only( verify_construction() ); NOT_PRODUCT(nodes_created++); @@ -373,7 +356,7 @@ //------------------------------Node------------------------------------------- Node::Node(Node *n0, Node *n1, Node *n2) - : _idx(IDX_INIT(3)) + : _idx(Init(3)) { debug_only( verify_construction() ); NOT_PRODUCT(nodes_created++); @@ -389,7 +372,7 @@ //------------------------------Node------------------------------------------- Node::Node(Node *n0, Node *n1, Node *n2, Node *n3) - : _idx(IDX_INIT(4)) + : _idx(Init(4)) { debug_only( verify_construction() ); NOT_PRODUCT(nodes_created++); @@ -407,7 +390,7 @@ //------------------------------Node------------------------------------------- Node::Node(Node *n0, Node *n1, Node *n2, Node *n3, Node *n4) - : _idx(IDX_INIT(5)) + : _idx(Init(5)) { debug_only( verify_construction() ); NOT_PRODUCT(nodes_created++); @@ -428,7 +411,7 @@ //------------------------------Node------------------------------------------- Node::Node(Node *n0, Node *n1, Node *n2, Node *n3, Node *n4, Node *n5) - : _idx(IDX_INIT(6)) + : _idx(Init(6)) { debug_only( verify_construction() ); NOT_PRODUCT(nodes_created++); @@ -451,7 +434,7 @@ //------------------------------Node------------------------------------------- Node::Node(Node *n0, Node *n1, Node *n2, Node *n3, Node *n4, Node *n5, Node *n6) - : _idx(IDX_INIT(7)) + : _idx(Init(7)) { debug_only( verify_construction() ); NOT_PRODUCT(nodes_created++); @@ -473,10 +456,6 @@ _in[6] = n6; if (n6 != NULL) n6->add_out((Node *)this); } -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - //------------------------------clone------------------------------------------ // Clone a Node. @@ -535,6 +514,9 @@ if (n->is_Call()) { n->as_Call()->clone_jvms(C); } + if (n->is_SafePoint()) { + n->as_SafePoint()->clone_replaced_nodes(); + } return n; // Return the clone } @@ -630,6 +612,9 @@ if (is_expensive()) { compile->remove_expensive_node(this); } + if (is_SafePoint()) { + as_SafePoint()->delete_replaced_nodes(); + } #ifdef ASSERT // We will not actually delete the storage, but we'll make the node unusable. *(address*)this = badAddress; // smash the C++ vtbl, probably @@ -1066,15 +1051,15 @@ // set_req(2, phase->intcon(7)); // return this; // Example: reshape "X*4" into "X<<2" -// return new (C) LShiftINode(in(1), phase->intcon(2)); +// return new LShiftINode(in(1), phase->intcon(2)); // // You must call 'phase->transform(X)' on any new Nodes X you make, except // for the returned root node. Example: reshape "X*31" with "(X<<5)-X". -// Node *shift=phase->transform(new(C)LShiftINode(in(1),phase->intcon(5))); -// return new (C) AddINode(shift, in(1)); +// Node *shift=phase->transform(new LShiftINode(in(1),phase->intcon(5))); +// return new AddINode(shift, in(1)); // // When making a Node for a constant use 'phase->makecon' or 'phase->intcon'. -// These forms are faster than 'phase->transform(new (C) ConNode())' and Do +// These forms are faster than 'phase->transform(new ConNode())' and Do // The Right Thing with def-use info. // // You cannot bury the 'this' Node inside of a graph reshape. If the reshaped diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/node.hpp --- a/hotspot/src/share/vm/opto/node.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/node.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -208,14 +208,12 @@ // field is a local cache of a value defined in some "program fragment" for // which these Nodes are just a part of. - // New Operator that takes a Compile pointer, this will eventually - // be the "new" New operator. - inline void* operator new( size_t x, Compile* C) throw() { + inline void* operator new(size_t x) throw() { + Compile* C = Compile::current(); Node* n = (Node*)C->node_arena()->Amalloc_D(x); #ifdef ASSERT n->_in = (Node**)n; // magic cookie for assertion check #endif - n->_out = (Node**)C; return (void*)n; } @@ -259,7 +257,7 @@ // Puts initial values in all Node fields except _idx. // Returns the initial value for _idx, which cannot // be initialized by assignment. - inline int Init(int req, Compile* C); + inline int Init(int req); //----------------- input edge handling protected: diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/output.cpp --- a/hotspot/src/share/vm/opto/output.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/output.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -67,7 +67,7 @@ const StartNode *start = entry->head()->as_Start(); // Replace StartNode with prolog - MachPrologNode *prolog = new (this) MachPrologNode(); + MachPrologNode *prolog = new MachPrologNode(); entry->map_node(prolog, 0); _cfg->map_node_to_block(prolog, entry); _cfg->unmap_node_from_block(start); // start is no longer in any block @@ -77,12 +77,12 @@ if( is_osr_compilation() ) { if( PoisonOSREntry ) { // TODO: Should use a ShouldNotReachHereNode... - _cfg->insert( broot, 0, new (this) MachBreakpointNode() ); + _cfg->insert( broot, 0, new MachBreakpointNode() ); } } else { if( _method && !_method->flags().is_static() ) { // Insert unvalidated entry point - _cfg->insert( broot, 0, new (this) MachUEPNode() ); + _cfg->insert( broot, 0, new MachUEPNode() ); } } @@ -98,7 +98,7 @@ ) { // checking for _method means that OptoBreakpoint does not apply to // runtime stubs or frame converters - _cfg->insert( entry, 1, new (this) MachBreakpointNode() ); + _cfg->insert( entry, 1, new MachBreakpointNode() ); } // Insert epilogs before every return @@ -107,7 +107,7 @@ if (!block->is_connector() && block->non_connector_successor(0) == _cfg->get_root_block()) { // Found a program exit point? Node* m = block->end(); if (m->is_Mach() && m->as_Mach()->ideal_Opcode() != Op_Halt) { - MachEpilogNode* epilog = new (this) MachEpilogNode(m->as_Mach()->ideal_Opcode() == Op_Return); + MachEpilogNode* epilog = new MachEpilogNode(m->as_Mach()->ideal_Opcode() == Op_Return); block->add_inst(epilog); _cfg->map_node_to_block(epilog, block); } @@ -268,7 +268,7 @@ Node* Compile::call_zap_node(MachSafePointNode* node_to_check, int block_no) { const TypeFunc *tf = OptoRuntime::zap_dead_locals_Type(); CallStaticJavaNode* ideal_node = - new (this) CallStaticJavaNode( tf, + new CallStaticJavaNode( tf, OptoRuntime::zap_dead_locals_stub(_method->flags().is_native()), "call zap dead locals stub", 0, TypePtr::BOTTOM); // We need to copy the OopMap from the site we're zapping at. @@ -368,7 +368,7 @@ // Step one, perform a pessimistic sizing pass. uint last_call_adr = max_juint; uint last_avoid_back_to_back_adr = max_juint; - uint nop_size = (new (this) MachNopNode())->size(_regalloc); + uint nop_size = (new MachNopNode())->size(_regalloc); for (uint i = 0; i < nblocks; i++) { // For all blocks Block* block = _cfg->get_block(i); @@ -1201,7 +1201,7 @@ uint *call_returns = NEW_RESOURCE_ARRAY(uint, nblocks+1); uint return_offset = 0; - int nop_size = (new (this) MachNopNode())->size(_regalloc); + int nop_size = (new MachNopNode())->size(_regalloc); int previous_offset = 0; int current_offset = 0; @@ -1327,7 +1327,7 @@ if(padding > 0) { assert((padding % nop_size) == 0, "padding is not a multiple of NOP size"); int nops_cnt = padding / nop_size; - MachNode *nop = new (this) MachNopNode(nops_cnt); + MachNode *nop = new MachNopNode(nops_cnt); block->insert_node(nop, j++); last_inst++; _cfg->map_node_to_block(nop, block); @@ -1413,7 +1413,7 @@ assert((br_size - new_size) >= (int)nop_size, "short_branch size should be smaller"); // Insert padding between avoid_back_to_back branches. if (needs_padding && replacement->avoid_back_to_back(MachNode::AVOID_BEFORE)) { - MachNode *nop = new (this) MachNopNode(); + MachNode *nop = new MachNopNode(); block->insert_node(nop, j++); _cfg->map_node_to_block(nop, block); last_inst++; @@ -1573,7 +1573,7 @@ Block *nb = _cfg->get_block(i + 1); int padding = nb->alignment_padding(current_offset); if( padding > 0 ) { - MachNode *nop = new (this) MachNopNode(padding / nop_size); + MachNode *nop = new MachNopNode(padding / nop_size); block->insert_node(nop, block->number_of_nodes()); _cfg->map_node_to_block(nop, block); nop->emit(*cb, _regalloc); @@ -1786,7 +1786,7 @@ #endif { // Create a MachNopNode - _nop = new (&compile) MachNopNode(); + _nop = new MachNopNode(); // Now that the nops are in the array, save the count // (but allow entries for the nops) @@ -2688,7 +2688,7 @@ if ( _pinch_free_list.size() > 0) { pinch = _pinch_free_list.pop(); } else { - pinch = new (_cfg->C) Node(1); // Pinch point to-be + pinch = new Node(1); // Pinch point to-be } if (pinch->_idx >= _regalloc->node_regs_max_index()) { _cfg->C->record_method_not_compilable("too many D-U pinch points"); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/parse.hpp --- a/hotspot/src/share/vm/opto/parse.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/parse.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -359,12 +359,13 @@ int _est_switch_depth; // Debugging SwitchRanges. #endif - // parser for the caller of the method of this object - Parse* const _parent; + bool _first_return; // true if return is the first to be parsed + bool _replaced_nodes_for_exceptions; // needs processing of replaced nodes in exception paths? + uint _new_idx; // any node with _idx above were new during this parsing. Used to trim the replaced nodes list. public: // Constructor - Parse(JVMState* caller, ciMethod* parse_method, float expected_uses, Parse* parent); + Parse(JVMState* caller, ciMethod* parse_method, float expected_uses); virtual Parse* is_Parse() const { return (Parse*)this; } @@ -425,8 +426,6 @@ return block()->successor_for_bci(bci); } - Parse* parent_parser() const { return _parent; } - private: // Create a JVMS & map for the initial state of this method. SafePointNode* create_entry_map(); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/parse1.cpp --- a/hotspot/src/share/vm/opto/parse1.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/parse1.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -109,10 +109,10 @@ // doubles on Sparc. Intel can handle them just fine directly. Node *l; switch (bt) { // Signature is flattened - case T_INT: l = new (C) LoadINode(ctl, mem, adr, TypeRawPtr::BOTTOM, TypeInt::INT, MemNode::unordered); break; - case T_FLOAT: l = new (C) LoadFNode(ctl, mem, adr, TypeRawPtr::BOTTOM, Type::FLOAT, MemNode::unordered); break; - case T_ADDRESS: l = new (C) LoadPNode(ctl, mem, adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM, MemNode::unordered); break; - case T_OBJECT: l = new (C) LoadPNode(ctl, mem, adr, TypeRawPtr::BOTTOM, TypeInstPtr::BOTTOM, MemNode::unordered); break; + case T_INT: l = new LoadINode(ctl, mem, adr, TypeRawPtr::BOTTOM, TypeInt::INT, MemNode::unordered); break; + case T_FLOAT: l = new LoadFNode(ctl, mem, adr, TypeRawPtr::BOTTOM, Type::FLOAT, MemNode::unordered); break; + case T_ADDRESS: l = new LoadPNode(ctl, mem, adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM, MemNode::unordered); break; + case T_OBJECT: l = new LoadPNode(ctl, mem, adr, TypeRawPtr::BOTTOM, TypeInstPtr::BOTTOM, MemNode::unordered); break; case T_LONG: case T_DOUBLE: { // Since arguments are in reverse order, the argument address 'adr' @@ -120,12 +120,12 @@ adr = basic_plus_adr(local_addrs_base, local_addrs, -(index+1)*wordSize); if (Matcher::misaligned_doubles_ok) { l = (bt == T_DOUBLE) - ? (Node*)new (C) LoadDNode(ctl, mem, adr, TypeRawPtr::BOTTOM, Type::DOUBLE, MemNode::unordered) - : (Node*)new (C) LoadLNode(ctl, mem, adr, TypeRawPtr::BOTTOM, TypeLong::LONG, MemNode::unordered); + ? (Node*)new LoadDNode(ctl, mem, adr, TypeRawPtr::BOTTOM, Type::DOUBLE, MemNode::unordered) + : (Node*)new LoadLNode(ctl, mem, adr, TypeRawPtr::BOTTOM, TypeLong::LONG, MemNode::unordered); } else { l = (bt == T_DOUBLE) - ? (Node*)new (C) LoadD_unalignedNode(ctl, mem, adr, TypeRawPtr::BOTTOM, MemNode::unordered) - : (Node*)new (C) LoadL_unalignedNode(ctl, mem, adr, TypeRawPtr::BOTTOM, MemNode::unordered); + ? (Node*)new LoadD_unalignedNode(ctl, mem, adr, TypeRawPtr::BOTTOM, MemNode::unordered) + : (Node*)new LoadL_unalignedNode(ctl, mem, adr, TypeRawPtr::BOTTOM, MemNode::unordered); } break; } @@ -149,11 +149,11 @@ if (type == TypePtr::NULL_PTR || (tp != NULL && !tp->klass()->is_loaded())) { // Value must be null, not a real oop. - Node* chk = _gvn.transform( new (C) CmpPNode(l, null()) ); - Node* tst = _gvn.transform( new (C) BoolNode(chk, BoolTest::eq) ); + Node* chk = _gvn.transform( new CmpPNode(l, null()) ); + Node* tst = _gvn.transform( new BoolNode(chk, BoolTest::eq) ); IfNode* iff = create_and_map_if(control(), tst, PROB_MAX, COUNT_UNKNOWN); - set_control(_gvn.transform( new (C) IfTrueNode(iff) )); - Node* bad_type = _gvn.transform( new (C) IfFalseNode(iff) ); + set_control(_gvn.transform( new IfTrueNode(iff) )); + Node* bad_type = _gvn.transform( new IfFalseNode(iff) ); bad_type_exit->control()->add_req(bad_type); l = null(); } @@ -220,7 +220,7 @@ Node *monitors_addr = basic_plus_adr(osr_buf, osr_buf, (max_locals+mcnt*2-1)*wordSize); for (index = 0; index < mcnt; index++) { // Make a BoxLockNode for the monitor. - Node *box = _gvn.transform(new (C) BoxLockNode(next_monitor())); + Node *box = _gvn.transform(new BoxLockNode(next_monitor())); // Displaced headers and locked objects are interleaved in the @@ -235,7 +235,7 @@ // Build a bogus FastLockNode (no code will be generated) and push the // monitor into our debug info. - const FastLockNode *flock = _gvn.transform(new (C) FastLockNode( 0, lock_object, box ))->as_FastLock(); + const FastLockNode *flock = _gvn.transform(new FastLockNode( 0, lock_object, box ))->as_FastLock(); map()->push_monitor(flock); // If the lock is our method synchronization lock, tuck it away in @@ -325,7 +325,7 @@ // Now that the interpreter state is loaded, make sure it will match // at execution time what the compiler is expecting now: SafePointNode* bad_type_exit = clone_map(); - bad_type_exit->set_control(new (C) RegionNode(1)); + bad_type_exit->set_control(new RegionNode(1)); assert(osr_block->flow()->jsrs()->size() == 0, "should be no jsrs live at osr point"); for (index = 0; index < max_locals; index++) { @@ -383,8 +383,8 @@ //------------------------------Parse------------------------------------------ // Main parser constructor. -Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses, Parse* parent) - : _exits(caller), _parent(parent) +Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses) + : _exits(caller) { // Init some variables _caller = caller; @@ -399,6 +399,9 @@ _entry_bci = InvocationEntryBci; _tf = NULL; _block = NULL; + _first_return = true; + _replaced_nodes_for_exceptions = false; + _new_idx = C->unique(); debug_only(_block_count = -1); debug_only(_blocks = (Block*)-1); #ifndef PRODUCT @@ -661,7 +664,7 @@ add_predicate(); // Add new region for back branches. int edges = block->pred_count() - block->preds_parsed() + 1; // +1 for original region - RegionNode *r = new (C) RegionNode(edges+1); + RegionNode *r = new RegionNode(edges+1); _gvn.set_type(r, Type::CONTROL); record_for_igvn(r); r->init_req(edges, control()); @@ -728,14 +731,14 @@ _exits.clean_stack(_exits.sp()); _exits.sync_jvms(); - RegionNode* region = new (C) RegionNode(1); + RegionNode* region = new RegionNode(1); record_for_igvn(region); gvn().set_type_bottom(region); _exits.set_control(region); // Note: iophi and memphi are not transformed until do_exits. - Node* iophi = new (C) PhiNode(region, Type::ABIO); - Node* memphi = new (C) PhiNode(region, Type::MEMORY, TypePtr::BOTTOM); + Node* iophi = new PhiNode(region, Type::ABIO); + Node* memphi = new PhiNode(region, Type::MEMORY, TypePtr::BOTTOM); gvn().set_type_bottom(iophi); gvn().set_type_bottom(memphi); _exits.set_i_o(iophi); @@ -752,7 +755,7 @@ ret_type = TypeOopPtr::BOTTOM; } int ret_size = type2size[ret_type->basic_type()]; - Node* ret_phi = new (C) PhiNode(region, ret_type); + Node* ret_phi = new PhiNode(region, ret_type); gvn().set_type_bottom(ret_phi); _exits.ensure_stack(ret_size); assert((int)(tf()->range()->cnt() - TypeFunc::Parms) == ret_size, "good tf range"); @@ -770,7 +773,7 @@ int arg_size = tf->domain()->cnt(); int max_size = MAX2(arg_size, (int)tf->range()->cnt()); JVMState* jvms = new (this) JVMState(max_size - TypeFunc::Parms); - SafePointNode* map = new (this) SafePointNode(max_size, NULL); + SafePointNode* map = new SafePointNode(max_size, NULL); record_for_igvn(map); assert(arg_size == TypeFunc::Parms + (is_osr_compilation() ? 1 : method()->arg_size()), "correct arg_size"); Node_Notes* old_nn = default_node_notes(); @@ -784,7 +787,7 @@ } uint i; for (i = 0; i < (uint)arg_size; i++) { - Node* parm = initial_gvn()->transform(new (this) ParmNode(start, i)); + Node* parm = initial_gvn()->transform(new ParmNode(start, i)); map->init_req(i, parm); // Record all these guys for later GVN. record_for_igvn(parm); @@ -815,7 +818,7 @@ //--------------------------return_values-------------------------------------- void Compile::return_values(JVMState* jvms) { GraphKit kit(jvms); - Node* ret = new (this) ReturnNode(TypeFunc::Parms, + Node* ret = new ReturnNode(TypeFunc::Parms, kit.control(), kit.i_o(), kit.reset_memory(), @@ -843,7 +846,7 @@ // Load my combined exception state into the kit, with all phis transformed: SafePointNode* ex_map = kit.combine_and_pop_all_exception_states(); Node* ex_oop = kit.use_exception_state(ex_map); - RethrowNode* exit = new (this) RethrowNode(kit.control(), + RethrowNode* exit = new RethrowNode(kit.control(), kit.i_o(), kit.reset_memory(), kit.frameptr(), kit.returnadr(), // like a return but with exception input @@ -901,6 +904,10 @@ for (uint i = 0; i < TypeFunc::Parms; i++) { caller.map()->set_req(i, ex_map->in(i)); } + if (ex_map->has_replaced_nodes()) { + _replaced_nodes_for_exceptions = true; + } + caller.map()->transfer_replaced_nodes_from(ex_map, _new_idx); // ...and the exception: Node* ex_oop = saved_ex_oop(ex_map); SafePointNode* caller_ex_map = caller.make_exception_state(ex_oop); @@ -991,7 +998,7 @@ bool do_synch = method()->is_synchronized() && GenerateSynchronizationCode; // record exit from a method if compiled while Dtrace is turned on. - if (do_synch || C->env()->dtrace_method_probes()) { + if (do_synch || C->env()->dtrace_method_probes() || _replaced_nodes_for_exceptions) { // First move the exception list out of _exits: GraphKit kit(_exits.transfer_exceptions_into_jvms()); SafePointNode* normal_map = kit.map(); // keep this guy safe @@ -1016,6 +1023,9 @@ if (C->env()->dtrace_method_probes()) { kit.make_dtrace_method_exit(method()); } + if (_replaced_nodes_for_exceptions) { + kit.map()->apply_replaced_nodes(); + } // Done with exception-path processing. ex_map = kit.make_exception_state(ex_oop); assert(ex_jvms->same_calls_as(ex_map->jvms()), "sanity"); @@ -1035,6 +1045,7 @@ _exits.add_exception_state(ex_map); } } + _exits.map()->apply_replaced_nodes(); } //-----------------------------create_entry_map------------------------------- @@ -1049,6 +1060,9 @@ return NULL; } + // clear current replaced nodes that are of no use from here on (map was cloned in build_exits). + _caller->map()->delete_replaced_nodes(); + // If this is an inlined method, we may have to do a receiver null check. if (_caller->has_method() && is_normal_parse() && !method()->is_static()) { GraphKit kit(_caller); @@ -1065,13 +1079,15 @@ // Create an initial safepoint to hold JVM state during parsing JVMState* jvms = new (C) JVMState(method(), _caller->has_method() ? _caller : NULL); - set_map(new (C) SafePointNode(len, jvms)); + set_map(new SafePointNode(len, jvms)); jvms->set_map(map()); record_for_igvn(map()); assert(jvms->endoff() == len, "correct jvms sizing"); SafePointNode* inmap = _caller->map(); assert(inmap != NULL, "must have inmap"); + // In case of null check on receiver above + map()->transfer_replaced_nodes_from(inmap, _new_idx); uint i; @@ -1578,7 +1594,7 @@ // later lazily. int edges = target->pred_count(); if (edges < pnum) edges = pnum; // might be a new path! - RegionNode *r = new (C) RegionNode(edges+1); + RegionNode *r = new RegionNode(edges+1); gvn().set_type(r, Type::CONTROL); record_for_igvn(r); // zap all inputs to NULL for debugging (done in Node(uint) constructor) @@ -1701,6 +1717,8 @@ set_control(r->nonnull_req()); } + map()->merge_replaced_nodes_with(newin); + // newin has been subsumed into the lazy merge, and is now dead. set_block(save_block); @@ -1973,19 +1991,19 @@ Node* access_flags_addr = basic_plus_adr(klass, klass, in_bytes(Klass::access_flags_offset())); Node* access_flags = make_load(NULL, access_flags_addr, TypeInt::INT, T_INT, MemNode::unordered); - Node* mask = _gvn.transform(new (C) AndINode(access_flags, intcon(JVM_ACC_HAS_FINALIZER))); - Node* check = _gvn.transform(new (C) CmpINode(mask, intcon(0))); - Node* test = _gvn.transform(new (C) BoolNode(check, BoolTest::ne)); + Node* mask = _gvn.transform(new AndINode(access_flags, intcon(JVM_ACC_HAS_FINALIZER))); + Node* check = _gvn.transform(new CmpINode(mask, intcon(0))); + Node* test = _gvn.transform(new BoolNode(check, BoolTest::ne)); IfNode* iff = create_and_map_if(control(), test, PROB_MAX, COUNT_UNKNOWN); - RegionNode* result_rgn = new (C) RegionNode(3); + RegionNode* result_rgn = new RegionNode(3); record_for_igvn(result_rgn); - Node *skip_register = _gvn.transform(new (C) IfFalseNode(iff)); + Node *skip_register = _gvn.transform(new IfFalseNode(iff)); result_rgn->init_req(1, skip_register); - Node *needs_register = _gvn.transform(new (C) IfTrueNode(iff)); + Node *needs_register = _gvn.transform(new IfTrueNode(iff)); set_control(needs_register); if (stopped()) { // There is no slow path. @@ -2039,9 +2057,9 @@ // or with ProfileRTM (cmp->in(2)) otherwise so that // the check will fold. Node* profile_state = makecon(TypeInt::make(ProfileRTM)); - Node* opq = _gvn.transform( new (C) Opaque3Node(C, rtm_state, Opaque3Node::RTM_OPT) ); - Node* chk = _gvn.transform( new (C) CmpINode(opq, profile_state) ); - Node* tst = _gvn.transform( new (C) BoolNode(chk, BoolTest::eq) ); + Node* opq = _gvn.transform( new Opaque3Node(C, rtm_state, Opaque3Node::RTM_OPT) ); + Node* chk = _gvn.transform( new CmpINode(opq, profile_state) ); + Node* tst = _gvn.transform( new BoolNode(chk, BoolTest::eq) ); // Branch to failure if state was changed { BuildCutout unless(this, tst, PROB_ALWAYS); uncommon_trap(Deoptimization::Reason_rtm_state_change, @@ -2066,10 +2084,10 @@ Node* mc_adr = makecon(adr_type); Node* cnt_adr = basic_plus_adr(mc_adr, mc_adr, in_bytes(MethodCounters::nmethod_age_offset())); Node* cnt = make_load(control(), cnt_adr, TypeInt::INT, T_INT, adr_type, MemNode::unordered); - Node* decr = _gvn.transform(new (C) SubINode(cnt, makecon(TypeInt::ONE))); + Node* decr = _gvn.transform(new SubINode(cnt, makecon(TypeInt::ONE))); store_to_memory(control(), cnt_adr, decr, T_INT, adr_type, MemNode::unordered); - Node *chk = _gvn.transform(new (C) CmpINode(decr, makecon(TypeInt::ZERO))); - Node* tst = _gvn.transform(new (C) BoolNode(chk, BoolTest::gt)); + Node *chk = _gvn.transform(new CmpINode(decr, makecon(TypeInt::ZERO))); + Node* tst = _gvn.transform(new BoolNode(chk, BoolTest::gt)); { BuildCutout unless(this, tst, PROB_ALWAYS); uncommon_trap(Deoptimization::Reason_tenured, Deoptimization::Action_make_not_entrant); @@ -2124,12 +2142,19 @@ // sharpen the type eagerly; this eases certain assert checking if (tp->higher_equal(TypeInstPtr::NOTNULL)) tr = tr->join_speculative(TypeInstPtr::NOTNULL)->is_instptr(); - value = _gvn.transform(new (C) CheckCastPPNode(0,value,tr)); + value = _gvn.transform(new CheckCastPPNode(0,value,tr)); } } phi->add_req(value); } + if (_first_return) { + _exits.map()->transfer_replaced_nodes_from(map(), _new_idx); + _first_return = false; + } else { + _exits.map()->merge_replaced_nodes_with(map()); + } + stop_and_kill_map(); // This CFG path dies here } @@ -2159,7 +2184,7 @@ kill_dead_locals(); // Clone the JVM State - SafePointNode *sfpnt = new (C) SafePointNode(parms, NULL); + SafePointNode *sfpnt = new SafePointNode(parms, NULL); // Capture memory state BEFORE a SafePoint. Since we can block at a // SafePoint we need our GC state to be safe; i.e. we need all our current diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/parse2.cpp --- a/hotspot/src/share/vm/opto/parse2.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/parse2.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -130,9 +130,9 @@ Node* len = load_array_length(ary); // Test length vs index (standard trick using unsigned compare) - Node* chk = _gvn.transform( new (C) CmpUNode(idx, len) ); + Node* chk = _gvn.transform( new CmpUNode(idx, len) ); BoolTest::mask btest = BoolTest::lt; - tst = _gvn.transform( new (C) BoolNode(chk, btest) ); + tst = _gvn.transform( new BoolNode(chk, btest) ); } // Branch to failure if out of bounds { BuildCutout unless(this, tst, PROB_MAX); @@ -168,15 +168,15 @@ // returns IfNode IfNode* Parse::jump_if_fork_int(Node* a, Node* b, BoolTest::mask mask) { - Node *cmp = _gvn.transform( new (C) CmpINode( a, b)); // two cases: shiftcount > 32 and shiftcount <= 32 - Node *tst = _gvn.transform( new (C) BoolNode( cmp, mask)); + Node *cmp = _gvn.transform( new CmpINode( a, b)); // two cases: shiftcount > 32 and shiftcount <= 32 + Node *tst = _gvn.transform( new BoolNode( cmp, mask)); IfNode *iff = create_and_map_if( control(), tst, ((mask == BoolTest::eq) ? PROB_STATIC_INFREQUENT : PROB_FAIR), COUNT_UNKNOWN ); return iff; } // return Region node Node* Parse::jump_if_join(Node* iffalse, Node* iftrue) { - Node *region = new (C) RegionNode(3); // 2 results + Node *region = new RegionNode(3); // 2 results record_for_igvn(region); region->init_req(1, iffalse); region->init_req(2, iftrue ); @@ -191,28 +191,28 @@ void Parse::jump_if_true_fork(IfNode *iff, int dest_bci_if_true, int prof_table_index) { // True branch, use existing map info { PreserveJVMState pjvms(this); - Node *iftrue = _gvn.transform( new (C) IfTrueNode (iff) ); + Node *iftrue = _gvn.transform( new IfTrueNode (iff) ); set_control( iftrue ); profile_switch_case(prof_table_index); merge_new_path(dest_bci_if_true); } // False branch - Node *iffalse = _gvn.transform( new (C) IfFalseNode(iff) ); + Node *iffalse = _gvn.transform( new IfFalseNode(iff) ); set_control( iffalse ); } void Parse::jump_if_false_fork(IfNode *iff, int dest_bci_if_true, int prof_table_index) { // True branch, use existing map info { PreserveJVMState pjvms(this); - Node *iffalse = _gvn.transform( new (C) IfFalseNode (iff) ); + Node *iffalse = _gvn.transform( new IfFalseNode (iff) ); set_control( iffalse ); profile_switch_case(prof_table_index); merge_new_path(dest_bci_if_true); } // False branch - Node *iftrue = _gvn.transform( new (C) IfTrueNode(iff) ); + Node *iftrue = _gvn.transform( new IfTrueNode(iff) ); set_control( iftrue ); } @@ -440,14 +440,14 @@ // Normalize table lookups to zero int lowval = lo->lo(); - key_val = _gvn.transform( new (C) SubINode(key_val, _gvn.intcon(lowval)) ); + key_val = _gvn.transform( new SubINode(key_val, _gvn.intcon(lowval)) ); // Generate a guard to protect against input keyvals that aren't // in the switch domain. if (needs_guard) { Node* size = _gvn.intcon(num_cases); - Node* cmp = _gvn.transform( new (C) CmpUNode(key_val, size) ); - Node* tst = _gvn.transform( new (C) BoolNode(cmp, BoolTest::ge) ); + Node* cmp = _gvn.transform( new CmpUNode(key_val, size) ); + Node* tst = _gvn.transform( new BoolNode(cmp, BoolTest::ge) ); IfNode* iff = create_and_map_if( control(), tst, PROB_FAIR, COUNT_UNKNOWN); jump_if_true_fork(iff, default_dest, NullTableIndex); } @@ -460,21 +460,21 @@ // Clean the 32-bit int into a real 64-bit offset. // Otherwise, the jint value 0 might turn into an offset of 0x0800000000. const TypeLong* lkeytype = TypeLong::make(CONST64(0), num_cases-1, Type::WidenMin); - key_val = _gvn.transform( new (C) ConvI2LNode(key_val, lkeytype) ); + key_val = _gvn.transform( new ConvI2LNode(key_val, lkeytype) ); #endif // Shift the value by wordsize so we have an index into the table, rather // than a switch value Node *shiftWord = _gvn.MakeConX(wordSize); - key_val = _gvn.transform( new (C) MulXNode( key_val, shiftWord)); + key_val = _gvn.transform( new MulXNode( key_val, shiftWord)); // Create the JumpNode - Node* jtn = _gvn.transform( new (C) JumpNode(control(), key_val, num_cases) ); + Node* jtn = _gvn.transform( new JumpNode(control(), key_val, num_cases) ); // These are the switch destinations hanging off the jumpnode int i = 0; for (SwitchRange* r = lo; r <= hi; r++) { for (int64_t j = r->lo(); j <= r->hi(); j++, i++) { - Node* input = _gvn.transform(new (C) JumpProjNode(jtn, i, r->dest(), (int)(j - lowval))); + Node* input = _gvn.transform(new JumpProjNode(jtn, i, r->dest(), (int)(j - lowval))); { PreserveJVMState pjvms(this); set_control(input); @@ -575,8 +575,8 @@ // two comparisons of same values--should enable 1 test for 2 branches // Use BoolTest::le instead of BoolTest::gt IfNode *iff_le = jump_if_fork_int(key_val, test_val, BoolTest::le); - Node *iftrue = _gvn.transform( new (C) IfTrueNode(iff_le) ); - Node *iffalse = _gvn.transform( new (C) IfFalseNode(iff_le) ); + Node *iftrue = _gvn.transform( new IfTrueNode(iff_le) ); + Node *iffalse = _gvn.transform( new IfFalseNode(iff_le) ); { PreserveJVMState pjvms(this); set_control(iffalse); jump_switch_ranges(key_val, mid+1, hi, switch_depth+1); @@ -592,8 +592,8 @@ if (mid == hi) { jump_if_true_fork(iff_ge, mid->dest(), mid->table_index()); } else { - Node *iftrue = _gvn.transform( new (C) IfTrueNode(iff_ge) ); - Node *iffalse = _gvn.transform( new (C) IfFalseNode(iff_ge) ); + Node *iftrue = _gvn.transform( new IfTrueNode(iff_ge) ); + Node *iffalse = _gvn.transform( new IfFalseNode(iff_ge) ); { PreserveJVMState pjvms(this); set_control(iftrue); jump_switch_ranges(key_val, mid, hi, switch_depth+1); @@ -648,7 +648,7 @@ CAST_FROM_FN_PTR(address, SharedRuntime::frem), "frem", NULL, //no memory effects f1, f2); - Node* res = _gvn.transform(new (C) ProjNode(c, TypeFunc::Parms + 0)); + Node* res = _gvn.transform(new ProjNode(c, TypeFunc::Parms + 0)); push(res); } @@ -660,10 +660,10 @@ CAST_FROM_FN_PTR(address, SharedRuntime::drem), "drem", NULL, //no memory effects d1, top(), d2, top()); - Node* res_d = _gvn.transform(new (C) ProjNode(c, TypeFunc::Parms + 0)); + Node* res_d = _gvn.transform(new ProjNode(c, TypeFunc::Parms + 0)); #ifdef ASSERT - Node* res_top = _gvn.transform(new (C) ProjNode(c, TypeFunc::Parms + 1)); + Node* res_top = _gvn.transform(new ProjNode(c, TypeFunc::Parms + 1)); assert(res_top == top(), "second value must be top"); #endif @@ -677,7 +677,7 @@ CAST_FROM_FN_PTR(address, SharedRuntime::l2f), "l2f", NULL, //no memory effects f1, f2); - Node* res = _gvn.transform(new (C) ProjNode(c, TypeFunc::Parms + 0)); + Node* res = _gvn.transform(new ProjNode(c, TypeFunc::Parms + 0)); push(res); } @@ -704,17 +704,17 @@ // Sigh, must handle negative dividends Node *zero = _gvn.intcon(0); IfNode *ifff = jump_if_fork_int(a, zero, BoolTest::lt); - Node *iff = _gvn.transform( new (C) IfFalseNode(ifff) ); - Node *ift = _gvn.transform( new (C) IfTrueNode (ifff) ); + Node *iff = _gvn.transform( new IfFalseNode(ifff) ); + Node *ift = _gvn.transform( new IfTrueNode (ifff) ); Node *reg = jump_if_join(ift, iff); Node *phi = PhiNode::make(reg, NULL, TypeInt::INT); // Negative path; negate/and/negate - Node *neg = _gvn.transform( new (C) SubINode(zero, a) ); - Node *andn= _gvn.transform( new (C) AndINode(neg, mask) ); - Node *negn= _gvn.transform( new (C) SubINode(zero, andn) ); + Node *neg = _gvn.transform( new SubINode(zero, a) ); + Node *andn= _gvn.transform( new AndINode(neg, mask) ); + Node *negn= _gvn.transform( new SubINode(zero, andn) ); phi->init_req(1, negn); // Fast positive case - Node *andx = _gvn.transform( new (C) AndINode(a, mask) ); + Node *andx = _gvn.transform( new AndINode(a, mask) ); phi->init_req(2, andx); // Push the merge push( _gvn.transform(phi) ); @@ -723,7 +723,7 @@ } } // Default case - push( _gvn.transform( new (C) ModINode(control(),a,b) ) ); + push( _gvn.transform( new ModINode(control(),a,b) ) ); } // Handle jsr and jsr_w bytecode @@ -897,53 +897,12 @@ // if a path is never taken, its controlling comparison is // already acting in a stable fashion. If the comparison // seems stable, we will put an expensive uncommon trap -// on the untaken path. To be conservative, and to allow -// partially executed counted loops to be compiled fully, -// we will plant uncommon traps only after pointer comparisons. +// on the untaken path. bool Parse::seems_stable_comparison(BoolTest::mask btest, Node* cmp) { - for (int depth = 4; depth > 0; depth--) { - // The following switch can find CmpP here over half the time for - // dynamic language code rich with type tests. - // Code using counted loops or array manipulations (typical - // of benchmarks) will have many (>80%) CmpI instructions. - switch (cmp->Opcode()) { - case Op_CmpP: - // A never-taken null check looks like CmpP/BoolTest::eq. - // These certainly should be closed off as uncommon traps. - if (btest == BoolTest::eq) - return true; - // A never-failed type check looks like CmpP/BoolTest::ne. - // Let's put traps on those, too, so that we don't have to compile - // unused paths with indeterminate dynamic type information. - if (ProfileDynamicTypes) - return true; - return false; - - case Op_CmpI: - // A small minority (< 10%) of CmpP are masked as CmpI, - // as if by boolean conversion ((p == q? 1: 0) != 0). - // Detect that here, even if it hasn't optimized away yet. - // Specifically, this covers the 'instanceof' operator. - if (btest == BoolTest::ne || btest == BoolTest::eq) { - if (_gvn.type(cmp->in(2))->singleton() && - cmp->in(1)->is_Phi()) { - PhiNode* phi = cmp->in(1)->as_Phi(); - int true_path = phi->is_diamond_phi(); - if (true_path > 0 && - _gvn.type(phi->in(1))->singleton() && - _gvn.type(phi->in(2))->singleton()) { - // phi->region->if_proj->ifnode->bool->cmp - BoolNode* bol = phi->in(0)->in(1)->in(0)->in(1)->as_Bool(); - btest = bol->_test._test; - cmp = bol->in(1); - continue; - } - } - } - return false; - } + if (C->too_many_traps(method(), bci(), Deoptimization::Reason_unstable_if)) { + return false; } - return false; + return true; } //-------------------------------repush_if_args-------------------------------- @@ -1000,7 +959,7 @@ explicit_null_checks_inserted++; // Generate real control flow - Node *tst = _gvn.transform( new (C) BoolNode( c, btest ) ); + Node *tst = _gvn.transform( new BoolNode( c, btest ) ); // Sanity check the probability value assert(prob > 0.0f,"Bad probability in Parser"); @@ -1009,7 +968,7 @@ assert(iff->_prob > 0.0f,"Optimizer made bad probability in parser"); // True branch { PreserveJVMState pjvms(this); - Node* iftrue = _gvn.transform( new (C) IfTrueNode (iff) ); + Node* iftrue = _gvn.transform( new IfTrueNode (iff) ); set_control(iftrue); if (stopped()) { // Path is dead? @@ -1029,7 +988,7 @@ } // False branch - Node* iffalse = _gvn.transform( new (C) IfFalseNode(iff) ); + Node* iffalse = _gvn.transform( new IfFalseNode(iff) ); set_control(iffalse); if (stopped()) { // Path is dead? @@ -1092,7 +1051,7 @@ } assert(btest != BoolTest::eq, "!= is the only canonical exact test"); - Node* tst0 = new (C) BoolNode(c, btest); + Node* tst0 = new BoolNode(c, btest); Node* tst = _gvn.transform(tst0); BoolTest::mask taken_btest = BoolTest::illegal; BoolTest::mask untaken_btest = BoolTest::illegal; @@ -1123,8 +1082,8 @@ float true_prob = (taken_if_true ? prob : untaken_prob); IfNode* iff = create_and_map_if(control(), tst, true_prob, cnt); assert(iff->_prob > 0.0f,"Optimizer made bad probability in parser"); - Node* taken_branch = new (C) IfTrueNode(iff); - Node* untaken_branch = new (C) IfFalseNode(iff); + Node* taken_branch = new IfTrueNode(iff); + Node* untaken_branch = new IfFalseNode(iff); if (!taken_if_true) { // Finish conversion to canonical form Node* tmp = taken_branch; taken_branch = untaken_branch; @@ -1182,32 +1141,8 @@ bool is_fallthrough = (path == successor_for_bci(iter().next_bci())); if (seems_never_taken(prob) && seems_stable_comparison(btest, c)) { - // If this might possibly turn into an implicit null check, - // and the null has never yet been seen, we need to generate - // an uncommon trap, so as to recompile instead of suffering - // with very slow branches. (We'll get the slow branches if - // the program ever changes phase and starts seeing nulls here.) - // - // We do not inspect for a null constant, since a node may - // optimize to 'null' later on. - // - // Null checks, and other tests which expect inequality, - // show btest == BoolTest::eq along the non-taken branch. - // On the other hand, type tests, must-be-null tests, - // and other tests which expect pointer equality, - // show btest == BoolTest::ne along the non-taken branch. - // We prune both types of branches if they look unused. repush_if_args(); - // We need to mark this branch as taken so that if we recompile we will - // see that it is possible. In the tiered system the interpreter doesn't - // do profiling and by the time we get to the lower tier from the interpreter - // the path may be cold again. Make sure it doesn't look untaken - if (is_fallthrough) { - profile_not_taken_branch(!ProfileInterpreter); - } else { - profile_taken_branch(iter().get_dest(), !ProfileInterpreter); - } - uncommon_trap(Deoptimization::Reason_unreached, + uncommon_trap(Deoptimization::Reason_unstable_if, Deoptimization::Action_reinterpret, NULL, (is_fallthrough ? "taken always" : "taken never")); @@ -1288,7 +1223,7 @@ JVMState* jvms = this->jvms(); if (obj_in_map >= 0 && (jvms->is_loc(obj_in_map) || jvms->is_stk(obj_in_map))) { - TypeNode* ccast = new (C) CheckCastPPNode(control(), obj, tboth); + TypeNode* ccast = new CheckCastPPNode(control(), obj, tboth); const Type* tcc = ccast->as_Type()->type(); assert(tcc != obj_type && tcc->higher_equal(obj_type), "must improve"); // Delay transform() call to allow recovery of pre-cast value @@ -1323,10 +1258,10 @@ const Type* tboth = tcon->join_speculative(tval); if (tboth == tval) break; // Nothing to gain. if (tcon->isa_int()) { - ccast = new (C) CastIINode(val, tboth); + ccast = new CastIINode(val, tboth); } else if (tcon == TypePtr::NULL_PTR) { // Cast to null, but keep the pointer identity temporarily live. - ccast = new (C) CastPPNode(val, tboth); + ccast = new CastPPNode(val, tboth); } else { const TypeF* tf = tcon->isa_float_constant(); const TypeD* td = tcon->isa_double_constant(); @@ -1792,59 +1727,59 @@ if (stopped()) return; b = pop(); a = pop(); - push( _gvn.transform( new (C) DivINode(control(),a,b) ) ); + push( _gvn.transform( new DivINode(control(),a,b) ) ); break; case Bytecodes::_imul: b = pop(); a = pop(); - push( _gvn.transform( new (C) MulINode(a,b) ) ); + push( _gvn.transform( new MulINode(a,b) ) ); break; case Bytecodes::_iadd: b = pop(); a = pop(); - push( _gvn.transform( new (C) AddINode(a,b) ) ); + push( _gvn.transform( new AddINode(a,b) ) ); break; case Bytecodes::_ineg: a = pop(); - push( _gvn.transform( new (C) SubINode(_gvn.intcon(0),a)) ); + push( _gvn.transform( new SubINode(_gvn.intcon(0),a)) ); break; case Bytecodes::_isub: b = pop(); a = pop(); - push( _gvn.transform( new (C) SubINode(a,b) ) ); + push( _gvn.transform( new SubINode(a,b) ) ); break; case Bytecodes::_iand: b = pop(); a = pop(); - push( _gvn.transform( new (C) AndINode(a,b) ) ); + push( _gvn.transform( new AndINode(a,b) ) ); break; case Bytecodes::_ior: b = pop(); a = pop(); - push( _gvn.transform( new (C) OrINode(a,b) ) ); + push( _gvn.transform( new OrINode(a,b) ) ); break; case Bytecodes::_ixor: b = pop(); a = pop(); - push( _gvn.transform( new (C) XorINode(a,b) ) ); + push( _gvn.transform( new XorINode(a,b) ) ); break; case Bytecodes::_ishl: b = pop(); a = pop(); - push( _gvn.transform( new (C) LShiftINode(a,b) ) ); + push( _gvn.transform( new LShiftINode(a,b) ) ); break; case Bytecodes::_ishr: b = pop(); a = pop(); - push( _gvn.transform( new (C) RShiftINode(a,b) ) ); + push( _gvn.transform( new RShiftINode(a,b) ) ); break; case Bytecodes::_iushr: b = pop(); a = pop(); - push( _gvn.transform( new (C) URShiftINode(a,b) ) ); + push( _gvn.transform( new URShiftINode(a,b) ) ); break; case Bytecodes::_fneg: a = pop(); - b = _gvn.transform(new (C) NegFNode (a)); + b = _gvn.transform(new NegFNode (a)); push(b); break; case Bytecodes::_fsub: b = pop(); a = pop(); - c = _gvn.transform( new (C) SubFNode(a,b) ); + c = _gvn.transform( new SubFNode(a,b) ); d = precision_rounding(c); push( d ); break; @@ -1852,7 +1787,7 @@ case Bytecodes::_fadd: b = pop(); a = pop(); - c = _gvn.transform( new (C) AddFNode(a,b) ); + c = _gvn.transform( new AddFNode(a,b) ); d = precision_rounding(c); push( d ); break; @@ -1860,7 +1795,7 @@ case Bytecodes::_fmul: b = pop(); a = pop(); - c = _gvn.transform( new (C) MulFNode(a,b) ); + c = _gvn.transform( new MulFNode(a,b) ); d = precision_rounding(c); push( d ); break; @@ -1868,7 +1803,7 @@ case Bytecodes::_fdiv: b = pop(); a = pop(); - c = _gvn.transform( new (C) DivFNode(0,a,b) ); + c = _gvn.transform( new DivFNode(0,a,b) ); d = precision_rounding(c); push( d ); break; @@ -1878,7 +1813,7 @@ // Generate a ModF node. b = pop(); a = pop(); - c = _gvn.transform( new (C) ModFNode(0,a,b) ); + c = _gvn.transform( new ModFNode(0,a,b) ); d = precision_rounding(c); push( d ); } @@ -1891,7 +1826,7 @@ case Bytecodes::_fcmpl: b = pop(); a = pop(); - c = _gvn.transform( new (C) CmpF3Node( a, b)); + c = _gvn.transform( new CmpF3Node( a, b)); push(c); break; case Bytecodes::_fcmpg: @@ -1903,40 +1838,40 @@ // as well by using CmpF3 which implements unordered-lesser instead of // unordered-greater semantics. Finally, commute the result bits. Result // is same as using a CmpF3Greater except we did it with CmpF3 alone. - c = _gvn.transform( new (C) CmpF3Node( b, a)); - c = _gvn.transform( new (C) SubINode(_gvn.intcon(0),c) ); + c = _gvn.transform( new CmpF3Node( b, a)); + c = _gvn.transform( new SubINode(_gvn.intcon(0),c) ); push(c); break; case Bytecodes::_f2i: a = pop(); - push(_gvn.transform(new (C) ConvF2INode(a))); + push(_gvn.transform(new ConvF2INode(a))); break; case Bytecodes::_d2i: a = pop_pair(); - b = _gvn.transform(new (C) ConvD2INode(a)); + b = _gvn.transform(new ConvD2INode(a)); push( b ); break; case Bytecodes::_f2d: a = pop(); - b = _gvn.transform( new (C) ConvF2DNode(a)); + b = _gvn.transform( new ConvF2DNode(a)); push_pair( b ); break; case Bytecodes::_d2f: a = pop_pair(); - b = _gvn.transform( new (C) ConvD2FNode(a)); + b = _gvn.transform( new ConvD2FNode(a)); // This breaks _227_mtrt (speed & correctness) and _222_mpegaudio (speed) - //b = _gvn.transform(new (C) RoundFloatNode(0, b) ); + //b = _gvn.transform(new RoundFloatNode(0, b) ); push( b ); break; case Bytecodes::_l2f: if (Matcher::convL2FSupported()) { a = pop_pair(); - b = _gvn.transform( new (C) ConvL2FNode(a)); + b = _gvn.transform( new ConvL2FNode(a)); // For i486.ad, FILD doesn't restrict precision to 24 or 53 bits. // Rather than storing the result into an FP register then pushing // out to memory to round, the machine instruction that implements @@ -1951,7 +1886,7 @@ case Bytecodes::_l2d: a = pop_pair(); - b = _gvn.transform( new (C) ConvL2DNode(a)); + b = _gvn.transform( new ConvL2DNode(a)); // For i486.ad, rounding is always necessary (see _l2f above). // c = dprecision_rounding(b); c = _gvn.transform(b); @@ -1960,20 +1895,20 @@ case Bytecodes::_f2l: a = pop(); - b = _gvn.transform( new (C) ConvF2LNode(a)); + b = _gvn.transform( new ConvF2LNode(a)); push_pair(b); break; case Bytecodes::_d2l: a = pop_pair(); - b = _gvn.transform( new (C) ConvD2LNode(a)); + b = _gvn.transform( new ConvD2LNode(a)); push_pair(b); break; case Bytecodes::_dsub: b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C) SubDNode(a,b) ); + c = _gvn.transform( new SubDNode(a,b) ); d = dprecision_rounding(c); push_pair( d ); break; @@ -1981,7 +1916,7 @@ case Bytecodes::_dadd: b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C) AddDNode(a,b) ); + c = _gvn.transform( new AddDNode(a,b) ); d = dprecision_rounding(c); push_pair( d ); break; @@ -1989,7 +1924,7 @@ case Bytecodes::_dmul: b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C) MulDNode(a,b) ); + c = _gvn.transform( new MulDNode(a,b) ); d = dprecision_rounding(c); push_pair( d ); break; @@ -1997,14 +1932,14 @@ case Bytecodes::_ddiv: b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C) DivDNode(0,a,b) ); + c = _gvn.transform( new DivDNode(0,a,b) ); d = dprecision_rounding(c); push_pair( d ); break; case Bytecodes::_dneg: a = pop_pair(); - b = _gvn.transform(new (C) NegDNode (a)); + b = _gvn.transform(new NegDNode (a)); push_pair(b); break; @@ -2015,7 +1950,7 @@ a = pop_pair(); // a % b - c = _gvn.transform( new (C) ModDNode(0,a,b) ); + c = _gvn.transform( new ModDNode(0,a,b) ); d = dprecision_rounding(c); push_pair( d ); } @@ -2028,7 +1963,7 @@ case Bytecodes::_dcmpl: b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C) CmpD3Node( a, b)); + c = _gvn.transform( new CmpD3Node( a, b)); push(c); break; @@ -2041,8 +1976,8 @@ // unordered-lesser instead of unordered-greater semantics. // Finally, negate the result bits. Result is same as using a // CmpD3Greater except we did it with CmpD3 alone. - c = _gvn.transform( new (C) CmpD3Node( b, a)); - c = _gvn.transform( new (C) SubINode(_gvn.intcon(0),c) ); + c = _gvn.transform( new CmpD3Node( b, a)); + c = _gvn.transform( new SubINode(_gvn.intcon(0),c) ); push(c); break; @@ -2051,44 +1986,44 @@ case Bytecodes::_land: b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C) AndLNode(a,b) ); + c = _gvn.transform( new AndLNode(a,b) ); push_pair(c); break; case Bytecodes::_lor: b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C) OrLNode(a,b) ); + c = _gvn.transform( new OrLNode(a,b) ); push_pair(c); break; case Bytecodes::_lxor: b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C) XorLNode(a,b) ); + c = _gvn.transform( new XorLNode(a,b) ); push_pair(c); break; case Bytecodes::_lshl: b = pop(); // the shift count a = pop_pair(); // value to be shifted - c = _gvn.transform( new (C) LShiftLNode(a,b) ); + c = _gvn.transform( new LShiftLNode(a,b) ); push_pair(c); break; case Bytecodes::_lshr: b = pop(); // the shift count a = pop_pair(); // value to be shifted - c = _gvn.transform( new (C) RShiftLNode(a,b) ); + c = _gvn.transform( new RShiftLNode(a,b) ); push_pair(c); break; case Bytecodes::_lushr: b = pop(); // the shift count a = pop_pair(); // value to be shifted - c = _gvn.transform( new (C) URShiftLNode(a,b) ); + c = _gvn.transform( new URShiftLNode(a,b) ); push_pair(c); break; case Bytecodes::_lmul: b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C) MulLNode(a,b) ); + c = _gvn.transform( new MulLNode(a,b) ); push_pair(c); break; @@ -2100,7 +2035,7 @@ if (stopped()) return; b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C) ModLNode(control(),a,b) ); + c = _gvn.transform( new ModLNode(control(),a,b) ); push_pair(c); break; @@ -2112,20 +2047,20 @@ if (stopped()) return; b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C) DivLNode(control(),a,b) ); + c = _gvn.transform( new DivLNode(control(),a,b) ); push_pair(c); break; case Bytecodes::_ladd: b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C) AddLNode(a,b) ); + c = _gvn.transform( new AddLNode(a,b) ); push_pair(c); break; case Bytecodes::_lsub: b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C) SubLNode(a,b) ); + c = _gvn.transform( new SubLNode(a,b) ); push_pair(c); break; case Bytecodes::_lcmp: @@ -2156,58 +2091,58 @@ } b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C) CmpL3Node( a, b )); + c = _gvn.transform( new CmpL3Node( a, b )); push(c); break; case Bytecodes::_lneg: a = pop_pair(); - b = _gvn.transform( new (C) SubLNode(longcon(0),a)); + b = _gvn.transform( new SubLNode(longcon(0),a)); push_pair(b); break; case Bytecodes::_l2i: a = pop_pair(); - push( _gvn.transform( new (C) ConvL2INode(a))); + push( _gvn.transform( new ConvL2INode(a))); break; case Bytecodes::_i2l: a = pop(); - b = _gvn.transform( new (C) ConvI2LNode(a)); + b = _gvn.transform( new ConvI2LNode(a)); push_pair(b); break; case Bytecodes::_i2b: // Sign extend a = pop(); - a = _gvn.transform( new (C) LShiftINode(a,_gvn.intcon(24)) ); - a = _gvn.transform( new (C) RShiftINode(a,_gvn.intcon(24)) ); + a = _gvn.transform( new LShiftINode(a,_gvn.intcon(24)) ); + a = _gvn.transform( new RShiftINode(a,_gvn.intcon(24)) ); push( a ); break; case Bytecodes::_i2s: a = pop(); - a = _gvn.transform( new (C) LShiftINode(a,_gvn.intcon(16)) ); - a = _gvn.transform( new (C) RShiftINode(a,_gvn.intcon(16)) ); + a = _gvn.transform( new LShiftINode(a,_gvn.intcon(16)) ); + a = _gvn.transform( new RShiftINode(a,_gvn.intcon(16)) ); push( a ); break; case Bytecodes::_i2c: a = pop(); - push( _gvn.transform( new (C) AndINode(a,_gvn.intcon(0xFFFF)) ) ); + push( _gvn.transform( new AndINode(a,_gvn.intcon(0xFFFF)) ) ); break; case Bytecodes::_i2f: a = pop(); - b = _gvn.transform( new (C) ConvI2FNode(a) ) ; + b = _gvn.transform( new ConvI2FNode(a) ) ; c = precision_rounding(b); push (b); break; case Bytecodes::_i2d: a = pop(); - b = _gvn.transform( new (C) ConvI2DNode(a)); + b = _gvn.transform( new ConvI2DNode(a)); push_pair(b); break; case Bytecodes::_iinc: // Increment local i = iter().get_index(); // Get local index - set_local( i, _gvn.transform( new (C) AddINode( _gvn.intcon(iter().get_iinc_con()), local(i) ) ) ); + set_local( i, _gvn.transform( new AddINode( _gvn.intcon(iter().get_iinc_con()), local(i) ) ) ); break; // Exit points of synchronized methods must have an unlock node @@ -2287,7 +2222,7 @@ assert(null_ctl->is_top(), "no null control here"); dec_sp(1); } - c = _gvn.transform( new (C) CmpPNode(b, a) ); + c = _gvn.transform( new CmpPNode(b, a) ); do_ifnull(btest, c); break; @@ -2298,7 +2233,7 @@ maybe_add_safepoint(iter().get_dest()); a = pop(); b = pop(); - c = _gvn.transform( new (C) CmpPNode(b, a) ); + c = _gvn.transform( new CmpPNode(b, a) ); c = optimize_cmp_with_klass(c); do_if(btest, c); break; @@ -2314,7 +2249,7 @@ maybe_add_safepoint(iter().get_dest()); a = _gvn.intcon(0); b = pop(); - c = _gvn.transform( new (C) CmpINode(b, a) ); + c = _gvn.transform( new CmpINode(b, a) ); do_if(btest, c); break; @@ -2329,7 +2264,7 @@ maybe_add_safepoint(iter().get_dest()); a = pop(); b = pop(); - c = _gvn.transform( new (C) CmpINode( b, a ) ); + c = _gvn.transform( new CmpINode( b, a ) ); do_if(btest, c); break; diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/parse3.cpp --- a/hotspot/src/share/vm/opto/parse3.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/parse3.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -552,7 +552,7 @@ } make_slow_call_ex(c, env()->Throwable_klass(), false); - Node* res = _gvn.transform(new (C) ProjNode(c, TypeFunc::Parms)); + Node* res = _gvn.transform(new ProjNode(c, TypeFunc::Parms)); const Type* type = TypeOopPtr::make_from_klass_raw(array_klass); @@ -566,7 +566,7 @@ // We cannot sharpen the nested sub-arrays, since the top level is mutable. - Node* cast = _gvn.transform( new (C) CheckCastPPNode(control(), res, type) ); + Node* cast = _gvn.transform( new CheckCastPPNode(control(), res, type) ); push(cast); // Possible improvements: diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/parseHelper.cpp --- a/hotspot/src/share/vm/opto/parseHelper.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/parseHelper.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -43,7 +43,7 @@ const char *call_name = is_entry ? "dtrace_method_entry" : "dtrace_method_exit"; // Get base of thread-local storage area - Node* thread = _gvn.transform( new (C) ThreadLocalNode() ); + Node* thread = _gvn.transform( new ThreadLocalNode() ); // Get method const TypePtr* method_type = TypeMetadataPtr::make(method); @@ -175,8 +175,8 @@ // Make a constant out of the inexact array klass const TypeKlassPtr *extak = tak->cast_to_exactness(true)->is_klassptr(); Node* con = makecon(extak); - Node* cmp = _gvn.transform(new (C) CmpPNode( array_klass, con )); - Node* bol = _gvn.transform(new (C) BoolNode( cmp, BoolTest::eq )); + Node* cmp = _gvn.transform(new CmpPNode( array_klass, con )); + Node* bol = _gvn.transform(new BoolNode( cmp, BoolTest::eq )); Node* ctrl= control(); { BuildCutout unless(this, bol, PROB_MAX); uncommon_trap(Deoptimization::Reason_array_check, @@ -215,8 +215,8 @@ // if (klass->_init_thread != current_thread || // klass->_init_state != being_initialized) // uncommon_trap - Node* cur_thread = _gvn.transform( new (C) ThreadLocalNode() ); - Node* merge = new (C) RegionNode(3); + Node* cur_thread = _gvn.transform( new ThreadLocalNode() ); + Node* merge = new RegionNode(3); _gvn.set_type(merge, Type::CONTROL); Node* kls = makecon(TypeKlassPtr::make(klass)); @@ -327,9 +327,9 @@ // Test invocation count vs threshold Node *threshold = makecon(TypeInt::make(limit)); - Node *chk = _gvn.transform( new (C) CmpUNode( cnt, threshold) ); + Node *chk = _gvn.transform( new CmpUNode( cnt, threshold) ); BoolTest::mask btest = BoolTest::lt; - Node *tst = _gvn.transform( new (C) BoolNode( chk, btest) ); + Node *tst = _gvn.transform( new BoolNode( chk, btest) ); // Branch to failure if threshold exceeded { BuildCutout unless(this, tst, PROB_ALWAYS); uncommon_trap(Deoptimization::Reason_age, @@ -359,7 +359,7 @@ test_counter_against_threshold(cnt, limit); // Add one to the counter and store - Node* incr = _gvn.transform(new (C) AddINode(cnt, _gvn.intcon(1))); + Node* incr = _gvn.transform(new AddINode(cnt, _gvn.intcon(1))); store_to_memory(ctrl, adr_iic_node, incr, T_INT, adr_type, MemNode::unordered); } @@ -380,8 +380,8 @@ if (stride != 0) { Node* str = _gvn.MakeConX(stride); - Node* scale = _gvn.transform( new (C) MulXNode( idx, str ) ); - ptr = _gvn.transform( new (C) AddPNode( mdo, ptr, scale ) ); + Node* scale = _gvn.transform( new MulXNode( idx, str ) ); + ptr = _gvn.transform( new AddPNode( mdo, ptr, scale ) ); } return ptr; @@ -393,7 +393,7 @@ const TypePtr* adr_type = _gvn.type(adr_node)->is_ptr(); Node* cnt = make_load(NULL, adr_node, TypeInt::INT, T_INT, adr_type, MemNode::unordered); - Node* incr = _gvn.transform(new (C) AddINode(cnt, _gvn.intcon(DataLayout::counter_increment))); + Node* incr = _gvn.transform(new AddINode(cnt, _gvn.intcon(DataLayout::counter_increment))); store_to_memory(NULL, adr_node, incr, T_INT, adr_type, MemNode::unordered); } @@ -413,7 +413,7 @@ const TypePtr* adr_type = _gvn.type(adr_node)->is_ptr(); Node* flags = make_load(NULL, adr_node, TypeInt::BYTE, T_BYTE, adr_type, MemNode::unordered); - Node* incr = _gvn.transform(new (C) OrINode(flags, _gvn.intcon(flag_constant))); + Node* incr = _gvn.transform(new OrINode(flags, _gvn.intcon(flag_constant))); store_to_memory(NULL, adr_node, incr, T_BYTE, adr_type, MemNode::unordered); } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/phaseX.cpp --- a/hotspot/src/share/vm/opto/phaseX.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/phaseX.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -47,7 +47,7 @@ _total_insert_probes(0), _total_inserts(0), _insert_probes(0), _grows(0) { // _sentinel must be in the current node space - _sentinel = new (Compile::current()) ProjNode(NULL, TypeFunc::Control); + _sentinel = new ProjNode(NULL, TypeFunc::Control); memset(_table,0,sizeof(Node*)*_max); } @@ -62,7 +62,7 @@ _total_insert_probes(0), _total_inserts(0), _insert_probes(0), _grows(0) { // _sentinel must be in the current node space - _sentinel = new (Compile::current()) ProjNode(NULL, TypeFunc::Control); + _sentinel = new ProjNode(NULL, TypeFunc::Control); memset(_table,0,sizeof(Node*)*_max); } @@ -1309,7 +1309,7 @@ } // Smash all inputs to 'old', isolating him completely - Node *temp = new (C) Node(1); + Node *temp = new Node(1); temp->init_req(0,nn); // Add a use to nn to prevent him from dying remove_dead_node( old ); temp->del_req(0); // Yank bogus edge diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/reg_split.cpp --- a/hotspot/src/share/vm/opto/reg_split.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/reg_split.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -93,7 +93,7 @@ // Here we assume a trip through memory is required. w_i_mask = &C->FIRST_STACK_mask(); } - return new (C) MachSpillCopyNode(spill_type, def, *w_i_mask, *w_o_mask ); + return new MachSpillCopyNode(spill_type, def, *w_i_mask, *w_o_mask ); } //------------------------------insert_proj------------------------------------ @@ -663,7 +663,7 @@ // create a new phi node and insert it into the block // type is taken from left over pointer to a predecessor assert(n3,"No non-NULL reaching DEF for a Phi"); - phi = new (C) PhiNode(b->head(), n3->bottom_type()); + phi = new PhiNode(b->head(), n3->bottom_type()); // initialize the Reaches entry for this LRG Reachblock[slidx] = phi; @@ -1075,7 +1075,7 @@ // First Split-UP to move value into Register uint def_ideal = def->ideal_reg(); const RegMask* tmp_rm = Matcher::idealreg2regmask[def_ideal]; - Node *spill = new (C) MachSpillCopyNode(MachSpillCopyNode::MemToReg, def, dmask, *tmp_rm); + Node *spill = new MachSpillCopyNode(MachSpillCopyNode::MemToReg, def, dmask, *tmp_rm); insert_proj( b, insidx, spill, maxlrg ); // Then Split-DOWN as if previous Split was DEF maxlrg = split_USE(MachSpillCopyNode::RegToMem, spill,b,n,inpidx,maxlrg,false,false, splits,slidx); @@ -1229,7 +1229,7 @@ if (C->check_node_count(NodeLimitFudgeFactor, out_of_nodes)) { // Check when generating nodes return 0; } - Node *spill = new (C) MachSpillCopyNode(MachSpillCopyNode::MemToReg, use,use_rm,def_rm); + Node *spill = new MachSpillCopyNode(MachSpillCopyNode::MemToReg, use,use_rm,def_rm); n->set_req(copyidx,spill); n->as_MachSpillCopy()->set_in_RegMask(def_rm); // Put the spill just before the copy diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/replacednodes.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/opto/replacednodes.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "opto/cfgnode.hpp" +#include "opto/phaseX.hpp" +#include "opto/replacednodes.hpp" + +void ReplacedNodes::allocate_if_necessary() { + if (_replaced_nodes == NULL) { + _replaced_nodes = new GrowableArray(); + } +} + +bool ReplacedNodes::is_empty() const { + return _replaced_nodes == NULL || _replaced_nodes->length() == 0; +} + +bool ReplacedNodes::has_node(const ReplacedNode& r) const { + return _replaced_nodes->find(r) != -1; +} + +bool ReplacedNodes::has_target_node(Node* n) const { + for (int i = 0; i < _replaced_nodes->length(); i++) { + if (_replaced_nodes->at(i).improved() == n) { + return true; + } + } + return false; +} + +// Record replaced node if not seen before +void ReplacedNodes::record(Node* initial, Node* improved) { + allocate_if_necessary(); + ReplacedNode r(initial, improved); + if (!has_node(r)) { + _replaced_nodes->push(r); + } +} + +// Copy replaced nodes from one map to another. idx is used to +// identify nodes that are too new to be of interest in the target +// node list. +void ReplacedNodes::transfer_from(const ReplacedNodes& other, uint idx) { + if (other.is_empty()) { + return; + } + allocate_if_necessary(); + for (int i = 0; i < other._replaced_nodes->length(); i++) { + ReplacedNode replaced = other._replaced_nodes->at(i); + // Only transfer the nodes that can actually be useful + if (!has_node(replaced) && (replaced.initial()->_idx < idx || has_target_node(replaced.initial()))) { + _replaced_nodes->push(replaced); + } + } +} + +void ReplacedNodes::clone() { + if (_replaced_nodes != NULL) { + GrowableArray* replaced_nodes_clone = new GrowableArray(); + replaced_nodes_clone->appendAll(_replaced_nodes); + _replaced_nodes = replaced_nodes_clone; + } +} + +void ReplacedNodes::reset() { + if (_replaced_nodes != NULL) { + _replaced_nodes->clear(); + } +} + +// Perfom node replacement (used when returning to caller) +void ReplacedNodes::apply(Node* n) { + if (is_empty()) { + return; + } + for (int i = 0; i < _replaced_nodes->length(); i++) { + ReplacedNode replaced = _replaced_nodes->at(i); + n->replace_edge(replaced.initial(), replaced.improved()); + } +} + +static void enqueue_use(Node* n, Node* use, Unique_Node_List& work) { + if (use->is_Phi()) { + Node* r = use->in(0); + assert(r->is_Region(), "Phi should have Region"); + for (uint i = 1; i < use->req(); i++) { + if (use->in(i) == n) { + work.push(r->in(i)); + } + } + } else { + work.push(use); + } +} + +// Perfom node replacement following late inlining +void ReplacedNodes::apply(Compile* C, Node* ctl) { + // ctl is the control on exit of the method that was late inlined + if (is_empty()) { + return; + } + for (int i = 0; i < _replaced_nodes->length(); i++) { + ReplacedNode replaced = _replaced_nodes->at(i); + Node* initial = replaced.initial(); + Node* improved = replaced.improved(); + assert (ctl != NULL && !ctl->is_top(), "replaced node should have actual control"); + + ResourceMark rm; + Unique_Node_List work; + // Go over all the uses of the node that is considered for replacement... + for (DUIterator j = initial->outs(); initial->has_out(j); j++) { + Node* use = initial->out(j); + + if (use == improved || use->outcnt() == 0) { + continue; + } + work.clear(); + enqueue_use(initial, use, work); + bool replace = true; + // Check that this use is dominated by ctl. Go ahead with the + // replacement if it is. + while (work.size() != 0 && replace) { + Node* n = work.pop(); + if (use->outcnt() == 0) { + continue; + } + if (n->is_CFG() || (n->in(0) != NULL && !n->in(0)->is_top())) { + int depth = 0; + Node *m = n; + if (!n->is_CFG()) { + n = n->in(0); + } + assert(n->is_CFG(), "should be CFG now"); + while(n != ctl) { + n = IfNode::up_one_dom(n); + depth++; + // limit search depth + if (depth >= 100 || n == NULL) { + replace = false; + break; + } + } + } else { + for (DUIterator k = n->outs(); n->has_out(k); k++) { + enqueue_use(n, n->out(k), work); + } + } + } + if (replace) { + bool is_in_table = C->initial_gvn()->hash_delete(use); + int replaced = use->replace_edge(initial, improved); + if (is_in_table) { + C->initial_gvn()->hash_find_insert(use); + } + C->record_for_igvn(use); + + assert(replaced > 0, "inconsistent"); + --j; + } + } + } +} + +void ReplacedNodes::dump(outputStream *st) const { + if (!is_empty()) { + tty->print("replaced nodes: "); + for (int i = 0; i < _replaced_nodes->length(); i++) { + tty->print("%d->%d", _replaced_nodes->at(i).initial()->_idx, _replaced_nodes->at(i).improved()->_idx); + if (i < _replaced_nodes->length()-1) { + tty->print(","); + } + } + } +} + +// Merge 2 list of replaced node at a point where control flow paths merge +void ReplacedNodes::merge_with(const ReplacedNodes& other) { + if (is_empty()) { + return; + } + if (other.is_empty()) { + reset(); + return; + } + int shift = 0; + int len = _replaced_nodes->length(); + for (int i = 0; i < len; i++) { + if (!other.has_node(_replaced_nodes->at(i))) { + shift++; + } else if (shift > 0) { + _replaced_nodes->at_put(i-shift, _replaced_nodes->at(i)); + } + } + if (shift > 0) { + _replaced_nodes->trunc_to(len - shift); + } +} diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/replacednodes.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/opto/replacednodes.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_OPTO_REPLACEDNODES_HPP +#define SHARE_VM_OPTO_REPLACEDNODES_HPP + +#include "opto/connode.hpp" + +// During parsing, when a node is "improved", +// GraphKit::replace_in_map() is called to update the current map so +// that the improved node is used from that point +// on. GraphKit::replace_in_map() doesn't operate on the callers maps +// and so some optimization opportunities may be lost. The +// ReplacedNodes class addresses that problem. +// +// A ReplacedNodes object is a list of pair of nodes. Every +// SafePointNode carries a ReplacedNodes object. Every time +// GraphKit::replace_in_map() is called, a new pair of nodes is pushed +// on the list of replaced nodes. When control flow paths merge, their +// replaced nodes are also merged. When parsing exits a method to +// return to a caller, the replaced nodes on the exit path are used to +// update the caller's map. +class ReplacedNodes VALUE_OBJ_CLASS_SPEC { + private: + class ReplacedNode VALUE_OBJ_CLASS_SPEC { + private: + Node* _initial; + Node* _improved; + public: + ReplacedNode() : _initial(NULL), _improved(NULL) {} + ReplacedNode(Node* initial, Node* improved) : _initial(initial), _improved(improved) {} + Node* initial() const { return _initial; } + Node* improved() const { return _improved; } + + bool operator==(const ReplacedNode& other) { + return _initial == other._initial && _improved == other._improved; + } + }; + GrowableArray* _replaced_nodes; + + void allocate_if_necessary(); + bool has_node(const ReplacedNode& r) const; + bool has_target_node(Node* n) const; + + public: + ReplacedNodes() + : _replaced_nodes(NULL) {} + + void clone(); + void record(Node* initial, Node* improved); + void transfer_from(const ReplacedNodes& other, uint idx); + void reset(); + void apply(Node* n); + void merge_with(const ReplacedNodes& other); + bool is_empty() const; + void dump(outputStream *st) const; + void apply(Compile* C, Node* ctl); +}; + +#endif // SHARE_VM_OPTO_REPLACEDNODES_HPP diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/runtime.cpp --- a/hotspot/src/share/vm/opto/runtime.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/runtime.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -896,6 +896,50 @@ return TypeFunc::make(domain, range); } +/* + * void implCompress(byte[] buf, int ofs) + */ +const TypeFunc* OptoRuntime::sha_implCompress_Type() { + // create input type (domain) + int num_args = 2; + int argcnt = num_args; + const Type** fields = TypeTuple::fields(argcnt); + int argp = TypeFunc::Parms; + fields[argp++] = TypePtr::NOTNULL; // buf + fields[argp++] = TypePtr::NOTNULL; // state + assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); + const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); + + // no result type needed + fields = TypeTuple::fields(1); + fields[TypeFunc::Parms+0] = NULL; // void + const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields); + return TypeFunc::make(domain, range); +} + +/* + * int implCompressMultiBlock(byte[] b, int ofs, int limit) + */ +const TypeFunc* OptoRuntime::digestBase_implCompressMB_Type() { + // create input type (domain) + int num_args = 4; + int argcnt = num_args; + const Type** fields = TypeTuple::fields(argcnt); + int argp = TypeFunc::Parms; + fields[argp++] = TypePtr::NOTNULL; // buf + fields[argp++] = TypePtr::NOTNULL; // state + fields[argp++] = TypeInt::INT; // ofs + fields[argp++] = TypeInt::INT; // limit + assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); + const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); + + // returning ofs (int) + fields = TypeTuple::fields(1); + fields[TypeFunc::Parms+0] = TypeInt::INT; // ofs + const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields); + return TypeFunc::make(domain, range); +} + //------------- Interpreter state access for on stack replacement const TypeFunc* OptoRuntime::osr_end_Type() { // create input type (domain) diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/runtime.hpp --- a/hotspot/src/share/vm/opto/runtime.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/runtime.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -300,6 +300,9 @@ static const TypeFunc* aescrypt_block_Type(); static const TypeFunc* cipherBlockChaining_aescrypt_Type(); + static const TypeFunc* sha_implCompress_Type(); + static const TypeFunc* digestBase_implCompressMB_Type(); + static const TypeFunc* updateBytesCRC32_Type(); // leaf on stack replacement interpreter accessor types diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/split_if.cpp --- a/hotspot/src/share/vm/opto/split_if.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/split_if.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -35,7 +35,7 @@ uint wins = 0; assert( n->is_CFG(), "" ); assert( region->is_Region(), "" ); - Node *r = new (C) RegionNode( region->req() ); + Node *r = new RegionNode( region->req() ); IdealLoopTree *loop = get_loop( n ); for( uint i = 1; i < region->req(); i++ ) { Node *x = n->clone(); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/stringopts.cpp --- a/hotspot/src/share/vm/opto/stringopts.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/stringopts.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -70,7 +70,7 @@ _multiple(false), _string_alloc(NULL), _stringopts(stringopts) { - _arguments = new (_stringopts->C) Node(1); + _arguments = new Node(1); _arguments->del_req(0); } @@ -228,8 +228,8 @@ const TypeFunc* call_type = OptoRuntime::uncommon_trap_Type(); const TypePtr* no_memory_effects = NULL; Compile* C = _stringopts->C; - CallStaticJavaNode* call = new (C) CallStaticJavaNode(call_type, call_addr, "uncommon_trap", - jvms->bci(), no_memory_effects); + CallStaticJavaNode* call = new CallStaticJavaNode(call_type, call_addr, "uncommon_trap", + jvms->bci(), no_memory_effects); for (int e = 0; e < TypeFunc::Parms; e++) { call->init_req(e, uct->in(e)); } @@ -1127,9 +1127,9 @@ } Node* PhaseStringOpts::int_stringSize(GraphKit& kit, Node* arg) { - RegionNode *final_merge = new (C) RegionNode(3); + RegionNode *final_merge = new RegionNode(3); kit.gvn().set_type(final_merge, Type::CONTROL); - Node* final_size = new (C) PhiNode(final_merge, TypeInt::INT); + Node* final_size = new PhiNode(final_merge, TypeInt::INT); kit.gvn().set_type(final_size, TypeInt::INT); IfNode* iff = kit.create_and_map_if(kit.control(), @@ -1146,11 +1146,11 @@ } else { // int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i); - RegionNode *r = new (C) RegionNode(3); + RegionNode *r = new RegionNode(3); kit.gvn().set_type(r, Type::CONTROL); - Node *phi = new (C) PhiNode(r, TypeInt::INT); + Node *phi = new PhiNode(r, TypeInt::INT); kit.gvn().set_type(phi, TypeInt::INT); - Node *size = new (C) PhiNode(r, TypeInt::INT); + Node *size = new PhiNode(r, TypeInt::INT); kit.gvn().set_type(size, TypeInt::INT); Node* chk = __ CmpI(arg, __ intcon(0)); Node* p = __ Bool(chk, BoolTest::lt); @@ -1175,11 +1175,11 @@ // Add loop predicate first. kit.add_predicate(); - RegionNode *loop = new (C) RegionNode(3); + RegionNode *loop = new RegionNode(3); loop->init_req(1, kit.control()); kit.gvn().set_type(loop, Type::CONTROL); - Node *index = new (C) PhiNode(loop, TypeInt::INT); + Node *index = new PhiNode(loop, TypeInt::INT); index->init_req(1, __ intcon(0)); kit.gvn().set_type(index, TypeInt::INT); kit.set_control(loop); @@ -1212,7 +1212,7 @@ } void PhaseStringOpts::int_getChars(GraphKit& kit, Node* arg, Node* char_array, Node* start, Node* end) { - RegionNode *final_merge = new (C) RegionNode(4); + RegionNode *final_merge = new RegionNode(4); kit.gvn().set_type(final_merge, Type::CONTROL); Node *final_mem = PhiNode::make(final_merge, kit.memory(char_adr_idx), Type::MEMORY, TypeAryPtr::CHARS); kit.gvn().set_type(final_mem, Type::MEMORY); @@ -1262,11 +1262,11 @@ __ Bool(__ CmpI(arg, __ intcon(0)), BoolTest::lt), PROB_FAIR, COUNT_UNKNOWN); - RegionNode *merge = new (C) RegionNode(3); + RegionNode *merge = new RegionNode(3); kit.gvn().set_type(merge, Type::CONTROL); - i = new (C) PhiNode(merge, TypeInt::INT); + i = new PhiNode(merge, TypeInt::INT); kit.gvn().set_type(i, TypeInt::INT); - sign = new (C) PhiNode(merge, TypeInt::INT); + sign = new PhiNode(merge, TypeInt::INT); kit.gvn().set_type(sign, TypeInt::INT); merge->init_req(1, __ IfTrue(iff)); @@ -1295,10 +1295,10 @@ // Add loop predicate first. kit.add_predicate(); - RegionNode *head = new (C) RegionNode(3); + RegionNode *head = new RegionNode(3); head->init_req(1, kit.control()); kit.gvn().set_type(head, Type::CONTROL); - Node *i_phi = new (C) PhiNode(head, TypeInt::INT); + Node *i_phi = new PhiNode(head, TypeInt::INT); i_phi->init_req(1, i); kit.gvn().set_type(i_phi, TypeInt::INT); charPos = PhiNode::make(head, charPos); @@ -1420,7 +1420,7 @@ // as a shim for the insertion of the new code. JVMState* jvms = sc->begin()->jvms()->clone_shallow(C); uint size = sc->begin()->req(); - SafePointNode* map = new (C) SafePointNode(size, jvms); + SafePointNode* map = new SafePointNode(size, jvms); // copy the control and memory state from the final call into our // new starting state. This allows any preceeding tests to feed @@ -1465,12 +1465,12 @@ // Create a region for the overflow checks to merge into. int args = MAX2(sc->num_arguments(), 1); - RegionNode* overflow = new (C) RegionNode(args); + RegionNode* overflow = new RegionNode(args); kit.gvn().set_type(overflow, Type::CONTROL); // Create a hook node to hold onto the individual sizes since they // are need for the copying phase. - Node* string_sizes = new (C) Node(args); + Node* string_sizes = new Node(args); Node* length = __ intcon(0); for (int argi = 0; argi < sc->num_arguments(); argi++) { @@ -1514,9 +1514,9 @@ } else if (!type->higher_equal(TypeInstPtr::NOTNULL)) { // s = s != null ? s : "null"; // length = length + (s.count - s.offset); - RegionNode *r = new (C) RegionNode(3); + RegionNode *r = new RegionNode(3); kit.gvn().set_type(r, Type::CONTROL); - Node *phi = new (C) PhiNode(r, type); + Node *phi = new PhiNode(r, type); kit.gvn().set_type(phi, phi->bottom_type()); Node* p = __ Bool(__ CmpP(arg, kit.null()), BoolTest::ne); IfNode* iff = kit.create_and_map_if(kit.control(), p, PROB_MIN, COUNT_UNKNOWN); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/subnode.cpp --- a/hotspot/src/share/vm/opto/subnode.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/subnode.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -159,7 +159,7 @@ if( t2->base() == Type::Int ){ // Might be bottom or top... const TypeInt *i = t2->is_int(); if( i->is_con() ) - return new (phase->C) AddINode(in1, phase->intcon(-i->get_con())); + return new AddINode(in1, phase->intcon(-i->get_con())); } // Convert "(x+c0) - y" into (x-y) + c0" @@ -168,8 +168,8 @@ if( op1 == Op_AddI && ok_to_convert(in1, in2) ) { const Type *tadd = phase->type( in1->in(2) ); if( tadd->singleton() && tadd != Type::TOP ) { - Node *sub2 = phase->transform( new (phase->C) SubINode( in1->in(1), in2 )); - return new (phase->C) AddINode( sub2, in1->in(2) ); + Node *sub2 = phase->transform( new SubINode( in1->in(1), in2 )); + return new AddINode( sub2, in1->in(2) ); } } @@ -181,9 +181,9 @@ Node* in22 = in2->in(2); const TypeInt* tcon = phase->type(in22)->isa_int(); if (tcon != NULL && tcon->is_con()) { - Node* sub2 = phase->transform( new (phase->C) SubINode(in1, in21) ); + Node* sub2 = phase->transform( new SubINode(in1, in21) ); Node* neg_c0 = phase->intcon(- tcon->get_con()); - return new (phase->C) AddINode(sub2, neg_c0); + return new AddINode(sub2, neg_c0); } } @@ -201,47 +201,47 @@ // Convert "x - (x+y)" into "-y" if( op2 == Op_AddI && phase->eqv( in1, in2->in(1) ) ) - return new (phase->C) SubINode( phase->intcon(0),in2->in(2)); + return new SubINode( phase->intcon(0),in2->in(2)); // Convert "(x-y) - x" into "-y" if( op1 == Op_SubI && phase->eqv( in1->in(1), in2 ) ) - return new (phase->C) SubINode( phase->intcon(0),in1->in(2)); + return new SubINode( phase->intcon(0),in1->in(2)); // Convert "x - (y+x)" into "-y" if( op2 == Op_AddI && phase->eqv( in1, in2->in(2) ) ) - return new (phase->C) SubINode( phase->intcon(0),in2->in(1)); + return new SubINode( phase->intcon(0),in2->in(1)); // Convert "0 - (x-y)" into "y-x" if( t1 == TypeInt::ZERO && op2 == Op_SubI ) - return new (phase->C) SubINode( in2->in(2), in2->in(1) ); + return new SubINode( in2->in(2), in2->in(1) ); // Convert "0 - (x+con)" into "-con-x" jint con; if( t1 == TypeInt::ZERO && op2 == Op_AddI && (con = in2->in(2)->find_int_con(0)) != 0 ) - return new (phase->C) SubINode( phase->intcon(-con), in2->in(1) ); + return new SubINode( phase->intcon(-con), in2->in(1) ); // Convert "(X+A) - (X+B)" into "A - B" if( op1 == Op_AddI && op2 == Op_AddI && in1->in(1) == in2->in(1) ) - return new (phase->C) SubINode( in1->in(2), in2->in(2) ); + return new SubINode( in1->in(2), in2->in(2) ); // Convert "(A+X) - (B+X)" into "A - B" if( op1 == Op_AddI && op2 == Op_AddI && in1->in(2) == in2->in(2) ) - return new (phase->C) SubINode( in1->in(1), in2->in(1) ); + return new SubINode( in1->in(1), in2->in(1) ); // Convert "(A+X) - (X+B)" into "A - B" if( op1 == Op_AddI && op2 == Op_AddI && in1->in(2) == in2->in(1) ) - return new (phase->C) SubINode( in1->in(1), in2->in(2) ); + return new SubINode( in1->in(1), in2->in(2) ); // Convert "(X+A) - (B+X)" into "A - B" if( op1 == Op_AddI && op2 == Op_AddI && in1->in(1) == in2->in(2) ) - return new (phase->C) SubINode( in1->in(2), in2->in(1) ); + return new SubINode( in1->in(2), in2->in(1) ); // Convert "A-(B-C)" into (A+C)-B", since add is commutative and generally // nicer to optimize than subtract. if( op2 == Op_SubI && in2->outcnt() == 1) { - Node *add1 = phase->transform( new (phase->C) AddINode( in1, in2->in(2) ) ); - return new (phase->C) SubINode( add1, in2->in(1) ); + Node *add1 = phase->transform( new AddINode( in1, in2->in(2) ) ); + return new SubINode( add1, in2->in(1) ); } return NULL; @@ -288,7 +288,7 @@ // Convert "x-c0" into "x+ -c0". if( i && // Might be bottom or top... i->is_con() ) - return new (phase->C) AddLNode(in1, phase->longcon(-i->get_con())); + return new AddLNode(in1, phase->longcon(-i->get_con())); // Convert "(x+c0) - y" into (x-y) + c0" // Do not collapse (x+c0)-y if "+" is a loop increment or @@ -297,8 +297,8 @@ Node *in11 = in1->in(1); const Type *tadd = phase->type( in1->in(2) ); if( tadd->singleton() && tadd != Type::TOP ) { - Node *sub2 = phase->transform( new (phase->C) SubLNode( in11, in2 )); - return new (phase->C) AddLNode( sub2, in1->in(2) ); + Node *sub2 = phase->transform( new SubLNode( in11, in2 )); + return new AddLNode( sub2, in1->in(2) ); } } @@ -309,9 +309,9 @@ Node* in22 = in2->in(2); const TypeLong* tcon = phase->type(in22)->isa_long(); if (tcon != NULL && tcon->is_con()) { - Node* sub2 = phase->transform( new (phase->C) SubLNode(in1, in21) ); + Node* sub2 = phase->transform( new SubLNode(in1, in21) ); Node* neg_c0 = phase->longcon(- tcon->get_con()); - return new (phase->C) AddLNode(sub2, neg_c0); + return new AddLNode(sub2, neg_c0); } } @@ -329,28 +329,28 @@ // Convert "x - (x+y)" into "-y" if( op2 == Op_AddL && phase->eqv( in1, in2->in(1) ) ) - return new (phase->C) SubLNode( phase->makecon(TypeLong::ZERO), in2->in(2)); + return new SubLNode( phase->makecon(TypeLong::ZERO), in2->in(2)); // Convert "x - (y+x)" into "-y" if( op2 == Op_AddL && phase->eqv( in1, in2->in(2) ) ) - return new (phase->C) SubLNode( phase->makecon(TypeLong::ZERO),in2->in(1)); + return new SubLNode( phase->makecon(TypeLong::ZERO),in2->in(1)); // Convert "0 - (x-y)" into "y-x" if( phase->type( in1 ) == TypeLong::ZERO && op2 == Op_SubL ) - return new (phase->C) SubLNode( in2->in(2), in2->in(1) ); + return new SubLNode( in2->in(2), in2->in(1) ); // Convert "(X+A) - (X+B)" into "A - B" if( op1 == Op_AddL && op2 == Op_AddL && in1->in(1) == in2->in(1) ) - return new (phase->C) SubLNode( in1->in(2), in2->in(2) ); + return new SubLNode( in1->in(2), in2->in(2) ); // Convert "(A+X) - (B+X)" into "A - B" if( op1 == Op_AddL && op2 == Op_AddL && in1->in(2) == in2->in(2) ) - return new (phase->C) SubLNode( in1->in(1), in2->in(1) ); + return new SubLNode( in1->in(1), in2->in(1) ); // Convert "A-(B-C)" into (A+C)-B" if( op2 == Op_SubL && in2->outcnt() == 1) { - Node *add1 = phase->transform( new (phase->C) AddLNode( in1, in2->in(2) ) ); - return new (phase->C) SubLNode( add1, in2->in(1) ); + Node *add1 = phase->transform( new AddLNode( in1, in2->in(2) ) ); + return new SubLNode( add1, in2->in(1) ); } return NULL; @@ -417,7 +417,7 @@ // Convert "x - (x+y)" into "-y" if( in(2)->is_Add() && phase->eqv(in(1),in(2)->in(1) ) ) - return new (phase->C) SubFNode( phase->makecon(TypeF::ZERO),in(2)->in(2)); + return new SubFNode( phase->makecon(TypeF::ZERO),in(2)->in(2)); } // Cannot replace 0.0-X with -X because a 'fsub' bytecode computes @@ -460,7 +460,7 @@ // Convert "x - (x+y)" into "-y" if( in(2)->is_Add() && phase->eqv(in(1),in(2)->in(1) ) ) - return new (phase->C) SubDNode( phase->makecon(TypeD::ZERO),in(2)->in(2)); + return new SubDNode( phase->makecon(TypeD::ZERO),in(2)->in(2)); } // Cannot replace 0.0-X with -X because a 'dsub' bytecode computes @@ -666,11 +666,11 @@ if (phase->type(in(2))->higher_equal(TypeInt::ZERO)) { switch (in(1)->Opcode()) { case Op_CmpL3: // Collapse a CmpL3/CmpI into a CmpL - return new (phase->C) CmpLNode(in(1)->in(1),in(1)->in(2)); + return new CmpLNode(in(1)->in(1),in(1)->in(2)); case Op_CmpF3: // Collapse a CmpF3/CmpI into a CmpF - return new (phase->C) CmpFNode(in(1)->in(1),in(1)->in(2)); + return new CmpFNode(in(1)->in(1),in(1)->in(2)); case Op_CmpD3: // Collapse a CmpD3/CmpI into a CmpD - return new (phase->C) CmpDNode(in(1)->in(1),in(1)->in(2)); + return new CmpDNode(in(1)->in(1),in(1)->in(2)); //case Op_SubI: // If (x - y) cannot overflow, then ((x - y) 0) // can be turned into (x y). @@ -1109,8 +1109,8 @@ new_in2 = tmp; } CmpFNode *new_cmp = (Opcode() == Op_CmpD3) - ? new (phase->C) CmpF3Node( new_in1, new_in2 ) - : new (phase->C) CmpFNode ( new_in1, new_in2 ) ; + ? new CmpF3Node( new_in1, new_in2 ) + : new CmpFNode ( new_in1, new_in2 ) ; return new_cmp; // Changed to CmpFNode } // Testing value required the precision of a double @@ -1182,9 +1182,9 @@ // Else fall through. The CMove gets in the way of the test. // It should be the case that make_predicate(bol->as_int_value()) == bol. } - Node* cmp = new (C) CmpINode(test_value, phase->intcon(0)); + Node* cmp = new CmpINode(test_value, phase->intcon(0)); cmp = phase->transform(cmp); - Node* bol = new (C) BoolNode(cmp, BoolTest::ne); + Node* bol = new BoolNode(cmp, BoolTest::ne); return phase->transform(bol); } @@ -1200,7 +1200,7 @@ //----------------------------------negate------------------------------------- BoolNode* BoolNode::negate(PhaseGVN* phase) { Compile* C = phase->C; - return new (C) BoolNode(in(1), _test.negate()); + return new BoolNode(in(1), _test.negate()); } @@ -1238,7 +1238,7 @@ // Swap inputs to the clone cmp->swap_edges(1, 2); cmp = phase->transform( cmp ); - return new (phase->C) BoolNode( cmp, _test.commute() ); + return new BoolNode( cmp, _test.commute() ); } // Change "bool eq/ne (cmp (xor X 1) 0)" into "bool ne/eq (cmp X 0)". @@ -1255,8 +1255,8 @@ phase->type( j_xor->in(2) ) == TypeInt::ONE && (_test._test == BoolTest::eq || _test._test == BoolTest::ne) ) { - Node *ncmp = phase->transform(new (phase->C) CmpINode(j_xor->in(1),cmp2)); - return new (phase->C) BoolNode( ncmp, _test.negate() ); + Node *ncmp = phase->transform(new CmpINode(j_xor->in(1),cmp2)); + return new BoolNode( ncmp, _test.negate() ); } // Change "bool eq/ne (cmp (Conv2B X) 0)" into "bool eq/ne (cmp X 0)". @@ -1267,10 +1267,10 @@ (_test._test == BoolTest::eq || _test._test == BoolTest::ne) ) { Node *ncmp = phase->transform(phase->type(c2b->in(1))->isa_int() - ? (Node*)new (phase->C) CmpINode(c2b->in(1),cmp2) - : (Node*)new (phase->C) CmpPNode(c2b->in(1),phase->makecon(TypePtr::NULL_PTR)) + ? (Node*)new CmpINode(c2b->in(1),cmp2) + : (Node*)new CmpPNode(c2b->in(1),phase->makecon(TypePtr::NULL_PTR)) ); - return new (phase->C) BoolNode( ncmp, _test._test ); + return new BoolNode( ncmp, _test._test ); } // Comparing a SubI against a zero is equal to comparing the SubI @@ -1280,8 +1280,8 @@ (cop == Op_CmpI) && (cmp1->Opcode() == Op_SubI) && ( cmp2_type == TypeInt::ZERO ) ) { - Node *ncmp = phase->transform( new (phase->C) CmpINode(cmp1->in(1),cmp1->in(2))); - return new (phase->C) BoolNode( ncmp, _test._test ); + Node *ncmp = phase->transform( new CmpINode(cmp1->in(1),cmp1->in(2))); + return new BoolNode( ncmp, _test._test ); } // Change (-A vs 0) into (A vs 0) by commuting the test. Disallow in the @@ -1292,8 +1292,8 @@ cmp2_type == TypeInt::ZERO && phase->type( cmp1->in(1) ) == TypeInt::ZERO && phase->type( cmp1->in(2) )->higher_equal(TypeInt::SYMINT) ) { - Node *ncmp = phase->transform( new (phase->C) CmpINode(cmp1->in(2),cmp2)); - return new (phase->C) BoolNode( ncmp, _test.commute() ); + Node *ncmp = phase->transform( new CmpINode(cmp1->in(2),cmp2)); + return new BoolNode( ncmp, _test.commute() ); } // The transformation below is not valid for either signed or unsigned diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/superword.cpp --- a/hotspot/src/share/vm/opto/superword.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/superword.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -1456,7 +1456,7 @@ if (t == NULL || t->_lo < 0 || t->_hi > (int)mask) { cnt = ConNode::make(C, TypeInt::make(mask)); _igvn.register_new_node_with_optimizer(cnt); - cnt = new (C) AndINode(opd, cnt); + cnt = new AndINode(opd, cnt); _igvn.register_new_node_with_optimizer(cnt); _phase->set_ctrl(cnt, _phase->get_ctrl(opd)); } @@ -2067,42 +2067,42 @@ if (align_to_ref_p.invar() != NULL) { // incorporate any extra invariant piece producing (offset +/- invar) >>> log2(elt) Node* log2_elt = _igvn.intcon(exact_log2(elt_size)); - Node* aref = new (_phase->C) URShiftINode(align_to_ref_p.invar(), log2_elt); + Node* aref = new URShiftINode(align_to_ref_p.invar(), log2_elt); _igvn.register_new_node_with_optimizer(aref); _phase->set_ctrl(aref, pre_ctrl); if (align_to_ref_p.negate_invar()) { - e = new (_phase->C) SubINode(e, aref); + e = new SubINode(e, aref); } else { - e = new (_phase->C) AddINode(e, aref); + e = new AddINode(e, aref); } _igvn.register_new_node_with_optimizer(e); _phase->set_ctrl(e, pre_ctrl); } if (vw > ObjectAlignmentInBytes) { // incorporate base e +/- base && Mask >>> log2(elt) - Node* xbase = new(_phase->C) CastP2XNode(NULL, align_to_ref_p.base()); + Node* xbase = new CastP2XNode(NULL, align_to_ref_p.base()); _igvn.register_new_node_with_optimizer(xbase); #ifdef _LP64 - xbase = new (_phase->C) ConvL2INode(xbase); + xbase = new ConvL2INode(xbase); _igvn.register_new_node_with_optimizer(xbase); #endif Node* mask = _igvn.intcon(vw-1); - Node* masked_xbase = new (_phase->C) AndINode(xbase, mask); + Node* masked_xbase = new AndINode(xbase, mask); _igvn.register_new_node_with_optimizer(masked_xbase); Node* log2_elt = _igvn.intcon(exact_log2(elt_size)); - Node* bref = new (_phase->C) URShiftINode(masked_xbase, log2_elt); + Node* bref = new URShiftINode(masked_xbase, log2_elt); _igvn.register_new_node_with_optimizer(bref); _phase->set_ctrl(bref, pre_ctrl); - e = new (_phase->C) AddINode(e, bref); + e = new AddINode(e, bref); _igvn.register_new_node_with_optimizer(e); _phase->set_ctrl(e, pre_ctrl); } // compute e +/- lim0 if (scale < 0) { - e = new (_phase->C) SubINode(e, lim0); + e = new SubINode(e, lim0); } else { - e = new (_phase->C) AddINode(e, lim0); + e = new AddINode(e, lim0); } _igvn.register_new_node_with_optimizer(e); _phase->set_ctrl(e, pre_ctrl); @@ -2110,13 +2110,13 @@ if (stride * scale > 0) { // compute V - (e +/- lim0) Node* va = _igvn.intcon(v_align); - e = new (_phase->C) SubINode(va, e); + e = new SubINode(va, e); _igvn.register_new_node_with_optimizer(e); _phase->set_ctrl(e, pre_ctrl); } // compute N = (exp) % V Node* va_msk = _igvn.intcon(v_align - 1); - Node* N = new (_phase->C) AndINode(e, va_msk); + Node* N = new AndINode(e, va_msk); _igvn.register_new_node_with_optimizer(N); _phase->set_ctrl(N, pre_ctrl); @@ -2124,15 +2124,15 @@ // lim = lim0 + N Node* lim; if (stride < 0) { - lim = new (_phase->C) SubINode(lim0, N); + lim = new SubINode(lim0, N); } else { - lim = new (_phase->C) AddINode(lim0, N); + lim = new AddINode(lim0, N); } _igvn.register_new_node_with_optimizer(lim); _phase->set_ctrl(lim, pre_ctrl); Node* constrained = - (stride > 0) ? (Node*) new (_phase->C) MinINode(lim, orig_limit) - : (Node*) new (_phase->C) MaxINode(lim, orig_limit); + (stride > 0) ? (Node*) new MinINode(lim, orig_limit) + : (Node*) new MaxINode(lim, orig_limit); _igvn.register_new_node_with_optimizer(constrained); _phase->set_ctrl(constrained, pre_ctrl); _igvn.hash_delete(pre_opaq); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/opto/vectornode.cpp --- a/hotspot/src/share/vm/opto/vectornode.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/vectornode.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -252,46 +252,46 @@ guarantee(vopc > 0, err_msg_res("Vector for '%s' is not implemented", NodeClassNames[opc])); switch (vopc) { - case Op_AddVB: return new (C) AddVBNode(n1, n2, vt); - case Op_AddVS: return new (C) AddVSNode(n1, n2, vt); - case Op_AddVI: return new (C) AddVINode(n1, n2, vt); - case Op_AddVL: return new (C) AddVLNode(n1, n2, vt); - case Op_AddVF: return new (C) AddVFNode(n1, n2, vt); - case Op_AddVD: return new (C) AddVDNode(n1, n2, vt); + case Op_AddVB: return new AddVBNode(n1, n2, vt); + case Op_AddVS: return new AddVSNode(n1, n2, vt); + case Op_AddVI: return new AddVINode(n1, n2, vt); + case Op_AddVL: return new AddVLNode(n1, n2, vt); + case Op_AddVF: return new AddVFNode(n1, n2, vt); + case Op_AddVD: return new AddVDNode(n1, n2, vt); - case Op_SubVB: return new (C) SubVBNode(n1, n2, vt); - case Op_SubVS: return new (C) SubVSNode(n1, n2, vt); - case Op_SubVI: return new (C) SubVINode(n1, n2, vt); - case Op_SubVL: return new (C) SubVLNode(n1, n2, vt); - case Op_SubVF: return new (C) SubVFNode(n1, n2, vt); - case Op_SubVD: return new (C) SubVDNode(n1, n2, vt); + case Op_SubVB: return new SubVBNode(n1, n2, vt); + case Op_SubVS: return new SubVSNode(n1, n2, vt); + case Op_SubVI: return new SubVINode(n1, n2, vt); + case Op_SubVL: return new SubVLNode(n1, n2, vt); + case Op_SubVF: return new SubVFNode(n1, n2, vt); + case Op_SubVD: return new SubVDNode(n1, n2, vt); - case Op_MulVS: return new (C) MulVSNode(n1, n2, vt); - case Op_MulVI: return new (C) MulVINode(n1, n2, vt); - case Op_MulVF: return new (C) MulVFNode(n1, n2, vt); - case Op_MulVD: return new (C) MulVDNode(n1, n2, vt); + case Op_MulVS: return new MulVSNode(n1, n2, vt); + case Op_MulVI: return new MulVINode(n1, n2, vt); + case Op_MulVF: return new MulVFNode(n1, n2, vt); + case Op_MulVD: return new MulVDNode(n1, n2, vt); - case Op_DivVF: return new (C) DivVFNode(n1, n2, vt); - case Op_DivVD: return new (C) DivVDNode(n1, n2, vt); + case Op_DivVF: return new DivVFNode(n1, n2, vt); + case Op_DivVD: return new DivVDNode(n1, n2, vt); - case Op_LShiftVB: return new (C) LShiftVBNode(n1, n2, vt); - case Op_LShiftVS: return new (C) LShiftVSNode(n1, n2, vt); - case Op_LShiftVI: return new (C) LShiftVINode(n1, n2, vt); - case Op_LShiftVL: return new (C) LShiftVLNode(n1, n2, vt); + case Op_LShiftVB: return new LShiftVBNode(n1, n2, vt); + case Op_LShiftVS: return new LShiftVSNode(n1, n2, vt); + case Op_LShiftVI: return new LShiftVINode(n1, n2, vt); + case Op_LShiftVL: return new LShiftVLNode(n1, n2, vt); - case Op_RShiftVB: return new (C) RShiftVBNode(n1, n2, vt); - case Op_RShiftVS: return new (C) RShiftVSNode(n1, n2, vt); - case Op_RShiftVI: return new (C) RShiftVINode(n1, n2, vt); - case Op_RShiftVL: return new (C) RShiftVLNode(n1, n2, vt); + case Op_RShiftVB: return new RShiftVBNode(n1, n2, vt); + case Op_RShiftVS: return new RShiftVSNode(n1, n2, vt); + case Op_RShiftVI: return new RShiftVINode(n1, n2, vt); + case Op_RShiftVL: return new RShiftVLNode(n1, n2, vt); - case Op_URShiftVB: return new (C) URShiftVBNode(n1, n2, vt); - case Op_URShiftVS: return new (C) URShiftVSNode(n1, n2, vt); - case Op_URShiftVI: return new (C) URShiftVINode(n1, n2, vt); - case Op_URShiftVL: return new (C) URShiftVLNode(n1, n2, vt); + case Op_URShiftVB: return new URShiftVBNode(n1, n2, vt); + case Op_URShiftVS: return new URShiftVSNode(n1, n2, vt); + case Op_URShiftVI: return new URShiftVINode(n1, n2, vt); + case Op_URShiftVL: return new URShiftVLNode(n1, n2, vt); - case Op_AndV: return new (C) AndVNode(n1, n2, vt); - case Op_OrV: return new (C) OrVNode (n1, n2, vt); - case Op_XorV: return new (C) XorVNode(n1, n2, vt); + case Op_AndV: return new AndVNode(n1, n2, vt); + case Op_OrV: return new OrVNode (n1, n2, vt); + case Op_XorV: return new XorVNode(n1, n2, vt); } fatal(err_msg_res("Missed vector creation for '%s'", NodeClassNames[vopc])); return NULL; @@ -306,18 +306,18 @@ switch (bt) { case T_BOOLEAN: case T_BYTE: - return new (C) ReplicateBNode(s, vt); + return new ReplicateBNode(s, vt); case T_CHAR: case T_SHORT: - return new (C) ReplicateSNode(s, vt); + return new ReplicateSNode(s, vt); case T_INT: - return new (C) ReplicateINode(s, vt); + return new ReplicateINode(s, vt); case T_LONG: - return new (C) ReplicateLNode(s, vt); + return new ReplicateLNode(s, vt); case T_FLOAT: - return new (C) ReplicateFNode(s, vt); + return new ReplicateFNode(s, vt); case T_DOUBLE: - return new (C) ReplicateDNode(s, vt); + return new ReplicateDNode(s, vt); } fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt))); return NULL; @@ -330,12 +330,12 @@ switch (shift->Opcode()) { case Op_LShiftI: case Op_LShiftL: - return new (C) LShiftCntVNode(cnt, vt); + return new LShiftCntVNode(cnt, vt); case Op_RShiftI: case Op_RShiftL: case Op_URShiftI: case Op_URShiftL: - return new (C) RShiftCntVNode(cnt, vt); + return new RShiftCntVNode(cnt, vt); } fatal(err_msg_res("Missed vector creation for '%s'", NodeClassNames[shift->Opcode()])); return NULL; @@ -347,18 +347,18 @@ switch (bt) { case T_BOOLEAN: case T_BYTE: - return new (C) PackBNode(s, vt); + return new PackBNode(s, vt); case T_CHAR: case T_SHORT: - return new (C) PackSNode(s, vt); + return new PackSNode(s, vt); case T_INT: - return new (C) PackINode(s, vt); + return new PackINode(s, vt); case T_LONG: - return new (C) PackLNode(s, vt); + return new PackLNode(s, vt); case T_FLOAT: - return new (C) PackFNode(s, vt); + return new PackFNode(s, vt); case T_DOUBLE: - return new (C) PackDNode(s, vt); + return new PackDNode(s, vt); } fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt))); return NULL; @@ -383,18 +383,18 @@ switch (bt) { case T_BOOLEAN: case T_BYTE: - return new (C) PackSNode(n1, n2, TypeVect::make(T_SHORT, 2)); + return new PackSNode(n1, n2, TypeVect::make(T_SHORT, 2)); case T_CHAR: case T_SHORT: - return new (C) PackINode(n1, n2, TypeVect::make(T_INT, 2)); + return new PackINode(n1, n2, TypeVect::make(T_INT, 2)); case T_INT: - return new (C) PackLNode(n1, n2, TypeVect::make(T_LONG, 2)); + return new PackLNode(n1, n2, TypeVect::make(T_LONG, 2)); case T_LONG: - return new (C) Pack2LNode(n1, n2, TypeVect::make(T_LONG, 2)); + return new Pack2LNode(n1, n2, TypeVect::make(T_LONG, 2)); case T_FLOAT: - return new (C) PackDNode(n1, n2, TypeVect::make(T_DOUBLE, 2)); + return new PackDNode(n1, n2, TypeVect::make(T_DOUBLE, 2)); case T_DOUBLE: - return new (C) Pack2DNode(n1, n2, TypeVect::make(T_DOUBLE, 2)); + return new Pack2DNode(n1, n2, TypeVect::make(T_DOUBLE, 2)); } fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt))); } @@ -405,14 +405,14 @@ LoadVectorNode* LoadVectorNode::make(Compile* C, int opc, Node* ctl, Node* mem, Node* adr, const TypePtr* atyp, uint vlen, BasicType bt) { const TypeVect* vt = TypeVect::make(bt, vlen); - return new (C) LoadVectorNode(ctl, mem, adr, atyp, vt); + return new LoadVectorNode(ctl, mem, adr, atyp, vt); } // Return the vector version of a scalar store node. StoreVectorNode* StoreVectorNode::make(Compile* C, int opc, Node* ctl, Node* mem, Node* adr, const TypePtr* atyp, Node* val, uint vlen) { - return new (C) StoreVectorNode(ctl, mem, adr, atyp, val); + return new StoreVectorNode(ctl, mem, adr, atyp, val); } // Extract a scalar element of vector. @@ -421,21 +421,21 @@ ConINode* pos = ConINode::make(C, (int)position); switch (bt) { case T_BOOLEAN: - return new (C) ExtractUBNode(v, pos); + return new ExtractUBNode(v, pos); case T_BYTE: - return new (C) ExtractBNode(v, pos); + return new ExtractBNode(v, pos); case T_CHAR: - return new (C) ExtractCNode(v, pos); + return new ExtractCNode(v, pos); case T_SHORT: - return new (C) ExtractSNode(v, pos); + return new ExtractSNode(v, pos); case T_INT: - return new (C) ExtractINode(v, pos); + return new ExtractINode(v, pos); case T_LONG: - return new (C) ExtractLNode(v, pos); + return new ExtractLNode(v, pos); case T_FLOAT: - return new (C) ExtractFNode(v, pos); + return new ExtractFNode(v, pos); case T_DOUBLE: - return new (C) ExtractDNode(v, pos); + return new ExtractDNode(v, pos); } fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt))); return NULL; diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/prims/whitebox.cpp --- a/hotspot/src/share/vm/prims/whitebox.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/prims/whitebox.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -503,6 +503,159 @@ } WB_END +template +static bool GetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, bool (*TAt)(const char*, T*)) { + if (name == NULL) { + return false; + } + ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI + const char* flag_name = env->GetStringUTFChars(name, NULL); + bool result = (*TAt)(flag_name, value); + env->ReleaseStringUTFChars(name, flag_name); + return result; +} + +template +static bool SetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, bool (*TAtPut)(const char*, T*, Flag::Flags)) { + if (name == NULL) { + return false; + } + ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI + const char* flag_name = env->GetStringUTFChars(name, NULL); + bool result = (*TAtPut)(flag_name, value, Flag::INTERNAL); + env->ReleaseStringUTFChars(name, flag_name); + return result; +} + +template +static jobject box(JavaThread* thread, JNIEnv* env, Symbol* name, Symbol* sig, T value) { + ResourceMark rm(thread); + jclass clazz = env->FindClass(name->as_C_string()); + CHECK_JNI_EXCEPTION_(env, NULL); + jmethodID methodID = env->GetStaticMethodID(clazz, + vmSymbols::valueOf_name()->as_C_string(), + sig->as_C_string()); + CHECK_JNI_EXCEPTION_(env, NULL); + jobject result = env->CallStaticObjectMethod(clazz, methodID, value); + CHECK_JNI_EXCEPTION_(env, NULL); + return result; +} + +static jobject booleanBox(JavaThread* thread, JNIEnv* env, jboolean value) { + return box(thread, env, vmSymbols::java_lang_Boolean(), vmSymbols::Boolean_valueOf_signature(), value); +} +static jobject integerBox(JavaThread* thread, JNIEnv* env, jint value) { + return box(thread, env, vmSymbols::java_lang_Integer(), vmSymbols::Integer_valueOf_signature(), value); +} +static jobject longBox(JavaThread* thread, JNIEnv* env, jlong value) { + return box(thread, env, vmSymbols::java_lang_Long(), vmSymbols::Long_valueOf_signature(), value); +} +/* static jobject floatBox(JavaThread* thread, JNIEnv* env, jfloat value) { + return box(thread, env, vmSymbols::java_lang_Float(), vmSymbols::Float_valueOf_signature(), value); +}*/ +static jobject doubleBox(JavaThread* thread, JNIEnv* env, jdouble value) { + return box(thread, env, vmSymbols::java_lang_Double(), vmSymbols::Double_valueOf_signature(), value); +} + +WB_ENTRY(jobject, WB_GetBooleanVMFlag(JNIEnv* env, jobject o, jstring name)) + bool result; + if (GetVMFlag (thread, env, name, &result, &CommandLineFlags::boolAt)) { + ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI + return booleanBox(thread, env, result); + } + return NULL; +WB_END + +WB_ENTRY(jobject, WB_GetIntxVMFlag(JNIEnv* env, jobject o, jstring name)) + intx result; + if (GetVMFlag (thread, env, name, &result, &CommandLineFlags::intxAt)) { + ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI + return longBox(thread, env, result); + } + return NULL; +WB_END + +WB_ENTRY(jobject, WB_GetUintxVMFlag(JNIEnv* env, jobject o, jstring name)) + uintx result; + if (GetVMFlag (thread, env, name, &result, &CommandLineFlags::uintxAt)) { + ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI + return longBox(thread, env, result); + } + return NULL; +WB_END + +WB_ENTRY(jobject, WB_GetUint64VMFlag(JNIEnv* env, jobject o, jstring name)) + uint64_t result; + if (GetVMFlag (thread, env, name, &result, &CommandLineFlags::uint64_tAt)) { + ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI + return longBox(thread, env, result); + } + return NULL; +WB_END + +WB_ENTRY(jobject, WB_GetDoubleVMFlag(JNIEnv* env, jobject o, jstring name)) + double result; + if (GetVMFlag (thread, env, name, &result, &CommandLineFlags::doubleAt)) { + ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI + return doubleBox(thread, env, result); + } + return NULL; +WB_END + +WB_ENTRY(jstring, WB_GetStringVMFlag(JNIEnv* env, jobject o, jstring name)) + ccstr ccstrResult; + if (GetVMFlag (thread, env, name, &ccstrResult, &CommandLineFlags::ccstrAt)) { + ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI + jstring result = env->NewStringUTF(ccstrResult); + CHECK_JNI_EXCEPTION_(env, NULL); + return result; + } + return NULL; +WB_END + +WB_ENTRY(void, WB_SetBooleanVMFlag(JNIEnv* env, jobject o, jstring name, jboolean value)) + bool result = value == JNI_TRUE ? true : false; + SetVMFlag (thread, env, name, &result, &CommandLineFlags::boolAtPut); +WB_END + +WB_ENTRY(void, WB_SetIntxVMFlag(JNIEnv* env, jobject o, jstring name, jlong value)) + intx result = value; + SetVMFlag (thread, env, name, &result, &CommandLineFlags::intxAtPut); +WB_END + +WB_ENTRY(void, WB_SetUintxVMFlag(JNIEnv* env, jobject o, jstring name, jlong value)) + uintx result = value; + SetVMFlag (thread, env, name, &result, &CommandLineFlags::uintxAtPut); +WB_END + +WB_ENTRY(void, WB_SetUint64VMFlag(JNIEnv* env, jobject o, jstring name, jlong value)) + uint64_t result = value; + SetVMFlag (thread, env, name, &result, &CommandLineFlags::uint64_tAtPut); +WB_END + +WB_ENTRY(void, WB_SetDoubleVMFlag(JNIEnv* env, jobject o, jstring name, jdouble value)) + double result = value; + SetVMFlag (thread, env, name, &result, &CommandLineFlags::doubleAtPut); +WB_END + +WB_ENTRY(void, WB_SetStringVMFlag(JNIEnv* env, jobject o, jstring name, jstring value)) + ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI + const char* ccstrValue = (value == NULL) ? NULL : env->GetStringUTFChars(value, NULL); + ccstr ccstrResult = ccstrValue; + bool needFree; + { + ThreadInVMfromNative ttvfn(thread); // back to VM + needFree = SetVMFlag (thread, env, name, &ccstrResult, &CommandLineFlags::ccstrAtPut); + } + if (value != NULL) { + env->ReleaseStringUTFChars(value, ccstrValue); + } + if (needFree) { + FREE_C_HEAP_ARRAY(char, ccstrResult, mtInternal); + } +WB_END + + WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString)) ResourceMark rm(THREAD); int len; @@ -561,11 +714,7 @@ return result; } - clazz = env->FindClass(vmSymbols::java_lang_Integer()->as_C_string()); - CHECK_JNI_EXCEPTION_(env, NULL); - jmethodID constructor = env->GetMethodID(clazz, vmSymbols::object_initializer_name()->as_C_string(), vmSymbols::int_void_signature()->as_C_string()); - CHECK_JNI_EXCEPTION_(env, NULL); - jobject obj = env->NewObject(clazz, constructor, code->comp_level()); + jobject obj = integerBox(thread, env, code->comp_level()); CHECK_JNI_EXCEPTION_(env, NULL); env->SetObjectArrayElement(result, 0, obj); @@ -695,7 +844,26 @@ CC"(Ljava/lang/reflect/Executable;II)Z", (void*)&WB_EnqueueMethodForCompilation}, {CC"clearMethodState", CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_ClearMethodState}, - {CC"isInStringTable", CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable }, + {CC"setBooleanVMFlag", CC"(Ljava/lang/String;Z)V",(void*)&WB_SetBooleanVMFlag}, + {CC"setIntxVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetIntxVMFlag}, + {CC"setUintxVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetUintxVMFlag}, + {CC"setUint64VMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetUint64VMFlag}, + {CC"setDoubleVMFlag", CC"(Ljava/lang/String;D)V",(void*)&WB_SetDoubleVMFlag}, + {CC"setStringVMFlag", CC"(Ljava/lang/String;Ljava/lang/String;)V", + (void*)&WB_SetStringVMFlag}, + {CC"getBooleanVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Boolean;", + (void*)&WB_GetBooleanVMFlag}, + {CC"getIntxVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Long;", + (void*)&WB_GetIntxVMFlag}, + {CC"getUintxVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Long;", + (void*)&WB_GetUintxVMFlag}, + {CC"getUint64VMFlag", CC"(Ljava/lang/String;)Ljava/lang/Long;", + (void*)&WB_GetUint64VMFlag}, + {CC"getDoubleVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Double;", + (void*)&WB_GetDoubleVMFlag}, + {CC"getStringVMFlag", CC"(Ljava/lang/String;)Ljava/lang/String;", + (void*)&WB_GetStringVMFlag}, + {CC"isInStringTable", CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable }, {CC"fullGC", CC"()V", (void*)&WB_FullGC }, {CC"readReservedMemory", CC"()V", (void*)&WB_ReadReservedMemory }, {CC"getCPUFeatures", CC"()Ljava/lang/String;", (void*)&WB_GetCPUFeatures }, diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/runtime/arguments.cpp --- a/hotspot/src/share/vm/runtime/arguments.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -2187,6 +2187,10 @@ } } + if (!(UseParallelGC || UseParallelOldGC) && FLAG_IS_DEFAULT(ScavengeBeforeFullGC)) { + FLAG_SET_DEFAULT(ScavengeBeforeFullGC, false); + } + status = status && verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit"); status = status && verify_percentage(GCTimeLimit, "GCTimeLimit"); if (GCTimeLimit == 100) { @@ -3834,10 +3838,6 @@ // nothing to use the profiling, turn if off FLAG_SET_DEFAULT(TypeProfileLevel, 0); } - if (UseTypeSpeculation && FLAG_IS_DEFAULT(ReplaceInParentMaps)) { - // Doing the replace in parent maps helps speculation - FLAG_SET_DEFAULT(ReplaceInParentMaps, true); - } #endif if (PrintAssembly && FLAG_IS_DEFAULT(DebugNonSafepoints)) { diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/runtime/deoptimization.cpp --- a/hotspot/src/share/vm/runtime/deoptimization.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/runtime/deoptimization.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -1840,6 +1840,7 @@ "speculate_class_check", "speculate_null_check", "rtm_state_change", + "unstable_if", "tenured" }; const char* Deoptimization::_trap_action_name[] = { diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/runtime/deoptimization.hpp --- a/hotspot/src/share/vm/runtime/deoptimization.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/runtime/deoptimization.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -62,6 +62,10 @@ Reason_speculate_class_check, // saw unexpected object class from type speculation Reason_speculate_null_check, // saw unexpected null from type speculation Reason_rtm_state_change, // rtm state change detected + Reason_unstable_if, // a branch predicted always false was taken + + // Reason_tenured is counted separately, add normal counted Reasons above. + // Related to MethodData::_trap_hist_limit where Reason_tenured isn't included Reason_tenured, // age of the code has reached the limit Reason_LIMIT, // Note: Keep this enum in sync. with _trap_reason_name. @@ -319,6 +323,8 @@ return Reason_class_check; else if (reason == Reason_speculate_null_check) return Reason_null_check; + else if (reason == Reason_unstable_if) + return Reason_intrinsic; else return Reason_none; } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/runtime/globals.cpp --- a/hotspot/src/share/vm/runtime/globals.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/runtime/globals.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -611,7 +611,7 @@ e.commit(); } -bool CommandLineFlags::boolAt(char* name, size_t len, bool* value) { +bool CommandLineFlags::boolAt(const char* name, size_t len, bool* value) { Flag* result = Flag::find_flag(name, len); if (result == NULL) return false; if (!result->is_bool()) return false; @@ -619,7 +619,7 @@ return true; } -bool CommandLineFlags::boolAtPut(char* name, size_t len, bool* value, Flag::Flags origin) { +bool CommandLineFlags::boolAtPut(const char* name, size_t len, bool* value, Flag::Flags origin) { Flag* result = Flag::find_flag(name, len); if (result == NULL) return false; if (!result->is_bool()) return false; @@ -639,7 +639,7 @@ faddr->set_origin(origin); } -bool CommandLineFlags::intxAt(char* name, size_t len, intx* value) { +bool CommandLineFlags::intxAt(const char* name, size_t len, intx* value) { Flag* result = Flag::find_flag(name, len); if (result == NULL) return false; if (!result->is_intx()) return false; @@ -647,7 +647,7 @@ return true; } -bool CommandLineFlags::intxAtPut(char* name, size_t len, intx* value, Flag::Flags origin) { +bool CommandLineFlags::intxAtPut(const char* name, size_t len, intx* value, Flag::Flags origin) { Flag* result = Flag::find_flag(name, len); if (result == NULL) return false; if (!result->is_intx()) return false; @@ -667,7 +667,7 @@ faddr->set_origin(origin); } -bool CommandLineFlags::uintxAt(char* name, size_t len, uintx* value) { +bool CommandLineFlags::uintxAt(const char* name, size_t len, uintx* value) { Flag* result = Flag::find_flag(name, len); if (result == NULL) return false; if (!result->is_uintx()) return false; @@ -675,7 +675,7 @@ return true; } -bool CommandLineFlags::uintxAtPut(char* name, size_t len, uintx* value, Flag::Flags origin) { +bool CommandLineFlags::uintxAtPut(const char* name, size_t len, uintx* value, Flag::Flags origin) { Flag* result = Flag::find_flag(name, len); if (result == NULL) return false; if (!result->is_uintx()) return false; @@ -695,7 +695,7 @@ faddr->set_origin(origin); } -bool CommandLineFlags::uint64_tAt(char* name, size_t len, uint64_t* value) { +bool CommandLineFlags::uint64_tAt(const char* name, size_t len, uint64_t* value) { Flag* result = Flag::find_flag(name, len); if (result == NULL) return false; if (!result->is_uint64_t()) return false; @@ -703,7 +703,7 @@ return true; } -bool CommandLineFlags::uint64_tAtPut(char* name, size_t len, uint64_t* value, Flag::Flags origin) { +bool CommandLineFlags::uint64_tAtPut(const char* name, size_t len, uint64_t* value, Flag::Flags origin) { Flag* result = Flag::find_flag(name, len); if (result == NULL) return false; if (!result->is_uint64_t()) return false; @@ -723,7 +723,7 @@ faddr->set_origin(origin); } -bool CommandLineFlags::doubleAt(char* name, size_t len, double* value) { +bool CommandLineFlags::doubleAt(const char* name, size_t len, double* value) { Flag* result = Flag::find_flag(name, len); if (result == NULL) return false; if (!result->is_double()) return false; @@ -731,7 +731,7 @@ return true; } -bool CommandLineFlags::doubleAtPut(char* name, size_t len, double* value, Flag::Flags origin) { +bool CommandLineFlags::doubleAtPut(const char* name, size_t len, double* value, Flag::Flags origin) { Flag* result = Flag::find_flag(name, len); if (result == NULL) return false; if (!result->is_double()) return false; @@ -751,7 +751,7 @@ faddr->set_origin(origin); } -bool CommandLineFlags::ccstrAt(char* name, size_t len, ccstr* value) { +bool CommandLineFlags::ccstrAt(const char* name, size_t len, ccstr* value) { Flag* result = Flag::find_flag(name, len); if (result == NULL) return false; if (!result->is_ccstr()) return false; @@ -759,7 +759,7 @@ return true; } -bool CommandLineFlags::ccstrAtPut(char* name, size_t len, ccstr* value, Flag::Flags origin) { +bool CommandLineFlags::ccstrAtPut(const char* name, size_t len, ccstr* value, Flag::Flags origin) { Flag* result = Flag::find_flag(name, len); if (result == NULL) return false; if (!result->is_ccstr()) return false; diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/runtime/globals.hpp --- a/hotspot/src/share/vm/runtime/globals.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/runtime/globals.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -362,37 +362,37 @@ class CommandLineFlags { public: - static bool boolAt(char* name, size_t len, bool* value); - static bool boolAt(char* name, bool* value) { return boolAt(name, strlen(name), value); } - static bool boolAtPut(char* name, size_t len, bool* value, Flag::Flags origin); - static bool boolAtPut(char* name, bool* value, Flag::Flags origin) { return boolAtPut(name, strlen(name), value, origin); } + static bool boolAt(const char* name, size_t len, bool* value); + static bool boolAt(const char* name, bool* value) { return boolAt(name, strlen(name), value); } + static bool boolAtPut(const char* name, size_t len, bool* value, Flag::Flags origin); + static bool boolAtPut(const char* name, bool* value, Flag::Flags origin) { return boolAtPut(name, strlen(name), value, origin); } - static bool intxAt(char* name, size_t len, intx* value); - static bool intxAt(char* name, intx* value) { return intxAt(name, strlen(name), value); } - static bool intxAtPut(char* name, size_t len, intx* value, Flag::Flags origin); - static bool intxAtPut(char* name, intx* value, Flag::Flags origin) { return intxAtPut(name, strlen(name), value, origin); } + static bool intxAt(const char* name, size_t len, intx* value); + static bool intxAt(const char* name, intx* value) { return intxAt(name, strlen(name), value); } + static bool intxAtPut(const char* name, size_t len, intx* value, Flag::Flags origin); + static bool intxAtPut(const char* name, intx* value, Flag::Flags origin) { return intxAtPut(name, strlen(name), value, origin); } - static bool uintxAt(char* name, size_t len, uintx* value); - static bool uintxAt(char* name, uintx* value) { return uintxAt(name, strlen(name), value); } - static bool uintxAtPut(char* name, size_t len, uintx* value, Flag::Flags origin); - static bool uintxAtPut(char* name, uintx* value, Flag::Flags origin) { return uintxAtPut(name, strlen(name), value, origin); } + static bool uintxAt(const char* name, size_t len, uintx* value); + static bool uintxAt(const char* name, uintx* value) { return uintxAt(name, strlen(name), value); } + static bool uintxAtPut(const char* name, size_t len, uintx* value, Flag::Flags origin); + static bool uintxAtPut(const char* name, uintx* value, Flag::Flags origin) { return uintxAtPut(name, strlen(name), value, origin); } - static bool uint64_tAt(char* name, size_t len, uint64_t* value); - static bool uint64_tAt(char* name, uint64_t* value) { return uint64_tAt(name, strlen(name), value); } - static bool uint64_tAtPut(char* name, size_t len, uint64_t* value, Flag::Flags origin); - static bool uint64_tAtPut(char* name, uint64_t* value, Flag::Flags origin) { return uint64_tAtPut(name, strlen(name), value, origin); } + static bool uint64_tAt(const char* name, size_t len, uint64_t* value); + static bool uint64_tAt(const char* name, uint64_t* value) { return uint64_tAt(name, strlen(name), value); } + static bool uint64_tAtPut(const char* name, size_t len, uint64_t* value, Flag::Flags origin); + static bool uint64_tAtPut(const char* name, uint64_t* value, Flag::Flags origin) { return uint64_tAtPut(name, strlen(name), value, origin); } - static bool doubleAt(char* name, size_t len, double* value); - static bool doubleAt(char* name, double* value) { return doubleAt(name, strlen(name), value); } - static bool doubleAtPut(char* name, size_t len, double* value, Flag::Flags origin); - static bool doubleAtPut(char* name, double* value, Flag::Flags origin) { return doubleAtPut(name, strlen(name), value, origin); } + static bool doubleAt(const char* name, size_t len, double* value); + static bool doubleAt(const char* name, double* value) { return doubleAt(name, strlen(name), value); } + static bool doubleAtPut(const char* name, size_t len, double* value, Flag::Flags origin); + static bool doubleAtPut(const char* name, double* value, Flag::Flags origin) { return doubleAtPut(name, strlen(name), value, origin); } - static bool ccstrAt(char* name, size_t len, ccstr* value); - static bool ccstrAt(char* name, ccstr* value) { return ccstrAt(name, strlen(name), value); } + static bool ccstrAt(const char* name, size_t len, ccstr* value); + static bool ccstrAt(const char* name, ccstr* value) { return ccstrAt(name, strlen(name), value); } // Contract: Flag will make private copy of the incoming value. // Outgoing value is always malloc-ed, and caller MUST call free. - static bool ccstrAtPut(char* name, size_t len, ccstr* value, Flag::Flags origin); - static bool ccstrAtPut(char* name, ccstr* value, Flag::Flags origin) { return ccstrAtPut(name, strlen(name), value, origin); } + static bool ccstrAtPut(const char* name, size_t len, ccstr* value, Flag::Flags origin); + static bool ccstrAtPut(const char* name, ccstr* value, Flag::Flags origin) { return ccstrAtPut(name, strlen(name), value, origin); } // Returns false if name is not a command line flag. static bool wasSetOnCmdline(const char* name, bool* value); @@ -599,6 +599,9 @@ product(bool, UseAES, false, \ "Control whether AES instructions can be used on x86/x64") \ \ + product(bool, UseSHA, false, \ + "Control whether SHA instructions can be used on SPARC") \ + \ product(uintx, LargePageSizeInBytes, 0, \ "Large page size (0 to let VM choose the page size)") \ \ @@ -705,6 +708,15 @@ product(bool, UseAESIntrinsics, false, \ "Use intrinsics for AES versions of crypto") \ \ + product(bool, UseSHA1Intrinsics, false, \ + "Use intrinsics for SHA-1 crypto hash function") \ + \ + product(bool, UseSHA256Intrinsics, false, \ + "Use intrinsics for SHA-224 and SHA-256 crypto hash functions") \ + \ + product(bool, UseSHA512Intrinsics, false, \ + "Use intrinsics for SHA-384 and SHA-512 crypto hash functions") \ + \ product(bool, UseCRC32Intrinsics, false, \ "use intrinsics for java.util.zip.CRC32") \ \ @@ -1097,7 +1109,7 @@ "Call loadClassInternal() rather than loadClass()") \ \ product_pd(bool, DontYieldALot, \ - "Throw away obvious excess yield calls (for Solaris only)") \ + "Throw away obvious excess yield calls") \ \ product_pd(bool, ConvertSleepToYield, \ "Convert sleep(0) to thread yield " \ @@ -1105,7 +1117,7 @@ \ product(bool, ConvertYieldToSleep, false, \ "Convert yield to a sleep of MinSleepInterval to simulate Win32 " \ - "behavior (Solaris only)") \ + "behavior") \ \ product(bool, UseBoundThreads, true, \ "Bind user level threads to kernel threads (for Solaris only)") \ @@ -1143,8 +1155,8 @@ "avoid NPTL-FUTEX hang pthread_cond_timedwait") \ \ product(bool, FilterSpuriousWakeups, true, \ - "Prevent spurious or premature wakeups from object.wait " \ - "(Solaris only)") \ + "When true prevents OS-level spurious, or premature, wakeups " \ + "from Object.wait (Ignored for Windows)") \ \ product(intx, NativeMonitorTimeout, -1, "(Unstable)") \ \ @@ -1450,8 +1462,7 @@ "(ParallelGC only)") \ \ product(bool, ScavengeBeforeFullGC, true, \ - "Scavenge youngest generation before each full GC, " \ - "used with UseParallelGC") \ + "Scavenge youngest generation before each full GC.") \ \ develop(bool, ScavengeWithObjectsInToSpace, false, \ "Allow scavenges to occur when to-space contains objects") \ @@ -2252,9 +2263,6 @@ notproduct(bool, CheckMemoryInitialization, false, \ "Check memory initialization") \ \ - product(bool, CollectGen0First, false, \ - "Collect youngest generation before each full GC") \ - \ diagnostic(bool, BindCMSThreadToCPU, false, \ "Bind CMS Thread to CPU if possible") \ \ @@ -2333,11 +2341,11 @@ NOT_LP64(2200*K) LP64_ONLY(4*M), \ "Initial size of the boot class loader data metaspace") \ \ - product(bool, TraceGen0Time, false, \ - "Trace accumulated time for Gen 0 collection") \ - \ - product(bool, TraceGen1Time, false, \ - "Trace accumulated time for Gen 1 collection") \ + product(bool, TraceYoungGenTime, false, \ + "Trace accumulated time for young collection") \ + \ + product(bool, TraceOldGenTime, false, \ + "Trace accumulated time for old collection") \ \ product(bool, PrintTenuringDistribution, false, \ "Print tenuring age information") \ diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/runtime/stubRoutines.cpp --- a/hotspot/src/share/vm/runtime/stubRoutines.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/runtime/stubRoutines.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -125,6 +125,13 @@ address StubRoutines::_cipherBlockChaining_encryptAESCrypt = NULL; address StubRoutines::_cipherBlockChaining_decryptAESCrypt = NULL; +address StubRoutines::_sha1_implCompress = NULL; +address StubRoutines::_sha1_implCompressMB = NULL; +address StubRoutines::_sha256_implCompress = NULL; +address StubRoutines::_sha256_implCompressMB = NULL; +address StubRoutines::_sha512_implCompress = NULL; +address StubRoutines::_sha512_implCompressMB = NULL; + address StubRoutines::_updateBytesCRC32 = NULL; address StubRoutines::_crc_table_adr = NULL; diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/runtime/stubRoutines.hpp --- a/hotspot/src/share/vm/runtime/stubRoutines.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/runtime/stubRoutines.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -207,6 +207,13 @@ static address _cipherBlockChaining_encryptAESCrypt; static address _cipherBlockChaining_decryptAESCrypt; + static address _sha1_implCompress; + static address _sha1_implCompressMB; + static address _sha256_implCompress; + static address _sha256_implCompressMB; + static address _sha512_implCompress; + static address _sha512_implCompressMB; + static address _updateBytesCRC32; static address _crc_table_adr; @@ -356,6 +363,13 @@ static address cipherBlockChaining_encryptAESCrypt() { return _cipherBlockChaining_encryptAESCrypt; } static address cipherBlockChaining_decryptAESCrypt() { return _cipherBlockChaining_decryptAESCrypt; } + static address sha1_implCompress() { return _sha1_implCompress; } + static address sha1_implCompressMB() { return _sha1_implCompressMB; } + static address sha256_implCompress() { return _sha256_implCompress; } + static address sha256_implCompressMB() { return _sha256_implCompressMB; } + static address sha512_implCompress() { return _sha512_implCompress; } + static address sha512_implCompressMB() { return _sha512_implCompressMB; } + static address updateBytesCRC32() { return _updateBytesCRC32; } static address crc_table_addr() { return _crc_table_adr; } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/runtime/vframe.cpp --- a/hotspot/src/share/vm/runtime/vframe.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/runtime/vframe.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -274,7 +274,8 @@ // Get oopmap describing oops and int for current bci InterpreterOopMap oop_mask; if (TraceDeoptimization && Verbose) { - methodHandle m_h(thread(), method()); + // need the current JavaThread and not thread() + methodHandle m_h(Thread::current(), method()); OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask); } else { method()->mask_for(bci(), &oop_mask); @@ -335,7 +336,8 @@ if (!method()->is_native()) { // Get oopmap describing oops and int for current bci if (TraceDeoptimization && Verbose) { - methodHandle m_h(method()); + // need the current JavaThread and not thread() + methodHandle m_h(Thread::current(), method()); OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask); } else { method()->mask_for(bci(), &oop_mask); diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/runtime/vmStructs.cpp --- a/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Jun 18 10:56:06 2014 -0700 @@ -2504,6 +2504,7 @@ declare_constant(Deoptimization::Reason_speculate_class_check) \ declare_constant(Deoptimization::Reason_speculate_null_check) \ declare_constant(Deoptimization::Reason_rtm_state_change) \ + declare_constant(Deoptimization::Reason_unstable_if) \ declare_constant(Deoptimization::Reason_tenured) \ declare_constant(Deoptimization::Reason_LIMIT) \ declare_constant(Deoptimization::Reason_RECORDED_LIMIT) \ diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/src/share/vm/utilities/growableArray.hpp --- a/hotspot/src/share/vm/utilities/growableArray.hpp Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/src/share/vm/utilities/growableArray.hpp Wed Jun 18 10:56:06 2014 -0700 @@ -349,6 +349,7 @@ // inserts the given element before the element at index i void insert_before(const int idx, const E& elem) { + assert(0 <= idx && idx <= _len, "illegal index"); check_nesting(); if (_len == _max) grow(_len); for (int j = _len - 1; j >= idx; j--) { @@ -360,7 +361,7 @@ void appendAll(const GrowableArray* l) { for (int i = 0; i < l->_len; i++) { - raw_at_put_grow(_len, l->_data[i], 0); + raw_at_put_grow(_len, l->_data[i], E()); } } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/test/TEST.groups --- a/hotspot/test/TEST.groups Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/test/TEST.groups Wed Jun 18 10:56:06 2014 -0700 @@ -117,6 +117,7 @@ # Tests that require compact3 API's # needs_compact3 = \ + compiler/8009761/Test8009761.java \ compiler/whitebox/DeoptimizeMethodTest.java \ compiler/whitebox/SetForceInlineMethodTest.java \ compiler/whitebox/SetDontInlineMethodTest.java \ @@ -216,3 +217,111 @@ -:needs_compact3 \ -:needs_jre \ -:needs_jdk + +# All tests that explicitly set the G1 GC +# +needs_g1gc = \ + compiler/regalloc/C1ObjectSpillInLogicOp.java \ + gc/8000311/Test8000311.java \ + gc/TestG1ZeroPGCTJcmdThreadPrint.java \ + gc/TestSystemGC.java \ + gc/arguments/TestAlignmentToUseLargePages.java \ + gc/arguments/TestG1HeapRegionSize.java \ + gc/arguments/TestG1HeapSizeFlags.java \ + gc/arguments/TestMaxHeapSizeTools.java \ + gc/arguments/TestMaxNewSize.java \ + gc/arguments/TestUseCompressedOopsErgo.java \ + gc/g1/ \ + gc/metaspace/G1AddMetaspaceDependency.java \ + gc/metaspace/TestMetaspacePerfCounters.java \ + gc/startup_warnings/TestG1.java + +# All tests that explicitly set the serial GC +# +needs_serialgc = \ + gc/TestSystemGC.java \ + gc/arguments/TestAlignmentToUseLargePages.java \ + gc/arguments/TestMaxNewSize.java \ + gc/arguments/TestSerialHeapSizeFlags.java \ + gc/arguments/TestUseCompressedOopsErgo.java \ + gc/defnew/HeapChangeLogging.java \ + gc/metaspace/TestMetaspacePerfCounters.java \ + gc/metaspace/TestPerfCountersAndMemoryPools.java \ + gc/startup_warnings/TestSerialGC.java + +# All tests that explicitly set the parallel GC +# +needs_parallelgc = \ + gc/TestSystemGC.java \ + gc/arguments/TestAlignmentToUseLargePages.java \ + gc/arguments/TestMaxNewSize.java \ + gc/arguments/TestMinInitialErgonomics.java \ + gc/arguments/TestUseCompressedOopsErgo.java \ + gc/metaspace/TestMetaspacePerfCounters.java \ + gc/parallelScavenge/ \ + gc/startup_warnings/TestParallelGC.java \ + gc/startup_warnings/TestParallelScavengeSerialOld.java + +# All tests that explicitly set the CMS GC +# +needs_cmsgc = \ + gc/6581734/Test6581734.java \ + gc/TestSystemGC.java \ + gc/arguments/TestAlignmentToUseLargePages.java \ + gc/arguments/TestCMSHeapSizeFlags.java \ + gc/arguments/TestMaxNewSize.java \ + gc/arguments/TestUseCompressedOopsErgo.java \ + gc/concurrentMarkSweep/ \ + gc/startup_warnings/TestCMS.java \ + gc/startup_warnings/TestCMSIncrementalMode.java \ + gc/startup_warnings/TestCMSNoIncrementalMode.java \ + gc/startup_warnings/TestDefNewCMS.java \ + gc/startup_warnings/TestParNewCMS.java + +# All tests that explicitly set some GC +# +needs_gc = \ + :needs_g1gc \ + :needs_serialgc \ + :needs_parallelgc \ + :needs_cmsgc + +# All tests that do not set any GC explicitly +# +not_needs_gc = \ + :jdk \ + -:needs_gc + +# All tests that could be executed with the G1 GC without VM flags conflict +# +applicable_g1gc = \ + :jdk \ + -:needs_serialgc \ + -:needs_parallelgc \ + -:needs_cmsgc + +# All tests that could be executed with the serial GC without VM flags conflict +# +applicable_serialgc = \ + :jdk \ + -:needs_g1gc \ + -:needs_parallelgc \ + -:needs_cmsgc + +# All tests that could be executed with the parallel GC without VM flags conflict +# +applicable_parallelgc = \ + :jdk \ + -:needs_g1gc \ + -:needs_serialgc \ + -:needs_cmsgc + +# All tests that could be executed with the CMS GC without VM flags conflict +# +applicable_cmsgc = \ + :jdk \ + -:needs_g1gc \ + -:needs_serialgc \ + -:needs_parallelgc + + diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/test/compiler/8009761/Test8009761.java --- a/hotspot/test/compiler/8009761/Test8009761.java Wed Jul 05 19:45:37 2017 +0200 +++ b/hotspot/test/compiler/8009761/Test8009761.java Wed Jun 18 10:56:06 2014 -0700 @@ -21,19 +21,27 @@ * questions. */ +import com.sun.management.HotSpotDiagnosticMXBean; +import com.sun.management.VMOption; +import sun.hotspot.WhiteBox; +import sun.management.ManagementFactoryHelper; + +import java.lang.reflect.Method; + /* * @test * @bug 8009761 + * @library /testlibrary /testlibrary/whitebox * @summary Deoptimization on sparc doesn't set Llast_SP correctly in the interpreter frames it creates - * @run main/othervm -XX:CompileCommand=exclude,Test8009761::m2 -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -Xss256K Test8009761 - * + * @build Test8009761 + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=exclude,Test8009761::m2 -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -Xss256K Test8009761 */ - public class Test8009761 { - static class UnloadedClass { - volatile int i; - } + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + private static int COMP_LEVEL_FULL_OPTIMIZATION = 4; + private static Method m3 = null; static Object m1(boolean deopt) { // When running interpreted, on sparc, the caller's stack is @@ -142,9 +150,11 @@ ll508, ll509, ll510, ll511; if (deopt) { - UnloadedClass res = new UnloadedClass(); // sufficient to force deopt with c2 but not c1 - res.i = 0; // forces deopt with c1 - return res; + // Force deoptimization of m3 + WHITE_BOX.deoptimizeMethod(m3); + if(WHITE_BOX.isMethodCompiled(m3)) { + throw new RuntimeException(m3 + " not deoptimized"); + } } return null; } @@ -225,6 +235,18 @@ } static public void main(String[] args) { + // Make sure background compilation is disabled + if (backgroundCompilationEnabled()) { + throw new RuntimeException("Background compilation enabled"); + } + + try { + // Get Method object for m3 + m3 = Test8009761.class.getDeclaredMethod("m3", boolean.class, boolean.class); + } catch (NoSuchMethodException | SecurityException ex) { + throw new RuntimeException("Failed to retrieve method m3"); + } + int c1; // Call m2 from m3 recursively until stack overflow. Count the number of recursive calls. try { @@ -232,10 +254,14 @@ } catch(StackOverflowError soe) { } c1 = count; + // Force the compilation of m3() that will inline m1() - for (int i = 0; i < 20000; i++) { - m3(false, false); + WHITE_BOX.enqueueMethodForCompilation(m3, COMP_LEVEL_FULL_OPTIMIZATION); + // Because background compilation is disabled, method should now be compiled + if(!WHITE_BOX.isMethodCompiled(m3)) { + throw new RuntimeException(m3 + " not compiled"); } + count = 0; // Force deoptimization of m3() in m1(), then return from m1() // to m3(), call recursively m2(). If deoptimization correctly @@ -245,11 +271,26 @@ m3(false, true); } catch(StackOverflowError soe) { } - if (c1 != count) { - System.out.println("Failed: init recursive calls: " + c1 + ". After deopt " + count); - System.exit(97); + // Allow number of recursive calls to vary by 1 + if ((c1 < (count - 1)) || (c1 > (count + 1))) { + throw new RuntimeException("Failed: init recursive calls: " + c1 + ". After deopt " + count); } else { System.out.println("PASSED " + c1); } } + + /** + * Checks if background compilation (-XX:+BackgroundCompilation) is enabled. + * @return True if background compilation is enabled, false otherwise + */ + private static boolean backgroundCompilationEnabled() { + HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean(); + VMOption backgroundCompilation; + try { + backgroundCompilation = diagnostic.getVMOption("BackgroundCompilation"); + } catch (IllegalArgumentException e) { + return false; + } + return Boolean.valueOf(backgroundCompilation.getValue()); + } } diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/test/compiler/intrinsics/clone/TestObjectClone.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/intrinsics/clone/TestObjectClone.java Wed Jun 18 10:56:06 2014 -0700 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test + * @bug 8033626 + * @summary assert(ex_map->jvms()->same_calls_as(_exceptions->jvms())) failed: all collected exceptions must come from the same place + * @library /testlibrary + * @run main/othervm -XX:-TieredCompilation -Xbatch -XX:CompileOnly=TestObjectClone::f TestObjectClone + */ +import com.oracle.java.testlibrary.Asserts; + +public class TestObjectClone implements Cloneable { + static class A extends TestObjectClone {} + static class B extends TestObjectClone { + public B clone() { + return (B)TestObjectClone.b; + } + } + static class C extends TestObjectClone { + public C clone() { + return (C)TestObjectClone.c; + } + } + static class D extends TestObjectClone { + public D clone() { + return (D)TestObjectClone.d; + } + } + static TestObjectClone a = new A(), b = new B(), c = new C(), d = new D(); + + public static Object f(TestObjectClone o) throws CloneNotSupportedException { + // Polymorphic call site: >90% Object::clone / <10% other methods + return o.clone(); + } + + public static void main(String[] args) throws Exception { + TestObjectClone[] params1 = {a, a, a, a, a, a, a, a, a, a, a, + a, a, a, a, a, a, a, a, a, a, a, + a, a, a, a, a, a, a, a, a, a, a, + b, c, d}; + + for (int i = 0; i < 15000; i++) { + f(params1[i % params1.length]); + } + + Asserts.assertTrue(f(a) != a); + Asserts.assertTrue(f(b) == b); + Asserts.assertTrue(f(c) == c); + Asserts.assertTrue(f(d) == d); + + try { + f(null); + throw new AssertionError(""); + } catch (NullPointerException e) { /* expected */ } + + System.out.println("TEST PASSED"); + } +} diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/test/compiler/intrinsics/hashcode/TestHashCode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/intrinsics/hashcode/TestHashCode.java Wed Jun 18 10:56:06 2014 -0700 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8011646 + * @summary SEGV in compiled code with loop predication + * @run main/othervm -XX:-TieredCompilation -XX:CompileOnly=TestHashCode.m1,Object.hashCode TestHashCode + * + */ + +public class TestHashCode { + static class A { + int i; + } + + static class B extends A { + } + + static boolean crash = false; + + static A m2() { + if (crash) { + return null; + } + return new A(); + } + + static int m1(A aa) { + int res = 0; + for (int i = 0; i < 10; i++) { + A a = m2(); + int j = a.i; + if (aa instanceof B) { + } + res += a.hashCode(); + } + return res; + } + + public static void main(String[] args) { + A a = new A(); + for (int i = 0; i < 20000; i++) { + m1(a); + } + crash = true; + try { + m1(a); + } catch (NullPointerException e) { + System.out.println("Test passed"); + } + } +} diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/test/compiler/intrinsics/sha/TestSHA.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/intrinsics/sha/TestSHA.java Wed Jun 18 10:56:06 2014 -0700 @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/** + * @test + * @bug 8035968 + * @summary C2 support for SHA on SPARC + * + * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-1 TestSHA + * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-224 TestSHA + * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-256 TestSHA + * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-384 TestSHA + * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-512 TestSHA + * + * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-1 -Doffset=1 TestSHA + * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-224 -Doffset=1 TestSHA + * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-256 -Doffset=1 TestSHA + * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-384 -Doffset=1 TestSHA + * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-512 -Doffset=1 TestSHA + * + * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-1 -Dalgorithm2=SHA-256 TestSHA + * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-1 -Dalgorithm2=SHA-512 TestSHA + * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-256 -Dalgorithm2=SHA-512 TestSHA + * + * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-1 -Dalgorithm2=MD5 TestSHA + * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=MD5 -Dalgorithm2=SHA-1 TestSHA + */ + +import java.security.MessageDigest; +import java.util.Arrays; + +public class TestSHA { + private static final int HASH_LEN = 64; /* up to 512-bit */ + private static final int ALIGN = 8; /* for different data alignments */ + + public static void main(String[] args) throws Exception { + String provider = System.getProperty("provider", "SUN"); + String algorithm = System.getProperty("algorithm", "SHA-1"); + String algorithm2 = System.getProperty("algorithm2", ""); + int msgSize = Integer.getInteger("msgSize", 1024); + int offset = Integer.getInteger("offset", 0) % ALIGN; + int iters = (args.length > 0 ? Integer.valueOf(args[0]) : 100000); + int warmupIters = (args.length > 1 ? Integer.valueOf(args[1]) : 20000); + + testSHA(provider, algorithm, msgSize, offset, iters, warmupIters); + + if (algorithm2.equals("") == false) { + testSHA(provider, algorithm2, msgSize, offset, iters, warmupIters); + } + } + + static void testSHA(String provider, String algorithm, int msgSize, + int offset, int iters, int warmupIters) throws Exception { + System.out.println("provider = " + provider); + System.out.println("algorithm = " + algorithm); + System.out.println("msgSize = " + msgSize + " bytes"); + System.out.println("offset = " + offset); + System.out.println("iters = " + iters); + + byte[] expectedHash = new byte[HASH_LEN]; + byte[] hash = new byte[HASH_LEN]; + byte[] data = new byte[msgSize + offset]; + for (int i = 0; i < (msgSize + offset); i++) { + data[i] = (byte)(i & 0xff); + } + + try { + MessageDigest sha = MessageDigest.getInstance(algorithm, provider); + + /* do once, which doesn't use intrinsics */ + sha.reset(); + sha.update(data, offset, msgSize); + expectedHash = sha.digest(); + + /* warm up */ + for (int i = 0; i < warmupIters; i++) { + sha.reset(); + sha.update(data, offset, msgSize); + hash = sha.digest(); + } + + /* check result */ + if (Arrays.equals(hash, expectedHash) == false) { + System.out.println("TestSHA Error: "); + showArray(expectedHash, "expectedHash"); + showArray(hash, "computedHash"); + //System.exit(1); + throw new Exception("TestSHA Error"); + } else { + showArray(hash, "hash"); + } + + /* measure performance */ + long start = System.nanoTime(); + for (int i = 0; i < iters; i++) { + sha.reset(); + sha.update(data, offset, msgSize); + hash = sha.digest(); + } + long end = System.nanoTime(); + double total = (double)(end - start)/1e9; /* in seconds */ + double thruput = (double)msgSize*iters/1e6/total; /* in MB/s */ + System.out.println("TestSHA runtime = " + total + " seconds"); + System.out.println("TestSHA throughput = " + thruput + " MB/s"); + System.out.println(); + } catch (Exception e) { + System.out.println("Exception: " + e); + //System.exit(1); + throw new Exception(e); + } + } + + static void showArray(byte b[], String name) { + System.out.format("%s [%d]: ", name, b.length); + for (int i = 0; i < Math.min(b.length, HASH_LEN); i++) { + System.out.format("%02x ", b[i] & 0xff); + } + System.out.println(); + } +} diff -r 2dcf544eb7ed -r e77007eacea5 hotspot/test/compiler/loopopts/TestLogSum.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/loopopts/TestLogSum.java Wed Jun 18 10:56:06 2014 -0700 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046516 + * @summary Segmentation fault in JVM (easily reproducible) + * @run main/othervm -XX:-TieredCompilation -Xbatch TestLogSum + * @author jackkamm@gmail.com + */ + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +public class TestLogSum { + public static void main(String[] args) { + double sum; + + for (int i = 0; i < 6; i++) { + for (int n = 2; n < 30; n++) { + for (int j = 1; j <= n; j++) { + for (int k = 1; k <= j; k++) { + // System.out.println(computeSum(k, j)); + sum = computeSum(k, j); + } + } + } + } + } + + private static Map, Double> cache = new HashMap, Double>(); + public static double computeSum(int x, int y) { + List key = Arrays.asList(new Integer[] {x, y}); + + if (!cache.containsKey(key)) { + + // explicitly creating/updating a double[] array, instead of using the LogSumArray wrapper object, will prevent the error + LogSumArray toReturn = new LogSumArray(x); + + // changing loop indices will prevent the error + // in particular, for(z=0; z { + public static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + + private static final String NONEXISTENT_FLAG = "NonexistentFlag"; + private final String flagName; + private final BiConsumer test; + private final BiConsumer set; + private final Function get; + + protected VmFlagTest(String flagName, BiConsumer set, + Function get, boolean isPositive) { + this.flagName = flagName; + this.set = set; + this.get = get; + if (isPositive) { + test = this::testPositive; + } else { + test = this::testNegative; + } + } + + private void setNewValue(T value) { + set.accept(flagName, value); + } + + private T getValue() { + return get.apply(flagName); + } + + protected static void runTest(String existentFlag, T[] tests, + BiConsumer set, Function get) { + runTest(existentFlag, tests, tests, set, get); + } + + protected static void runTest(String existentFlag, T[] tests, + T[] results, BiConsumer set, Function get) { + if (existentFlag != null) { + new VmFlagTest(existentFlag, set, get, true).test(tests, results); + } + new VmFlagTest(NONEXISTENT_FLAG, set, get, false).test(tests, results); + } + + public final void test(T[] tests, T[] results) { + Asserts.assertEQ(tests.length, results.length, "[TESTBUG] tests.length != results.length"); + for (int i = 0, n = tests.length ; i < n; ++i) { + test.accept(tests[i], results[i]); + } + } + + protected String getVMOptionAsString() { + HotSpotDiagnosticMXBean diagnostic + = ManagementFactoryHelper.getDiagnosticMXBean(); + VMOption tmp; + try { + tmp = diagnostic.getVMOption(flagName); + } catch (IllegalArgumentException e) { + tmp = null; + } + return tmp == null ? null : tmp.getValue(); + } + + private void testPositive(T value, T expected) { + Asserts.assertEQ(getVMOptionAsString(), asString(getValue())); + setNewValue(value); + String newValue = getVMOptionAsString(); + Asserts.assertEQ(newValue, asString(expected)); + Asserts.assertEQ(getVMOptionAsString(), asString(getValue())); + } + + private void testNegative(T value, T expected) { + String oldValue = getVMOptionAsString(); + Asserts.assertEQ(oldValue, asString(getValue())); + setNewValue(value); + String newValue = getVMOptionAsString(); + Asserts.assertEQ(oldValue, newValue); + } + + private String asString(Object value) { + return value == null ? null : "" + value; + } +} +