Merge
This commit is contained in:
commit
27cdb7684e
@ -52,3 +52,4 @@ e1b972ff53cd58f825791f8ed9b2deffd16e768c jdk7-b68
|
|||||||
d1516b9f23954b29b8e76e6f4efc467c08c78133 jdk7-b75
|
d1516b9f23954b29b8e76e6f4efc467c08c78133 jdk7-b75
|
||||||
c8b63075403d53a208104a8a6ea5072c1cb66aab jdk7-b76
|
c8b63075403d53a208104a8a6ea5072c1cb66aab jdk7-b76
|
||||||
1f17ca8353babb13f4908c1f87d11508232518c8 jdk7-b77
|
1f17ca8353babb13f4908c1f87d11508232518c8 jdk7-b77
|
||||||
|
ab4ae8f4514693a9fe17ca2fec0239d8f8450d2c jdk7-b78
|
||||||
|
@ -52,3 +52,4 @@ f4b900403d6e4b0af51447bd13bbe23fe3a1dac7 jdk7-b74
|
|||||||
d8dd291a362acb656026a9c0a9da48501505a1e7 jdk7-b75
|
d8dd291a362acb656026a9c0a9da48501505a1e7 jdk7-b75
|
||||||
9174bb32e934965288121f75394874eeb1fcb649 jdk7-b76
|
9174bb32e934965288121f75394874eeb1fcb649 jdk7-b76
|
||||||
455105fc81d941482f8f8056afaa7aa0949c9300 jdk7-b77
|
455105fc81d941482f8f8056afaa7aa0949c9300 jdk7-b77
|
||||||
|
e703499b4b51e3af756ae77c3d5e8b3058a14e4e jdk7-b78
|
||||||
|
@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2009
|
|||||||
|
|
||||||
HS_MAJOR_VER=17
|
HS_MAJOR_VER=17
|
||||||
HS_MINOR_VER=0
|
HS_MINOR_VER=0
|
||||||
HS_BUILD_NUMBER=05
|
HS_BUILD_NUMBER=06
|
||||||
|
|
||||||
JDK_MAJOR_VER=1
|
JDK_MAJOR_VER=1
|
||||||
JDK_MINOR_VER=7
|
JDK_MINOR_VER=7
|
||||||
|
@ -38,7 +38,7 @@ _JUNK_ := $(shell echo -e >&2 ""\
|
|||||||
"Please use 'make jvmg' to build debug JVM. \n" \
|
"Please use 'make jvmg' to build debug JVM. \n" \
|
||||||
"----------------------------------------------------------------------\n")
|
"----------------------------------------------------------------------\n")
|
||||||
|
|
||||||
G_SUFFIX =
|
G_SUFFIX = _g
|
||||||
VERSION = debug
|
VERSION = debug
|
||||||
SYSDEFS += -DASSERT -DDEBUG
|
SYSDEFS += -DASSERT -DDEBUG
|
||||||
PICFLAGS = DEFAULT
|
PICFLAGS = DEFAULT
|
||||||
|
@ -58,7 +58,7 @@ CFLAGS$(HOTSPARC_GENERIC) += $(OPT_CFLAGS/BYFILE)
|
|||||||
# Linker mapfile
|
# Linker mapfile
|
||||||
MAPFILE = $(GAMMADIR)/make/linux/makefiles/mapfile-vers-debug
|
MAPFILE = $(GAMMADIR)/make/linux/makefiles/mapfile-vers-debug
|
||||||
|
|
||||||
G_SUFFIX =
|
G_SUFFIX = _g
|
||||||
VERSION = optimized
|
VERSION = optimized
|
||||||
SYSDEFS += -DASSERT -DFASTDEBUG
|
SYSDEFS += -DASSERT -DFASTDEBUG
|
||||||
PICFLAGS = DEFAULT
|
PICFLAGS = DEFAULT
|
||||||
|
@ -25,9 +25,12 @@
|
|||||||
# Rules to build signal interposition library, used by vm.make
|
# Rules to build signal interposition library, used by vm.make
|
||||||
|
|
||||||
# libjsig[_g].so: signal interposition library
|
# libjsig[_g].so: signal interposition library
|
||||||
JSIG = jsig$(G_SUFFIX)
|
JSIG = jsig
|
||||||
LIBJSIG = lib$(JSIG).so
|
LIBJSIG = lib$(JSIG).so
|
||||||
|
|
||||||
|
JSIG_G = $(JSIG)$(G_SUFFIX)
|
||||||
|
LIBJSIG_G = lib$(JSIG_G).so
|
||||||
|
|
||||||
JSIGSRCDIR = $(GAMMADIR)/src/os/$(Platform_os_family)/vm
|
JSIGSRCDIR = $(GAMMADIR)/src/os/$(Platform_os_family)/vm
|
||||||
|
|
||||||
DEST_JSIG = $(JDK_LIBDIR)/$(LIBJSIG)
|
DEST_JSIG = $(JDK_LIBDIR)/$(LIBJSIG)
|
||||||
@ -50,6 +53,7 @@ $(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE)
|
|||||||
@echo Making signal interposition lib...
|
@echo Making signal interposition lib...
|
||||||
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
|
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
|
||||||
$(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) -o $@ $< -ldl
|
$(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) -o $@ $< -ldl
|
||||||
|
$(QUIETLY) [ -f $(LIBJSIG_G) ] || { ln -s $@ $(LIBJSIG_G); }
|
||||||
|
|
||||||
install_jsig: $(LIBJSIG)
|
install_jsig: $(LIBJSIG)
|
||||||
@echo "Copying $(LIBJSIG) to $(DEST_JSIG)"
|
@echo "Copying $(LIBJSIG) to $(DEST_JSIG)"
|
||||||
|
@ -35,7 +35,7 @@ CFLAGS += $(DEBUG_CFLAGS/BYFILE)
|
|||||||
# Linker mapfile
|
# Linker mapfile
|
||||||
MAPFILE = $(GAMMADIR)/make/linux/makefiles/mapfile-vers-debug
|
MAPFILE = $(GAMMADIR)/make/linux/makefiles/mapfile-vers-debug
|
||||||
|
|
||||||
G_SUFFIX =
|
G_SUFFIX = _g
|
||||||
VERSION = debug
|
VERSION = debug
|
||||||
SYSDEFS += -DASSERT -DDEBUG
|
SYSDEFS += -DASSERT -DDEBUG
|
||||||
PICFLAGS = DEFAULT
|
PICFLAGS = DEFAULT
|
||||||
|
@ -25,7 +25,9 @@
|
|||||||
# Rules to build gamma launcher, used by vm.make
|
# Rules to build gamma launcher, used by vm.make
|
||||||
|
|
||||||
# gamma[_g]: launcher
|
# gamma[_g]: launcher
|
||||||
LAUNCHER = gamma$(G_SUFFIX)
|
|
||||||
|
LAUNCHER = gamma
|
||||||
|
LAUNCHER_G = $(LAUNCHER)$(G_SUFFIX)
|
||||||
|
|
||||||
LAUNCHERDIR = $(GAMMADIR)/src/os/$(Platform_os_family)/launcher
|
LAUNCHERDIR = $(GAMMADIR)/src/os/$(Platform_os_family)/launcher
|
||||||
LAUNCHERFLAGS = $(ARCHFLAG) \
|
LAUNCHERFLAGS = $(ARCHFLAG) \
|
||||||
@ -70,4 +72,5 @@ $(LAUNCHER): $(LAUNCHER.o) $(LIBJVM) $(LAUNCHER_MAPFILE)
|
|||||||
$(LINK_LAUNCHER/PRE_HOOK) \
|
$(LINK_LAUNCHER/PRE_HOOK) \
|
||||||
$(LINK_LAUNCHER) $(LFLAGS_LAUNCHER) -o $@ $(LAUNCHER.o) $(LIBS_LAUNCHER); \
|
$(LINK_LAUNCHER) $(LFLAGS_LAUNCHER) -o $@ $(LAUNCHER.o) $(LIBS_LAUNCHER); \
|
||||||
$(LINK_LAUNCHER/POST_HOOK) \
|
$(LINK_LAUNCHER/POST_HOOK) \
|
||||||
|
[ -f $(LAUNCHER_G) ] || { ln -s $@ $(LAUNCHER_G); }; \
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,13 @@
|
|||||||
# Rules to build serviceability agent library, used by vm.make
|
# Rules to build serviceability agent library, used by vm.make
|
||||||
|
|
||||||
# libsaproc[_g].so: serviceability agent
|
# libsaproc[_g].so: serviceability agent
|
||||||
SAPROC = saproc$(G_SUFFIX)
|
|
||||||
|
SAPROC = saproc
|
||||||
LIBSAPROC = lib$(SAPROC).so
|
LIBSAPROC = lib$(SAPROC).so
|
||||||
|
|
||||||
|
SAPROC_G = $(SAPROC)$(G_SUFFIX)
|
||||||
|
LIBSAPROC_G = lib$(SAPROC_G).so
|
||||||
|
|
||||||
AGENT_DIR = $(GAMMADIR)/agent
|
AGENT_DIR = $(GAMMADIR)/agent
|
||||||
|
|
||||||
SASRCDIR = $(AGENT_DIR)/src/os/$(Platform_os_family)
|
SASRCDIR = $(AGENT_DIR)/src/os/$(Platform_os_family)
|
||||||
@ -75,6 +79,7 @@ $(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE)
|
|||||||
$(SA_DEBUG_CFLAGS) \
|
$(SA_DEBUG_CFLAGS) \
|
||||||
-o $@ \
|
-o $@ \
|
||||||
-lthread_db
|
-lthread_db
|
||||||
|
$(QUIETLY) [ -f $(LIBSAPROC_G) ] || { ln -s $@ $(LIBSAPROC_G); }
|
||||||
|
|
||||||
install_saproc: checkAndBuildSA
|
install_saproc: checkAndBuildSA
|
||||||
$(QUIETLY) if [ -e $(LIBSAPROC) ] ; then \
|
$(QUIETLY) if [ -e $(LIBSAPROC) ] ; then \
|
||||||
|
@ -113,8 +113,9 @@ include $(MAKEFILES_DIR)/dtrace.make
|
|||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
# JVM
|
# JVM
|
||||||
|
|
||||||
JVM = jvm$(G_SUFFIX)
|
JVM = jvm
|
||||||
LIBJVM = lib$(JVM).so
|
LIBJVM = lib$(JVM).so
|
||||||
|
LIBJVM_G = lib$(JVM)$(G_SUFFIX).so
|
||||||
|
|
||||||
JVM_OBJ_FILES = $(Obj_Files)
|
JVM_OBJ_FILES = $(Obj_Files)
|
||||||
|
|
||||||
@ -201,6 +202,7 @@ $(LIBJVM): $(LIBJVM.o) $(LIBJVM_MAPFILE) $(LD_SCRIPT)
|
|||||||
$(LFLAGS_VM) -o $@ $(LIBJVM.o) $(LIBS_VM); \
|
$(LFLAGS_VM) -o $@ $(LIBJVM.o) $(LIBS_VM); \
|
||||||
$(LINK_LIB.CC/POST_HOOK) \
|
$(LINK_LIB.CC/POST_HOOK) \
|
||||||
rm -f $@.1; ln -s $@ $@.1; \
|
rm -f $@.1; ln -s $@ $@.1; \
|
||||||
|
[ -f $(LIBJVM_G) ] || { ln -s $@ $(LIBJVM_G); ln -s $@.1 $(LIBJVM_G).1; }; \
|
||||||
if [ -x /usr/sbin/selinuxenabled ] ; then \
|
if [ -x /usr/sbin/selinuxenabled ] ; then \
|
||||||
/usr/sbin/selinuxenabled; \
|
/usr/sbin/selinuxenabled; \
|
||||||
if [ $$? = 0 ] ; then \
|
if [ $$? = 0 ] ; then \
|
||||||
|
@ -54,7 +54,7 @@ _JUNK_ := $(shell echo >&2 ""\
|
|||||||
"Please use 'gnumake jvmg' to build debug JVM. \n" \
|
"Please use 'gnumake jvmg' to build debug JVM. \n" \
|
||||||
"-------------------------------------------------------------------------\n")
|
"-------------------------------------------------------------------------\n")
|
||||||
|
|
||||||
G_SUFFIX =
|
G_SUFFIX = _g
|
||||||
VERSION = debug
|
VERSION = debug
|
||||||
SYSDEFS += -DASSERT -DDEBUG
|
SYSDEFS += -DASSERT -DDEBUG
|
||||||
PICFLAGS = DEFAULT
|
PICFLAGS = DEFAULT
|
||||||
|
@ -24,8 +24,8 @@
|
|||||||
|
|
||||||
# Rules to build jvm_db/dtrace, used by vm.make
|
# Rules to build jvm_db/dtrace, used by vm.make
|
||||||
|
|
||||||
# we build libjvm_dtrace/libjvm_db/dtrace for COMPILER1 and COMPILER2
|
# We build libjvm_dtrace/libjvm_db/dtrace for COMPILER1 and COMPILER2
|
||||||
# but not for CORE configuration
|
# but not for CORE or KERNEL configurations.
|
||||||
|
|
||||||
ifneq ("${TYPE}", "CORE")
|
ifneq ("${TYPE}", "CORE")
|
||||||
ifneq ("${TYPE}", "KERNEL")
|
ifneq ("${TYPE}", "KERNEL")
|
||||||
@ -37,12 +37,13 @@ dtraceCheck:
|
|||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
|
|
||||||
JVM_DB = libjvm_db
|
JVM_DB = libjvm_db
|
||||||
LIBJVM_DB = libjvm$(G_SUFFIX)_db.so
|
LIBJVM_DB = libjvm_db.so
|
||||||
|
LIBJVM_DB_G = libjvm$(G_SUFFIX)_db.so
|
||||||
|
|
||||||
JVM_DTRACE = jvm_dtrace
|
JVM_DTRACE = jvm_dtrace
|
||||||
LIBJVM_DTRACE = libjvm$(G_SUFFIX)_dtrace.so
|
LIBJVM_DTRACE = libjvm_dtrace.so
|
||||||
|
LIBJVM_DTRACE_G = libjvm$(G_SUFFIX)_dtrace.so
|
||||||
|
|
||||||
JVMOFFS = JvmOffsets
|
JVMOFFS = JvmOffsets
|
||||||
JVMOFFS.o = $(JVMOFFS).o
|
JVMOFFS.o = $(JVMOFFS).o
|
||||||
@ -77,7 +78,7 @@ LFLAGS_JVM_DB += -D_REENTRANT $(PICFLAG)
|
|||||||
LFLAGS_JVM_DTRACE += -D_REENTRANT $(PICFLAG)
|
LFLAGS_JVM_DTRACE += -D_REENTRANT $(PICFLAG)
|
||||||
else
|
else
|
||||||
LFLAGS_JVM_DB += -mt $(PICFLAG) -xnolib
|
LFLAGS_JVM_DB += -mt $(PICFLAG) -xnolib
|
||||||
LFLAGS_JVM_DTRACE += -mt $(PICFLAG) -xnolib
|
LFLAGS_JVM_DTRACE += -mt $(PICFLAG) -xnolib -ldl
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ISA = $(subst i386,i486,$(shell isainfo -n))
|
ISA = $(subst i386,i486,$(shell isainfo -n))
|
||||||
@ -86,18 +87,24 @@ ISA = $(subst i386,i486,$(shell isainfo -n))
|
|||||||
ifneq ("${ISA}","${BUILDARCH}")
|
ifneq ("${ISA}","${BUILDARCH}")
|
||||||
|
|
||||||
XLIBJVM_DB = 64/$(LIBJVM_DB)
|
XLIBJVM_DB = 64/$(LIBJVM_DB)
|
||||||
|
XLIBJVM_DB_G = 64/$(LIBJVM_DB_G)
|
||||||
XLIBJVM_DTRACE = 64/$(LIBJVM_DTRACE)
|
XLIBJVM_DTRACE = 64/$(LIBJVM_DTRACE)
|
||||||
|
XLIBJVM_DTRACE_G = 64/$(LIBJVM_DTRACE_G)
|
||||||
|
|
||||||
$(XLIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE)
|
$(XLIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE)
|
||||||
@echo Making $@
|
@echo Making $@
|
||||||
$(QUIETLY) mkdir -p 64/ ; \
|
$(QUIETLY) mkdir -p 64/ ; \
|
||||||
$(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. -I$(GENERATED) \
|
$(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. -I$(GENERATED) \
|
||||||
$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
|
$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
|
||||||
|
[ -f $(XLIBJVM_DB_G) ] || { ln -s $(LIBJVM_DB) $(XLIBJVM_DB_G); }
|
||||||
|
|
||||||
$(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
|
$(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
|
||||||
@echo Making $@
|
@echo Making $@
|
||||||
$(QUIETLY) mkdir -p 64/ ; \
|
$(QUIETLY) mkdir -p 64/ ; \
|
||||||
$(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. \
|
$(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. \
|
||||||
$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
|
$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
|
||||||
|
[ -f $(XLIBJVM_DTRACE_G) ] || { ln -s $(LIBJVM_DTRACE) $(XLIBJVM_DTRACE_G); }
|
||||||
|
|
||||||
endif # ifneq ("${ISA}","${BUILDARCH}")
|
endif # ifneq ("${ISA}","${BUILDARCH}")
|
||||||
|
|
||||||
ifdef USE_GCC
|
ifdef USE_GCC
|
||||||
@ -142,11 +149,13 @@ $(LIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS.o) $(XLIBJVM_DB) $(LIBJVM_D
|
|||||||
@echo Making $@
|
@echo Making $@
|
||||||
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. -I$(GENERATED) \
|
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. -I$(GENERATED) \
|
||||||
$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
|
$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
|
||||||
|
[ -f $(LIBJVM_DB_G) ] || { ln -s $@ $(LIBJVM_DB_G); }
|
||||||
|
|
||||||
$(LIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(XLIBJVM_DTRACE) $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
|
$(LIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(XLIBJVM_DTRACE) $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
|
||||||
@echo Making $@
|
@echo Making $@
|
||||||
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. \
|
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. \
|
||||||
$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
|
$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
|
||||||
|
[ -f $(LIBJVM_DTRACE_G) ] || { ln -s $@ $(LIBJVM_DTRACE_G); }
|
||||||
|
|
||||||
$(DTRACE).d: $(DTRACE_SRCDIR)/hotspot.d $(DTRACE_SRCDIR)/hotspot_jni.d \
|
$(DTRACE).d: $(DTRACE_SRCDIR)/hotspot.d $(DTRACE_SRCDIR)/hotspot_jni.d \
|
||||||
$(DTRACE_SRCDIR)/hs_private.d $(DTRACE_SRCDIR)/jhelper.d
|
$(DTRACE_SRCDIR)/hs_private.d $(DTRACE_SRCDIR)/jhelper.d
|
||||||
|
@ -90,7 +90,6 @@ endif # Platform_compiler == sparcWorks
|
|||||||
# for this method for now. (fix this when dtrace bug 6258412 is fixed)
|
# for this method for now. (fix this when dtrace bug 6258412 is fixed)
|
||||||
OPT_CFLAGS/ciEnv.o = $(OPT_CFLAGS) -xinline=no%__1cFciEnvbFpost_compiled_method_load_event6MpnHnmethod__v_
|
OPT_CFLAGS/ciEnv.o = $(OPT_CFLAGS) -xinline=no%__1cFciEnvbFpost_compiled_method_load_event6MpnHnmethod__v_
|
||||||
|
|
||||||
|
|
||||||
# (OPT_CFLAGS/SLOWER is also available, to alter compilation of buggy files)
|
# (OPT_CFLAGS/SLOWER is also available, to alter compilation of buggy files)
|
||||||
|
|
||||||
# If you set HOTSPARC_GENERIC=yes, you disable all OPT_CFLAGS settings
|
# If you set HOTSPARC_GENERIC=yes, you disable all OPT_CFLAGS settings
|
||||||
@ -115,8 +114,7 @@ MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers \
|
|||||||
# and mustn't be otherwise.
|
# and mustn't be otherwise.
|
||||||
MAPFILE_DTRACE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-$(TYPE)
|
MAPFILE_DTRACE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-$(TYPE)
|
||||||
|
|
||||||
|
G_SUFFIX = _g
|
||||||
G_SUFFIX =
|
|
||||||
VERSION = optimized
|
VERSION = optimized
|
||||||
SYSDEFS += -DASSERT -DFASTDEBUG -DCHECK_UNHANDLED_OOPS
|
SYSDEFS += -DASSERT -DFASTDEBUG -DCHECK_UNHANDLED_OOPS
|
||||||
PICFLAGS = DEFAULT
|
PICFLAGS = DEFAULT
|
||||||
|
@ -25,8 +25,11 @@
|
|||||||
# Rules to build signal interposition library, used by vm.make
|
# Rules to build signal interposition library, used by vm.make
|
||||||
|
|
||||||
# libjsig[_g].so: signal interposition library
|
# libjsig[_g].so: signal interposition library
|
||||||
JSIG = jsig$(G_SUFFIX)
|
JSIG = jsig
|
||||||
LIBJSIG = lib$(JSIG).so
|
LIBJSIG = lib$(JSIG).so
|
||||||
|
|
||||||
|
JSIG_G = $(JSIG)$(G_SUFFIX)
|
||||||
|
LIBJSIG_G = lib$(JSIG_G).so
|
||||||
|
|
||||||
JSIGSRCDIR = $(GAMMADIR)/src/os/$(Platform_os_family)/vm
|
JSIGSRCDIR = $(GAMMADIR)/src/os/$(Platform_os_family)/vm
|
||||||
|
|
||||||
@ -46,6 +49,7 @@ $(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE)
|
|||||||
@echo Making signal interposition lib...
|
@echo Making signal interposition lib...
|
||||||
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
|
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
|
||||||
$(LFLAGS_JSIG) -o $@ $< -ldl
|
$(LFLAGS_JSIG) -o $@ $< -ldl
|
||||||
|
[ -f $(LIBJSIG_G) ] || { ln -s $@ $(LIBJSIG_G); }
|
||||||
|
|
||||||
install_jsig: $(LIBJSIG)
|
install_jsig: $(LIBJSIG)
|
||||||
@echo "Copying $(LIBJSIG) to $(DEST_JSIG)"
|
@echo "Copying $(LIBJSIG) to $(DEST_JSIG)"
|
||||||
|
@ -51,7 +51,7 @@ MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers \
|
|||||||
# and mustn't be otherwise.
|
# and mustn't be otherwise.
|
||||||
MAPFILE_DTRACE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-$(TYPE)
|
MAPFILE_DTRACE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-$(TYPE)
|
||||||
|
|
||||||
G_SUFFIX =
|
G_SUFFIX = _g
|
||||||
VERSION = debug
|
VERSION = debug
|
||||||
SYSDEFS += -DASSERT -DDEBUG
|
SYSDEFS += -DASSERT -DDEBUG
|
||||||
PICFLAGS = DEFAULT
|
PICFLAGS = DEFAULT
|
||||||
|
@ -25,7 +25,8 @@
|
|||||||
# Rules to build gamma launcher, used by vm.make
|
# Rules to build gamma launcher, used by vm.make
|
||||||
|
|
||||||
# gamma[_g]: launcher
|
# gamma[_g]: launcher
|
||||||
LAUNCHER = gamma$(G_SUFFIX)
|
LAUNCHER = gamma
|
||||||
|
LAUNCHER_G = $(LAUNCHER)$(G_SUFFIX)
|
||||||
|
|
||||||
LAUNCHERDIR = $(GAMMADIR)/src/os/$(Platform_os_family)/launcher
|
LAUNCHERDIR = $(GAMMADIR)/src/os/$(Platform_os_family)/launcher
|
||||||
LAUNCHERFLAGS = $(ARCHFLAG) \
|
LAUNCHERFLAGS = $(ARCHFLAG) \
|
||||||
@ -88,5 +89,6 @@ $(LAUNCHER): $(LAUNCHER.o) $(LIBJVM) $(LAUNCHER_MAPFILE)
|
|||||||
$(LINK_LAUNCHER/PRE_HOOK) \
|
$(LINK_LAUNCHER/PRE_HOOK) \
|
||||||
$(LINK_LAUNCHER) $(LFLAGS_LAUNCHER) -o $@ $(LAUNCHER.o) $(LIBS_LAUNCHER); \
|
$(LINK_LAUNCHER) $(LFLAGS_LAUNCHER) -o $@ $(LAUNCHER.o) $(LIBS_LAUNCHER); \
|
||||||
$(LINK_LAUNCHER/POST_HOOK) \
|
$(LINK_LAUNCHER/POST_HOOK) \
|
||||||
|
[ -f $(LAUNCHER_G) ] || { ln -s $@ $(LAUNCHER_G); }; \
|
||||||
;; \
|
;; \
|
||||||
esac
|
esac
|
||||||
|
@ -25,9 +25,13 @@
|
|||||||
# Rules to build serviceability agent library, used by vm.make
|
# Rules to build serviceability agent library, used by vm.make
|
||||||
|
|
||||||
# libsaproc[_g].so: serviceability agent
|
# libsaproc[_g].so: serviceability agent
|
||||||
SAPROC = saproc$(G_SUFFIX)
|
|
||||||
|
SAPROC = saproc
|
||||||
LIBSAPROC = lib$(SAPROC).so
|
LIBSAPROC = lib$(SAPROC).so
|
||||||
|
|
||||||
|
SAPROC_G = $(SAPROC)$(G_SUFFIX)
|
||||||
|
LIBSAPROC_G = lib$(SAPROC_G).so
|
||||||
|
|
||||||
AGENT_DIR = $(GAMMADIR)/agent
|
AGENT_DIR = $(GAMMADIR)/agent
|
||||||
|
|
||||||
SASRCDIR = $(AGENT_DIR)/src/os/$(Platform_os_family)/proc
|
SASRCDIR = $(AGENT_DIR)/src/os/$(Platform_os_family)/proc
|
||||||
@ -69,6 +73,7 @@ $(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE)
|
|||||||
$(SA_LFLAGS) \
|
$(SA_LFLAGS) \
|
||||||
-o $@ \
|
-o $@ \
|
||||||
-ldl -ldemangle -lthread -lc
|
-ldl -ldemangle -lthread -lc
|
||||||
|
[ -f $(LIBSAPROC_G) ] || { ln -s $@ $(LIBSAPROC_G); }
|
||||||
|
|
||||||
install_saproc: checkAndBuildSA
|
install_saproc: checkAndBuildSA
|
||||||
$(QUIETLY) if [ -f $(LIBSAPROC) ] ; then \
|
$(QUIETLY) if [ -f $(LIBSAPROC) ] ; then \
|
||||||
|
@ -281,8 +281,6 @@ else
|
|||||||
OPT_CFLAGS=-xO4 $(EXTRA_OPT_CFLAGS)
|
OPT_CFLAGS=-xO4 $(EXTRA_OPT_CFLAGS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CFLAGS += $(GAMMADIR)/src/os_cpu/solaris_sparc/vm/solaris_sparc.il
|
|
||||||
|
|
||||||
endif # sparc
|
endif # sparc
|
||||||
|
|
||||||
ifeq ("${Platform_arch_model}", "x86_32")
|
ifeq ("${Platform_arch_model}", "x86_32")
|
||||||
@ -293,13 +291,14 @@ OPT_CFLAGS=-xtarget=pentium $(EXTRA_OPT_CFLAGS)
|
|||||||
# [phh] Is this still true for 6.1?
|
# [phh] Is this still true for 6.1?
|
||||||
OPT_CFLAGS+=-xO3
|
OPT_CFLAGS+=-xO3
|
||||||
|
|
||||||
CFLAGS += $(GAMMADIR)/src/os_cpu/solaris_x86/vm/solaris_x86_32.il
|
|
||||||
|
|
||||||
endif # 32bit x86
|
endif # 32bit x86
|
||||||
|
|
||||||
# no more exceptions
|
# no more exceptions
|
||||||
CFLAGS/NOEX=-noex
|
CFLAGS/NOEX=-noex
|
||||||
|
|
||||||
|
# Inline functions
|
||||||
|
CFLAGS += $(GAMMADIR)/src/os_cpu/solaris_${Platform_arch}/vm/solaris_${Platform_arch_model}.il
|
||||||
|
|
||||||
# Reduce code bloat by reverting back to 5.0 behavior for static initializers
|
# Reduce code bloat by reverting back to 5.0 behavior for static initializers
|
||||||
CFLAGS += -Qoption ccfe -one_static_init
|
CFLAGS += -Qoption ccfe -one_static_init
|
||||||
|
|
||||||
@ -312,6 +311,15 @@ PICFLAG/DEFAULT = $(PICFLAG)
|
|||||||
PICFLAG/BETTER = $(PICFLAG/DEFAULT)
|
PICFLAG/BETTER = $(PICFLAG/DEFAULT)
|
||||||
PICFLAG/BYFILE = $(PICFLAG/$@)$(PICFLAG/DEFAULT$(PICFLAG/$@))
|
PICFLAG/BYFILE = $(PICFLAG/$@)$(PICFLAG/DEFAULT$(PICFLAG/$@))
|
||||||
|
|
||||||
|
# Use $(MAPFLAG:FILENAME=real_file_name) to specify a map file.
|
||||||
|
MAPFLAG = -M FILENAME
|
||||||
|
|
||||||
|
# Use $(SONAMEFLAG:SONAME=soname) to specify the intrinsic name of a shared obj
|
||||||
|
SONAMEFLAG = -h SONAME
|
||||||
|
|
||||||
|
# Build shared library
|
||||||
|
SHARED_FLAG = -G
|
||||||
|
|
||||||
# Would be better if these weren't needed, since we link with CC, but
|
# Would be better if these weren't needed, since we link with CC, but
|
||||||
# at present removing them causes run-time errors
|
# at present removing them causes run-time errors
|
||||||
LFLAGS += -library=Crun
|
LFLAGS += -library=Crun
|
||||||
|
@ -108,11 +108,16 @@ ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 505), 1)
|
|||||||
# older libm before libCrun, just to make sure it's found and used first.
|
# older libm before libCrun, just to make sure it's found and used first.
|
||||||
LIBS += -lsocket -lsched -ldl $(LIBM) -lCrun -lthread -ldoor -lc
|
LIBS += -lsocket -lsched -ldl $(LIBM) -lCrun -lthread -ldoor -lc
|
||||||
else
|
else
|
||||||
|
ifeq ($(COMPILER_REV_NUMERIC), 502)
|
||||||
|
# SC6.1 has it's own libm.so: specifying anything else provokes a name conflict.
|
||||||
|
LIBS += -ldl -lthread -lsocket -lm -lsched -ldoor
|
||||||
|
else
|
||||||
LIBS += -ldl -lthread -lsocket $(LIBM) -lsched -ldoor
|
LIBS += -ldl -lthread -lsocket $(LIBM) -lsched -ldoor
|
||||||
endif
|
endif # 502
|
||||||
|
endif # 505
|
||||||
else
|
else
|
||||||
LIBS += -lsocket -lsched -ldl $(LIBM) -lthread -lc
|
LIBS += -lsocket -lsched -ldl $(LIBM) -lthread -lc
|
||||||
endif
|
endif # sparcWorks
|
||||||
|
|
||||||
# By default, link the *.o into the library, not the executable.
|
# By default, link the *.o into the library, not the executable.
|
||||||
LINK_INTO$(LINK_INTO) = LIBJVM
|
LINK_INTO$(LINK_INTO) = LIBJVM
|
||||||
@ -126,8 +131,9 @@ include $(MAKEFILES_DIR)/dtrace.make
|
|||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
# JVM
|
# JVM
|
||||||
|
|
||||||
JVM = jvm$(G_SUFFIX)
|
JVM = jvm
|
||||||
LIBJVM = lib$(JVM).so
|
LIBJVM = lib$(JVM).so
|
||||||
|
LIBJVM_G = lib$(JVM)$(G_SUFFIX).so
|
||||||
|
|
||||||
JVM_OBJ_FILES = $(Obj_Files) $(DTRACE_OBJS)
|
JVM_OBJ_FILES = $(Obj_Files) $(DTRACE_OBJS)
|
||||||
|
|
||||||
@ -173,11 +179,12 @@ $(LIBJVM): $(LIBJVM.o) $(LIBJVM_MAPFILE)
|
|||||||
-sbfast|-xsbfast) \
|
-sbfast|-xsbfast) \
|
||||||
;; \
|
;; \
|
||||||
*) \
|
*) \
|
||||||
echo Linking vm...; \
|
echo Linking vm...; \
|
||||||
$(LINK_LIB.CC/PRE_HOOK) \
|
$(LINK_LIB.CC/PRE_HOOK) \
|
||||||
$(LINK_VM) $(LFLAGS_VM) -o $@ $(LIBJVM.o) $(LIBS_VM); \
|
$(LINK_VM) $(LFLAGS_VM) -o $@ $(LIBJVM.o) $(LIBS_VM); \
|
||||||
$(LINK_LIB.CC/POST_HOOK) \
|
$(LINK_LIB.CC/POST_HOOK) \
|
||||||
rm -f $@.1; ln -s $@ $@.1; \
|
rm -f $@.1; ln -s $@ $@.1; \
|
||||||
|
[ -f $(LIBJVM_G) ] || { ln -s $@ $(LIBJVM_G); ln -s $@.1 $(LIBJVM_G).1; }; \
|
||||||
;; \
|
;; \
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
@ -189,14 +189,17 @@ void LIR_Assembler::osr_entry() {
|
|||||||
Register OSR_buf = osrBufferPointer()->as_register();
|
Register OSR_buf = osrBufferPointer()->as_register();
|
||||||
{ assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below");
|
{ assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below");
|
||||||
int monitor_offset = BytesPerWord * method()->max_locals() +
|
int monitor_offset = BytesPerWord * method()->max_locals() +
|
||||||
(BasicObjectLock::size() * BytesPerWord) * (number_of_locks - 1);
|
(2 * BytesPerWord) * (number_of_locks - 1);
|
||||||
|
// SharedRuntime::OSR_migration_begin() packs BasicObjectLocks in
|
||||||
|
// the OSR buffer using 2 word entries: first the lock and then
|
||||||
|
// the oop.
|
||||||
for (int i = 0; i < number_of_locks; i++) {
|
for (int i = 0; i < number_of_locks; i++) {
|
||||||
int slot_offset = monitor_offset - ((i * BasicObjectLock::size()) * BytesPerWord);
|
int slot_offset = monitor_offset - ((i * 2) * BytesPerWord);
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
// verify the interpreter's monitor has a non-null object
|
// verify the interpreter's monitor has a non-null object
|
||||||
{
|
{
|
||||||
Label L;
|
Label L;
|
||||||
__ ld_ptr(OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes(), O7);
|
__ ld_ptr(OSR_buf, slot_offset + 1*BytesPerWord, O7);
|
||||||
__ cmp(G0, O7);
|
__ cmp(G0, O7);
|
||||||
__ br(Assembler::notEqual, false, Assembler::pt, L);
|
__ br(Assembler::notEqual, false, Assembler::pt, L);
|
||||||
__ delayed()->nop();
|
__ delayed()->nop();
|
||||||
@ -205,9 +208,9 @@ void LIR_Assembler::osr_entry() {
|
|||||||
}
|
}
|
||||||
#endif // ASSERT
|
#endif // ASSERT
|
||||||
// Copy the lock field into the compiled activation.
|
// Copy the lock field into the compiled activation.
|
||||||
__ ld_ptr(OSR_buf, slot_offset + BasicObjectLock::lock_offset_in_bytes(), O7);
|
__ ld_ptr(OSR_buf, slot_offset + 0, O7);
|
||||||
__ st_ptr(O7, frame_map()->address_for_monitor_lock(i));
|
__ st_ptr(O7, frame_map()->address_for_monitor_lock(i));
|
||||||
__ ld_ptr(OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes(), O7);
|
__ ld_ptr(OSR_buf, slot_offset + 1*BytesPerWord, O7);
|
||||||
__ st_ptr(O7, frame_map()->address_for_monitor_object(i));
|
__ st_ptr(O7, frame_map()->address_for_monitor_object(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -953,9 +956,11 @@ int LIR_Assembler::load(Register base, int offset, LIR_Opr to_reg, BasicType typ
|
|||||||
} else {
|
} else {
|
||||||
#ifdef _LP64
|
#ifdef _LP64
|
||||||
assert(base != to_reg->as_register_lo(), "can't handle this");
|
assert(base != to_reg->as_register_lo(), "can't handle this");
|
||||||
|
assert(O7 != to_reg->as_register_lo(), "can't handle this");
|
||||||
__ ld(base, offset + hi_word_offset_in_bytes, to_reg->as_register_lo());
|
__ ld(base, offset + hi_word_offset_in_bytes, to_reg->as_register_lo());
|
||||||
|
__ lduw(base, offset + lo_word_offset_in_bytes, O7); // in case O7 is base or offset, use it last
|
||||||
__ sllx(to_reg->as_register_lo(), 32, to_reg->as_register_lo());
|
__ sllx(to_reg->as_register_lo(), 32, to_reg->as_register_lo());
|
||||||
__ ld(base, offset + lo_word_offset_in_bytes, to_reg->as_register_lo());
|
__ or3(to_reg->as_register_lo(), O7, to_reg->as_register_lo());
|
||||||
#else
|
#else
|
||||||
if (base == to_reg->as_register_lo()) {
|
if (base == to_reg->as_register_lo()) {
|
||||||
__ ld(base, offset + hi_word_offset_in_bytes, to_reg->as_register_hi());
|
__ ld(base, offset + hi_word_offset_in_bytes, to_reg->as_register_hi());
|
||||||
@ -976,8 +981,8 @@ int LIR_Assembler::load(Register base, int offset, LIR_Opr to_reg, BasicType typ
|
|||||||
FloatRegister reg = to_reg->as_double_reg();
|
FloatRegister reg = to_reg->as_double_reg();
|
||||||
// split unaligned loads
|
// split unaligned loads
|
||||||
if (unaligned || PatchALot) {
|
if (unaligned || PatchALot) {
|
||||||
__ ldf(FloatRegisterImpl::S, base, offset + BytesPerWord, reg->successor());
|
__ ldf(FloatRegisterImpl::S, base, offset + 4, reg->successor());
|
||||||
__ ldf(FloatRegisterImpl::S, base, offset, reg);
|
__ ldf(FloatRegisterImpl::S, base, offset, reg);
|
||||||
} else {
|
} else {
|
||||||
__ ldf(FloatRegisterImpl::D, base, offset, to_reg->as_double_reg());
|
__ ldf(FloatRegisterImpl::D, base, offset, to_reg->as_double_reg());
|
||||||
}
|
}
|
||||||
@ -2200,6 +2205,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
|
|||||||
Register len = O2;
|
Register len = O2;
|
||||||
|
|
||||||
__ add(src, arrayOopDesc::base_offset_in_bytes(basic_type), src_ptr);
|
__ add(src, arrayOopDesc::base_offset_in_bytes(basic_type), src_ptr);
|
||||||
|
LP64_ONLY(__ sra(src_pos, 0, src_pos);) //higher 32bits must be null
|
||||||
if (shift == 0) {
|
if (shift == 0) {
|
||||||
__ add(src_ptr, src_pos, src_ptr);
|
__ add(src_ptr, src_pos, src_ptr);
|
||||||
} else {
|
} else {
|
||||||
@ -2208,6 +2214,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
__ add(dst, arrayOopDesc::base_offset_in_bytes(basic_type), dst_ptr);
|
__ add(dst, arrayOopDesc::base_offset_in_bytes(basic_type), dst_ptr);
|
||||||
|
LP64_ONLY(__ sra(dst_pos, 0, dst_pos);) //higher 32bits must be null
|
||||||
if (shift == 0) {
|
if (shift == 0) {
|
||||||
__ add(dst_ptr, dst_pos, dst_ptr);
|
__ add(dst_ptr, dst_pos, dst_ptr);
|
||||||
} else {
|
} else {
|
||||||
|
@ -144,17 +144,17 @@ LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,
|
|||||||
if (index->is_register()) {
|
if (index->is_register()) {
|
||||||
// apply the shift and accumulate the displacement
|
// apply the shift and accumulate the displacement
|
||||||
if (shift > 0) {
|
if (shift > 0) {
|
||||||
LIR_Opr tmp = new_register(T_INT);
|
LIR_Opr tmp = new_pointer_register();
|
||||||
__ shift_left(index, shift, tmp);
|
__ shift_left(index, shift, tmp);
|
||||||
index = tmp;
|
index = tmp;
|
||||||
}
|
}
|
||||||
if (disp != 0) {
|
if (disp != 0) {
|
||||||
LIR_Opr tmp = new_register(T_INT);
|
LIR_Opr tmp = new_pointer_register();
|
||||||
if (Assembler::is_simm13(disp)) {
|
if (Assembler::is_simm13(disp)) {
|
||||||
__ add(tmp, LIR_OprFact::intConst(disp), tmp);
|
__ add(tmp, LIR_OprFact::intptrConst(disp), tmp);
|
||||||
index = tmp;
|
index = tmp;
|
||||||
} else {
|
} else {
|
||||||
__ move(LIR_OprFact::intConst(disp), tmp);
|
__ move(LIR_OprFact::intptrConst(disp), tmp);
|
||||||
__ add(tmp, index, tmp);
|
__ add(tmp, index, tmp);
|
||||||
index = tmp;
|
index = tmp;
|
||||||
}
|
}
|
||||||
@ -162,8 +162,8 @@ LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,
|
|||||||
}
|
}
|
||||||
} else if (disp != 0 && !Assembler::is_simm13(disp)) {
|
} else if (disp != 0 && !Assembler::is_simm13(disp)) {
|
||||||
// index is illegal so replace it with the displacement loaded into a register
|
// index is illegal so replace it with the displacement loaded into a register
|
||||||
index = new_register(T_INT);
|
index = new_pointer_register();
|
||||||
__ move(LIR_OprFact::intConst(disp), index);
|
__ move(LIR_OprFact::intptrConst(disp), index);
|
||||||
disp = 0;
|
disp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,10 +22,9 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//
|
|
||||||
// Sets the default values for platform dependent flags used by the client compiler.
|
// Sets the default values for platform dependent flags used by the client compiler.
|
||||||
// (see c1_globals.hpp)
|
// (see c1_globals.hpp)
|
||||||
//
|
|
||||||
#ifndef TIERED
|
#ifndef TIERED
|
||||||
define_pd_global(bool, BackgroundCompilation, true );
|
define_pd_global(bool, BackgroundCompilation, true );
|
||||||
define_pd_global(bool, CICompileOSR, true );
|
define_pd_global(bool, CICompileOSR, true );
|
||||||
@ -48,27 +47,24 @@ define_pd_global(intx, OnStackReplacePercentage, 1400 );
|
|||||||
define_pd_global(bool, UseTLAB, true );
|
define_pd_global(bool, UseTLAB, true );
|
||||||
define_pd_global(bool, ProfileInterpreter, false);
|
define_pd_global(bool, ProfileInterpreter, false);
|
||||||
define_pd_global(intx, FreqInlineSize, 325 );
|
define_pd_global(intx, FreqInlineSize, 325 );
|
||||||
define_pd_global(intx, NewRatio, 8 ); // Design center runs on 1.3.1
|
|
||||||
define_pd_global(bool, ResizeTLAB, true );
|
define_pd_global(bool, ResizeTLAB, true );
|
||||||
define_pd_global(intx, ReservedCodeCacheSize, 32*M );
|
define_pd_global(intx, ReservedCodeCacheSize, 32*M );
|
||||||
define_pd_global(intx, CodeCacheExpansionSize, 32*K );
|
define_pd_global(intx, CodeCacheExpansionSize, 32*K );
|
||||||
define_pd_global(uintx,CodeCacheMinBlockLength, 1);
|
define_pd_global(uintx,CodeCacheMinBlockLength, 1);
|
||||||
define_pd_global(uintx, PermSize, 12*M );
|
define_pd_global(uintx,PermSize, 12*M );
|
||||||
define_pd_global(uintx, MaxPermSize, 64*M );
|
define_pd_global(uintx,MaxPermSize, 64*M );
|
||||||
define_pd_global(bool, NeverActAsServerClassMachine, true);
|
define_pd_global(bool, NeverActAsServerClassMachine, true );
|
||||||
define_pd_global(intx, NewSizeThreadIncrease, 16*K );
|
define_pd_global(intx, NewSizeThreadIncrease, 16*K );
|
||||||
define_pd_global(uintx, DefaultMaxRAM, 1*G);
|
define_pd_global(uint64_t,MaxRAM, 1ULL*G);
|
||||||
define_pd_global(intx, InitialCodeCacheSize, 160*K);
|
define_pd_global(intx, InitialCodeCacheSize, 160*K);
|
||||||
#endif // TIERED
|
#endif // !TIERED
|
||||||
|
|
||||||
define_pd_global(bool, UseTypeProfile, false);
|
define_pd_global(bool, UseTypeProfile, false);
|
||||||
define_pd_global(bool, RoundFPResults, false);
|
define_pd_global(bool, RoundFPResults, false);
|
||||||
|
|
||||||
|
define_pd_global(bool, LIRFillDelaySlots, true );
|
||||||
define_pd_global(bool, LIRFillDelaySlots, true);
|
|
||||||
define_pd_global(bool, OptimizeSinglePrecision, false);
|
define_pd_global(bool, OptimizeSinglePrecision, false);
|
||||||
define_pd_global(bool, CSEArrayLength, true);
|
define_pd_global(bool, CSEArrayLength, true );
|
||||||
define_pd_global(bool, TwoOperandLIRForm, false);
|
define_pd_global(bool, TwoOperandLIRForm, false);
|
||||||
|
|
||||||
|
define_pd_global(intx, SafepointPollOffset, 0 );
|
||||||
define_pd_global(intx, SafepointPollOffset, 0);
|
|
||||||
|
@ -59,7 +59,6 @@ define_pd_global(intx, FLOATPRESSURE, 52); // C2 on V9 gets to u
|
|||||||
define_pd_global(intx, FreqInlineSize, 175);
|
define_pd_global(intx, FreqInlineSize, 175);
|
||||||
define_pd_global(intx, INTPRESSURE, 48); // large register set
|
define_pd_global(intx, INTPRESSURE, 48); // large register set
|
||||||
define_pd_global(intx, InteriorEntryAlignment, 16); // = CodeEntryAlignment
|
define_pd_global(intx, InteriorEntryAlignment, 16); // = CodeEntryAlignment
|
||||||
define_pd_global(intx, NewRatio, 2);
|
|
||||||
define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
|
define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
|
||||||
// The default setting 16/16 seems to work best.
|
// The default setting 16/16 seems to work best.
|
||||||
// (For _228_jack 16/16 is 2% better than 4/4, 16/4, 32/32, 32/16, or 16/32.)
|
// (For _228_jack 16/16 is 2% better than 4/4, 16/4, 32/32, 32/16, or 16/32.)
|
||||||
@ -83,25 +82,25 @@ define_pd_global(bool, OptoScheduling, true);
|
|||||||
// sequence of instructions to load a 64 bit pointer.
|
// sequence of instructions to load a 64 bit pointer.
|
||||||
//
|
//
|
||||||
// InitialCodeCacheSize derived from specjbb2000 run.
|
// InitialCodeCacheSize derived from specjbb2000 run.
|
||||||
define_pd_global(intx, InitialCodeCacheSize, 2048*K); // Integral multiple of CodeCacheExpansionSize
|
define_pd_global(intx, InitialCodeCacheSize, 2048*K); // Integral multiple of CodeCacheExpansionSize
|
||||||
define_pd_global(intx, ReservedCodeCacheSize, 48*M);
|
define_pd_global(intx, ReservedCodeCacheSize, 48*M);
|
||||||
define_pd_global(intx, CodeCacheExpansionSize, 64*K);
|
define_pd_global(intx, CodeCacheExpansionSize, 64*K);
|
||||||
|
|
||||||
// Ergonomics related flags
|
// Ergonomics related flags
|
||||||
define_pd_global(uintx, DefaultMaxRAM, 32*G);
|
define_pd_global(uint64_t,MaxRAM, 128ULL*G);
|
||||||
#else
|
#else
|
||||||
// InitialCodeCacheSize derived from specjbb2000 run.
|
// InitialCodeCacheSize derived from specjbb2000 run.
|
||||||
define_pd_global(intx, InitialCodeCacheSize, 1536*K); // Integral multiple of CodeCacheExpansionSize
|
define_pd_global(intx, InitialCodeCacheSize, 1536*K); // Integral multiple of CodeCacheExpansionSize
|
||||||
define_pd_global(intx, ReservedCodeCacheSize, 32*M);
|
define_pd_global(intx, ReservedCodeCacheSize, 32*M);
|
||||||
define_pd_global(intx, CodeCacheExpansionSize, 32*K);
|
define_pd_global(intx, CodeCacheExpansionSize, 32*K);
|
||||||
// Ergonomics related flags
|
// Ergonomics related flags
|
||||||
define_pd_global(uintx, DefaultMaxRAM, 1*G);
|
define_pd_global(uint64_t,MaxRAM, 4ULL*G);
|
||||||
#endif
|
#endif
|
||||||
define_pd_global(uintx,CodeCacheMinBlockLength, 4);
|
define_pd_global(uintx,CodeCacheMinBlockLength, 4);
|
||||||
|
|
||||||
// Heap related flags
|
// Heap related flags
|
||||||
define_pd_global(uintx, PermSize, ScaleForWordSize(16*M));
|
define_pd_global(uintx,PermSize, ScaleForWordSize(16*M));
|
||||||
define_pd_global(uintx, MaxPermSize, ScaleForWordSize(64*M));
|
define_pd_global(uintx,MaxPermSize, ScaleForWordSize(64*M));
|
||||||
|
|
||||||
// Ergonomics related flags
|
// Ergonomics related flags
|
||||||
define_pd_global(bool, NeverActAsServerClassMachine, false);
|
define_pd_global(bool, NeverActAsServerClassMachine, false);
|
||||||
|
@ -22,10 +22,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//
|
|
||||||
// Sets the default values for platform dependent flags used by the runtime system.
|
// Sets the default values for platform dependent flags used by the runtime system.
|
||||||
// (see globals.hpp)
|
// (see globals.hpp)
|
||||||
//
|
|
||||||
|
|
||||||
// For sparc we do not do call backs when a thread is in the interpreter, because the
|
// For sparc we do not do call backs when a thread is in the interpreter, because the
|
||||||
// interpreter dispatch needs at least two instructions - first to load the dispatch address
|
// interpreter dispatch needs at least two instructions - first to load the dispatch address
|
||||||
@ -41,26 +39,23 @@ define_pd_global(bool, NeedsDeoptSuspend, true); // register window ma
|
|||||||
define_pd_global(bool, ImplicitNullChecks, true); // Generate code for implicit null checks
|
define_pd_global(bool, ImplicitNullChecks, true); // Generate code for implicit null checks
|
||||||
define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NULLs past to check cast
|
define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NULLs past to check cast
|
||||||
|
|
||||||
define_pd_global(intx, CodeEntryAlignment, 32);
|
define_pd_global(intx, CodeEntryAlignment, 32);
|
||||||
define_pd_global(uintx, TLABSize, 0);
|
define_pd_global(intx, InlineFrequencyCount, 50); // we can use more inlining on the SPARC
|
||||||
define_pd_global(uintx, NewSize, ScaleForWordSize((2048 * K) + (2 * (64 * K))));
|
define_pd_global(intx, InlineSmallCode, 1500);
|
||||||
define_pd_global(intx, SurvivorRatio, 8);
|
|
||||||
define_pd_global(intx, InlineFrequencyCount, 50); // we can use more inlining on the SPARC
|
|
||||||
define_pd_global(intx, InlineSmallCode, 1500);
|
|
||||||
#ifdef _LP64
|
#ifdef _LP64
|
||||||
// Stack slots are 2X larger in LP64 than in the 32 bit VM.
|
// Stack slots are 2X larger in LP64 than in the 32 bit VM.
|
||||||
define_pd_global(intx, ThreadStackSize, 1024);
|
define_pd_global(intx, ThreadStackSize, 1024);
|
||||||
define_pd_global(intx, VMThreadStackSize, 1024);
|
define_pd_global(intx, VMThreadStackSize, 1024);
|
||||||
#else
|
#else
|
||||||
define_pd_global(intx, ThreadStackSize, 512);
|
define_pd_global(intx, ThreadStackSize, 512);
|
||||||
define_pd_global(intx, VMThreadStackSize, 512);
|
define_pd_global(intx, VMThreadStackSize, 512);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
define_pd_global(intx, StackYellowPages, 2);
|
define_pd_global(intx, StackYellowPages, 2);
|
||||||
define_pd_global(intx, StackRedPages, 1);
|
define_pd_global(intx, StackRedPages, 1);
|
||||||
define_pd_global(intx, StackShadowPages, 3 DEBUG_ONLY(+1));
|
define_pd_global(intx, StackShadowPages, 3 DEBUG_ONLY(+1));
|
||||||
|
|
||||||
define_pd_global(intx, PreInflateSpin, 40); // Determined by running design center
|
define_pd_global(intx, PreInflateSpin, 40); // Determined by running design center
|
||||||
|
|
||||||
define_pd_global(bool, RewriteBytecodes, true);
|
define_pd_global(bool, RewriteBytecodes, true);
|
||||||
define_pd_global(bool, RewriteFrequentPairs, true);
|
define_pd_global(bool, RewriteFrequentPairs, true);
|
||||||
|
@ -150,8 +150,7 @@ address TemplateInterpreterGenerator::generate_StackOverflowError_handler() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, bool unbox) {
|
address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step) {
|
||||||
assert(!unbox, "NYI");//6815692//
|
|
||||||
address compiled_entry = __ pc();
|
address compiled_entry = __ pc();
|
||||||
Label cont;
|
Label cont;
|
||||||
|
|
||||||
|
@ -2251,6 +2251,7 @@ void Assembler::popf() {
|
|||||||
emit_byte(0x9D);
|
emit_byte(0x9D);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _LP64 // no 32bit push/pop on amd64
|
||||||
void Assembler::popl(Address dst) {
|
void Assembler::popl(Address dst) {
|
||||||
// NOTE: this will adjust stack by 8byte on 64bits
|
// NOTE: this will adjust stack by 8byte on 64bits
|
||||||
InstructionMark im(this);
|
InstructionMark im(this);
|
||||||
@ -2258,6 +2259,7 @@ void Assembler::popl(Address dst) {
|
|||||||
emit_byte(0x8F);
|
emit_byte(0x8F);
|
||||||
emit_operand(rax, dst);
|
emit_operand(rax, dst);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void Assembler::prefetch_prefix(Address src) {
|
void Assembler::prefetch_prefix(Address src) {
|
||||||
prefix(src);
|
prefix(src);
|
||||||
@ -2428,6 +2430,7 @@ void Assembler::pushf() {
|
|||||||
emit_byte(0x9C);
|
emit_byte(0x9C);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _LP64 // no 32bit push/pop on amd64
|
||||||
void Assembler::pushl(Address src) {
|
void Assembler::pushl(Address src) {
|
||||||
// Note this will push 64bit on 64bit
|
// Note this will push 64bit on 64bit
|
||||||
InstructionMark im(this);
|
InstructionMark im(this);
|
||||||
@ -2435,6 +2438,7 @@ void Assembler::pushl(Address src) {
|
|||||||
emit_byte(0xFF);
|
emit_byte(0xFF);
|
||||||
emit_operand(rsi, src);
|
emit_operand(rsi, src);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void Assembler::pxor(XMMRegister dst, Address src) {
|
void Assembler::pxor(XMMRegister dst, Address src) {
|
||||||
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
|
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
|
||||||
@ -5591,7 +5595,12 @@ void MacroAssembler::align(int modulus) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MacroAssembler::andpd(XMMRegister dst, AddressLiteral src) {
|
void MacroAssembler::andpd(XMMRegister dst, AddressLiteral src) {
|
||||||
andpd(dst, as_Address(src));
|
if (reachable(src)) {
|
||||||
|
andpd(dst, as_Address(src));
|
||||||
|
} else {
|
||||||
|
lea(rscratch1, src);
|
||||||
|
andpd(dst, Address(rscratch1, 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroAssembler::andptr(Register dst, int32_t imm32) {
|
void MacroAssembler::andptr(Register dst, int32_t imm32) {
|
||||||
@ -6078,11 +6087,21 @@ void MacroAssembler::cmpxchgptr(Register reg, Address adr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MacroAssembler::comisd(XMMRegister dst, AddressLiteral src) {
|
void MacroAssembler::comisd(XMMRegister dst, AddressLiteral src) {
|
||||||
comisd(dst, as_Address(src));
|
if (reachable(src)) {
|
||||||
|
comisd(dst, as_Address(src));
|
||||||
|
} else {
|
||||||
|
lea(rscratch1, src);
|
||||||
|
comisd(dst, Address(rscratch1, 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroAssembler::comiss(XMMRegister dst, AddressLiteral src) {
|
void MacroAssembler::comiss(XMMRegister dst, AddressLiteral src) {
|
||||||
comiss(dst, as_Address(src));
|
if (reachable(src)) {
|
||||||
|
comiss(dst, as_Address(src));
|
||||||
|
} else {
|
||||||
|
lea(rscratch1, src);
|
||||||
|
comiss(dst, Address(rscratch1, 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -7647,7 +7666,7 @@ RegisterOrConstant MacroAssembler::delayed_value_impl(intptr_t* delayed_value_ad
|
|||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
Label L;
|
Label L;
|
||||||
testl(tmp, tmp);
|
testptr(tmp, tmp);
|
||||||
jccb(Assembler::notZero, L);
|
jccb(Assembler::notZero, L);
|
||||||
hlt();
|
hlt();
|
||||||
bind(L);
|
bind(L);
|
||||||
|
@ -1244,7 +1244,9 @@ private:
|
|||||||
void pcmpestri(XMMRegister xmm1, XMMRegister xmm2, int imm8);
|
void pcmpestri(XMMRegister xmm1, XMMRegister xmm2, int imm8);
|
||||||
void pcmpestri(XMMRegister xmm1, Address src, int imm8);
|
void pcmpestri(XMMRegister xmm1, Address src, int imm8);
|
||||||
|
|
||||||
|
#ifndef _LP64 // no 32bit push/pop on amd64
|
||||||
void popl(Address dst);
|
void popl(Address dst);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _LP64
|
#ifdef _LP64
|
||||||
void popq(Address dst);
|
void popq(Address dst);
|
||||||
@ -1285,7 +1287,9 @@ private:
|
|||||||
// Interleave Low Bytes
|
// Interleave Low Bytes
|
||||||
void punpcklbw(XMMRegister dst, XMMRegister src);
|
void punpcklbw(XMMRegister dst, XMMRegister src);
|
||||||
|
|
||||||
|
#ifndef _LP64 // no 32bit push/pop on amd64
|
||||||
void pushl(Address src);
|
void pushl(Address src);
|
||||||
|
#endif
|
||||||
|
|
||||||
void pushq(Address src);
|
void pushq(Address src);
|
||||||
|
|
||||||
|
@ -301,22 +301,25 @@ void LIR_Assembler::osr_entry() {
|
|||||||
Register OSR_buf = osrBufferPointer()->as_pointer_register();
|
Register OSR_buf = osrBufferPointer()->as_pointer_register();
|
||||||
{ assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below");
|
{ assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below");
|
||||||
int monitor_offset = BytesPerWord * method()->max_locals() +
|
int monitor_offset = BytesPerWord * method()->max_locals() +
|
||||||
(BasicObjectLock::size() * BytesPerWord) * (number_of_locks - 1);
|
(2 * BytesPerWord) * (number_of_locks - 1);
|
||||||
|
// SharedRuntime::OSR_migration_begin() packs BasicObjectLocks in
|
||||||
|
// the OSR buffer using 2 word entries: first the lock and then
|
||||||
|
// the oop.
|
||||||
for (int i = 0; i < number_of_locks; i++) {
|
for (int i = 0; i < number_of_locks; i++) {
|
||||||
int slot_offset = monitor_offset - ((i * BasicObjectLock::size()) * BytesPerWord);
|
int slot_offset = monitor_offset - ((i * 2) * BytesPerWord);
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
// verify the interpreter's monitor has a non-null object
|
// verify the interpreter's monitor has a non-null object
|
||||||
{
|
{
|
||||||
Label L;
|
Label L;
|
||||||
__ cmpptr(Address(OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD);
|
__ cmpptr(Address(OSR_buf, slot_offset + 1*BytesPerWord), (int32_t)NULL_WORD);
|
||||||
__ jcc(Assembler::notZero, L);
|
__ jcc(Assembler::notZero, L);
|
||||||
__ stop("locked object is NULL");
|
__ stop("locked object is NULL");
|
||||||
__ bind(L);
|
__ bind(L);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
__ movptr(rbx, Address(OSR_buf, slot_offset + BasicObjectLock::lock_offset_in_bytes()));
|
__ movptr(rbx, Address(OSR_buf, slot_offset + 0));
|
||||||
__ movptr(frame_map()->address_for_monitor_lock(i), rbx);
|
__ movptr(frame_map()->address_for_monitor_lock(i), rbx);
|
||||||
__ movptr(rbx, Address(OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes()));
|
__ movptr(rbx, Address(OSR_buf, slot_offset + 1*BytesPerWord));
|
||||||
__ movptr(frame_map()->address_for_monitor_object(i), rbx);
|
__ movptr(frame_map()->address_for_monitor_object(i), rbx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -785,7 +788,13 @@ void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmi
|
|||||||
ShouldNotReachHere();
|
ShouldNotReachHere();
|
||||||
__ movoop(as_Address(addr, noreg), c->as_jobject());
|
__ movoop(as_Address(addr, noreg), c->as_jobject());
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef _LP64
|
||||||
|
__ movoop(rscratch1, c->as_jobject());
|
||||||
|
null_check_here = code_offset();
|
||||||
|
__ movptr(as_Address_lo(addr), rscratch1);
|
||||||
|
#else
|
||||||
__ movoop(as_Address(addr), c->as_jobject());
|
__ movoop(as_Address(addr), c->as_jobject());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1118,8 +1127,14 @@ void LIR_Assembler::stack2stack(LIR_Opr src, LIR_Opr dest, BasicType type) {
|
|||||||
__ pushptr(frame_map()->address_for_slot(src ->single_stack_ix()));
|
__ pushptr(frame_map()->address_for_slot(src ->single_stack_ix()));
|
||||||
__ popptr (frame_map()->address_for_slot(dest->single_stack_ix()));
|
__ popptr (frame_map()->address_for_slot(dest->single_stack_ix()));
|
||||||
} else {
|
} else {
|
||||||
|
#ifndef _LP64
|
||||||
__ pushl(frame_map()->address_for_slot(src ->single_stack_ix()));
|
__ pushl(frame_map()->address_for_slot(src ->single_stack_ix()));
|
||||||
__ popl (frame_map()->address_for_slot(dest->single_stack_ix()));
|
__ popl (frame_map()->address_for_slot(dest->single_stack_ix()));
|
||||||
|
#else
|
||||||
|
//no pushl on 64bits
|
||||||
|
__ movl(rscratch1, frame_map()->address_for_slot(src ->single_stack_ix()));
|
||||||
|
__ movl(frame_map()->address_for_slot(dest->single_stack_ix()), rscratch1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (src->is_double_stack()) {
|
} else if (src->is_double_stack()) {
|
||||||
@ -3136,8 +3151,10 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
|
|||||||
|
|
||||||
#ifdef _LP64
|
#ifdef _LP64
|
||||||
assert_different_registers(c_rarg0, dst, dst_pos, length);
|
assert_different_registers(c_rarg0, dst, dst_pos, length);
|
||||||
|
__ movl2ptr(src_pos, src_pos); //higher 32bits must be null
|
||||||
__ lea(c_rarg0, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));
|
__ lea(c_rarg0, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));
|
||||||
assert_different_registers(c_rarg1, length);
|
assert_different_registers(c_rarg1, length);
|
||||||
|
__ movl2ptr(dst_pos, dst_pos); //higher 32bits must be null
|
||||||
__ lea(c_rarg1, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));
|
__ lea(c_rarg1, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));
|
||||||
__ mov(c_rarg2, length);
|
__ mov(c_rarg2, length);
|
||||||
|
|
||||||
|
@ -755,8 +755,19 @@ void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LIR_Opr addr = new_pointer_register();
|
LIR_Opr addr = new_pointer_register();
|
||||||
__ move(obj.result(), addr);
|
LIR_Address* a;
|
||||||
__ add(addr, offset.result(), addr);
|
if(offset.result()->is_constant()) {
|
||||||
|
a = new LIR_Address(obj.result(),
|
||||||
|
NOT_LP64(offset.result()->as_constant_ptr()->as_jint()) LP64_ONLY((int)offset.result()->as_constant_ptr()->as_jlong()),
|
||||||
|
as_BasicType(type));
|
||||||
|
} else {
|
||||||
|
a = new LIR_Address(obj.result(),
|
||||||
|
offset.result(),
|
||||||
|
LIR_Address::times_1,
|
||||||
|
0,
|
||||||
|
as_BasicType(type));
|
||||||
|
}
|
||||||
|
__ leal(LIR_OprFact::address(a), addr);
|
||||||
|
|
||||||
if (type == objectType) { // Write-barrier needed for Object fields.
|
if (type == objectType) { // Write-barrier needed for Object fields.
|
||||||
// Do the pre-write barrier, if any.
|
// Do the pre-write barrier, if any.
|
||||||
|
@ -22,10 +22,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//
|
|
||||||
// Sets the default values for platform dependent flags used by the client compiler.
|
// Sets the default values for platform dependent flags used by the client compiler.
|
||||||
// (see c1_globals.hpp)
|
// (see c1_globals.hpp)
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef TIERED
|
#ifndef TIERED
|
||||||
define_pd_global(bool, BackgroundCompilation, true );
|
define_pd_global(bool, BackgroundCompilation, true );
|
||||||
@ -48,27 +46,24 @@ define_pd_global(intx, Tier4BackEdgeThreshold, 100000);
|
|||||||
|
|
||||||
define_pd_global(intx, OnStackReplacePercentage, 933 );
|
define_pd_global(intx, OnStackReplacePercentage, 933 );
|
||||||
define_pd_global(intx, FreqInlineSize, 325 );
|
define_pd_global(intx, FreqInlineSize, 325 );
|
||||||
define_pd_global(intx, NewRatio, 12 );
|
|
||||||
define_pd_global(intx, NewSizeThreadIncrease, 4*K );
|
define_pd_global(intx, NewSizeThreadIncrease, 4*K );
|
||||||
define_pd_global(intx, InitialCodeCacheSize, 160*K);
|
define_pd_global(intx, InitialCodeCacheSize, 160*K);
|
||||||
define_pd_global(intx, ReservedCodeCacheSize, 32*M );
|
define_pd_global(intx, ReservedCodeCacheSize, 32*M );
|
||||||
define_pd_global(bool, ProfileInterpreter, false);
|
define_pd_global(bool, ProfileInterpreter, false);
|
||||||
define_pd_global(intx, CodeCacheExpansionSize, 32*K );
|
define_pd_global(intx, CodeCacheExpansionSize, 32*K );
|
||||||
define_pd_global(uintx,CodeCacheMinBlockLength, 1);
|
define_pd_global(uintx,CodeCacheMinBlockLength, 1);
|
||||||
define_pd_global(uintx, PermSize, 12*M );
|
define_pd_global(uintx,PermSize, 12*M );
|
||||||
define_pd_global(uintx, MaxPermSize, 64*M );
|
define_pd_global(uintx,MaxPermSize, 64*M );
|
||||||
define_pd_global(bool, NeverActAsServerClassMachine, true);
|
define_pd_global(bool, NeverActAsServerClassMachine, true );
|
||||||
define_pd_global(uintx, DefaultMaxRAM, 1*G);
|
define_pd_global(uint64_t,MaxRAM, 1ULL*G);
|
||||||
define_pd_global(bool, CICompileOSR, true );
|
define_pd_global(bool, CICompileOSR, true );
|
||||||
#endif // TIERED
|
#endif // !TIERED
|
||||||
define_pd_global(bool, UseTypeProfile, false);
|
define_pd_global(bool, UseTypeProfile, false);
|
||||||
define_pd_global(bool, RoundFPResults, true );
|
define_pd_global(bool, RoundFPResults, true );
|
||||||
|
|
||||||
|
|
||||||
define_pd_global(bool, LIRFillDelaySlots, false);
|
define_pd_global(bool, LIRFillDelaySlots, false);
|
||||||
define_pd_global(bool, OptimizeSinglePrecision, true);
|
define_pd_global(bool, OptimizeSinglePrecision, true );
|
||||||
define_pd_global(bool, CSEArrayLength, false);
|
define_pd_global(bool, CSEArrayLength, false);
|
||||||
define_pd_global(bool, TwoOperandLIRForm, true);
|
define_pd_global(bool, TwoOperandLIRForm, true );
|
||||||
|
|
||||||
|
define_pd_global(intx, SafepointPollOffset, 256 );
|
||||||
define_pd_global(intx, SafepointPollOffset, 256);
|
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//
|
|
||||||
// Sets the default values for platform dependent flags used by the server compiler.
|
// Sets the default values for platform dependent flags used by the server compiler.
|
||||||
// (see c2_globals.hpp). Alpha-sorted.
|
// (see c2_globals.hpp). Alpha-sorted.
|
||||||
|
|
||||||
@ -46,8 +45,8 @@ define_pd_global(intx, CompileThreshold, 1000);
|
|||||||
define_pd_global(intx, CompileThreshold, 10000);
|
define_pd_global(intx, CompileThreshold, 10000);
|
||||||
#endif // TIERED
|
#endif // TIERED
|
||||||
define_pd_global(intx, Tier2CompileThreshold, 10000);
|
define_pd_global(intx, Tier2CompileThreshold, 10000);
|
||||||
define_pd_global(intx, Tier3CompileThreshold, 20000 );
|
define_pd_global(intx, Tier3CompileThreshold, 20000);
|
||||||
define_pd_global(intx, Tier4CompileThreshold, 40000 );
|
define_pd_global(intx, Tier4CompileThreshold, 40000);
|
||||||
|
|
||||||
define_pd_global(intx, BackEdgeThreshold, 100000);
|
define_pd_global(intx, BackEdgeThreshold, 100000);
|
||||||
define_pd_global(intx, Tier2BackEdgeThreshold, 100000);
|
define_pd_global(intx, Tier2BackEdgeThreshold, 100000);
|
||||||
@ -61,7 +60,6 @@ define_pd_global(intx, FreqInlineSize, 325);
|
|||||||
#ifdef AMD64
|
#ifdef AMD64
|
||||||
define_pd_global(intx, INTPRESSURE, 13);
|
define_pd_global(intx, INTPRESSURE, 13);
|
||||||
define_pd_global(intx, InteriorEntryAlignment, 16);
|
define_pd_global(intx, InteriorEntryAlignment, 16);
|
||||||
define_pd_global(intx, NewRatio, 2);
|
|
||||||
define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
|
define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
|
||||||
define_pd_global(intx, LoopUnrollLimit, 60);
|
define_pd_global(intx, LoopUnrollLimit, 60);
|
||||||
// InitialCodeCacheSize derived from specjbb2000 run.
|
// InitialCodeCacheSize derived from specjbb2000 run.
|
||||||
@ -69,19 +67,18 @@ define_pd_global(intx, InitialCodeCacheSize, 2496*K); // Integral multip
|
|||||||
define_pd_global(intx, CodeCacheExpansionSize, 64*K);
|
define_pd_global(intx, CodeCacheExpansionSize, 64*K);
|
||||||
|
|
||||||
// Ergonomics related flags
|
// Ergonomics related flags
|
||||||
define_pd_global(uintx, DefaultMaxRAM, 32*G);
|
define_pd_global(uint64_t,MaxRAM, 128ULL*G);
|
||||||
#else
|
#else
|
||||||
define_pd_global(intx, INTPRESSURE, 6);
|
define_pd_global(intx, INTPRESSURE, 6);
|
||||||
define_pd_global(intx, InteriorEntryAlignment, 4);
|
define_pd_global(intx, InteriorEntryAlignment, 4);
|
||||||
define_pd_global(intx, NewRatio, 8); // Design center runs on 1.3.1
|
|
||||||
define_pd_global(intx, NewSizeThreadIncrease, 4*K);
|
define_pd_global(intx, NewSizeThreadIncrease, 4*K);
|
||||||
define_pd_global(intx, LoopUnrollLimit, 50); // Design center runs on 1.3.1
|
define_pd_global(intx, LoopUnrollLimit, 50); // Design center runs on 1.3.1
|
||||||
// InitialCodeCacheSize derived from specjbb2000 run.
|
// InitialCodeCacheSize derived from specjbb2000 run.
|
||||||
define_pd_global(intx, InitialCodeCacheSize, 2304*K); // Integral multiple of CodeCacheExpansionSize
|
define_pd_global(intx, InitialCodeCacheSize, 2304*K); // Integral multiple of CodeCacheExpansionSize
|
||||||
define_pd_global(intx, CodeCacheExpansionSize, 32*K);
|
define_pd_global(intx, CodeCacheExpansionSize, 32*K);
|
||||||
|
|
||||||
// Ergonomics related flags
|
// Ergonomics related flags
|
||||||
define_pd_global(uintx, DefaultMaxRAM, 1*G);
|
define_pd_global(uint64_t,MaxRAM, 4ULL*G);
|
||||||
#endif // AMD64
|
#endif // AMD64
|
||||||
define_pd_global(intx, OptoLoopAlignment, 16);
|
define_pd_global(intx, OptoLoopAlignment, 16);
|
||||||
define_pd_global(intx, RegisterCostAreaRatio, 16000);
|
define_pd_global(intx, RegisterCostAreaRatio, 16000);
|
||||||
@ -97,8 +94,8 @@ define_pd_global(intx, ReservedCodeCacheSize, 48*M);
|
|||||||
define_pd_global(uintx,CodeCacheMinBlockLength, 4);
|
define_pd_global(uintx,CodeCacheMinBlockLength, 4);
|
||||||
|
|
||||||
// Heap related flags
|
// Heap related flags
|
||||||
define_pd_global(uintx, PermSize, ScaleForWordSize(16*M));
|
define_pd_global(uintx,PermSize, ScaleForWordSize(16*M));
|
||||||
define_pd_global(uintx, MaxPermSize, ScaleForWordSize(64*M));
|
define_pd_global(uintx,MaxPermSize, ScaleForWordSize(64*M));
|
||||||
|
|
||||||
// Ergonomics related flags
|
// Ergonomics related flags
|
||||||
define_pd_global(bool, NeverActAsServerClassMachine, false);
|
define_pd_global(bool, NeverActAsServerClassMachine, false);
|
||||||
|
@ -22,17 +22,16 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//
|
|
||||||
// Sets the default values for platform dependent flags used by the runtime system.
|
// Sets the default values for platform dependent flags used by the runtime system.
|
||||||
// (see globals.hpp)
|
// (see globals.hpp)
|
||||||
//
|
|
||||||
|
|
||||||
define_pd_global(bool, ConvertSleepToYield, true);
|
define_pd_global(bool, ConvertSleepToYield, true);
|
||||||
define_pd_global(bool, ShareVtableStubs, true);
|
define_pd_global(bool, ShareVtableStubs, true);
|
||||||
define_pd_global(bool, CountInterpCalls, true);
|
define_pd_global(bool, CountInterpCalls, true);
|
||||||
|
define_pd_global(bool, NeedsDeoptSuspend, false); // only register window machines need this
|
||||||
|
|
||||||
define_pd_global(bool, ImplicitNullChecks, true); // Generate code for implicit null checks
|
define_pd_global(bool, ImplicitNullChecks, true); // Generate code for implicit null checks
|
||||||
define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NULLs past to check cast
|
define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NULLs past to check cast
|
||||||
|
|
||||||
// See 4827828 for this change. There is no globals_core_i486.hpp. I can't
|
// See 4827828 for this change. There is no globals_core_i486.hpp. I can't
|
||||||
// assign a different value for C2 without touching a number of files. Use
|
// assign a different value for C2 without touching a number of files. Use
|
||||||
@ -42,29 +41,24 @@ define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NUL
|
|||||||
// the uep and the vep doesn't get real alignment but just slops on by
|
// the uep and the vep doesn't get real alignment but just slops on by
|
||||||
// only assured that the entry instruction meets the 5 byte size requirement.
|
// only assured that the entry instruction meets the 5 byte size requirement.
|
||||||
#ifdef COMPILER2
|
#ifdef COMPILER2
|
||||||
define_pd_global(intx, CodeEntryAlignment, 32);
|
define_pd_global(intx, CodeEntryAlignment, 32);
|
||||||
#else
|
#else
|
||||||
define_pd_global(intx, CodeEntryAlignment, 16);
|
define_pd_global(intx, CodeEntryAlignment, 16);
|
||||||
#endif // COMPILER2
|
#endif // COMPILER2
|
||||||
|
define_pd_global(intx, InlineFrequencyCount, 100);
|
||||||
|
define_pd_global(intx, InlineSmallCode, 1000);
|
||||||
|
|
||||||
define_pd_global(bool, NeedsDeoptSuspend, false); // only register window machines need this
|
define_pd_global(intx, StackYellowPages, 2);
|
||||||
|
define_pd_global(intx, StackRedPages, 1);
|
||||||
define_pd_global(uintx, TLABSize, 0);
|
|
||||||
#ifdef AMD64
|
#ifdef AMD64
|
||||||
define_pd_global(uintx, NewSize, ScaleForWordSize(2048 * K));
|
|
||||||
// Very large C++ stack frames using solaris-amd64 optimized builds
|
// Very large C++ stack frames using solaris-amd64 optimized builds
|
||||||
// due to lack of optimization caused by C++ compiler bugs
|
// due to lack of optimization caused by C++ compiler bugs
|
||||||
define_pd_global(intx, StackShadowPages, SOLARIS_ONLY(20) NOT_SOLARIS(6) DEBUG_ONLY(+2));
|
define_pd_global(intx, StackShadowPages, SOLARIS_ONLY(20) NOT_SOLARIS(6) DEBUG_ONLY(+2));
|
||||||
#else
|
#else
|
||||||
define_pd_global(uintx, NewSize, 1024 * K);
|
|
||||||
define_pd_global(intx, StackShadowPages, 3 DEBUG_ONLY(+1));
|
define_pd_global(intx, StackShadowPages, 3 DEBUG_ONLY(+1));
|
||||||
#endif // AMD64
|
#endif // AMD64
|
||||||
define_pd_global(intx, InlineFrequencyCount, 100);
|
|
||||||
define_pd_global(intx, InlineSmallCode, 1000);
|
|
||||||
define_pd_global(intx, PreInflateSpin, 10);
|
|
||||||
|
|
||||||
define_pd_global(intx, StackYellowPages, 2);
|
define_pd_global(intx, PreInflateSpin, 10);
|
||||||
define_pd_global(intx, StackRedPages, 1);
|
|
||||||
|
|
||||||
define_pd_global(bool, RewriteBytecodes, true);
|
define_pd_global(bool, RewriteBytecodes, true);
|
||||||
define_pd_global(bool, RewriteFrequentPairs, true);
|
define_pd_global(bool, RewriteFrequentPairs, true);
|
||||||
|
@ -196,6 +196,9 @@ void InterpreterMacroAssembler::get_cache_index_at_bcp(Register reg, int bcp_off
|
|||||||
} else {
|
} else {
|
||||||
assert(EnableInvokeDynamic, "giant index used only for EnableInvokeDynamic");
|
assert(EnableInvokeDynamic, "giant index used only for EnableInvokeDynamic");
|
||||||
movl(reg, Address(rsi, bcp_offset));
|
movl(reg, Address(rsi, bcp_offset));
|
||||||
|
// Check if the secondary index definition is still ~x, otherwise
|
||||||
|
// we have to change the following assembler code to calculate the
|
||||||
|
// plain index.
|
||||||
assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line");
|
assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line");
|
||||||
notl(reg); // convert to plain index
|
notl(reg); // convert to plain index
|
||||||
}
|
}
|
||||||
|
@ -185,12 +185,30 @@ void InterpreterMacroAssembler::get_unsigned_2_byte_index_at_bcp(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void InterpreterMacroAssembler::get_cache_index_at_bcp(Register index,
|
||||||
|
int bcp_offset,
|
||||||
|
bool giant_index) {
|
||||||
|
assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
|
||||||
|
if (!giant_index) {
|
||||||
|
load_unsigned_short(index, Address(r13, bcp_offset));
|
||||||
|
} else {
|
||||||
|
assert(EnableInvokeDynamic, "giant index used only for EnableInvokeDynamic");
|
||||||
|
movl(index, Address(r13, bcp_offset));
|
||||||
|
// Check if the secondary index definition is still ~x, otherwise
|
||||||
|
// we have to change the following assembler code to calculate the
|
||||||
|
// plain index.
|
||||||
|
assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line");
|
||||||
|
notl(index); // convert to plain index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache,
|
void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache,
|
||||||
Register index,
|
Register index,
|
||||||
int bcp_offset) {
|
int bcp_offset,
|
||||||
assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
|
bool giant_index) {
|
||||||
assert(cache != index, "must use different registers");
|
assert(cache != index, "must use different registers");
|
||||||
load_unsigned_short(index, Address(r13, bcp_offset));
|
get_cache_index_at_bcp(index, bcp_offset, giant_index);
|
||||||
movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
|
movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
|
||||||
assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
|
assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
|
||||||
// convert from field index to ConstantPoolCacheEntry index
|
// convert from field index to ConstantPoolCacheEntry index
|
||||||
@ -200,10 +218,10 @@ void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache,
|
|||||||
|
|
||||||
void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache,
|
void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache,
|
||||||
Register tmp,
|
Register tmp,
|
||||||
int bcp_offset) {
|
int bcp_offset,
|
||||||
assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
|
bool giant_index) {
|
||||||
assert(cache != tmp, "must use different register");
|
assert(cache != tmp, "must use different register");
|
||||||
load_unsigned_short(tmp, Address(r13, bcp_offset));
|
get_cache_index_at_bcp(tmp, bcp_offset, giant_index);
|
||||||
assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
|
assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
|
||||||
// convert from field index to ConstantPoolCacheEntry index
|
// convert from field index to ConstantPoolCacheEntry index
|
||||||
// and from word offset to byte offset
|
// and from word offset to byte offset
|
||||||
@ -1236,7 +1254,8 @@ void InterpreterMacroAssembler::profile_final_call(Register mdp) {
|
|||||||
|
|
||||||
void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
|
void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
|
||||||
Register mdp,
|
Register mdp,
|
||||||
Register reg2) {
|
Register reg2,
|
||||||
|
bool receiver_can_be_null) {
|
||||||
if (ProfileInterpreter) {
|
if (ProfileInterpreter) {
|
||||||
Label profile_continue;
|
Label profile_continue;
|
||||||
|
|
||||||
@ -1246,8 +1265,15 @@ void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
|
|||||||
// We are making a call. Increment the count.
|
// We are making a call. Increment the count.
|
||||||
increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
|
increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
|
||||||
|
|
||||||
|
Label skip_receiver_profile;
|
||||||
|
if (receiver_can_be_null) {
|
||||||
|
testptr(receiver, receiver);
|
||||||
|
jcc(Assembler::zero, skip_receiver_profile);
|
||||||
|
}
|
||||||
|
|
||||||
// Record the receiver type.
|
// Record the receiver type.
|
||||||
record_klass_in_profile(receiver, mdp, reg2);
|
record_klass_in_profile(receiver, mdp, reg2);
|
||||||
|
bind(skip_receiver_profile);
|
||||||
|
|
||||||
// The method data pointer needs to be updated to reflect the new target.
|
// The method data pointer needs to be updated to reflect the new target.
|
||||||
update_mdp_by_constant(mdp,
|
update_mdp_by_constant(mdp,
|
||||||
|
@ -95,9 +95,10 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
|||||||
|
|
||||||
void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset);
|
void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset);
|
||||||
void get_cache_and_index_at_bcp(Register cache, Register index,
|
void get_cache_and_index_at_bcp(Register cache, Register index,
|
||||||
int bcp_offset);
|
int bcp_offset, bool giant_index = false);
|
||||||
void get_cache_entry_pointer_at_bcp(Register cache, Register tmp,
|
void get_cache_entry_pointer_at_bcp(Register cache, Register tmp,
|
||||||
int bcp_offset);
|
int bcp_offset, bool giant_index = false);
|
||||||
|
void get_cache_index_at_bcp(Register index, int bcp_offset, bool giant_index = false);
|
||||||
|
|
||||||
|
|
||||||
void pop_ptr(Register r = rax);
|
void pop_ptr(Register r = rax);
|
||||||
@ -236,7 +237,8 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
|||||||
void profile_call(Register mdp);
|
void profile_call(Register mdp);
|
||||||
void profile_final_call(Register mdp);
|
void profile_final_call(Register mdp);
|
||||||
void profile_virtual_call(Register receiver, Register mdp,
|
void profile_virtual_call(Register receiver, Register mdp,
|
||||||
Register scratch2);
|
Register scratch2,
|
||||||
|
bool receiver_can_be_null = false);
|
||||||
void profile_ret(Register return_bci, Register mdp);
|
void profile_ret(Register return_bci, Register mdp);
|
||||||
void profile_null_seen(Register mdp);
|
void profile_null_seen(Register mdp);
|
||||||
void profile_typecheck(Register mdp, Register klass, Register scratch);
|
void profile_typecheck(Register mdp, Register klass, Register scratch);
|
||||||
|
@ -277,12 +277,11 @@ address InterpreterGenerator::generate_abstract_entry(void) {
|
|||||||
address entry_point = __ pc();
|
address entry_point = __ pc();
|
||||||
|
|
||||||
// abstract method entry
|
// abstract method entry
|
||||||
// remove return address. Not really needed, since exception
|
|
||||||
// handling throws away expression stack
|
|
||||||
__ pop(rbx);
|
|
||||||
|
|
||||||
// adjust stack to what a normal return would do
|
// pop return address, reset last_sp to NULL
|
||||||
__ mov(rsp, r13);
|
__ empty_expression_stack();
|
||||||
|
__ restore_bcp(); // rsi must be correct for exception handler (was destroyed)
|
||||||
|
__ restore_locals(); // make sure locals pointer is correct as well (was destroyed)
|
||||||
|
|
||||||
// throw exception
|
// throw exception
|
||||||
__ call_VM(noreg, CAST_FROM_FN_PTR(address,
|
__ call_VM(noreg, CAST_FROM_FN_PTR(address,
|
||||||
@ -300,7 +299,10 @@ address InterpreterGenerator::generate_method_handle_entry(void) {
|
|||||||
if (!EnableMethodHandles) {
|
if (!EnableMethodHandles) {
|
||||||
return generate_abstract_entry();
|
return generate_abstract_entry();
|
||||||
}
|
}
|
||||||
return generate_abstract_entry(); //6815692//
|
|
||||||
|
address entry_point = MethodHandles::generate_method_handle_interpreter_entry(_masm);
|
||||||
|
|
||||||
|
return entry_point;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -448,7 +448,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
|
|||||||
rbx_index, Address::times_ptr,
|
rbx_index, Address::times_ptr,
|
||||||
base + vtableEntry::method_offset_in_bytes());
|
base + vtableEntry::method_offset_in_bytes());
|
||||||
Register rbx_method = rbx_temp;
|
Register rbx_method = rbx_temp;
|
||||||
__ movl(rbx_method, vtable_entry_addr);
|
__ movptr(rbx_method, vtable_entry_addr);
|
||||||
|
|
||||||
__ verify_oop(rbx_method);
|
__ verify_oop(rbx_method);
|
||||||
__ jmp(rbx_method_fie);
|
__ jmp(rbx_method_fie);
|
||||||
|
@ -2935,6 +2935,16 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
|
|
||||||
// arraycopy stubs used by compilers
|
// arraycopy stubs used by compilers
|
||||||
generate_arraycopy_stubs();
|
generate_arraycopy_stubs();
|
||||||
|
|
||||||
|
// generic method handle stubs
|
||||||
|
if (EnableMethodHandles && SystemDictionary::MethodHandle_klass() != NULL) {
|
||||||
|
for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST;
|
||||||
|
ek < MethodHandles::_EK_LIMIT;
|
||||||
|
ek = MethodHandles::EntryKind(1 + (int)ek)) {
|
||||||
|
StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek));
|
||||||
|
MethodHandles::generate_method_handle_stub(_masm, ek);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -155,15 +155,8 @@ address TemplateInterpreterGenerator::generate_continuation_for(TosState state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, bool unbox) {
|
address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step) {
|
||||||
TosState incoming_state = state;
|
TosState incoming_state = state;
|
||||||
if (EnableInvokeDynamic) {
|
|
||||||
if (unbox) {
|
|
||||||
incoming_state = atos;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
assert(!unbox, "old behavior");
|
|
||||||
}
|
|
||||||
|
|
||||||
Label interpreter_entry;
|
Label interpreter_entry;
|
||||||
address compiled_entry = __ pc();
|
address compiled_entry = __ pc();
|
||||||
@ -216,46 +209,6 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
|
|||||||
__ restore_bcp();
|
__ restore_bcp();
|
||||||
__ restore_locals();
|
__ restore_locals();
|
||||||
|
|
||||||
Label L_fail;
|
|
||||||
|
|
||||||
if (unbox && state != atos) {
|
|
||||||
// cast and unbox
|
|
||||||
BasicType type = as_BasicType(state);
|
|
||||||
if (type == T_BYTE) type = T_BOOLEAN; // FIXME
|
|
||||||
KlassHandle boxk = SystemDictionaryHandles::box_klass(type);
|
|
||||||
__ mov32(rbx, ExternalAddress((address) boxk.raw_value()));
|
|
||||||
__ testl(rax, rax);
|
|
||||||
Label L_got_value, L_get_value;
|
|
||||||
// convert nulls to zeroes (avoid NPEs here)
|
|
||||||
if (!(type == T_FLOAT || type == T_DOUBLE)) {
|
|
||||||
// if rax already contains zero bits, forge ahead
|
|
||||||
__ jcc(Assembler::zero, L_got_value);
|
|
||||||
} else {
|
|
||||||
__ jcc(Assembler::notZero, L_get_value);
|
|
||||||
__ fldz();
|
|
||||||
__ jmp(L_got_value);
|
|
||||||
}
|
|
||||||
__ bind(L_get_value);
|
|
||||||
__ cmp32(rbx, Address(rax, oopDesc::klass_offset_in_bytes()));
|
|
||||||
__ jcc(Assembler::notEqual, L_fail);
|
|
||||||
int offset = java_lang_boxing_object::value_offset_in_bytes(type);
|
|
||||||
// Cf. TemplateTable::getfield_or_static
|
|
||||||
switch (type) {
|
|
||||||
case T_BYTE: // fall through:
|
|
||||||
case T_BOOLEAN: __ load_signed_byte(rax, Address(rax, offset)); break;
|
|
||||||
case T_CHAR: __ load_unsigned_short(rax, Address(rax, offset)); break;
|
|
||||||
case T_SHORT: __ load_signed_short(rax, Address(rax, offset)); break;
|
|
||||||
case T_INT: __ movl(rax, Address(rax, offset)); break;
|
|
||||||
case T_FLOAT: __ fld_s(Address(rax, offset)); break;
|
|
||||||
case T_DOUBLE: __ fld_d(Address(rax, offset)); break;
|
|
||||||
// Access to java.lang.Double.value does not need to be atomic:
|
|
||||||
case T_LONG: { __ movl(rdx, Address(rax, offset + 4));
|
|
||||||
__ movl(rax, Address(rax, offset + 0)); } break;
|
|
||||||
default: ShouldNotReachHere();
|
|
||||||
}
|
|
||||||
__ bind(L_got_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
Label L_got_cache, L_giant_index;
|
Label L_got_cache, L_giant_index;
|
||||||
if (EnableInvokeDynamic) {
|
if (EnableInvokeDynamic) {
|
||||||
__ cmpb(Address(rsi, 0), Bytecodes::_invokedynamic);
|
__ cmpb(Address(rsi, 0), Bytecodes::_invokedynamic);
|
||||||
@ -263,32 +216,6 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
|
|||||||
}
|
}
|
||||||
__ get_cache_and_index_at_bcp(rbx, rcx, 1, false);
|
__ get_cache_and_index_at_bcp(rbx, rcx, 1, false);
|
||||||
__ bind(L_got_cache);
|
__ bind(L_got_cache);
|
||||||
if (unbox && state == atos) {
|
|
||||||
// insert a casting conversion, to keep verifier sane
|
|
||||||
Label L_ok, L_ok_pops;
|
|
||||||
__ testl(rax, rax);
|
|
||||||
__ jcc(Assembler::zero, L_ok);
|
|
||||||
__ push(rax); // save the object to check
|
|
||||||
__ push(rbx); // save CP cache reference
|
|
||||||
__ movl(rdx, Address(rax, oopDesc::klass_offset_in_bytes()));
|
|
||||||
__ movl(rbx, Address(rbx, rcx,
|
|
||||||
Address::times_4, constantPoolCacheOopDesc::base_offset() +
|
|
||||||
ConstantPoolCacheEntry::f1_offset()));
|
|
||||||
__ movl(rbx, Address(rbx, __ delayed_value(sun_dyn_CallSiteImpl::type_offset_in_bytes, rcx)));
|
|
||||||
__ movl(rbx, Address(rbx, __ delayed_value(java_dyn_MethodType::rtype_offset_in_bytes, rcx)));
|
|
||||||
__ movl(rax, Address(rbx, __ delayed_value(java_lang_Class::klass_offset_in_bytes, rcx)));
|
|
||||||
__ check_klass_subtype(rdx, rax, rbx, L_ok_pops);
|
|
||||||
__ pop(rcx); // pop and discard CP cache
|
|
||||||
__ mov(rbx, rax); // target supertype into rbx for L_fail
|
|
||||||
__ pop(rax); // failed object into rax for L_fail
|
|
||||||
__ jmp(L_fail);
|
|
||||||
|
|
||||||
__ bind(L_ok_pops);
|
|
||||||
// restore pushed temp regs:
|
|
||||||
__ pop(rbx);
|
|
||||||
__ pop(rax);
|
|
||||||
__ bind(L_ok);
|
|
||||||
}
|
|
||||||
__ movl(rbx, Address(rbx, rcx,
|
__ movl(rbx, Address(rbx, rcx,
|
||||||
Address::times_ptr, constantPoolCacheOopDesc::base_offset() +
|
Address::times_ptr, constantPoolCacheOopDesc::base_offset() +
|
||||||
ConstantPoolCacheEntry::flags_offset()));
|
ConstantPoolCacheEntry::flags_offset()));
|
||||||
@ -301,14 +228,6 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
|
|||||||
__ bind(L_giant_index);
|
__ bind(L_giant_index);
|
||||||
__ get_cache_and_index_at_bcp(rbx, rcx, 1, true);
|
__ get_cache_and_index_at_bcp(rbx, rcx, 1, true);
|
||||||
__ jmp(L_got_cache);
|
__ jmp(L_got_cache);
|
||||||
|
|
||||||
if (unbox) {
|
|
||||||
__ bind(L_fail);
|
|
||||||
__ push(rbx); // missed klass (required)
|
|
||||||
__ push(rax); // bad object (actual)
|
|
||||||
__ movptr(rdx, ExternalAddress((address) &Interpreter::_throw_WrongMethodType_entry));
|
|
||||||
__ call(rdx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
|
@ -100,21 +100,26 @@ address TemplateInterpreterGenerator::generate_ClassCastException_handler() {
|
|||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Arguments are: required type in rarg1, failing object (or NULL) in rarg2
|
// Arguments are: required type at TOS+8, failing object (or NULL) at TOS+4.
|
||||||
address TemplateInterpreterGenerator::generate_WrongMethodType_handler() {
|
address TemplateInterpreterGenerator::generate_WrongMethodType_handler() {
|
||||||
address entry = __ pc();
|
address entry = __ pc();
|
||||||
|
|
||||||
__ pop(c_rarg2); // failing object is at TOS
|
__ pop(c_rarg2); // failing object is at TOS
|
||||||
__ pop(c_rarg1); // required type is at TOS+8
|
__ pop(c_rarg1); // required type is at TOS+8
|
||||||
|
|
||||||
// expression stack must be empty before entering the VM if an
|
__ verify_oop(c_rarg1);
|
||||||
// exception happened
|
__ verify_oop(c_rarg2);
|
||||||
|
|
||||||
|
// Various method handle types use interpreter registers as temps.
|
||||||
|
__ restore_bcp();
|
||||||
|
__ restore_locals();
|
||||||
|
|
||||||
|
// Expression stack must be empty before entering the VM for an exception.
|
||||||
__ empty_expression_stack();
|
__ empty_expression_stack();
|
||||||
|
|
||||||
__ call_VM(noreg,
|
__ call_VM(noreg,
|
||||||
CAST_FROM_FN_PTR(address,
|
CAST_FROM_FN_PTR(address,
|
||||||
InterpreterRuntime::
|
InterpreterRuntime::throw_WrongMethodTypeException),
|
||||||
throw_WrongMethodTypeException),
|
|
||||||
// pass required type, failing object (or NULL)
|
// pass required type, failing object (or NULL)
|
||||||
c_rarg1, c_rarg2);
|
c_rarg1, c_rarg2);
|
||||||
return entry;
|
return entry;
|
||||||
@ -166,8 +171,7 @@ address TemplateInterpreterGenerator::generate_continuation_for(TosState state)
|
|||||||
|
|
||||||
|
|
||||||
address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
|
address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
|
||||||
int step, bool unbox) {
|
int step) {
|
||||||
assert(!unbox, "NYI");//6815692//
|
|
||||||
|
|
||||||
// amd64 doesn't need to do anything special about compiled returns
|
// amd64 doesn't need to do anything special about compiled returns
|
||||||
// to the interpreter so the code that exists on x86 to place a sentinel
|
// to the interpreter so the code that exists on x86 to place a sentinel
|
||||||
@ -183,15 +187,29 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
|
|||||||
__ restore_bcp();
|
__ restore_bcp();
|
||||||
__ restore_locals();
|
__ restore_locals();
|
||||||
|
|
||||||
__ get_cache_and_index_at_bcp(rbx, rcx, 1);
|
Label L_got_cache, L_giant_index;
|
||||||
|
if (EnableInvokeDynamic) {
|
||||||
|
__ cmpb(Address(r13, 0), Bytecodes::_invokedynamic);
|
||||||
|
__ jcc(Assembler::equal, L_giant_index);
|
||||||
|
}
|
||||||
|
__ get_cache_and_index_at_bcp(rbx, rcx, 1, false);
|
||||||
|
__ bind(L_got_cache);
|
||||||
__ movl(rbx, Address(rbx, rcx,
|
__ movl(rbx, Address(rbx, rcx,
|
||||||
Address::times_8,
|
Address::times_ptr,
|
||||||
in_bytes(constantPoolCacheOopDesc::base_offset()) +
|
in_bytes(constantPoolCacheOopDesc::base_offset()) +
|
||||||
3 * wordSize));
|
3 * wordSize));
|
||||||
__ andl(rbx, 0xFF);
|
__ andl(rbx, 0xFF);
|
||||||
if (TaggedStackInterpreter) __ shll(rbx, 1); // 2 slots per parameter.
|
if (TaggedStackInterpreter) __ shll(rbx, 1); // 2 slots per parameter.
|
||||||
__ lea(rsp, Address(rsp, rbx, Address::times_8));
|
__ lea(rsp, Address(rsp, rbx, Address::times_8));
|
||||||
__ dispatch_next(state, step);
|
__ dispatch_next(state, step);
|
||||||
|
|
||||||
|
// out of the main line of code...
|
||||||
|
if (EnableInvokeDynamic) {
|
||||||
|
__ bind(L_giant_index);
|
||||||
|
__ get_cache_and_index_at_bcp(rbx, rcx, 1, true);
|
||||||
|
__ jmp(L_got_cache);
|
||||||
|
}
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2890,9 +2890,6 @@ void TemplateTable::count_calls(Register method, Register temp) {
|
|||||||
|
|
||||||
|
|
||||||
void TemplateTable::prepare_invoke(Register method, Register index, int byte_no) {
|
void TemplateTable::prepare_invoke(Register method, Register index, int byte_no) {
|
||||||
bool is_invdyn_bootstrap = (byte_no < 0);
|
|
||||||
if (is_invdyn_bootstrap) byte_no = -byte_no;
|
|
||||||
|
|
||||||
// determine flags
|
// determine flags
|
||||||
Bytecodes::Code code = bytecode();
|
Bytecodes::Code code = bytecode();
|
||||||
const bool is_invokeinterface = code == Bytecodes::_invokeinterface;
|
const bool is_invokeinterface = code == Bytecodes::_invokeinterface;
|
||||||
@ -2907,8 +2904,6 @@ void TemplateTable::prepare_invoke(Register method, Register index, int byte_no)
|
|||||||
const Register flags = rdx;
|
const Register flags = rdx;
|
||||||
assert_different_registers(method, index, recv, flags);
|
assert_different_registers(method, index, recv, flags);
|
||||||
|
|
||||||
assert(!is_invdyn_bootstrap || is_invokedynamic, "byte_no<0 hack only for invdyn");
|
|
||||||
|
|
||||||
// save 'interpreter return address'
|
// save 'interpreter return address'
|
||||||
__ save_bcp();
|
__ save_bcp();
|
||||||
|
|
||||||
@ -2944,9 +2939,7 @@ void TemplateTable::prepare_invoke(Register method, Register index, int byte_no)
|
|||||||
// load return address
|
// load return address
|
||||||
{
|
{
|
||||||
address table_addr;
|
address table_addr;
|
||||||
if (is_invdyn_bootstrap)
|
if (is_invokeinterface || is_invokedynamic)
|
||||||
table_addr = (address)Interpreter::return_5_unbox_addrs_by_index_table();
|
|
||||||
else if (is_invokeinterface || is_invokedynamic)
|
|
||||||
table_addr = (address)Interpreter::return_5_addrs_by_index_table();
|
table_addr = (address)Interpreter::return_5_addrs_by_index_table();
|
||||||
else
|
else
|
||||||
table_addr = (address)Interpreter::return_3_addrs_by_index_table();
|
table_addr = (address)Interpreter::return_3_addrs_by_index_table();
|
||||||
@ -3153,54 +3146,10 @@ void TemplateTable::invokedynamic(int byte_no) {
|
|||||||
__ profile_call(rsi);
|
__ profile_call(rsi);
|
||||||
}
|
}
|
||||||
|
|
||||||
Label handle_unlinked_site;
|
__ movptr(rcx, Address(rax, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx)));
|
||||||
__ movptr(rcx, Address(rax, __ delayed_value(sun_dyn_CallSiteImpl::target_offset_in_bytes, rcx)));
|
__ null_check(rcx);
|
||||||
__ testptr(rcx, rcx);
|
|
||||||
__ jcc(Assembler::zero, handle_unlinked_site);
|
|
||||||
|
|
||||||
__ prepare_to_jump_from_interpreted();
|
__ prepare_to_jump_from_interpreted();
|
||||||
__ jump_to_method_handle_entry(rcx, rdx);
|
__ jump_to_method_handle_entry(rcx, rdx);
|
||||||
|
|
||||||
// Initial calls come here...
|
|
||||||
__ bind(handle_unlinked_site);
|
|
||||||
__ pop(rcx); // remove return address pushed by prepare_invoke
|
|
||||||
|
|
||||||
// box stacked arguments into an array for the bootstrap method
|
|
||||||
address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::bootstrap_invokedynamic);
|
|
||||||
__ restore_bcp(); // rsi must be correct for call_VM
|
|
||||||
__ call_VM(rax, entry, rax);
|
|
||||||
__ movl(rdi, rax); // protect bootstrap MH from prepare_invoke
|
|
||||||
|
|
||||||
// recompute return address
|
|
||||||
__ restore_bcp(); // rsi must be correct for prepare_invoke
|
|
||||||
prepare_invoke(rax, rbx, -byte_no); // smashes rcx, rdx
|
|
||||||
// rax: CallSite object (f1)
|
|
||||||
// rbx: unused (f2)
|
|
||||||
// rdi: bootstrap MH
|
|
||||||
// rdx: flags
|
|
||||||
|
|
||||||
// now load up the arglist, which has been neatly boxed
|
|
||||||
__ get_thread(rcx);
|
|
||||||
__ movptr(rdx, Address(rcx, JavaThread::vm_result_2_offset()));
|
|
||||||
__ movptr(Address(rcx, JavaThread::vm_result_2_offset()), NULL_WORD);
|
|
||||||
__ verify_oop(rdx);
|
|
||||||
// rdx = arglist
|
|
||||||
|
|
||||||
// save SP now, before we add the bootstrap call to the stack
|
|
||||||
// We must preserve a fiction that the original arguments are outgoing,
|
|
||||||
// because the return sequence will reset the stack to this point
|
|
||||||
// and then pop all those arguments. It seems error-prone to use
|
|
||||||
// a different argument list size just for bootstrapping.
|
|
||||||
__ prepare_to_jump_from_interpreted();
|
|
||||||
|
|
||||||
// Now let's play adapter, pushing the real arguments on the stack.
|
|
||||||
__ pop(rbx); // return PC
|
|
||||||
__ push(rdi); // boot MH
|
|
||||||
__ push(rax); // call site
|
|
||||||
__ push(rdx); // arglist
|
|
||||||
__ push(rbx); // return PC, again
|
|
||||||
__ mov(rcx, rdi);
|
|
||||||
__ jump_to_method_handle_entry(rcx, rdx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
@ -203,18 +203,15 @@ void TemplateTable::patch_bytecode(Bytecodes::Code bytecode, Register bc,
|
|||||||
__ jcc(Assembler::notEqual, fast_patch);
|
__ jcc(Assembler::notEqual, fast_patch);
|
||||||
__ get_method(scratch);
|
__ get_method(scratch);
|
||||||
// Let breakpoint table handling rewrite to quicker bytecode
|
// Let breakpoint table handling rewrite to quicker bytecode
|
||||||
__ call_VM(noreg,
|
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), scratch, r13, bc);
|
||||||
CAST_FROM_FN_PTR(address,
|
|
||||||
InterpreterRuntime::set_original_bytecode_at),
|
|
||||||
scratch, r13, bc);
|
|
||||||
#ifndef ASSERT
|
#ifndef ASSERT
|
||||||
__ jmpb(patch_done);
|
__ jmpb(patch_done);
|
||||||
__ bind(fast_patch);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
__ jmp(patch_done);
|
__ jmp(patch_done);
|
||||||
|
#endif
|
||||||
__ bind(fast_patch);
|
__ bind(fast_patch);
|
||||||
}
|
}
|
||||||
|
#ifdef ASSERT
|
||||||
Label okay;
|
Label okay;
|
||||||
__ load_unsigned_byte(scratch, at_bcp(0));
|
__ load_unsigned_byte(scratch, at_bcp(0));
|
||||||
__ cmpl(scratch, (int) Bytecodes::java_code(bytecode));
|
__ cmpl(scratch, (int) Bytecodes::java_code(bytecode));
|
||||||
@ -2054,26 +2051,28 @@ void TemplateTable::volatile_barrier(Assembler::Membar_mask_bits
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TemplateTable::resolve_cache_and_index(int byte_no,
|
void TemplateTable::resolve_cache_and_index(int byte_no, Register Rcache, Register index) {
|
||||||
Register Rcache,
|
|
||||||
Register index) {
|
|
||||||
assert(byte_no == 1 || byte_no == 2, "byte_no out of range");
|
assert(byte_no == 1 || byte_no == 2, "byte_no out of range");
|
||||||
|
bool is_invokedynamic = (bytecode() == Bytecodes::_invokedynamic);
|
||||||
|
|
||||||
const Register temp = rbx;
|
const Register temp = rbx;
|
||||||
assert_different_registers(Rcache, index, temp);
|
assert_different_registers(Rcache, index, temp);
|
||||||
|
|
||||||
const int shift_count = (1 + byte_no) * BitsPerByte;
|
const int shift_count = (1 + byte_no) * BitsPerByte;
|
||||||
Label resolved;
|
Label resolved;
|
||||||
__ get_cache_and_index_at_bcp(Rcache, index, 1);
|
__ get_cache_and_index_at_bcp(Rcache, index, 1, is_invokedynamic);
|
||||||
__ movl(temp, Address(Rcache,
|
if (is_invokedynamic) {
|
||||||
index, Address::times_8,
|
// we are resolved if the f1 field contains a non-null CallSite object
|
||||||
constantPoolCacheOopDesc::base_offset() +
|
__ cmpptr(Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset()), (int32_t) NULL_WORD);
|
||||||
ConstantPoolCacheEntry::indices_offset()));
|
__ jcc(Assembler::notEqual, resolved);
|
||||||
__ shrl(temp, shift_count);
|
} else {
|
||||||
// have we resolved this bytecode?
|
__ movl(temp, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset()));
|
||||||
__ andl(temp, 0xFF);
|
__ shrl(temp, shift_count);
|
||||||
__ cmpl(temp, (int) bytecode());
|
// have we resolved this bytecode?
|
||||||
__ jcc(Assembler::equal, resolved);
|
__ andl(temp, 0xFF);
|
||||||
|
__ cmpl(temp, (int) bytecode());
|
||||||
|
__ jcc(Assembler::equal, resolved);
|
||||||
|
}
|
||||||
|
|
||||||
// resolve first time through
|
// resolve first time through
|
||||||
address entry;
|
address entry;
|
||||||
@ -2090,6 +2089,9 @@ void TemplateTable::resolve_cache_and_index(int byte_no,
|
|||||||
case Bytecodes::_invokeinterface:
|
case Bytecodes::_invokeinterface:
|
||||||
entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);
|
entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);
|
||||||
break;
|
break;
|
||||||
|
case Bytecodes::_invokedynamic:
|
||||||
|
entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ShouldNotReachHere();
|
ShouldNotReachHere();
|
||||||
break;
|
break;
|
||||||
@ -2098,7 +2100,7 @@ void TemplateTable::resolve_cache_and_index(int byte_no,
|
|||||||
__ call_VM(noreg, entry, temp);
|
__ call_VM(noreg, entry, temp);
|
||||||
|
|
||||||
// Update registers with resolved info
|
// Update registers with resolved info
|
||||||
__ get_cache_and_index_at_bcp(Rcache, index, 1);
|
__ get_cache_and_index_at_bcp(Rcache, index, 1, is_invokedynamic);
|
||||||
__ bind(resolved);
|
__ bind(resolved);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2832,15 +2834,14 @@ void TemplateTable::count_calls(Register method, Register temp) {
|
|||||||
ShouldNotReachHere();
|
ShouldNotReachHere();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TemplateTable::prepare_invoke(Register method,
|
void TemplateTable::prepare_invoke(Register method, Register index, int byte_no) {
|
||||||
Register index,
|
|
||||||
int byte_no,
|
|
||||||
Bytecodes::Code code) {
|
|
||||||
// determine flags
|
// determine flags
|
||||||
|
Bytecodes::Code code = bytecode();
|
||||||
const bool is_invokeinterface = code == Bytecodes::_invokeinterface;
|
const bool is_invokeinterface = code == Bytecodes::_invokeinterface;
|
||||||
|
const bool is_invokedynamic = code == Bytecodes::_invokedynamic;
|
||||||
const bool is_invokevirtual = code == Bytecodes::_invokevirtual;
|
const bool is_invokevirtual = code == Bytecodes::_invokevirtual;
|
||||||
const bool is_invokespecial = code == Bytecodes::_invokespecial;
|
const bool is_invokespecial = code == Bytecodes::_invokespecial;
|
||||||
const bool load_receiver = code != Bytecodes::_invokestatic;
|
const bool load_receiver = (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic);
|
||||||
const bool receiver_null_check = is_invokespecial;
|
const bool receiver_null_check = is_invokespecial;
|
||||||
const bool save_flags = is_invokeinterface || is_invokevirtual;
|
const bool save_flags = is_invokeinterface || is_invokevirtual;
|
||||||
// setup registers & access constant pool cache
|
// setup registers & access constant pool cache
|
||||||
@ -2858,9 +2859,13 @@ void TemplateTable::prepare_invoke(Register method,
|
|||||||
__ movl(recv, flags);
|
__ movl(recv, flags);
|
||||||
__ andl(recv, 0xFF);
|
__ andl(recv, 0xFF);
|
||||||
if (TaggedStackInterpreter) __ shll(recv, 1); // index*2
|
if (TaggedStackInterpreter) __ shll(recv, 1); // index*2
|
||||||
__ movptr(recv, Address(rsp, recv, Address::times_8,
|
Address recv_addr(rsp, recv, Address::times_8, -Interpreter::expr_offset_in_bytes(1));
|
||||||
-Interpreter::expr_offset_in_bytes(1)));
|
if (is_invokedynamic) {
|
||||||
__ verify_oop(recv);
|
__ lea(recv, recv_addr);
|
||||||
|
} else {
|
||||||
|
__ movptr(recv, recv_addr);
|
||||||
|
__ verify_oop(recv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// do null check if needed
|
// do null check if needed
|
||||||
@ -2878,10 +2883,14 @@ void TemplateTable::prepare_invoke(Register method,
|
|||||||
ConstantPoolCacheEntry::verify_tosBits();
|
ConstantPoolCacheEntry::verify_tosBits();
|
||||||
// load return address
|
// load return address
|
||||||
{
|
{
|
||||||
ExternalAddress return_5((address)Interpreter::return_5_addrs_by_index_table());
|
address table_addr;
|
||||||
ExternalAddress return_3((address)Interpreter::return_3_addrs_by_index_table());
|
if (is_invokeinterface || is_invokedynamic)
|
||||||
__ lea(rscratch1, (is_invokeinterface ? return_5 : return_3));
|
table_addr = (address)Interpreter::return_5_addrs_by_index_table();
|
||||||
__ movptr(flags, Address(rscratch1, flags, Address::times_8));
|
else
|
||||||
|
table_addr = (address)Interpreter::return_3_addrs_by_index_table();
|
||||||
|
ExternalAddress table(table_addr);
|
||||||
|
__ lea(rscratch1, table);
|
||||||
|
__ movptr(flags, Address(rscratch1, flags, Address::times_ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
// push return address
|
// push return address
|
||||||
@ -2947,7 +2956,7 @@ void TemplateTable::invokevirtual_helper(Register index,
|
|||||||
|
|
||||||
void TemplateTable::invokevirtual(int byte_no) {
|
void TemplateTable::invokevirtual(int byte_no) {
|
||||||
transition(vtos, vtos);
|
transition(vtos, vtos);
|
||||||
prepare_invoke(rbx, noreg, byte_no, bytecode());
|
prepare_invoke(rbx, noreg, byte_no);
|
||||||
|
|
||||||
// rbx: index
|
// rbx: index
|
||||||
// rcx: receiver
|
// rcx: receiver
|
||||||
@ -2959,7 +2968,7 @@ void TemplateTable::invokevirtual(int byte_no) {
|
|||||||
|
|
||||||
void TemplateTable::invokespecial(int byte_no) {
|
void TemplateTable::invokespecial(int byte_no) {
|
||||||
transition(vtos, vtos);
|
transition(vtos, vtos);
|
||||||
prepare_invoke(rbx, noreg, byte_no, bytecode());
|
prepare_invoke(rbx, noreg, byte_no);
|
||||||
// do the call
|
// do the call
|
||||||
__ verify_oop(rbx);
|
__ verify_oop(rbx);
|
||||||
__ profile_call(rax);
|
__ profile_call(rax);
|
||||||
@ -2969,7 +2978,7 @@ void TemplateTable::invokespecial(int byte_no) {
|
|||||||
|
|
||||||
void TemplateTable::invokestatic(int byte_no) {
|
void TemplateTable::invokestatic(int byte_no) {
|
||||||
transition(vtos, vtos);
|
transition(vtos, vtos);
|
||||||
prepare_invoke(rbx, noreg, byte_no, bytecode());
|
prepare_invoke(rbx, noreg, byte_no);
|
||||||
// do the call
|
// do the call
|
||||||
__ verify_oop(rbx);
|
__ verify_oop(rbx);
|
||||||
__ profile_call(rax);
|
__ profile_call(rax);
|
||||||
@ -2983,7 +2992,7 @@ void TemplateTable::fast_invokevfinal(int byte_no) {
|
|||||||
|
|
||||||
void TemplateTable::invokeinterface(int byte_no) {
|
void TemplateTable::invokeinterface(int byte_no) {
|
||||||
transition(vtos, vtos);
|
transition(vtos, vtos);
|
||||||
prepare_invoke(rax, rbx, byte_no, bytecode());
|
prepare_invoke(rax, rbx, byte_no);
|
||||||
|
|
||||||
// rax: Interface
|
// rax: Interface
|
||||||
// rbx: index
|
// rbx: index
|
||||||
@ -3072,7 +3081,24 @@ void TemplateTable::invokedynamic(int byte_no) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
__ stop("invokedynamic NYI");//6815692//
|
prepare_invoke(rax, rbx, byte_no);
|
||||||
|
|
||||||
|
// rax: CallSite object (f1)
|
||||||
|
// rbx: unused (f2)
|
||||||
|
// rcx: receiver address
|
||||||
|
// rdx: flags (unused)
|
||||||
|
|
||||||
|
if (ProfileInterpreter) {
|
||||||
|
Label L;
|
||||||
|
// %%% should make a type profile for any invokedynamic that takes a ref argument
|
||||||
|
// profile this call
|
||||||
|
__ profile_call(r13);
|
||||||
|
}
|
||||||
|
|
||||||
|
__ movptr(rcx, Address(rax, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx)));
|
||||||
|
__ null_check(rcx);
|
||||||
|
__ prepare_to_jump_from_interpreted();
|
||||||
|
__ jump_to_method_handle_entry(rcx, rdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,8 +22,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void prepare_invoke(Register method, Register index, int byte_no,
|
static void prepare_invoke(Register method, Register index, int byte_no);
|
||||||
Bytecodes::Code code);
|
|
||||||
static void invokevirtual_helper(Register index, Register recv,
|
static void invokevirtual_helper(Register index, Register recv,
|
||||||
Register flags);
|
Register flags);
|
||||||
static void volatile_barrier(Assembler::Membar_mask_bits order_constraint);
|
static void volatile_barrier(Assembler::Membar_mask_bits order_constraint);
|
||||||
|
@ -255,6 +255,8 @@ void VM_Version::get_processor_features() {
|
|||||||
if (!VM_Version::supports_sse2()) {
|
if (!VM_Version::supports_sse2()) {
|
||||||
vm_exit_during_initialization("Unknown x64 processor: SSE2 not supported");
|
vm_exit_during_initialization("Unknown x64 processor: SSE2 not supported");
|
||||||
}
|
}
|
||||||
|
// in 64 bit the use of SSE2 is the minimum
|
||||||
|
if (UseSSE < 2) UseSSE = 2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// If the OS doesn't support SSE, we can't use this feature even if the HW does
|
// If the OS doesn't support SSE, we can't use this feature even if the HW does
|
||||||
|
@ -204,6 +204,20 @@ void CppInterpreter::native_entry(methodOop method, intptr_t UNUSED, TRAPS) {
|
|||||||
goto unwind_and_return;
|
goto unwind_and_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the invocation counter
|
||||||
|
if ((UseCompiler || CountCompiledCalls) && !method->is_synchronized()) {
|
||||||
|
thread->set_do_not_unlock();
|
||||||
|
InvocationCounter *counter = method->invocation_counter();
|
||||||
|
counter->increment();
|
||||||
|
if (counter->reached_InvocationLimit()) {
|
||||||
|
CALL_VM_NOCHECK(
|
||||||
|
InterpreterRuntime::frequency_counter_overflow(thread, NULL));
|
||||||
|
if (HAS_PENDING_EXCEPTION)
|
||||||
|
goto unwind_and_return;
|
||||||
|
}
|
||||||
|
thread->clr_do_not_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
// Lock if necessary
|
// Lock if necessary
|
||||||
BasicObjectLock *monitor;
|
BasicObjectLock *monitor;
|
||||||
monitor = NULL;
|
monitor = NULL;
|
||||||
|
@ -36,11 +36,8 @@ bool frame::is_interpreted_frame() const {
|
|||||||
return zeroframe()->is_interpreter_frame();
|
return zeroframe()->is_interpreter_frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool frame::is_fake_stub_frame() const {
|
|
||||||
return zeroframe()->is_fake_stub_frame();
|
|
||||||
}
|
|
||||||
|
|
||||||
frame frame::sender_for_entry_frame(RegisterMap *map) const {
|
frame frame::sender_for_entry_frame(RegisterMap *map) const {
|
||||||
|
assert(zeroframe()->is_entry_frame(), "wrong type of frame");
|
||||||
assert(map != NULL, "map must be set");
|
assert(map != NULL, "map must be set");
|
||||||
assert(!entry_frame_is_first(), "next Java fp must be non zero");
|
assert(!entry_frame_is_first(), "next Java fp must be non zero");
|
||||||
assert(entry_frame_call_wrapper()->anchor()->last_Java_sp() == sender_sp(),
|
assert(entry_frame_call_wrapper()->anchor()->last_Java_sp() == sender_sp(),
|
||||||
@ -50,15 +47,10 @@ frame frame::sender_for_entry_frame(RegisterMap *map) const {
|
|||||||
return frame(sender_sp(), sp() + 1);
|
return frame(sender_sp(), sp() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame frame::sender_for_interpreter_frame(RegisterMap *map) const {
|
frame frame::sender_for_nonentry_frame(RegisterMap *map) const {
|
||||||
return frame(sender_sp(), sp() + 1);
|
assert(zeroframe()->is_interpreter_frame() ||
|
||||||
}
|
zeroframe()->is_shark_frame() ||
|
||||||
|
zeroframe()->is_fake_stub_frame(), "wrong type of frame");
|
||||||
frame frame::sender_for_compiled_frame(RegisterMap *map) const {
|
|
||||||
return frame(sender_sp(), sp() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
frame frame::sender_for_fake_stub_frame(RegisterMap *map) const {
|
|
||||||
return frame(sender_sp(), sp() + 1);
|
return frame(sender_sp(), sp() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,17 +61,8 @@ frame frame::sender(RegisterMap* map) const {
|
|||||||
|
|
||||||
if (is_entry_frame())
|
if (is_entry_frame())
|
||||||
return sender_for_entry_frame(map);
|
return sender_for_entry_frame(map);
|
||||||
|
else
|
||||||
if (is_interpreted_frame())
|
return sender_for_nonentry_frame(map);
|
||||||
return sender_for_interpreter_frame(map);
|
|
||||||
|
|
||||||
if (is_compiled_frame())
|
|
||||||
return sender_for_compiled_frame(map);
|
|
||||||
|
|
||||||
if (is_fake_stub_frame())
|
|
||||||
return sender_for_fake_stub_frame(map);
|
|
||||||
|
|
||||||
ShouldNotReachHere();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CC_INTERP
|
#ifdef CC_INTERP
|
||||||
|
@ -65,10 +65,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool is_fake_stub_frame() const;
|
frame sender_for_nonentry_frame(RegisterMap* map) const;
|
||||||
|
|
||||||
public:
|
|
||||||
frame sender_for_fake_stub_frame(RegisterMap* map) const;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void zero_print_on_error(int index,
|
void zero_print_on_error(int index,
|
||||||
|
@ -23,10 +23,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//
|
|
||||||
// Set the default values for platform dependent flags used by the
|
// Set the default values for platform dependent flags used by the
|
||||||
// runtime system. See globals.hpp for details of what they do.
|
// runtime system. See globals.hpp for details of what they do.
|
||||||
//
|
|
||||||
|
|
||||||
define_pd_global(bool, ConvertSleepToYield, true);
|
define_pd_global(bool, ConvertSleepToYield, true);
|
||||||
define_pd_global(bool, ShareVtableStubs, true);
|
define_pd_global(bool, ShareVtableStubs, true);
|
||||||
@ -37,14 +35,7 @@ define_pd_global(bool, ImplicitNullChecks, true);
|
|||||||
define_pd_global(bool, UncommonNullCast, true);
|
define_pd_global(bool, UncommonNullCast, true);
|
||||||
|
|
||||||
define_pd_global(intx, CodeEntryAlignment, 32);
|
define_pd_global(intx, CodeEntryAlignment, 32);
|
||||||
define_pd_global(uintx, TLABSize, 0);
|
|
||||||
#ifdef _LP64
|
|
||||||
define_pd_global(uintx, NewSize, ScaleForWordSize(2048 * K));
|
|
||||||
#else
|
|
||||||
define_pd_global(uintx, NewSize, ScaleForWordSize(1024 * K));
|
|
||||||
#endif // _LP64
|
|
||||||
define_pd_global(intx, InlineFrequencyCount, 100);
|
define_pd_global(intx, InlineFrequencyCount, 100);
|
||||||
define_pd_global(intx, InlineSmallCode, 1000);
|
|
||||||
define_pd_global(intx, PreInflateSpin, 10);
|
define_pd_global(intx, PreInflateSpin, 10);
|
||||||
|
|
||||||
define_pd_global(intx, StackYellowPages, 2);
|
define_pd_global(intx, StackYellowPages, 2);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* Copyright 2007, 2008 Red Hat, Inc.
|
* Copyright 2007, 2008, 2009 Red Hat, Inc.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -61,7 +61,14 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
|||||||
BasicType *in_sig_bt,
|
BasicType *in_sig_bt,
|
||||||
VMRegPair *in_regs,
|
VMRegPair *in_regs,
|
||||||
BasicType ret_type) {
|
BasicType ret_type) {
|
||||||
|
#ifdef SHARK
|
||||||
|
return SharkCompiler::compiler()->generate_native_wrapper(masm,
|
||||||
|
method,
|
||||||
|
in_sig_bt,
|
||||||
|
ret_type);
|
||||||
|
#else
|
||||||
ShouldNotCallThis();
|
ShouldNotCallThis();
|
||||||
|
#endif // SHARK
|
||||||
}
|
}
|
||||||
|
|
||||||
int Deoptimization::last_frame_adjust(int callee_parameters,
|
int Deoptimization::last_frame_adjust(int callee_parameters,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* Copyright 2008 Red Hat, Inc.
|
* Copyright 2008, 2009 Red Hat, Inc.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -41,7 +41,7 @@
|
|||||||
// | ... |
|
// | ... |
|
||||||
|
|
||||||
class SharkFrame : public ZeroFrame {
|
class SharkFrame : public ZeroFrame {
|
||||||
friend class SharkFunction;
|
friend class SharkStack;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SharkFrame() : ZeroFrame() {
|
SharkFrame() : ZeroFrame() {
|
||||||
|
@ -223,8 +223,8 @@ static const char *unstable_chroot_error = "/proc file system not found.\n"
|
|||||||
"environment on Linux when /proc filesystem is not mounted.";
|
"environment on Linux when /proc filesystem is not mounted.";
|
||||||
|
|
||||||
void os::Linux::initialize_system_info() {
|
void os::Linux::initialize_system_info() {
|
||||||
_processor_count = sysconf(_SC_NPROCESSORS_CONF);
|
set_processor_count(sysconf(_SC_NPROCESSORS_CONF));
|
||||||
if (_processor_count == 1) {
|
if (processor_count() == 1) {
|
||||||
pid_t pid = os::Linux::gettid();
|
pid_t pid = os::Linux::gettid();
|
||||||
char fname[32];
|
char fname[32];
|
||||||
jio_snprintf(fname, sizeof(fname), "/proc/%d", pid);
|
jio_snprintf(fname, sizeof(fname), "/proc/%d", pid);
|
||||||
@ -236,7 +236,7 @@ void os::Linux::initialize_system_info() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_physical_memory = (julong)sysconf(_SC_PHYS_PAGES) * (julong)sysconf(_SC_PAGESIZE);
|
_physical_memory = (julong)sysconf(_SC_PHYS_PAGES) * (julong)sysconf(_SC_PAGESIZE);
|
||||||
assert(_processor_count > 0, "linux error");
|
assert(processor_count() > 0, "linux error");
|
||||||
}
|
}
|
||||||
|
|
||||||
void os::init_system_properties_values() {
|
void os::init_system_properties_values() {
|
||||||
@ -4683,6 +4683,7 @@ void Parker::park(bool isAbsolute, jlong time) {
|
|||||||
// Return immediately if a permit is available.
|
// Return immediately if a permit is available.
|
||||||
if (_counter > 0) {
|
if (_counter > 0) {
|
||||||
_counter = 0 ;
|
_counter = 0 ;
|
||||||
|
OrderAccess::fence();
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4725,6 +4726,7 @@ void Parker::park(bool isAbsolute, jlong time) {
|
|||||||
_counter = 0;
|
_counter = 0;
|
||||||
status = pthread_mutex_unlock(_mutex);
|
status = pthread_mutex_unlock(_mutex);
|
||||||
assert (status == 0, "invariant") ;
|
assert (status == 0, "invariant") ;
|
||||||
|
OrderAccess::fence();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4765,6 +4767,7 @@ void Parker::park(bool isAbsolute, jlong time) {
|
|||||||
jt->java_suspend_self();
|
jt->java_suspend_self();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OrderAccess::fence();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parker::unpark() {
|
void Parker::unpark() {
|
||||||
|
@ -937,54 +937,56 @@ scope_desc_at(Nmethod_t *N, int32_t decode_offset, Vframe_t *vf)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int scopeDesc_chain(Nmethod_t *N) {
|
||||||
scopeDesc_chain(Nmethod_t *N)
|
|
||||||
{
|
|
||||||
int32_t decode_offset = 0;
|
int32_t decode_offset = 0;
|
||||||
int32_t err;
|
int32_t err;
|
||||||
|
|
||||||
if (debug > 2)
|
if (debug > 2) {
|
||||||
fprintf(stderr, "\t scopeDesc_chain: BEGIN\n");
|
fprintf(stderr, "\t scopeDesc_chain: BEGIN\n");
|
||||||
|
}
|
||||||
|
|
||||||
err = ps_pread(N->J->P, N->pc_desc + OFFSET_PcDesc_scope_decode_offset,
|
err = ps_pread(N->J->P, N->pc_desc + OFFSET_PcDesc_scope_decode_offset,
|
||||||
&decode_offset, SZ32);
|
&decode_offset, SZ32);
|
||||||
CHECK_FAIL(err);
|
CHECK_FAIL(err);
|
||||||
|
|
||||||
while (decode_offset > 0) {
|
while (decode_offset > 0) {
|
||||||
if (debug > 2)
|
Vframe_t *vf = &N->vframes[N->vf_cnt];
|
||||||
fprintf(stderr, "\t scopeDesc_chain: decode_offset: %#x\n", decode_offset);
|
|
||||||
|
|
||||||
Vframe_t *vf = &N->vframes[N->vf_cnt];
|
if (debug > 2) {
|
||||||
|
fprintf(stderr, "\t scopeDesc_chain: decode_offset: %#x\n", decode_offset);
|
||||||
|
}
|
||||||
|
|
||||||
err = scope_desc_at(N, decode_offset, vf);
|
err = scope_desc_at(N, decode_offset, vf);
|
||||||
|
CHECK_FAIL(err);
|
||||||
|
|
||||||
|
if (vf->methodIdx > N->oops_len) {
|
||||||
|
fprintf(stderr, "\t scopeDesc_chain: (methodIdx > oops_len) !\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
err = read_pointer(N->J, N->nm + N->oops_beg + (vf->methodIdx-1)*POINTER_SIZE,
|
||||||
|
&vf->methodOop);
|
||||||
|
CHECK_FAIL(err);
|
||||||
|
|
||||||
|
if (vf->methodOop) {
|
||||||
|
N->vf_cnt++;
|
||||||
|
err = line_number_from_bci(N->J, vf);
|
||||||
CHECK_FAIL(err);
|
CHECK_FAIL(err);
|
||||||
|
if (debug > 2) {
|
||||||
if (vf->methodIdx > N->oops_len) {
|
fprintf(stderr, "\t scopeDesc_chain: methodOop: %#8llx, line: %ld\n",
|
||||||
fprintf(stderr, "\t scopeDesc_chain: (methodIdx > oops_len) !\n");
|
vf->methodOop, vf->line);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
err = read_pointer(N->J, N->nm + N->oops_beg + (vf->methodIdx-1)*POINTER_SIZE,
|
}
|
||||||
&vf->methodOop);
|
decode_offset = vf->sender_decode_offset;
|
||||||
CHECK_FAIL(err);
|
}
|
||||||
|
if (debug > 2) {
|
||||||
if (vf->methodOop) {
|
fprintf(stderr, "\t scopeDesc_chain: END \n\n");
|
||||||
N->vf_cnt++;
|
|
||||||
err = line_number_from_bci(N->J, vf);
|
|
||||||
CHECK_FAIL(err);
|
|
||||||
if (debug > 2) {
|
|
||||||
fprintf(stderr, "\t scopeDesc_chain: methodOop: %#8llx, line: %ld\n",
|
|
||||||
vf->methodOop, vf->line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
decode_offset = vf->sender_decode_offset;
|
|
||||||
}
|
}
|
||||||
if (debug > 2)
|
|
||||||
fprintf(stderr, "\t scopeDesc_chain: END \n\n");
|
|
||||||
return PS_OK;
|
return PS_OK;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (debug)
|
if (debug) {
|
||||||
fprintf(stderr, "\t scopeDesc_chain: FAIL \n\n");
|
fprintf(stderr, "\t scopeDesc_chain: FAIL \n\n");
|
||||||
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,7 +457,7 @@ static volatile int max_hrtime_lock = LOCK_FREE; // Update counter with LSB
|
|||||||
|
|
||||||
|
|
||||||
void os::Solaris::initialize_system_info() {
|
void os::Solaris::initialize_system_info() {
|
||||||
_processor_count = sysconf(_SC_NPROCESSORS_CONF);
|
set_processor_count(sysconf(_SC_NPROCESSORS_CONF));
|
||||||
_processors_online = sysconf (_SC_NPROCESSORS_ONLN);
|
_processors_online = sysconf (_SC_NPROCESSORS_ONLN);
|
||||||
_physical_memory = (julong)sysconf(_SC_PHYS_PAGES) * (julong)sysconf(_SC_PAGESIZE);
|
_physical_memory = (julong)sysconf(_SC_PHYS_PAGES) * (julong)sysconf(_SC_PAGESIZE);
|
||||||
}
|
}
|
||||||
@ -5803,6 +5803,7 @@ void Parker::park(bool isAbsolute, jlong time) {
|
|||||||
// Return immediately if a permit is available.
|
// Return immediately if a permit is available.
|
||||||
if (_counter > 0) {
|
if (_counter > 0) {
|
||||||
_counter = 0 ;
|
_counter = 0 ;
|
||||||
|
OrderAccess::fence();
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5846,6 +5847,7 @@ void Parker::park(bool isAbsolute, jlong time) {
|
|||||||
_counter = 0;
|
_counter = 0;
|
||||||
status = os::Solaris::mutex_unlock(_mutex);
|
status = os::Solaris::mutex_unlock(_mutex);
|
||||||
assert (status == 0, "invariant") ;
|
assert (status == 0, "invariant") ;
|
||||||
|
OrderAccess::fence();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5892,6 +5894,7 @@ void Parker::park(bool isAbsolute, jlong time) {
|
|||||||
jt->java_suspend_self();
|
jt->java_suspend_self();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OrderAccess::fence();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parker::unpark() {
|
void Parker::unpark() {
|
||||||
|
@ -3150,7 +3150,7 @@ void os::win32::initialize_system_info() {
|
|||||||
_vm_allocation_granularity = si.dwAllocationGranularity;
|
_vm_allocation_granularity = si.dwAllocationGranularity;
|
||||||
_processor_type = si.dwProcessorType;
|
_processor_type = si.dwProcessorType;
|
||||||
_processor_level = si.wProcessorLevel;
|
_processor_level = si.wProcessorLevel;
|
||||||
_processor_count = si.dwNumberOfProcessors;
|
set_processor_count(si.dwNumberOfProcessors);
|
||||||
|
|
||||||
MEMORYSTATUSEX ms;
|
MEMORYSTATUSEX ms;
|
||||||
ms.dwLength = sizeof(ms);
|
ms.dwLength = sizeof(ms);
|
||||||
|
@ -22,10 +22,9 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//
|
|
||||||
// Sets the default values for platform dependent flags used by the runtime system.
|
// Sets the default values for platform dependent flags used by the runtime system.
|
||||||
// (see globals.hpp)
|
// (see globals.hpp)
|
||||||
//
|
|
||||||
define_pd_global(bool, DontYieldALot, false);
|
define_pd_global(bool, DontYieldALot, false);
|
||||||
#ifdef AMD64
|
#ifdef AMD64
|
||||||
define_pd_global(intx, ThreadStackSize, 1024); // 0 => use system default
|
define_pd_global(intx, ThreadStackSize, 1024); // 0 => use system default
|
||||||
@ -39,11 +38,10 @@ define_pd_global(intx, VMThreadStackSize, 512);
|
|||||||
#endif // AMD64
|
#endif // AMD64
|
||||||
|
|
||||||
define_pd_global(intx, CompilerThreadStackSize, 0);
|
define_pd_global(intx, CompilerThreadStackSize, 0);
|
||||||
define_pd_global(intx, SurvivorRatio, 8);
|
|
||||||
|
|
||||||
define_pd_global(uintx, JVMInvokeMethodSlack, 8192);
|
define_pd_global(uintx,JVMInvokeMethodSlack, 8192);
|
||||||
|
|
||||||
// Only used on 64 bit platforms
|
// Only used on 64 bit platforms
|
||||||
define_pd_global(uintx, HeapBaseMinAddress, 2*G);
|
define_pd_global(uintx,HeapBaseMinAddress, 2*G);
|
||||||
// Only used on 64 bit Windows platforms
|
// Only used on 64 bit Windows platforms
|
||||||
define_pd_global(bool, UseVectoredExceptions, false);
|
define_pd_global(bool, UseVectoredExceptions, false);
|
||||||
|
@ -22,31 +22,25 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//
|
|
||||||
// Sets the default values for platform dependent flags used by the runtime system.
|
// Sets the default values for platform dependent flags used by the runtime system.
|
||||||
// (see globals.hpp)
|
// (see globals.hpp)
|
||||||
//
|
|
||||||
define_pd_global(bool, DontYieldALot, true); // Determined in the design center
|
define_pd_global(bool, DontYieldALot, true); // Determined in the design center
|
||||||
#ifdef AMD64
|
#ifdef AMD64
|
||||||
define_pd_global(intx, ThreadStackSize, 1024); // 0 => use system default
|
define_pd_global(intx, ThreadStackSize, 1024); // 0 => use system default
|
||||||
define_pd_global(intx, VMThreadStackSize, 1024);
|
define_pd_global(intx, VMThreadStackSize, 1024);
|
||||||
define_pd_global(intx, SurvivorRatio, 6);
|
define_pd_global(uintx,JVMInvokeMethodSlack, 8*K);
|
||||||
define_pd_global(uintx, JVMInvokeMethodSlack, 8*K);
|
|
||||||
#else
|
#else
|
||||||
// UseStackBanging is not pd
|
|
||||||
// define_pd_global(bool, UseStackBanging, true);
|
|
||||||
|
|
||||||
// ThreadStackSize 320 allows TaggedStackInterpreter and a couple of test cases
|
// ThreadStackSize 320 allows TaggedStackInterpreter and a couple of test cases
|
||||||
// to run while keeping the number of threads that can be created high.
|
// to run while keeping the number of threads that can be created high.
|
||||||
define_pd_global(intx, ThreadStackSize, 320);
|
define_pd_global(intx, ThreadStackSize, 320);
|
||||||
define_pd_global(intx, VMThreadStackSize, 512);
|
define_pd_global(intx, VMThreadStackSize, 512);
|
||||||
define_pd_global(intx, SurvivorRatio, 8);
|
define_pd_global(uintx,JVMInvokeMethodSlack, 10*K);
|
||||||
define_pd_global(uintx, JVMInvokeMethodSlack, 10*K);
|
|
||||||
#endif // AMD64
|
#endif // AMD64
|
||||||
|
|
||||||
define_pd_global(intx, CompilerThreadStackSize, 0);
|
define_pd_global(intx, CompilerThreadStackSize, 0);
|
||||||
|
|
||||||
// Only used on 64 bit platforms
|
// Only used on 64 bit platforms
|
||||||
define_pd_global(uintx, HeapBaseMinAddress, 256*M);
|
define_pd_global(uintx,HeapBaseMinAddress, 256*M);
|
||||||
// Only used on 64 bit Windows platforms
|
// Only used on 64 bit Windows platforms
|
||||||
define_pd_global(bool, UseVectoredExceptions, false);
|
define_pd_global(bool, UseVectoredExceptions, false);
|
||||||
|
@ -22,10 +22,9 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//
|
|
||||||
// Sets the default values for platform dependent flags used by the runtime system.
|
// Sets the default values for platform dependent flags used by the runtime system.
|
||||||
// (see globals.hpp)
|
// (see globals.hpp)
|
||||||
//
|
|
||||||
define_pd_global(bool, DontYieldALot, false);
|
define_pd_global(bool, DontYieldALot, false);
|
||||||
|
|
||||||
// Default stack size on Windows is determined by the executable (java.exe
|
// Default stack size on Windows is determined by the executable (java.exe
|
||||||
@ -35,8 +34,6 @@ define_pd_global(bool, DontYieldALot, false);
|
|||||||
define_pd_global(intx, ThreadStackSize, 0); // 0 => use system default
|
define_pd_global(intx, ThreadStackSize, 0); // 0 => use system default
|
||||||
define_pd_global(intx, VMThreadStackSize, 0); // 0 => use system default
|
define_pd_global(intx, VMThreadStackSize, 0); // 0 => use system default
|
||||||
|
|
||||||
define_pd_global(intx, SurvivorRatio, 8);
|
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
define_pd_global(intx, CompilerThreadStackSize, 1024);
|
define_pd_global(intx, CompilerThreadStackSize, 1024);
|
||||||
#else
|
#else
|
||||||
|
@ -365,7 +365,7 @@ void BlockListBuilder::make_loop_header(BlockBegin* block) {
|
|||||||
if (_next_loop_index < 31) _next_loop_index++;
|
if (_next_loop_index < 31) _next_loop_index++;
|
||||||
} else {
|
} else {
|
||||||
// block already marked as loop header
|
// block already marked as loop header
|
||||||
assert(is_power_of_2(_loop_map.at(block->block_id())), "exactly one bit must be set");
|
assert(is_power_of_2((unsigned int)_loop_map.at(block->block_id())), "exactly one bit must be set");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1855,12 +1855,26 @@ void LIRGenerator::do_UnsafeGetRaw(UnsafeGetRaw* x) {
|
|||||||
addr = new LIR_Address(base_op, index_op->as_jint(), dst_type);
|
addr = new LIR_Address(base_op, index_op->as_jint(), dst_type);
|
||||||
} else {
|
} else {
|
||||||
#ifdef X86
|
#ifdef X86
|
||||||
|
#ifdef _LP64
|
||||||
|
if (!index_op->is_illegal() && index_op->type() == T_INT) {
|
||||||
|
LIR_Opr tmp = new_pointer_register();
|
||||||
|
__ convert(Bytecodes::_i2l, index_op, tmp);
|
||||||
|
index_op = tmp;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
addr = new LIR_Address(base_op, index_op, LIR_Address::Scale(log2_scale), 0, dst_type);
|
addr = new LIR_Address(base_op, index_op, LIR_Address::Scale(log2_scale), 0, dst_type);
|
||||||
#else
|
#else
|
||||||
if (index_op->is_illegal() || log2_scale == 0) {
|
if (index_op->is_illegal() || log2_scale == 0) {
|
||||||
|
#ifdef _LP64
|
||||||
|
if (!index_op->is_illegal() && index_op->type() == T_INT) {
|
||||||
|
LIR_Opr tmp = new_pointer_register();
|
||||||
|
__ convert(Bytecodes::_i2l, index_op, tmp);
|
||||||
|
index_op = tmp;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
addr = new LIR_Address(base_op, index_op, dst_type);
|
addr = new LIR_Address(base_op, index_op, dst_type);
|
||||||
} else {
|
} else {
|
||||||
LIR_Opr tmp = new_register(T_INT);
|
LIR_Opr tmp = new_pointer_register();
|
||||||
__ shift_left(index_op, log2_scale, tmp);
|
__ shift_left(index_op, log2_scale, tmp);
|
||||||
addr = new LIR_Address(base_op, tmp, dst_type);
|
addr = new LIR_Address(base_op, tmp, dst_type);
|
||||||
}
|
}
|
||||||
@ -1915,10 +1929,25 @@ void LIRGenerator::do_UnsafePutRaw(UnsafePutRaw* x) {
|
|||||||
LIR_Opr index_op = idx.result();
|
LIR_Opr index_op = idx.result();
|
||||||
if (log2_scale != 0) {
|
if (log2_scale != 0) {
|
||||||
// temporary fix (platform dependent code without shift on Intel would be better)
|
// temporary fix (platform dependent code without shift on Intel would be better)
|
||||||
index_op = new_register(T_INT);
|
index_op = new_pointer_register();
|
||||||
__ move(idx.result(), index_op);
|
#ifdef _LP64
|
||||||
|
if(idx.result()->type() == T_INT) {
|
||||||
|
__ convert(Bytecodes::_i2l, idx.result(), index_op);
|
||||||
|
} else {
|
||||||
|
#endif
|
||||||
|
__ move(idx.result(), index_op);
|
||||||
|
#ifdef _LP64
|
||||||
|
}
|
||||||
|
#endif
|
||||||
__ shift_left(index_op, log2_scale, index_op);
|
__ shift_left(index_op, log2_scale, index_op);
|
||||||
}
|
}
|
||||||
|
#ifdef _LP64
|
||||||
|
else if(!index_op->is_illegal() && index_op->type() == T_INT) {
|
||||||
|
LIR_Opr tmp = new_pointer_register();
|
||||||
|
__ convert(Bytecodes::_i2l, index_op, tmp);
|
||||||
|
index_op = tmp;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
LIR_Address* addr = new LIR_Address(base_op, index_op, x->basic_type());
|
LIR_Address* addr = new LIR_Address(base_op, index_op, x->basic_type());
|
||||||
__ move(value.result(), addr);
|
__ move(value.result(), addr);
|
||||||
|
@ -2464,6 +2464,10 @@ int LinearScan::append_scope_value_for_constant(LIR_Opr opr, GrowableArray<Scope
|
|||||||
|
|
||||||
case T_LONG: // fall through
|
case T_LONG: // fall through
|
||||||
case T_DOUBLE: {
|
case T_DOUBLE: {
|
||||||
|
#ifdef _LP64
|
||||||
|
scope_values->append(&_int_0_scope_value);
|
||||||
|
scope_values->append(new ConstantLongValue(c->as_jlong_bits()));
|
||||||
|
#else
|
||||||
if (hi_word_offset_in_bytes > lo_word_offset_in_bytes) {
|
if (hi_word_offset_in_bytes > lo_word_offset_in_bytes) {
|
||||||
scope_values->append(new ConstantIntValue(c->as_jint_hi_bits()));
|
scope_values->append(new ConstantIntValue(c->as_jint_hi_bits()));
|
||||||
scope_values->append(new ConstantIntValue(c->as_jint_lo_bits()));
|
scope_values->append(new ConstantIntValue(c->as_jint_lo_bits()));
|
||||||
@ -2471,7 +2475,7 @@ int LinearScan::append_scope_value_for_constant(LIR_Opr opr, GrowableArray<Scope
|
|||||||
scope_values->append(new ConstantIntValue(c->as_jint_lo_bits()));
|
scope_values->append(new ConstantIntValue(c->as_jint_lo_bits()));
|
||||||
scope_values->append(new ConstantIntValue(c->as_jint_hi_bits()));
|
scope_values->append(new ConstantIntValue(c->as_jint_hi_bits()));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2503,17 +2507,18 @@ int LinearScan::append_scope_value_for_operand(LIR_Opr opr, GrowableArray<ScopeV
|
|||||||
} else if (opr->is_single_cpu()) {
|
} else if (opr->is_single_cpu()) {
|
||||||
bool is_oop = opr->is_oop_register();
|
bool is_oop = opr->is_oop_register();
|
||||||
int cache_idx = opr->cpu_regnr() * 2 + (is_oop ? 1 : 0);
|
int cache_idx = opr->cpu_regnr() * 2 + (is_oop ? 1 : 0);
|
||||||
|
Location::Type int_loc_type = NOT_LP64(Location::normal) LP64_ONLY(Location::int_in_long);
|
||||||
|
|
||||||
ScopeValue* sv = _scope_value_cache.at(cache_idx);
|
ScopeValue* sv = _scope_value_cache.at(cache_idx);
|
||||||
if (sv == NULL) {
|
if (sv == NULL) {
|
||||||
Location::Type loc_type = is_oop ? Location::oop : Location::normal;
|
Location::Type loc_type = is_oop ? Location::oop : int_loc_type;
|
||||||
VMReg rname = frame_map()->regname(opr);
|
VMReg rname = frame_map()->regname(opr);
|
||||||
sv = new LocationValue(Location::new_reg_loc(loc_type, rname));
|
sv = new LocationValue(Location::new_reg_loc(loc_type, rname));
|
||||||
_scope_value_cache.at_put(cache_idx, sv);
|
_scope_value_cache.at_put(cache_idx, sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if cached value is correct
|
// check if cached value is correct
|
||||||
DEBUG_ONLY(assert_equal(sv, new LocationValue(Location::new_reg_loc(is_oop ? Location::oop : Location::normal, frame_map()->regname(opr)))));
|
DEBUG_ONLY(assert_equal(sv, new LocationValue(Location::new_reg_loc(is_oop ? Location::oop : int_loc_type, frame_map()->regname(opr)))));
|
||||||
|
|
||||||
scope_values->append(sv);
|
scope_values->append(sv);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -61,9 +61,11 @@ class BCEscapeAnalyzer : public ResourceObj {
|
|||||||
BCEscapeAnalyzer* _parent;
|
BCEscapeAnalyzer* _parent;
|
||||||
int _level;
|
int _level;
|
||||||
|
|
||||||
|
public:
|
||||||
class ArgumentMap;
|
class ArgumentMap;
|
||||||
class StateInfo;
|
class StateInfo;
|
||||||
|
|
||||||
|
private:
|
||||||
// helper functions
|
// helper functions
|
||||||
bool is_argument(int i) { return i >= 0 && i < _arg_size; }
|
bool is_argument(int i) { return i >= 0 && i < _arg_size; }
|
||||||
|
|
||||||
|
@ -46,6 +46,9 @@ ciInstanceKlass* ciEnv::_Throwable;
|
|||||||
ciInstanceKlass* ciEnv::_Thread;
|
ciInstanceKlass* ciEnv::_Thread;
|
||||||
ciInstanceKlass* ciEnv::_OutOfMemoryError;
|
ciInstanceKlass* ciEnv::_OutOfMemoryError;
|
||||||
ciInstanceKlass* ciEnv::_String;
|
ciInstanceKlass* ciEnv::_String;
|
||||||
|
ciInstanceKlass* ciEnv::_StringBuffer;
|
||||||
|
ciInstanceKlass* ciEnv::_StringBuilder;
|
||||||
|
ciInstanceKlass* ciEnv::_Integer;
|
||||||
|
|
||||||
ciSymbol* ciEnv::_unloaded_cisymbol = NULL;
|
ciSymbol* ciEnv::_unloaded_cisymbol = NULL;
|
||||||
ciInstanceKlass* ciEnv::_unloaded_ciinstance_klass = NULL;
|
ciInstanceKlass* ciEnv::_unloaded_ciinstance_klass = NULL;
|
||||||
@ -110,6 +113,8 @@ ciEnv::ciEnv(CompileTask* task, int system_dictionary_modification_counter) {
|
|||||||
_ArrayIndexOutOfBoundsException_instance = NULL;
|
_ArrayIndexOutOfBoundsException_instance = NULL;
|
||||||
_ArrayStoreException_instance = NULL;
|
_ArrayStoreException_instance = NULL;
|
||||||
_ClassCastException_instance = NULL;
|
_ClassCastException_instance = NULL;
|
||||||
|
_the_null_string = NULL;
|
||||||
|
_the_min_jint_string = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ciEnv::ciEnv(Arena* arena) {
|
ciEnv::ciEnv(Arena* arena) {
|
||||||
@ -163,6 +168,8 @@ ciEnv::ciEnv(Arena* arena) {
|
|||||||
_ArrayIndexOutOfBoundsException_instance = NULL;
|
_ArrayIndexOutOfBoundsException_instance = NULL;
|
||||||
_ArrayStoreException_instance = NULL;
|
_ArrayStoreException_instance = NULL;
|
||||||
_ClassCastException_instance = NULL;
|
_ClassCastException_instance = NULL;
|
||||||
|
_the_null_string = NULL;
|
||||||
|
_the_min_jint_string = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ciEnv::~ciEnv() {
|
ciEnv::~ciEnv() {
|
||||||
@ -248,6 +255,22 @@ ciInstance* ciEnv::ClassCastException_instance() {
|
|||||||
return _ClassCastException_instance;
|
return _ClassCastException_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ciInstance* ciEnv::the_null_string() {
|
||||||
|
if (_the_null_string == NULL) {
|
||||||
|
VM_ENTRY_MARK;
|
||||||
|
_the_null_string = get_object(Universe::the_null_string())->as_instance();
|
||||||
|
}
|
||||||
|
return _the_null_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
ciInstance* ciEnv::the_min_jint_string() {
|
||||||
|
if (_the_min_jint_string == NULL) {
|
||||||
|
VM_ENTRY_MARK;
|
||||||
|
_the_min_jint_string = get_object(Universe::the_min_jint_string())->as_instance();
|
||||||
|
}
|
||||||
|
return _the_min_jint_string;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
// ciEnv::get_method_from_handle
|
// ciEnv::get_method_from_handle
|
||||||
ciMethod* ciEnv::get_method_from_handle(jobject method) {
|
ciMethod* ciEnv::get_method_from_handle(jobject method) {
|
||||||
@ -690,10 +713,8 @@ ciMethod* ciEnv::get_method_by_index_impl(ciInstanceKlass* accessor,
|
|||||||
ciInstanceKlass* declared_holder = get_instance_klass_for_declared_method_holder(holder);
|
ciInstanceKlass* declared_holder = get_instance_klass_for_declared_method_holder(holder);
|
||||||
|
|
||||||
// Get the method's name and signature.
|
// Get the method's name and signature.
|
||||||
int nt_index = cpool->name_and_type_ref_index_at(index);
|
|
||||||
int sig_index = cpool->signature_ref_index_at(nt_index);
|
|
||||||
symbolOop name_sym = cpool->name_ref_at(index);
|
symbolOop name_sym = cpool->name_ref_at(index);
|
||||||
symbolOop sig_sym = cpool->symbol_at(sig_index);
|
symbolOop sig_sym = cpool->signature_ref_at(index);
|
||||||
|
|
||||||
if (holder_is_accessible) { // Our declared holder is loaded.
|
if (holder_is_accessible) { // Our declared holder is loaded.
|
||||||
instanceKlass* lookup = declared_holder->get_instanceKlass();
|
instanceKlass* lookup = declared_holder->get_instanceKlass();
|
||||||
|
@ -82,6 +82,9 @@ private:
|
|||||||
static ciInstanceKlass* _Thread;
|
static ciInstanceKlass* _Thread;
|
||||||
static ciInstanceKlass* _OutOfMemoryError;
|
static ciInstanceKlass* _OutOfMemoryError;
|
||||||
static ciInstanceKlass* _String;
|
static ciInstanceKlass* _String;
|
||||||
|
static ciInstanceKlass* _StringBuffer;
|
||||||
|
static ciInstanceKlass* _StringBuilder;
|
||||||
|
static ciInstanceKlass* _Integer;
|
||||||
|
|
||||||
static ciSymbol* _unloaded_cisymbol;
|
static ciSymbol* _unloaded_cisymbol;
|
||||||
static ciInstanceKlass* _unloaded_ciinstance_klass;
|
static ciInstanceKlass* _unloaded_ciinstance_klass;
|
||||||
@ -97,6 +100,9 @@ private:
|
|||||||
ciInstance* _ArrayStoreException_instance;
|
ciInstance* _ArrayStoreException_instance;
|
||||||
ciInstance* _ClassCastException_instance;
|
ciInstance* _ClassCastException_instance;
|
||||||
|
|
||||||
|
ciInstance* _the_null_string; // The Java string "null"
|
||||||
|
ciInstance* _the_min_jint_string; // The Java string "-2147483648"
|
||||||
|
|
||||||
// Look up a klass by name from a particular class loader (the accessor's).
|
// Look up a klass by name from a particular class loader (the accessor's).
|
||||||
// If require_local, result must be defined in that class loader, or NULL.
|
// If require_local, result must be defined in that class loader, or NULL.
|
||||||
// If !require_local, a result from remote class loader may be reported,
|
// If !require_local, a result from remote class loader may be reported,
|
||||||
@ -310,6 +316,15 @@ public:
|
|||||||
ciInstanceKlass* String_klass() {
|
ciInstanceKlass* String_klass() {
|
||||||
return _String;
|
return _String;
|
||||||
}
|
}
|
||||||
|
ciInstanceKlass* StringBuilder_klass() {
|
||||||
|
return _StringBuilder;
|
||||||
|
}
|
||||||
|
ciInstanceKlass* StringBuffer_klass() {
|
||||||
|
return _StringBuffer;
|
||||||
|
}
|
||||||
|
ciInstanceKlass* Integer_klass() {
|
||||||
|
return _Integer;
|
||||||
|
}
|
||||||
ciInstance* NullPointerException_instance() {
|
ciInstance* NullPointerException_instance() {
|
||||||
assert(_NullPointerException_instance != NULL, "initialization problem");
|
assert(_NullPointerException_instance != NULL, "initialization problem");
|
||||||
return _NullPointerException_instance;
|
return _NullPointerException_instance;
|
||||||
@ -324,6 +339,9 @@ public:
|
|||||||
ciInstance* ArrayStoreException_instance();
|
ciInstance* ArrayStoreException_instance();
|
||||||
ciInstance* ClassCastException_instance();
|
ciInstance* ClassCastException_instance();
|
||||||
|
|
||||||
|
ciInstance* the_null_string();
|
||||||
|
ciInstance* the_min_jint_string();
|
||||||
|
|
||||||
static ciSymbol* unloaded_cisymbol() {
|
static ciSymbol* unloaded_cisymbol() {
|
||||||
return _unloaded_cisymbol;
|
return _unloaded_cisymbol;
|
||||||
}
|
}
|
||||||
|
@ -340,6 +340,20 @@ ciField* ciInstanceKlass::get_field_by_offset(int field_offset, bool is_static)
|
|||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
// ciInstanceKlass::get_field_by_name
|
||||||
|
ciField* ciInstanceKlass::get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static) {
|
||||||
|
VM_ENTRY_MARK;
|
||||||
|
instanceKlass* k = get_instanceKlass();
|
||||||
|
fieldDescriptor fd;
|
||||||
|
klassOop def = k->find_field(name->get_symbolOop(), signature->get_symbolOop(), is_static, &fd);
|
||||||
|
if (def == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd);
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
// ciInstanceKlass::non_static_fields.
|
// ciInstanceKlass::non_static_fields.
|
||||||
|
|
||||||
|
@ -148,6 +148,7 @@ public:
|
|||||||
|
|
||||||
ciInstanceKlass* get_canonical_holder(int offset);
|
ciInstanceKlass* get_canonical_holder(int offset);
|
||||||
ciField* get_field_by_offset(int field_offset, bool is_static);
|
ciField* get_field_by_offset(int field_offset, bool is_static);
|
||||||
|
ciField* get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static);
|
||||||
|
|
||||||
GrowableArray<ciField*>* non_static_fields();
|
GrowableArray<ciField*>* non_static_fields();
|
||||||
|
|
||||||
|
@ -168,6 +168,15 @@ void ciObjectFactory::init_shared_objects() {
|
|||||||
ciEnv::_String =
|
ciEnv::_String =
|
||||||
get(SystemDictionary::string_klass())
|
get(SystemDictionary::string_klass())
|
||||||
->as_instance_klass();
|
->as_instance_klass();
|
||||||
|
ciEnv::_StringBuffer =
|
||||||
|
get(SystemDictionary::stringBuffer_klass())
|
||||||
|
->as_instance_klass();
|
||||||
|
ciEnv::_StringBuilder =
|
||||||
|
get(SystemDictionary::StringBuilder_klass())
|
||||||
|
->as_instance_klass();
|
||||||
|
ciEnv::_Integer =
|
||||||
|
get(SystemDictionary::int_klass())
|
||||||
|
->as_instance_klass();
|
||||||
|
|
||||||
for (int len = -1; len != _ci_objects->length(); ) {
|
for (int len = -1; len != _ci_objects->length(); ) {
|
||||||
len = _ci_objects->length();
|
len = _ci_objects->length();
|
||||||
|
@ -2511,23 +2511,12 @@ void ClassFileParser::java_dyn_MethodHandle_fix_pre(constantPoolHandle cp,
|
|||||||
fac_ptr->nonstatic_byte_count -= 1;
|
fac_ptr->nonstatic_byte_count -= 1;
|
||||||
(*fields_ptr)->ushort_at_put(i + instanceKlass::signature_index_offset,
|
(*fields_ptr)->ushort_at_put(i + instanceKlass::signature_index_offset,
|
||||||
word_sig_index);
|
word_sig_index);
|
||||||
if (wordSize == jintSize) {
|
fac_ptr->nonstatic_word_count += 1;
|
||||||
fac_ptr->nonstatic_word_count += 1;
|
|
||||||
} else {
|
|
||||||
fac_ptr->nonstatic_double_count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
FieldAllocationType atype = (FieldAllocationType) (*fields_ptr)->ushort_at(i+4);
|
FieldAllocationType atype = (FieldAllocationType) (*fields_ptr)->ushort_at(i + instanceKlass::low_offset);
|
||||||
assert(atype == NONSTATIC_BYTE, "");
|
assert(atype == NONSTATIC_BYTE, "");
|
||||||
FieldAllocationType new_atype = NONSTATIC_WORD;
|
FieldAllocationType new_atype = NONSTATIC_WORD;
|
||||||
if (wordSize > jintSize) {
|
(*fields_ptr)->ushort_at_put(i + instanceKlass::low_offset, new_atype);
|
||||||
if (Universe::field_type_should_be_aligned(T_LONG)) {
|
|
||||||
atype = NONSTATIC_ALIGNED_DOUBLE;
|
|
||||||
} else {
|
|
||||||
atype = NONSTATIC_DOUBLE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(*fields_ptr)->ushort_at_put(i+4, new_atype);
|
|
||||||
|
|
||||||
found_vmentry = true;
|
found_vmentry = true;
|
||||||
break;
|
break;
|
||||||
@ -3085,7 +3074,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
|||||||
int len = fields->length();
|
int len = fields->length();
|
||||||
for (int i = 0; i < len; i += instanceKlass::next_offset) {
|
for (int i = 0; i < len; i += instanceKlass::next_offset) {
|
||||||
int real_offset;
|
int real_offset;
|
||||||
FieldAllocationType atype = (FieldAllocationType) fields->ushort_at(i+4);
|
FieldAllocationType atype = (FieldAllocationType) fields->ushort_at(i + instanceKlass::low_offset);
|
||||||
switch (atype) {
|
switch (atype) {
|
||||||
case STATIC_OOP:
|
case STATIC_OOP:
|
||||||
real_offset = next_static_oop_offset;
|
real_offset = next_static_oop_offset;
|
||||||
@ -3173,8 +3162,8 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
|||||||
default:
|
default:
|
||||||
ShouldNotReachHere();
|
ShouldNotReachHere();
|
||||||
}
|
}
|
||||||
fields->short_at_put(i+4, extract_low_short_from_int(real_offset) );
|
fields->short_at_put(i + instanceKlass::low_offset, extract_low_short_from_int(real_offset));
|
||||||
fields->short_at_put(i+5, extract_high_short_from_int(real_offset) );
|
fields->short_at_put(i + instanceKlass::high_offset, extract_high_short_from_int(real_offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size of instances
|
// Size of instances
|
||||||
@ -3766,8 +3755,9 @@ bool ClassFileParser::has_illegal_visibility(jint flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ClassFileParser::is_supported_version(u2 major, u2 minor) {
|
bool ClassFileParser::is_supported_version(u2 major, u2 minor) {
|
||||||
u2 max_version = JDK_Version::is_gte_jdk17x_version() ?
|
u2 max_version =
|
||||||
JAVA_MAX_SUPPORTED_VERSION : JAVA_6_VERSION;
|
JDK_Version::is_gte_jdk17x_version() ? JAVA_MAX_SUPPORTED_VERSION :
|
||||||
|
(JDK_Version::is_gte_jdk16x_version() ? JAVA_6_VERSION : JAVA_1_5_VERSION);
|
||||||
return (major >= JAVA_MIN_SUPPORTED_VERSION) &&
|
return (major >= JAVA_MIN_SUPPORTED_VERSION) &&
|
||||||
(major <= max_version) &&
|
(major <= max_version) &&
|
||||||
((major != max_version) ||
|
((major != max_version) ||
|
||||||
|
@ -1124,8 +1124,7 @@ class BacktraceBuilder: public StackObj {
|
|||||||
if (_dirty && _methods != NULL) {
|
if (_dirty && _methods != NULL) {
|
||||||
BarrierSet* bs = Universe::heap()->barrier_set();
|
BarrierSet* bs = Universe::heap()->barrier_set();
|
||||||
assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt");
|
assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt");
|
||||||
bs->write_ref_array(MemRegion((HeapWord*)_methods->base(),
|
bs->write_ref_array((HeapWord*)_methods->base(), _methods->length());
|
||||||
_methods->array_size()));
|
|
||||||
_dirty = false;
|
_dirty = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2430,15 +2429,15 @@ oop java_dyn_MethodTypeForm::erasedType(oop mtform) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Support for sun_dyn_CallSiteImpl
|
// Support for java_dyn_CallSite
|
||||||
|
|
||||||
int sun_dyn_CallSiteImpl::_type_offset;
|
int java_dyn_CallSite::_type_offset;
|
||||||
int sun_dyn_CallSiteImpl::_target_offset;
|
int java_dyn_CallSite::_target_offset;
|
||||||
int sun_dyn_CallSiteImpl::_vmmethod_offset;
|
int java_dyn_CallSite::_vmmethod_offset;
|
||||||
|
|
||||||
void sun_dyn_CallSiteImpl::compute_offsets() {
|
void java_dyn_CallSite::compute_offsets() {
|
||||||
if (!EnableInvokeDynamic) return;
|
if (!EnableInvokeDynamic) return;
|
||||||
klassOop k = SystemDictionary::CallSiteImpl_klass();
|
klassOop k = SystemDictionary::CallSite_klass();
|
||||||
if (k != NULL) {
|
if (k != NULL) {
|
||||||
compute_offset(_type_offset, k, vmSymbols::type_name(), vmSymbols::java_dyn_MethodType_signature(), true);
|
compute_offset(_type_offset, k, vmSymbols::type_name(), vmSymbols::java_dyn_MethodType_signature(), true);
|
||||||
compute_offset(_target_offset, k, vmSymbols::target_name(), vmSymbols::java_dyn_MethodHandle_signature(), true);
|
compute_offset(_target_offset, k, vmSymbols::target_name(), vmSymbols::java_dyn_MethodHandle_signature(), true);
|
||||||
@ -2446,23 +2445,23 @@ void sun_dyn_CallSiteImpl::compute_offsets() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
oop sun_dyn_CallSiteImpl::type(oop site) {
|
oop java_dyn_CallSite::type(oop site) {
|
||||||
return site->obj_field(_type_offset);
|
return site->obj_field(_type_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
oop sun_dyn_CallSiteImpl::target(oop site) {
|
oop java_dyn_CallSite::target(oop site) {
|
||||||
return site->obj_field(_target_offset);
|
return site->obj_field(_target_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sun_dyn_CallSiteImpl::set_target(oop site, oop target) {
|
void java_dyn_CallSite::set_target(oop site, oop target) {
|
||||||
site->obj_field_put(_target_offset, target);
|
site->obj_field_put(_target_offset, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
oop sun_dyn_CallSiteImpl::vmmethod(oop site) {
|
oop java_dyn_CallSite::vmmethod(oop site) {
|
||||||
return site->obj_field(_vmmethod_offset);
|
return site->obj_field(_vmmethod_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sun_dyn_CallSiteImpl::set_vmmethod(oop site, oop ref) {
|
void java_dyn_CallSite::set_vmmethod(oop site, oop ref) {
|
||||||
site->obj_field_put(_vmmethod_offset, ref);
|
site->obj_field_put(_vmmethod_offset, ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2811,7 +2810,7 @@ void JavaClasses::compute_offsets() {
|
|||||||
java_dyn_MethodTypeForm::compute_offsets();
|
java_dyn_MethodTypeForm::compute_offsets();
|
||||||
}
|
}
|
||||||
if (EnableInvokeDynamic) {
|
if (EnableInvokeDynamic) {
|
||||||
sun_dyn_CallSiteImpl::compute_offsets();
|
java_dyn_CallSite::compute_offsets();
|
||||||
}
|
}
|
||||||
java_security_AccessControlContext::compute_offsets();
|
java_security_AccessControlContext::compute_offsets();
|
||||||
// Initialize reflection classes. The layouts of these classes
|
// Initialize reflection classes. The layouts of these classes
|
||||||
|
@ -1061,9 +1061,9 @@ class java_dyn_MethodTypeForm: AllStatic {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Interface to sun.dyn.CallSiteImpl objects
|
// Interface to java.dyn.CallSite objects
|
||||||
|
|
||||||
class sun_dyn_CallSiteImpl: AllStatic {
|
class java_dyn_CallSite: AllStatic {
|
||||||
friend class JavaClasses;
|
friend class JavaClasses;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -99,6 +99,15 @@ bool SystemDictionary::is_parallelCapable(Handle class_loader) {
|
|||||||
return java_lang_Class::parallelCapable(class_loader());
|
return java_lang_Class::parallelCapable(class_loader());
|
||||||
}
|
}
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
// ParallelDefineClass flag does not apply to bootclass loader
|
||||||
|
bool SystemDictionary::is_parallelDefine(Handle class_loader) {
|
||||||
|
if (class_loader.is_null()) return false;
|
||||||
|
if (AllowParallelDefineClass && java_lang_Class::parallelCapable(class_loader())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
// Resolving of classes
|
// Resolving of classes
|
||||||
|
|
||||||
// Forwards to resolve_or_null
|
// Forwards to resolve_or_null
|
||||||
@ -724,13 +733,13 @@ klassOop SystemDictionary::resolve_instance_class_or_null(symbolHandle class_nam
|
|||||||
// Do actual loading
|
// Do actual loading
|
||||||
k = load_instance_class(name, class_loader, THREAD);
|
k = load_instance_class(name, class_loader, THREAD);
|
||||||
|
|
||||||
// For UnsyncloadClass and AllowParallelDefineClass only:
|
// For UnsyncloadClass only
|
||||||
// If they got a linkageError, check if a parallel class load succeeded.
|
// If they got a linkageError, check if a parallel class load succeeded.
|
||||||
// If it did, then for bytecode resolution the specification requires
|
// If it did, then for bytecode resolution the specification requires
|
||||||
// that we return the same result we did for the other thread, i.e. the
|
// that we return the same result we did for the other thread, i.e. the
|
||||||
// successfully loaded instanceKlass
|
// successfully loaded instanceKlass
|
||||||
// Should not get here for classloaders that support parallelism
|
// Should not get here for classloaders that support parallelism
|
||||||
// with the new cleaner mechanism
|
// with the new cleaner mechanism, even with AllowParallelDefineClass
|
||||||
// Bootstrap goes through here to allow for an extra guarantee check
|
// Bootstrap goes through here to allow for an extra guarantee check
|
||||||
if (UnsyncloadClass || (class_loader.is_null())) {
|
if (UnsyncloadClass || (class_loader.is_null())) {
|
||||||
if (k.is_null() && HAS_PENDING_EXCEPTION
|
if (k.is_null() && HAS_PENDING_EXCEPTION
|
||||||
@ -1483,14 +1492,17 @@ void SystemDictionary::define_instance_class(instanceKlassHandle k, TRAPS) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Support parallel classloading
|
// Support parallel classloading
|
||||||
// Initial implementation for bootstrap classloader
|
// All parallel class loaders, including bootstrap classloader
|
||||||
// For custom class loaders that support parallel classloading,
|
// lock a placeholder entry for this class/class_loader pair
|
||||||
|
// to allow parallel defines of different classes for this class loader
|
||||||
// With AllowParallelDefine flag==true, in case they do not synchronize around
|
// With AllowParallelDefine flag==true, in case they do not synchronize around
|
||||||
// FindLoadedClass/DefineClass, calls, we check for parallel
|
// FindLoadedClass/DefineClass, calls, we check for parallel
|
||||||
// loading for them, wait if a defineClass is in progress
|
// loading for them, wait if a defineClass is in progress
|
||||||
// and return the initial requestor's results
|
// and return the initial requestor's results
|
||||||
|
// This flag does not apply to the bootstrap classloader.
|
||||||
// With AllowParallelDefine flag==false, call through to define_instance_class
|
// With AllowParallelDefine flag==false, call through to define_instance_class
|
||||||
// which will throw LinkageError: duplicate class definition.
|
// which will throw LinkageError: duplicate class definition.
|
||||||
|
// False is the requested default.
|
||||||
// For better performance, the class loaders should synchronize
|
// For better performance, the class loaders should synchronize
|
||||||
// findClass(), i.e. FindLoadedClass/DefineClassIfAbsent or they
|
// findClass(), i.e. FindLoadedClass/DefineClassIfAbsent or they
|
||||||
// potentially waste time reading and parsing the bytestream.
|
// potentially waste time reading and parsing the bytestream.
|
||||||
@ -1511,9 +1523,11 @@ instanceKlassHandle SystemDictionary::find_or_define_instance_class(symbolHandle
|
|||||||
{
|
{
|
||||||
MutexLocker mu(SystemDictionary_lock, THREAD);
|
MutexLocker mu(SystemDictionary_lock, THREAD);
|
||||||
// First check if class already defined
|
// First check if class already defined
|
||||||
klassOop check = find_class(d_index, d_hash, name_h, class_loader);
|
if (UnsyncloadClass || (is_parallelDefine(class_loader))) {
|
||||||
if (check != NULL) {
|
klassOop check = find_class(d_index, d_hash, name_h, class_loader);
|
||||||
return(instanceKlassHandle(THREAD, check));
|
if (check != NULL) {
|
||||||
|
return(instanceKlassHandle(THREAD, check));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Acquire define token for this class/classloader
|
// Acquire define token for this class/classloader
|
||||||
@ -1529,7 +1543,7 @@ instanceKlassHandle SystemDictionary::find_or_define_instance_class(symbolHandle
|
|||||||
// Only special cases allow parallel defines and can use other thread's results
|
// Only special cases allow parallel defines and can use other thread's results
|
||||||
// Other cases fall through, and may run into duplicate defines
|
// Other cases fall through, and may run into duplicate defines
|
||||||
// caught by finding an entry in the SystemDictionary
|
// caught by finding an entry in the SystemDictionary
|
||||||
if ((UnsyncloadClass || AllowParallelDefineClass) && (probe->instanceKlass() != NULL)) {
|
if ((UnsyncloadClass || is_parallelDefine(class_loader)) && (probe->instanceKlass() != NULL)) {
|
||||||
probe->remove_seen_thread(THREAD, PlaceholderTable::DEFINE_CLASS);
|
probe->remove_seen_thread(THREAD, PlaceholderTable::DEFINE_CLASS);
|
||||||
placeholders()->find_and_remove(p_index, p_hash, name_h, class_loader, THREAD);
|
placeholders()->find_and_remove(p_index, p_hash, name_h, class_loader, THREAD);
|
||||||
SystemDictionary_lock->notify_all();
|
SystemDictionary_lock->notify_all();
|
||||||
@ -1973,7 +1987,7 @@ void SystemDictionary::initialize_preloaded_classes(TRAPS) {
|
|||||||
WKID indy_group_end = WK_KLASS_ENUM_NAME(Dynamic_klass);
|
WKID indy_group_end = WK_KLASS_ENUM_NAME(Dynamic_klass);
|
||||||
initialize_wk_klasses_until(indy_group_start, scan, CHECK);
|
initialize_wk_klasses_until(indy_group_start, scan, CHECK);
|
||||||
if (EnableInvokeDynamic) {
|
if (EnableInvokeDynamic) {
|
||||||
initialize_wk_klasses_through(indy_group_start, scan, CHECK);
|
initialize_wk_klasses_through(indy_group_end, scan, CHECK);
|
||||||
}
|
}
|
||||||
if (_well_known_klasses[indy_group_start] == NULL) {
|
if (_well_known_klasses[indy_group_start] == NULL) {
|
||||||
// Skip the rest of the dynamic typing classes, if Linkage is not loaded.
|
// Skip the rest of the dynamic typing classes, if Linkage is not loaded.
|
||||||
@ -2404,7 +2418,7 @@ Handle SystemDictionary::make_dynamic_call_site(KlassHandle caller,
|
|||||||
methodHandle mh_invdyn,
|
methodHandle mh_invdyn,
|
||||||
TRAPS) {
|
TRAPS) {
|
||||||
Handle empty;
|
Handle empty;
|
||||||
// call sun.dyn.CallSiteImpl::makeSite(caller, name, mtype, cmid, cbci)
|
// call java.dyn.CallSite::makeSite(caller, name, mtype, cmid, cbci)
|
||||||
oop name_str_oop = StringTable::intern(name(), CHECK_(empty)); // not a handle!
|
oop name_str_oop = StringTable::intern(name(), CHECK_(empty)); // not a handle!
|
||||||
JavaCallArguments args(Handle(THREAD, caller->java_mirror()));
|
JavaCallArguments args(Handle(THREAD, caller->java_mirror()));
|
||||||
args.push_oop(name_str_oop);
|
args.push_oop(name_str_oop);
|
||||||
@ -2413,17 +2427,19 @@ Handle SystemDictionary::make_dynamic_call_site(KlassHandle caller,
|
|||||||
args.push_int(caller_bci);
|
args.push_int(caller_bci);
|
||||||
JavaValue result(T_OBJECT);
|
JavaValue result(T_OBJECT);
|
||||||
JavaCalls::call_static(&result,
|
JavaCalls::call_static(&result,
|
||||||
SystemDictionary::CallSiteImpl_klass(),
|
SystemDictionary::CallSite_klass(),
|
||||||
vmSymbols::makeSite_name(), vmSymbols::makeSite_signature(),
|
vmSymbols::makeSite_name(), vmSymbols::makeSite_signature(),
|
||||||
&args, CHECK_(empty));
|
&args, CHECK_(empty));
|
||||||
oop call_site_oop = (oop) result.get_jobject();
|
oop call_site_oop = (oop) result.get_jobject();
|
||||||
assert(call_site_oop->is_oop()
|
assert(call_site_oop->is_oop()
|
||||||
/*&& sun_dyn_CallSiteImpl::is_instance(call_site_oop)*/, "must be sane");
|
/*&& java_dyn_CallSite::is_instance(call_site_oop)*/, "must be sane");
|
||||||
sun_dyn_CallSiteImpl::set_vmmethod(call_site_oop, mh_invdyn());
|
java_dyn_CallSite::set_vmmethod(call_site_oop, mh_invdyn());
|
||||||
if (TraceMethodHandles) {
|
if (TraceMethodHandles) {
|
||||||
|
#ifndef PRODUCT
|
||||||
tty->print_cr("Linked invokedynamic bci=%d site="INTPTR_FORMAT":", caller_bci, call_site_oop);
|
tty->print_cr("Linked invokedynamic bci=%d site="INTPTR_FORMAT":", caller_bci, call_site_oop);
|
||||||
call_site_oop->print();
|
call_site_oop->print();
|
||||||
tty->cr();
|
tty->cr();
|
||||||
|
#endif //PRODUCT
|
||||||
}
|
}
|
||||||
return call_site_oop;
|
return call_site_oop;
|
||||||
}
|
}
|
||||||
@ -2436,9 +2452,17 @@ Handle SystemDictionary::find_bootstrap_method(KlassHandle caller,
|
|||||||
|
|
||||||
instanceKlassHandle ik(THREAD, caller());
|
instanceKlassHandle ik(THREAD, caller());
|
||||||
|
|
||||||
if (ik->bootstrap_method() != NULL) {
|
oop boot_method_oop = ik->bootstrap_method();
|
||||||
return Handle(THREAD, ik->bootstrap_method());
|
if (boot_method_oop != NULL) {
|
||||||
|
if (TraceMethodHandles) {
|
||||||
|
tty->print_cr("bootstrap method for "PTR_FORMAT" cached as "PTR_FORMAT":", ik(), boot_method_oop);
|
||||||
|
}
|
||||||
|
NOT_PRODUCT(if (!boot_method_oop->is_oop()) { tty->print_cr("*** boot MH of "PTR_FORMAT" = "PTR_FORMAT, ik(), boot_method_oop); ik()->print(); });
|
||||||
|
assert(boot_method_oop->is_oop()
|
||||||
|
&& java_dyn_MethodHandle::is_instance(boot_method_oop), "must be sane");
|
||||||
|
return Handle(THREAD, boot_method_oop);
|
||||||
}
|
}
|
||||||
|
boot_method_oop = NULL; // GC safety
|
||||||
|
|
||||||
// call java.dyn.Linkage::findBootstrapMethod(caller, sbk)
|
// call java.dyn.Linkage::findBootstrapMethod(caller, sbk)
|
||||||
JavaCallArguments args(Handle(THREAD, ik->java_mirror()));
|
JavaCallArguments args(Handle(THREAD, ik->java_mirror()));
|
||||||
@ -2452,9 +2476,18 @@ Handle SystemDictionary::find_bootstrap_method(KlassHandle caller,
|
|||||||
vmSymbols::findBootstrapMethod_name(),
|
vmSymbols::findBootstrapMethod_name(),
|
||||||
vmSymbols::findBootstrapMethod_signature(),
|
vmSymbols::findBootstrapMethod_signature(),
|
||||||
&args, CHECK_(empty));
|
&args, CHECK_(empty));
|
||||||
oop boot_method_oop = (oop) result.get_jobject();
|
boot_method_oop = (oop) result.get_jobject();
|
||||||
|
|
||||||
if (boot_method_oop != NULL) {
|
if (boot_method_oop != NULL) {
|
||||||
|
if (TraceMethodHandles) {
|
||||||
|
#ifndef PRODUCT
|
||||||
|
tty->print_cr("--------");
|
||||||
|
tty->print_cr("bootstrap method for "PTR_FORMAT" computed as "PTR_FORMAT":", ik(), boot_method_oop);
|
||||||
|
ik()->print();
|
||||||
|
boot_method_oop->print();
|
||||||
|
tty->print_cr("========");
|
||||||
|
#endif //PRODUCT
|
||||||
|
}
|
||||||
assert(boot_method_oop->is_oop()
|
assert(boot_method_oop->is_oop()
|
||||||
&& java_dyn_MethodHandle::is_instance(boot_method_oop), "must be sane");
|
&& java_dyn_MethodHandle::is_instance(boot_method_oop), "must be sane");
|
||||||
// probably no race conditions, but let's be careful:
|
// probably no race conditions, but let's be careful:
|
||||||
@ -2463,6 +2496,14 @@ Handle SystemDictionary::find_bootstrap_method(KlassHandle caller,
|
|||||||
else
|
else
|
||||||
boot_method_oop = ik->bootstrap_method();
|
boot_method_oop = ik->bootstrap_method();
|
||||||
} else {
|
} else {
|
||||||
|
if (TraceMethodHandles) {
|
||||||
|
#ifndef PRODUCT
|
||||||
|
tty->print_cr("--------");
|
||||||
|
tty->print_cr("bootstrap method for "PTR_FORMAT" computed as NULL:", ik());
|
||||||
|
ik()->print();
|
||||||
|
tty->print_cr("========");
|
||||||
|
#endif //PRODUCT
|
||||||
|
}
|
||||||
boot_method_oop = ik->bootstrap_method();
|
boot_method_oop = ik->bootstrap_method();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,13 +144,13 @@ class SymbolPropertyTable;
|
|||||||
template(WrongMethodTypeException_klass, java_dyn_WrongMethodTypeException, Opt) \
|
template(WrongMethodTypeException_klass, java_dyn_WrongMethodTypeException, Opt) \
|
||||||
template(Linkage_klass, java_dyn_Linkage, Opt) \
|
template(Linkage_klass, java_dyn_Linkage, Opt) \
|
||||||
template(CallSite_klass, java_dyn_CallSite, Opt) \
|
template(CallSite_klass, java_dyn_CallSite, Opt) \
|
||||||
template(CallSiteImpl_klass, sun_dyn_CallSiteImpl, Opt) \
|
|
||||||
template(Dynamic_klass, java_dyn_Dynamic, Opt) \
|
template(Dynamic_klass, java_dyn_Dynamic, Opt) \
|
||||||
/* Note: MethodHandle must be first, and Dynamic last in group */ \
|
/* Note: MethodHandle must be first, and Dynamic last in group */ \
|
||||||
\
|
\
|
||||||
template(vector_klass, java_util_Vector, Pre) \
|
template(vector_klass, java_util_Vector, Pre) \
|
||||||
template(hashtable_klass, java_util_Hashtable, Pre) \
|
template(hashtable_klass, java_util_Hashtable, Pre) \
|
||||||
template(stringBuffer_klass, java_lang_StringBuffer, Pre) \
|
template(stringBuffer_klass, java_lang_StringBuffer, Pre) \
|
||||||
|
template(StringBuilder_klass, java_lang_StringBuilder, Pre) \
|
||||||
\
|
\
|
||||||
/* It's NULL in non-1.4 JDKs. */ \
|
/* It's NULL in non-1.4 JDKs. */ \
|
||||||
template(stackTraceElement_klass, java_lang_StackTraceElement, Opt) \
|
template(stackTraceElement_klass, java_lang_StackTraceElement, Opt) \
|
||||||
@ -578,6 +578,7 @@ private:
|
|||||||
static Handle compute_loader_lock_object(Handle class_loader, TRAPS);
|
static Handle compute_loader_lock_object(Handle class_loader, TRAPS);
|
||||||
static void check_loader_lock_contention(Handle loader_lock, TRAPS);
|
static void check_loader_lock_contention(Handle loader_lock, TRAPS);
|
||||||
static bool is_parallelCapable(Handle class_loader);
|
static bool is_parallelCapable(Handle class_loader);
|
||||||
|
static bool is_parallelDefine(Handle class_loader);
|
||||||
|
|
||||||
static klassOop find_shared_class(symbolHandle class_name);
|
static klassOop find_shared_class(symbolHandle class_name);
|
||||||
|
|
||||||
|
@ -1903,17 +1903,8 @@ void ClassVerifier::verify_invoke_instructions(
|
|||||||
verify_cp_type(index, cp, types, CHECK_VERIFY(this));
|
verify_cp_type(index, cp, types, CHECK_VERIFY(this));
|
||||||
|
|
||||||
// Get method name and signature
|
// Get method name and signature
|
||||||
symbolHandle method_name;
|
symbolHandle method_name(THREAD, cp->name_ref_at(index));
|
||||||
symbolHandle method_sig;
|
symbolHandle method_sig(THREAD, cp->signature_ref_at(index));
|
||||||
if (opcode == Bytecodes::_invokedynamic) {
|
|
||||||
int name_index = cp->name_ref_index_at(index);
|
|
||||||
int sig_index = cp->signature_ref_index_at(index);
|
|
||||||
method_name = symbolHandle(THREAD, cp->symbol_at(name_index));
|
|
||||||
method_sig = symbolHandle(THREAD, cp->symbol_at(sig_index));
|
|
||||||
} else {
|
|
||||||
method_name = symbolHandle(THREAD, cp->name_ref_at(index));
|
|
||||||
method_sig = symbolHandle(THREAD, cp->signature_ref_at(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SignatureVerifier::is_valid_method_signature(method_sig)) {
|
if (!SignatureVerifier::is_valid_method_signature(method_sig)) {
|
||||||
class_format_error(
|
class_format_error(
|
||||||
|
@ -303,6 +303,11 @@ inline bool match_F_R(jshort flags) {
|
|||||||
const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED;
|
const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED;
|
||||||
return (flags & (req | neg)) == req;
|
return (flags & (req | neg)) == req;
|
||||||
}
|
}
|
||||||
|
inline bool match_F_Y(jshort flags) {
|
||||||
|
const int req = JVM_ACC_SYNCHRONIZED;
|
||||||
|
const int neg = JVM_ACC_STATIC;
|
||||||
|
return (flags & (req | neg)) == req;
|
||||||
|
}
|
||||||
inline bool match_F_RN(jshort flags) {
|
inline bool match_F_RN(jshort flags) {
|
||||||
const int req = JVM_ACC_NATIVE;
|
const int req = JVM_ACC_NATIVE;
|
||||||
const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED;
|
const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED;
|
||||||
@ -361,6 +366,7 @@ const char* vmIntrinsics::short_name_as_C_string(vmIntrinsics::ID id, char* buf,
|
|||||||
const char* sname = vmSymbols::name_for(signature_for(id));
|
const char* sname = vmSymbols::name_for(signature_for(id));
|
||||||
const char* fname = "";
|
const char* fname = "";
|
||||||
switch (flags_for(id)) {
|
switch (flags_for(id)) {
|
||||||
|
case F_Y: fname = "synchronized "; break;
|
||||||
case F_RN: fname = "native "; break;
|
case F_RN: fname = "native "; break;
|
||||||
case F_SN: fname = "native static "; break;
|
case F_SN: fname = "native static "; break;
|
||||||
case F_S: fname = "static "; break;
|
case F_S: fname = "static "; break;
|
||||||
|
@ -84,6 +84,7 @@
|
|||||||
template(java_lang_reflect_Field, "java/lang/reflect/Field") \
|
template(java_lang_reflect_Field, "java/lang/reflect/Field") \
|
||||||
template(java_lang_reflect_Array, "java/lang/reflect/Array") \
|
template(java_lang_reflect_Array, "java/lang/reflect/Array") \
|
||||||
template(java_lang_StringBuffer, "java/lang/StringBuffer") \
|
template(java_lang_StringBuffer, "java/lang/StringBuffer") \
|
||||||
|
template(java_lang_StringBuilder, "java/lang/StringBuilder") \
|
||||||
template(java_lang_CharSequence, "java/lang/CharSequence") \
|
template(java_lang_CharSequence, "java/lang/CharSequence") \
|
||||||
template(java_security_AccessControlContext, "java/security/AccessControlContext") \
|
template(java_security_AccessControlContext, "java/security/AccessControlContext") \
|
||||||
template(java_security_ProtectionDomain, "java/security/ProtectionDomain") \
|
template(java_security_ProtectionDomain, "java/security/ProtectionDomain") \
|
||||||
@ -104,6 +105,7 @@
|
|||||||
template(java_lang_AssertionStatusDirectives, "java/lang/AssertionStatusDirectives") \
|
template(java_lang_AssertionStatusDirectives, "java/lang/AssertionStatusDirectives") \
|
||||||
template(sun_jkernel_DownloadManager, "sun/jkernel/DownloadManager") \
|
template(sun_jkernel_DownloadManager, "sun/jkernel/DownloadManager") \
|
||||||
template(getBootClassPathEntryForClass_name, "getBootClassPathEntryForClass") \
|
template(getBootClassPathEntryForClass_name, "getBootClassPathEntryForClass") \
|
||||||
|
template(setBootClassLoaderHook_name, "setBootClassLoaderHook") \
|
||||||
\
|
\
|
||||||
/* class file format tags */ \
|
/* class file format tags */ \
|
||||||
template(tag_source_file, "SourceFile") \
|
template(tag_source_file, "SourceFile") \
|
||||||
@ -233,10 +235,9 @@
|
|||||||
template(sun_dyn_AdapterMethodHandle, "sun/dyn/AdapterMethodHandle") \
|
template(sun_dyn_AdapterMethodHandle, "sun/dyn/AdapterMethodHandle") \
|
||||||
template(sun_dyn_BoundMethodHandle, "sun/dyn/BoundMethodHandle") \
|
template(sun_dyn_BoundMethodHandle, "sun/dyn/BoundMethodHandle") \
|
||||||
template(sun_dyn_DirectMethodHandle, "sun/dyn/DirectMethodHandle") \
|
template(sun_dyn_DirectMethodHandle, "sun/dyn/DirectMethodHandle") \
|
||||||
template(sun_dyn_CallSiteImpl, "sun/dyn/CallSiteImpl") \
|
|
||||||
template(makeImpl_name, "makeImpl") /*MethodType::makeImpl*/ \
|
template(makeImpl_name, "makeImpl") /*MethodType::makeImpl*/ \
|
||||||
template(makeImpl_signature, "(Ljava/lang/Class;[Ljava/lang/Class;ZZ)Ljava/dyn/MethodType;") \
|
template(makeImpl_signature, "(Ljava/lang/Class;[Ljava/lang/Class;ZZ)Ljava/dyn/MethodType;") \
|
||||||
template(makeSite_name, "makeSite") /*CallSiteImpl::makeImpl*/ \
|
template(makeSite_name, "makeSite") /*CallSite::makeSite*/ \
|
||||||
template(makeSite_signature, "(Ljava/lang/Class;Ljava/lang/String;Ljava/dyn/MethodType;II)Ljava/dyn/CallSite;") \
|
template(makeSite_signature, "(Ljava/lang/Class;Ljava/lang/String;Ljava/dyn/MethodType;II)Ljava/dyn/CallSite;") \
|
||||||
template(findBootstrapMethod_name, "findBootstrapMethod") \
|
template(findBootstrapMethod_name, "findBootstrapMethod") \
|
||||||
template(findBootstrapMethod_signature, "(Ljava/lang/Class;Ljava/lang/Class;)Ljava/dyn/MethodHandle;") \
|
template(findBootstrapMethod_signature, "(Ljava/lang/Class;Ljava/lang/Class;)Ljava/dyn/MethodHandle;") \
|
||||||
@ -335,6 +336,7 @@
|
|||||||
template(ptypes_name, "ptypes") \
|
template(ptypes_name, "ptypes") \
|
||||||
template(form_name, "form") \
|
template(form_name, "form") \
|
||||||
template(erasedType_name, "erasedType") \
|
template(erasedType_name, "erasedType") \
|
||||||
|
template(append_name, "append") \
|
||||||
\
|
\
|
||||||
/* non-intrinsic name/signature pairs: */ \
|
/* non-intrinsic name/signature pairs: */ \
|
||||||
template(register_method_name, "register") \
|
template(register_method_name, "register") \
|
||||||
@ -416,6 +418,13 @@
|
|||||||
template(string_signature, "Ljava/lang/String;") \
|
template(string_signature, "Ljava/lang/String;") \
|
||||||
template(reference_signature, "Ljava/lang/ref/Reference;") \
|
template(reference_signature, "Ljava/lang/ref/Reference;") \
|
||||||
template(concurrenthashmap_signature, "Ljava/util/concurrent/ConcurrentHashMap;") \
|
template(concurrenthashmap_signature, "Ljava/util/concurrent/ConcurrentHashMap;") \
|
||||||
|
template(String_StringBuilder_signature, "(Ljava/lang/String;)Ljava/lang/StringBuilder;") \
|
||||||
|
template(int_StringBuilder_signature, "(I)Ljava/lang/StringBuilder;") \
|
||||||
|
template(char_StringBuilder_signature, "(C)Ljava/lang/StringBuilder;") \
|
||||||
|
template(String_StringBuffer_signature, "(Ljava/lang/String;)Ljava/lang/StringBuffer;") \
|
||||||
|
template(int_StringBuffer_signature, "(I)Ljava/lang/StringBuffer;") \
|
||||||
|
template(char_StringBuffer_signature, "(C)Ljava/lang/StringBuffer;") \
|
||||||
|
template(int_String_signature, "(I)Ljava/lang/String;") \
|
||||||
/* signature symbols needed by intrinsics */ \
|
/* signature symbols needed by intrinsics */ \
|
||||||
VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, template, VM_ALIAS_IGNORE) \
|
VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, template, VM_ALIAS_IGNORE) \
|
||||||
\
|
\
|
||||||
@ -815,10 +824,34 @@
|
|||||||
/*the compiler does have special inlining code for these; bytecode inline is just fine */ \
|
/*the compiler does have special inlining code for these; bytecode inline is just fine */ \
|
||||||
\
|
\
|
||||||
do_intrinsic(_fillInStackTrace, java_lang_Throwable, fillInStackTrace_name, void_throwable_signature, F_RNY) \
|
do_intrinsic(_fillInStackTrace, java_lang_Throwable, fillInStackTrace_name, void_throwable_signature, F_RNY) \
|
||||||
\
|
\
|
||||||
do_intrinsic(_Object_init, java_lang_Object, object_initializer_name, void_method_signature, F_R) \
|
do_intrinsic(_StringBuilder_void, java_lang_StringBuilder, object_initializer_name, void_method_signature, F_R) \
|
||||||
/* (symbol object_initializer_name defined above) */ \
|
do_intrinsic(_StringBuilder_int, java_lang_StringBuilder, object_initializer_name, int_void_signature, F_R) \
|
||||||
\
|
do_intrinsic(_StringBuilder_String, java_lang_StringBuilder, object_initializer_name, string_void_signature, F_R) \
|
||||||
|
\
|
||||||
|
do_intrinsic(_StringBuilder_append_char, java_lang_StringBuilder, append_name, char_StringBuilder_signature, F_R) \
|
||||||
|
do_intrinsic(_StringBuilder_append_int, java_lang_StringBuilder, append_name, int_StringBuilder_signature, F_R) \
|
||||||
|
do_intrinsic(_StringBuilder_append_String, java_lang_StringBuilder, append_name, String_StringBuilder_signature, F_R) \
|
||||||
|
\
|
||||||
|
do_intrinsic(_StringBuilder_toString, java_lang_StringBuilder, toString_name, void_string_signature, F_R) \
|
||||||
|
\
|
||||||
|
do_intrinsic(_StringBuffer_void, java_lang_StringBuffer, object_initializer_name, void_method_signature, F_R) \
|
||||||
|
do_intrinsic(_StringBuffer_int, java_lang_StringBuffer, object_initializer_name, int_void_signature, F_R) \
|
||||||
|
do_intrinsic(_StringBuffer_String, java_lang_StringBuffer, object_initializer_name, string_void_signature, F_R) \
|
||||||
|
\
|
||||||
|
do_intrinsic(_StringBuffer_append_char, java_lang_StringBuffer, append_name, char_StringBuffer_signature, F_Y) \
|
||||||
|
do_intrinsic(_StringBuffer_append_int, java_lang_StringBuffer, append_name, int_StringBuffer_signature, F_Y) \
|
||||||
|
do_intrinsic(_StringBuffer_append_String, java_lang_StringBuffer, append_name, String_StringBuffer_signature, F_Y) \
|
||||||
|
\
|
||||||
|
do_intrinsic(_StringBuffer_toString, java_lang_StringBuffer, toString_name, void_string_signature, F_Y) \
|
||||||
|
\
|
||||||
|
do_intrinsic(_Integer_toString, java_lang_Integer, toString_name, int_String_signature, F_S) \
|
||||||
|
\
|
||||||
|
do_intrinsic(_String_String, java_lang_String, object_initializer_name, string_void_signature, F_R) \
|
||||||
|
\
|
||||||
|
do_intrinsic(_Object_init, java_lang_Object, object_initializer_name, void_method_signature, F_R) \
|
||||||
|
/* (symbol object_initializer_name defined above) */ \
|
||||||
|
\
|
||||||
do_intrinsic(_invoke, java_lang_reflect_Method, invoke_name, object_array_object_object_signature, F_R) \
|
do_intrinsic(_invoke, java_lang_reflect_Method, invoke_name, object_array_object_object_signature, F_R) \
|
||||||
/* (symbols invoke_name and invoke_signature defined above) */ \
|
/* (symbols invoke_name and invoke_signature defined above) */ \
|
||||||
\
|
\
|
||||||
@ -946,11 +979,12 @@ class vmIntrinsics: AllStatic {
|
|||||||
enum Flags {
|
enum Flags {
|
||||||
// AccessFlags syndromes relevant to intrinsics.
|
// AccessFlags syndromes relevant to intrinsics.
|
||||||
F_none = 0,
|
F_none = 0,
|
||||||
F_R, // !static !synchronized (R="regular")
|
F_R, // !static ?native !synchronized (R="regular")
|
||||||
F_S, // static !synchronized
|
F_S, // static ?native !synchronized
|
||||||
F_RN, // !static native !synchronized
|
F_Y, // !static ?native synchronized
|
||||||
F_SN, // static native !synchronized
|
F_RN, // !static native !synchronized
|
||||||
F_RNY // !static native synchronized
|
F_SN, // static native !synchronized
|
||||||
|
F_RNY // !static native synchronized
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -1528,19 +1528,23 @@ void DepChange::print() {
|
|||||||
int nsup = 0, nint = 0;
|
int nsup = 0, nint = 0;
|
||||||
for (ContextStream str(*this); str.next(); ) {
|
for (ContextStream str(*this); str.next(); ) {
|
||||||
klassOop k = str.klass();
|
klassOop k = str.klass();
|
||||||
switch (str._change_type) {
|
switch (str.change_type()) {
|
||||||
case Change_new_type:
|
case Change_new_type:
|
||||||
tty->print_cr(" dependee = %s", instanceKlass::cast(k)->external_name());
|
tty->print_cr(" dependee = %s", instanceKlass::cast(k)->external_name());
|
||||||
break;
|
break;
|
||||||
case Change_new_sub:
|
case Change_new_sub:
|
||||||
if (!WizardMode)
|
if (!WizardMode) {
|
||||||
++nsup;
|
++nsup;
|
||||||
else tty->print_cr(" context super = %s", instanceKlass::cast(k)->external_name());
|
} else {
|
||||||
|
tty->print_cr(" context super = %s", instanceKlass::cast(k)->external_name());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Change_new_impl:
|
case Change_new_impl:
|
||||||
if (!WizardMode)
|
if (!WizardMode) {
|
||||||
++nint;
|
++nint;
|
||||||
else tty->print_cr(" context interface = %s", instanceKlass::cast(k)->external_name());
|
} else {
|
||||||
|
tty->print_cr(" context interface = %s", instanceKlass::cast(k)->external_name());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -470,7 +470,7 @@ class Dependencies: public ResourceObj {
|
|||||||
// super types can be context types for a relevant dependency, which the
|
// super types can be context types for a relevant dependency, which the
|
||||||
// new type could invalidate.
|
// new type could invalidate.
|
||||||
class DepChange : public StackObj {
|
class DepChange : public StackObj {
|
||||||
private:
|
public:
|
||||||
enum ChangeType {
|
enum ChangeType {
|
||||||
NO_CHANGE = 0, // an uninvolved klass
|
NO_CHANGE = 0, // an uninvolved klass
|
||||||
Change_new_type, // a newly loaded type
|
Change_new_type, // a newly loaded type
|
||||||
@ -480,6 +480,7 @@ class DepChange : public StackObj {
|
|||||||
Start_Klass = CHANGE_LIMIT // internal indicator for ContextStream
|
Start_Klass = CHANGE_LIMIT // internal indicator for ContextStream
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
// each change set is rooted in exactly one new type (at present):
|
// each change set is rooted in exactly one new type (at present):
|
||||||
KlassHandle _new_type;
|
KlassHandle _new_type;
|
||||||
|
|
||||||
@ -510,15 +511,15 @@ class DepChange : public StackObj {
|
|||||||
// }
|
// }
|
||||||
class ContextStream : public StackObj {
|
class ContextStream : public StackObj {
|
||||||
private:
|
private:
|
||||||
DepChange& _changes;
|
DepChange& _changes;
|
||||||
friend class DepChange;
|
friend class DepChange;
|
||||||
|
|
||||||
// iteration variables:
|
// iteration variables:
|
||||||
ChangeType _change_type;
|
ChangeType _change_type;
|
||||||
klassOop _klass;
|
klassOop _klass;
|
||||||
objArrayOop _ti_base; // i.e., transitive_interfaces
|
objArrayOop _ti_base; // i.e., transitive_interfaces
|
||||||
int _ti_index;
|
int _ti_index;
|
||||||
int _ti_limit;
|
int _ti_limit;
|
||||||
|
|
||||||
// start at the beginning:
|
// start at the beginning:
|
||||||
void start() {
|
void start() {
|
||||||
@ -530,11 +531,11 @@ class DepChange : public StackObj {
|
|||||||
_ti_limit = 0;
|
_ti_limit = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
ContextStream(DepChange& changes)
|
ContextStream(DepChange& changes)
|
||||||
: _changes(changes)
|
: _changes(changes)
|
||||||
{ start(); }
|
{ start(); }
|
||||||
|
|
||||||
public:
|
|
||||||
ContextStream(DepChange& changes, No_Safepoint_Verifier& nsv)
|
ContextStream(DepChange& changes, No_Safepoint_Verifier& nsv)
|
||||||
: _changes(changes)
|
: _changes(changes)
|
||||||
// the nsv argument makes it safe to hold oops like _klass
|
// the nsv argument makes it safe to hold oops like _klass
|
||||||
@ -542,6 +543,7 @@ class DepChange : public StackObj {
|
|||||||
|
|
||||||
bool next();
|
bool next();
|
||||||
|
|
||||||
|
ChangeType change_type() { return _change_type; }
|
||||||
klassOop klass() { return _klass; }
|
klassOop klass() { return _klass; }
|
||||||
};
|
};
|
||||||
friend class DepChange::ContextStream;
|
friend class DepChange::ContextStream;
|
||||||
|
@ -414,9 +414,8 @@ int nmethod::total_size() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char* nmethod::compile_kind() const {
|
const char* nmethod::compile_kind() const {
|
||||||
if (method() == NULL) return "unloaded";
|
|
||||||
if (is_native_method()) return "c2n";
|
|
||||||
if (is_osr_method()) return "osr";
|
if (is_osr_method()) return "osr";
|
||||||
|
if (method() != NULL && is_native_method()) return "c2n";
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1127,6 +1126,9 @@ void nmethod::make_unloaded(BoolObjectClosure* is_alive, oop cause) {
|
|||||||
}
|
}
|
||||||
flags.state = unloaded;
|
flags.state = unloaded;
|
||||||
|
|
||||||
|
// Log the unloading.
|
||||||
|
log_state_change();
|
||||||
|
|
||||||
// The methodOop is gone at this point
|
// The methodOop is gone at this point
|
||||||
assert(_method == NULL, "Tautology");
|
assert(_method == NULL, "Tautology");
|
||||||
|
|
||||||
@ -1137,8 +1139,6 @@ void nmethod::make_unloaded(BoolObjectClosure* is_alive, oop cause) {
|
|||||||
|
|
||||||
void nmethod::invalidate_osr_method() {
|
void nmethod::invalidate_osr_method() {
|
||||||
assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod");
|
assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod");
|
||||||
if (_entry_bci != InvalidOSREntryBci)
|
|
||||||
inc_decompile_count();
|
|
||||||
// Remove from list of active nmethods
|
// Remove from list of active nmethods
|
||||||
if (method() != NULL)
|
if (method() != NULL)
|
||||||
instanceKlass::cast(method()->method_holder())->remove_osr_nmethod(this);
|
instanceKlass::cast(method()->method_holder())->remove_osr_nmethod(this);
|
||||||
@ -1146,59 +1146,63 @@ void nmethod::invalidate_osr_method() {
|
|||||||
_entry_bci = InvalidOSREntryBci;
|
_entry_bci = InvalidOSREntryBci;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nmethod::log_state_change(int state) const {
|
void nmethod::log_state_change() const {
|
||||||
if (LogCompilation) {
|
if (LogCompilation) {
|
||||||
if (xtty != NULL) {
|
if (xtty != NULL) {
|
||||||
ttyLocker ttyl; // keep the following output all in one block
|
ttyLocker ttyl; // keep the following output all in one block
|
||||||
xtty->begin_elem("make_not_entrant %sthread='" UINTX_FORMAT "'",
|
if (flags.state == unloaded) {
|
||||||
(state == zombie ? "zombie='1' " : ""),
|
xtty->begin_elem("make_unloaded thread='" UINTX_FORMAT "'",
|
||||||
os::current_thread_id());
|
os::current_thread_id());
|
||||||
|
} else {
|
||||||
|
xtty->begin_elem("make_not_entrant thread='" UINTX_FORMAT "'%s",
|
||||||
|
os::current_thread_id(),
|
||||||
|
(flags.state == zombie ? " zombie='1'" : ""));
|
||||||
|
}
|
||||||
log_identity(xtty);
|
log_identity(xtty);
|
||||||
xtty->stamp();
|
xtty->stamp();
|
||||||
xtty->end_elem();
|
xtty->end_elem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (PrintCompilation) {
|
if (PrintCompilation && flags.state != unloaded) {
|
||||||
print_on(tty, state == zombie ? "made zombie " : "made not entrant ");
|
print_on(tty, flags.state == zombie ? "made zombie " : "made not entrant ");
|
||||||
tty->cr();
|
tty->cr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Common functionality for both make_not_entrant and make_zombie
|
// Common functionality for both make_not_entrant and make_zombie
|
||||||
void nmethod::make_not_entrant_or_zombie(int state) {
|
bool nmethod::make_not_entrant_or_zombie(int state) {
|
||||||
assert(state == zombie || state == not_entrant, "must be zombie or not_entrant");
|
assert(state == zombie || state == not_entrant, "must be zombie or not_entrant");
|
||||||
|
|
||||||
// Code for an on-stack-replacement nmethod is removed when a class gets unloaded.
|
// If the method is already zombie there is nothing to do
|
||||||
// They never become zombie/non-entrant, so the nmethod sweeper will never remove
|
if (is_zombie()) {
|
||||||
// them. Instead the entry_bci is set to InvalidOSREntryBci, so the osr nmethod
|
return false;
|
||||||
// will never be used anymore. That the nmethods only gets removed when class unloading
|
|
||||||
// happens, make life much simpler, since the nmethods are not just going to disappear
|
|
||||||
// out of the blue.
|
|
||||||
if (is_osr_method()) {
|
|
||||||
if (osr_entry_bci() != InvalidOSREntryBci) {
|
|
||||||
// only log this once
|
|
||||||
log_state_change(state);
|
|
||||||
}
|
|
||||||
invalidate_osr_method();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the method is already zombie or set to the state we want, nothing to do
|
|
||||||
if (is_zombie() || (state == not_entrant && is_not_entrant())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_state_change(state);
|
|
||||||
|
|
||||||
// Make sure the nmethod is not flushed in case of a safepoint in code below.
|
// Make sure the nmethod is not flushed in case of a safepoint in code below.
|
||||||
nmethodLocker nml(this);
|
nmethodLocker nml(this);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
// invalidate osr nmethod before acquiring the patching lock since
|
||||||
|
// they both acquire leaf locks and we don't want a deadlock.
|
||||||
|
// This logic is equivalent to the logic below for patching the
|
||||||
|
// verified entry point of regular methods.
|
||||||
|
if (is_osr_method()) {
|
||||||
|
// this effectively makes the osr nmethod not entrant
|
||||||
|
invalidate_osr_method();
|
||||||
|
}
|
||||||
|
|
||||||
// Enter critical section. Does not block for safepoint.
|
// Enter critical section. Does not block for safepoint.
|
||||||
MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag);
|
MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag);
|
||||||
|
|
||||||
|
if (flags.state == state) {
|
||||||
|
// another thread already performed this transition so nothing
|
||||||
|
// to do, but return false to indicate this.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// The caller can be calling the method statically or through an inline
|
// The caller can be calling the method statically or through an inline
|
||||||
// cache call.
|
// cache call.
|
||||||
if (!is_not_entrant()) {
|
if (!is_osr_method() && !is_not_entrant()) {
|
||||||
NativeJump::patch_verified_entry(entry_point(), verified_entry_point(),
|
NativeJump::patch_verified_entry(entry_point(), verified_entry_point(),
|
||||||
SharedRuntime::get_handle_wrong_method_stub());
|
SharedRuntime::get_handle_wrong_method_stub());
|
||||||
assert (NativeJump::instruction_size == nmethod::_zombie_instruction_size, "");
|
assert (NativeJump::instruction_size == nmethod::_zombie_instruction_size, "");
|
||||||
@ -1217,6 +1221,10 @@ void nmethod::make_not_entrant_or_zombie(int state) {
|
|||||||
|
|
||||||
// Change state
|
// Change state
|
||||||
flags.state = state;
|
flags.state = state;
|
||||||
|
|
||||||
|
// Log the transition once
|
||||||
|
log_state_change();
|
||||||
|
|
||||||
} // leave critical region under Patching_lock
|
} // leave critical region under Patching_lock
|
||||||
|
|
||||||
if (state == not_entrant) {
|
if (state == not_entrant) {
|
||||||
@ -1240,7 +1248,6 @@ void nmethod::make_not_entrant_or_zombie(int state) {
|
|||||||
// It's a true state change, so mark the method as decompiled.
|
// It's a true state change, so mark the method as decompiled.
|
||||||
inc_decompile_count();
|
inc_decompile_count();
|
||||||
|
|
||||||
|
|
||||||
// zombie only - if a JVMTI agent has enabled the CompiledMethodUnload event
|
// zombie only - if a JVMTI agent has enabled the CompiledMethodUnload event
|
||||||
// and it hasn't already been reported for this nmethod then report it now.
|
// and it hasn't already been reported for this nmethod then report it now.
|
||||||
// (the event may have been reported earilier if the GC marked it for unloading).
|
// (the event may have been reported earilier if the GC marked it for unloading).
|
||||||
@ -1268,7 +1275,7 @@ void nmethod::make_not_entrant_or_zombie(int state) {
|
|||||||
|
|
||||||
// Check whether method got unloaded at a safepoint before this,
|
// Check whether method got unloaded at a safepoint before this,
|
||||||
// if so we can skip the flushing steps below
|
// if so we can skip the flushing steps below
|
||||||
if (method() == NULL) return;
|
if (method() == NULL) return true;
|
||||||
|
|
||||||
// Remove nmethod from method.
|
// Remove nmethod from method.
|
||||||
// We need to check if both the _code and _from_compiled_code_entry_point
|
// We need to check if both the _code and _from_compiled_code_entry_point
|
||||||
@ -1282,6 +1289,8 @@ void nmethod::make_not_entrant_or_zombie(int state) {
|
|||||||
HandleMark hm;
|
HandleMark hm;
|
||||||
method()->clear_code();
|
method()->clear_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -252,7 +252,9 @@ class nmethod : public CodeBlob {
|
|||||||
void* operator new(size_t size, int nmethod_size);
|
void* operator new(size_t size, int nmethod_size);
|
||||||
|
|
||||||
const char* reloc_string_for(u_char* begin, u_char* end);
|
const char* reloc_string_for(u_char* begin, u_char* end);
|
||||||
void make_not_entrant_or_zombie(int state);
|
// Returns true if this thread changed the state of the nmethod or
|
||||||
|
// false if another thread performed the transition.
|
||||||
|
bool make_not_entrant_or_zombie(int state);
|
||||||
void inc_decompile_count();
|
void inc_decompile_count();
|
||||||
|
|
||||||
// used to check that writes to nmFlags are done consistently.
|
// used to check that writes to nmFlags are done consistently.
|
||||||
@ -375,10 +377,12 @@ class nmethod : public CodeBlob {
|
|||||||
bool is_zombie() const { return flags.state == zombie; }
|
bool is_zombie() const { return flags.state == zombie; }
|
||||||
bool is_unloaded() const { return flags.state == unloaded; }
|
bool is_unloaded() const { return flags.state == unloaded; }
|
||||||
|
|
||||||
// Make the nmethod non entrant. The nmethod will continue to be alive.
|
// Make the nmethod non entrant. The nmethod will continue to be
|
||||||
// It is used when an uncommon trap happens.
|
// alive. It is used when an uncommon trap happens. Returns true
|
||||||
void make_not_entrant() { make_not_entrant_or_zombie(not_entrant); }
|
// if this thread changed the state of the nmethod or false if
|
||||||
void make_zombie() { make_not_entrant_or_zombie(zombie); }
|
// another thread performed the transition.
|
||||||
|
bool make_not_entrant() { return make_not_entrant_or_zombie(not_entrant); }
|
||||||
|
bool make_zombie() { return make_not_entrant_or_zombie(zombie); }
|
||||||
|
|
||||||
// used by jvmti to track if the unload event has been reported
|
// used by jvmti to track if the unload event has been reported
|
||||||
bool unload_reported() { return _unload_reported; }
|
bool unload_reported() { return _unload_reported; }
|
||||||
@ -563,7 +567,7 @@ class nmethod : public CodeBlob {
|
|||||||
// Logging
|
// Logging
|
||||||
void log_identity(xmlStream* log) const;
|
void log_identity(xmlStream* log) const;
|
||||||
void log_new_nmethod() const;
|
void log_new_nmethod() const;
|
||||||
void log_state_change(int state) const;
|
void log_state_change() const;
|
||||||
|
|
||||||
// Prints a comment for one native instruction (reloc info, pc desc)
|
// Prints a comment for one native instruction (reloc info, pc desc)
|
||||||
void print_code_comment_on(outputStream* st, int column, address begin, address end);
|
void print_code_comment_on(outputStream* st, int column, address begin, address end);
|
||||||
|
@ -709,7 +709,8 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen,
|
|||||||
|
|
||||||
// Support for parallelizing survivor space rescan
|
// Support for parallelizing survivor space rescan
|
||||||
if (CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) {
|
if (CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) {
|
||||||
size_t max_plab_samples = MaxNewSize/((SurvivorRatio+2)*MinTLABSize);
|
size_t max_plab_samples = cp->max_gen0_size()/
|
||||||
|
((SurvivorRatio+2)*MinTLABSize);
|
||||||
_survivor_plab_array = NEW_C_HEAP_ARRAY(ChunkArray, ParallelGCThreads);
|
_survivor_plab_array = NEW_C_HEAP_ARRAY(ChunkArray, ParallelGCThreads);
|
||||||
_survivor_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, 2*max_plab_samples);
|
_survivor_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, 2*max_plab_samples);
|
||||||
_cursor = NEW_C_HEAP_ARRAY(size_t, ParallelGCThreads);
|
_cursor = NEW_C_HEAP_ARRAY(size_t, ParallelGCThreads);
|
||||||
|
@ -351,9 +351,16 @@ void
|
|||||||
CollectionSetChooser::printSortedHeapRegions() {
|
CollectionSetChooser::printSortedHeapRegions() {
|
||||||
gclog_or_tty->print_cr("Printing %d Heap Regions sorted by amount of known garbage",
|
gclog_or_tty->print_cr("Printing %d Heap Regions sorted by amount of known garbage",
|
||||||
_numMarkedRegions);
|
_numMarkedRegions);
|
||||||
|
|
||||||
|
DEBUG_ONLY(int marked_count = 0;)
|
||||||
for (int i = 0; i < _markedRegions.length(); i++) {
|
for (int i = 0; i < _markedRegions.length(); i++) {
|
||||||
printHeapRegion(_markedRegions.at(i));
|
HeapRegion* r = _markedRegions.at(i);
|
||||||
|
if (r != NULL) {
|
||||||
|
printHeapRegion(r);
|
||||||
|
DEBUG_ONLY(marked_count++;)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
assert(marked_count == _numMarkedRegions, "must be");
|
||||||
gclog_or_tty->print_cr("Done sorted heap region print");
|
gclog_or_tty->print_cr("Done sorted heap region print");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,28 +42,49 @@ ConcurrentG1Refine::ConcurrentG1Refine() :
|
|||||||
_n_periods(0),
|
_n_periods(0),
|
||||||
_threads(NULL), _n_threads(0)
|
_threads(NULL), _n_threads(0)
|
||||||
{
|
{
|
||||||
if (G1ConcRefine) {
|
|
||||||
_n_threads = (int)thread_num();
|
// Ergomonically select initial concurrent refinement parameters
|
||||||
if (_n_threads > 0) {
|
if (FLAG_IS_DEFAULT(G1ConcRefineGreenZone)) {
|
||||||
_threads = NEW_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _n_threads);
|
FLAG_SET_DEFAULT(G1ConcRefineGreenZone, MAX2<int>(ParallelGCThreads, 1));
|
||||||
int worker_id_offset = (int)DirtyCardQueueSet::num_par_ids();
|
}
|
||||||
ConcurrentG1RefineThread *next = NULL;
|
set_green_zone(G1ConcRefineGreenZone);
|
||||||
for (int i = _n_threads - 1; i >= 0; i--) {
|
|
||||||
ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(this, next, worker_id_offset, i);
|
if (FLAG_IS_DEFAULT(G1ConcRefineYellowZone)) {
|
||||||
assert(t != NULL, "Conc refine should have been created");
|
FLAG_SET_DEFAULT(G1ConcRefineYellowZone, green_zone() * 3);
|
||||||
assert(t->cg1r() == this, "Conc refine thread should refer to this");
|
}
|
||||||
_threads[i] = t;
|
set_yellow_zone(MAX2<int>(G1ConcRefineYellowZone, green_zone()));
|
||||||
next = t;
|
|
||||||
}
|
if (FLAG_IS_DEFAULT(G1ConcRefineRedZone)) {
|
||||||
}
|
FLAG_SET_DEFAULT(G1ConcRefineRedZone, yellow_zone() * 2);
|
||||||
|
}
|
||||||
|
set_red_zone(MAX2<int>(G1ConcRefineRedZone, yellow_zone()));
|
||||||
|
_n_worker_threads = thread_num();
|
||||||
|
// We need one extra thread to do the young gen rset size sampling.
|
||||||
|
_n_threads = _n_worker_threads + 1;
|
||||||
|
reset_threshold_step();
|
||||||
|
|
||||||
|
_threads = NEW_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _n_threads);
|
||||||
|
int worker_id_offset = (int)DirtyCardQueueSet::num_par_ids();
|
||||||
|
ConcurrentG1RefineThread *next = NULL;
|
||||||
|
for (int i = _n_threads - 1; i >= 0; i--) {
|
||||||
|
ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(this, next, worker_id_offset, i);
|
||||||
|
assert(t != NULL, "Conc refine should have been created");
|
||||||
|
assert(t->cg1r() == this, "Conc refine thread should refer to this");
|
||||||
|
_threads[i] = t;
|
||||||
|
next = t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ConcurrentG1Refine::thread_num() {
|
void ConcurrentG1Refine::reset_threshold_step() {
|
||||||
if (G1ConcRefine) {
|
if (FLAG_IS_DEFAULT(G1ConcRefineThresholdStep)) {
|
||||||
return (G1ParallelRSetThreads > 0) ? G1ParallelRSetThreads : ParallelGCThreads;
|
_thread_threshold_step = (yellow_zone() - green_zone()) / (worker_thread_num() + 1);
|
||||||
|
} else {
|
||||||
|
_thread_threshold_step = G1ConcRefineThresholdStep;
|
||||||
}
|
}
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
int ConcurrentG1Refine::thread_num() {
|
||||||
|
return MAX2<int>((G1ParallelRSetThreads > 0) ? G1ParallelRSetThreads : ParallelGCThreads, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConcurrentG1Refine::init() {
|
void ConcurrentG1Refine::init() {
|
||||||
@ -123,6 +144,15 @@ void ConcurrentG1Refine::stop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConcurrentG1Refine::reinitialize_threads() {
|
||||||
|
reset_threshold_step();
|
||||||
|
if (_threads != NULL) {
|
||||||
|
for (int i = 0; i < _n_threads; i++) {
|
||||||
|
_threads[i]->initialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ConcurrentG1Refine::~ConcurrentG1Refine() {
|
ConcurrentG1Refine::~ConcurrentG1Refine() {
|
||||||
if (G1ConcRSLogCacheSize > 0) {
|
if (G1ConcRSLogCacheSize > 0) {
|
||||||
assert(_card_counts != NULL, "Logic");
|
assert(_card_counts != NULL, "Logic");
|
||||||
@ -384,4 +414,3 @@ void ConcurrentG1Refine::print_worker_threads_on(outputStream* st) const {
|
|||||||
st->cr();
|
st->cr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,31 @@ class G1RemSet;
|
|||||||
class ConcurrentG1Refine: public CHeapObj {
|
class ConcurrentG1Refine: public CHeapObj {
|
||||||
ConcurrentG1RefineThread** _threads;
|
ConcurrentG1RefineThread** _threads;
|
||||||
int _n_threads;
|
int _n_threads;
|
||||||
|
int _n_worker_threads;
|
||||||
|
/*
|
||||||
|
* The value of the update buffer queue length falls into one of 3 zones:
|
||||||
|
* green, yellow, red. If the value is in [0, green) nothing is
|
||||||
|
* done, the buffers are left unprocessed to enable the caching effect of the
|
||||||
|
* dirtied cards. In the yellow zone [green, yellow) the concurrent refinement
|
||||||
|
* threads are gradually activated. In [yellow, red) all threads are
|
||||||
|
* running. If the length becomes red (max queue length) the mutators start
|
||||||
|
* processing the buffers.
|
||||||
|
*
|
||||||
|
* There are some interesting cases (with G1AdaptiveConcRefine turned off):
|
||||||
|
* 1) green = yellow = red = 0. In this case the mutator will process all
|
||||||
|
* buffers. Except for those that are created by the deferred updates
|
||||||
|
* machinery during a collection.
|
||||||
|
* 2) green = 0. Means no caching. Can be a good way to minimize the
|
||||||
|
* amount of time spent updating rsets during a collection.
|
||||||
|
*/
|
||||||
|
int _green_zone;
|
||||||
|
int _yellow_zone;
|
||||||
|
int _red_zone;
|
||||||
|
|
||||||
|
int _thread_threshold_step;
|
||||||
|
|
||||||
|
// Reset the threshold step value based of the current zone boundaries.
|
||||||
|
void reset_threshold_step();
|
||||||
|
|
||||||
// The cache for card refinement.
|
// The cache for card refinement.
|
||||||
bool _use_cache;
|
bool _use_cache;
|
||||||
@ -147,6 +172,8 @@ class ConcurrentG1Refine: public CHeapObj {
|
|||||||
void init(); // Accomplish some initialization that has to wait.
|
void init(); // Accomplish some initialization that has to wait.
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
|
void reinitialize_threads();
|
||||||
|
|
||||||
// Iterate over the conc refine threads
|
// Iterate over the conc refine threads
|
||||||
void threads_do(ThreadClosure *tc);
|
void threads_do(ThreadClosure *tc);
|
||||||
|
|
||||||
@ -178,7 +205,20 @@ class ConcurrentG1Refine: public CHeapObj {
|
|||||||
|
|
||||||
void clear_and_record_card_counts();
|
void clear_and_record_card_counts();
|
||||||
|
|
||||||
static size_t thread_num();
|
static int thread_num();
|
||||||
|
|
||||||
void print_worker_threads_on(outputStream* st) const;
|
void print_worker_threads_on(outputStream* st) const;
|
||||||
|
|
||||||
|
void set_green_zone(int x) { _green_zone = x; }
|
||||||
|
void set_yellow_zone(int x) { _yellow_zone = x; }
|
||||||
|
void set_red_zone(int x) { _red_zone = x; }
|
||||||
|
|
||||||
|
int green_zone() const { return _green_zone; }
|
||||||
|
int yellow_zone() const { return _yellow_zone; }
|
||||||
|
int red_zone() const { return _red_zone; }
|
||||||
|
|
||||||
|
int total_thread_num() const { return _n_threads; }
|
||||||
|
int worker_thread_num() const { return _n_worker_threads; }
|
||||||
|
|
||||||
|
int thread_threshold_step() const { return _thread_threshold_step; }
|
||||||
};
|
};
|
||||||
|
@ -25,10 +25,6 @@
|
|||||||
#include "incls/_precompiled.incl"
|
#include "incls/_precompiled.incl"
|
||||||
#include "incls/_concurrentG1RefineThread.cpp.incl"
|
#include "incls/_concurrentG1RefineThread.cpp.incl"
|
||||||
|
|
||||||
// ======= Concurrent Mark Thread ========
|
|
||||||
|
|
||||||
// The CM thread is created when the G1 garbage collector is used
|
|
||||||
|
|
||||||
ConcurrentG1RefineThread::
|
ConcurrentG1RefineThread::
|
||||||
ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread *next,
|
ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread *next,
|
||||||
int worker_id_offset, int worker_id) :
|
int worker_id_offset, int worker_id) :
|
||||||
@ -37,19 +33,42 @@ ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread *nex
|
|||||||
_worker_id(worker_id),
|
_worker_id(worker_id),
|
||||||
_active(false),
|
_active(false),
|
||||||
_next(next),
|
_next(next),
|
||||||
|
_monitor(NULL),
|
||||||
_cg1r(cg1r),
|
_cg1r(cg1r),
|
||||||
_vtime_accum(0.0),
|
_vtime_accum(0.0)
|
||||||
_interval_ms(5.0)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Each thread has its own monitor. The i-th thread is responsible for signalling
|
||||||
|
// to thread i+1 if the number of buffers in the queue exceeds a threashold for this
|
||||||
|
// thread. Monitors are also used to wake up the threads during termination.
|
||||||
|
// The 0th worker in notified by mutator threads and has a special monitor.
|
||||||
|
// The last worker is used for young gen rset size sampling.
|
||||||
|
if (worker_id > 0) {
|
||||||
|
_monitor = new Monitor(Mutex::nonleaf, "Refinement monitor", true);
|
||||||
|
} else {
|
||||||
|
_monitor = DirtyCardQ_CBL_mon;
|
||||||
|
}
|
||||||
|
initialize();
|
||||||
create_and_start();
|
create_and_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConcurrentG1RefineThread::initialize() {
|
||||||
|
if (_worker_id < cg1r()->worker_thread_num()) {
|
||||||
|
// Current thread activation threshold
|
||||||
|
_threshold = MIN2<int>(cg1r()->thread_threshold_step() * (_worker_id + 1) + cg1r()->green_zone(),
|
||||||
|
cg1r()->yellow_zone());
|
||||||
|
// A thread deactivates once the number of buffer reached a deactivation threshold
|
||||||
|
_deactivation_threshold = MAX2<int>(_threshold - cg1r()->thread_threshold_step(), cg1r()->green_zone());
|
||||||
|
} else {
|
||||||
|
set_active(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ConcurrentG1RefineThread::sample_young_list_rs_lengths() {
|
void ConcurrentG1RefineThread::sample_young_list_rs_lengths() {
|
||||||
G1CollectedHeap* g1h = G1CollectedHeap::heap();
|
G1CollectedHeap* g1h = G1CollectedHeap::heap();
|
||||||
G1CollectorPolicy* g1p = g1h->g1_policy();
|
G1CollectorPolicy* g1p = g1h->g1_policy();
|
||||||
if (g1p->adaptive_young_list_length()) {
|
if (g1p->adaptive_young_list_length()) {
|
||||||
int regions_visited = 0;
|
int regions_visited = 0;
|
||||||
|
|
||||||
g1h->young_list_rs_length_sampling_init();
|
g1h->young_list_rs_length_sampling_init();
|
||||||
while (g1h->young_list_rs_length_sampling_more()) {
|
while (g1h->young_list_rs_length_sampling_more()) {
|
||||||
g1h->young_list_rs_length_sampling_next();
|
g1h->young_list_rs_length_sampling_next();
|
||||||
@ -70,99 +89,121 @@ void ConcurrentG1RefineThread::sample_young_list_rs_lengths() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConcurrentG1RefineThread::run_young_rs_sampling() {
|
||||||
|
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
||||||
|
_vtime_start = os::elapsedVTime();
|
||||||
|
while(!_should_terminate) {
|
||||||
|
_sts.join();
|
||||||
|
sample_young_list_rs_lengths();
|
||||||
|
_sts.leave();
|
||||||
|
|
||||||
|
if (os::supports_vtime()) {
|
||||||
|
_vtime_accum = (os::elapsedVTime() - _vtime_start);
|
||||||
|
} else {
|
||||||
|
_vtime_accum = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
|
||||||
|
if (_should_terminate) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_monitor->wait(Mutex::_no_safepoint_check_flag, G1ConcRefineServiceInterval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConcurrentG1RefineThread::wait_for_completed_buffers() {
|
||||||
|
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
||||||
|
MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
|
||||||
|
while (!_should_terminate && !is_active()) {
|
||||||
|
_monitor->wait(Mutex::_no_safepoint_check_flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConcurrentG1RefineThread::is_active() {
|
||||||
|
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
||||||
|
return _worker_id > 0 ? _active : dcqs.process_completed_buffers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConcurrentG1RefineThread::activate() {
|
||||||
|
MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
|
||||||
|
if (_worker_id > 0) {
|
||||||
|
if (G1TraceConcurrentRefinement) {
|
||||||
|
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
||||||
|
gclog_or_tty->print_cr("G1-Refine-activated worker %d, on threshold %d, current %d",
|
||||||
|
_worker_id, _threshold, (int)dcqs.completed_buffers_num());
|
||||||
|
}
|
||||||
|
set_active(true);
|
||||||
|
} else {
|
||||||
|
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
||||||
|
dcqs.set_process_completed(true);
|
||||||
|
}
|
||||||
|
_monitor->notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConcurrentG1RefineThread::deactivate() {
|
||||||
|
MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
|
||||||
|
if (_worker_id > 0) {
|
||||||
|
if (G1TraceConcurrentRefinement) {
|
||||||
|
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
||||||
|
gclog_or_tty->print_cr("G1-Refine-deactivated worker %d, off threshold %d, current %d",
|
||||||
|
_worker_id, _deactivation_threshold, (int)dcqs.completed_buffers_num());
|
||||||
|
}
|
||||||
|
set_active(false);
|
||||||
|
} else {
|
||||||
|
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
||||||
|
dcqs.set_process_completed(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ConcurrentG1RefineThread::run() {
|
void ConcurrentG1RefineThread::run() {
|
||||||
initialize_in_thread();
|
initialize_in_thread();
|
||||||
_vtime_start = os::elapsedVTime();
|
|
||||||
wait_for_universe_init();
|
wait_for_universe_init();
|
||||||
|
|
||||||
|
if (_worker_id >= cg1r()->worker_thread_num()) {
|
||||||
|
run_young_rs_sampling();
|
||||||
|
terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
_vtime_start = os::elapsedVTime();
|
||||||
while (!_should_terminate) {
|
while (!_should_terminate) {
|
||||||
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
||||||
// Wait for completed log buffers to exist.
|
|
||||||
{
|
// Wait for work
|
||||||
MutexLockerEx x(DirtyCardQ_CBL_mon, Mutex::_no_safepoint_check_flag);
|
wait_for_completed_buffers();
|
||||||
while (((_worker_id == 0 && !dcqs.process_completed_buffers()) ||
|
|
||||||
(_worker_id > 0 && !is_active())) &&
|
|
||||||
!_should_terminate) {
|
|
||||||
DirtyCardQ_CBL_mon->wait(Mutex::_no_safepoint_check_flag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_should_terminate) {
|
if (_should_terminate) {
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we take them off (this doesn't hold locks while it applies
|
|
||||||
// closures.) (If we did a full collection, then we'll do a full
|
|
||||||
// traversal.
|
|
||||||
_sts.join();
|
_sts.join();
|
||||||
int n_logs = 0;
|
|
||||||
int lower_limit = 0;
|
|
||||||
double start_vtime_sec; // only used when G1SmoothConcRefine is on
|
|
||||||
int prev_buffer_num; // only used when G1SmoothConcRefine is on
|
|
||||||
// This thread activation threshold
|
|
||||||
int threshold = G1UpdateBufferQueueProcessingThreshold * _worker_id;
|
|
||||||
// Next thread activation threshold
|
|
||||||
int next_threshold = threshold + G1UpdateBufferQueueProcessingThreshold;
|
|
||||||
int deactivation_threshold = MAX2<int>(threshold - G1UpdateBufferQueueProcessingThreshold / 2, 0);
|
|
||||||
|
|
||||||
if (G1SmoothConcRefine) {
|
do {
|
||||||
lower_limit = 0;
|
int curr_buffer_num = (int)dcqs.completed_buffers_num();
|
||||||
start_vtime_sec = os::elapsedVTime();
|
// If the number of the buffers falls down into the yellow zone,
|
||||||
prev_buffer_num = (int) dcqs.completed_buffers_num();
|
// that means that the transition period after the evacuation pause has ended.
|
||||||
} else {
|
if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= cg1r()->yellow_zone()) {
|
||||||
lower_limit = G1UpdateBufferQueueProcessingThreshold / 4; // For now.
|
dcqs.set_completed_queue_padding(0);
|
||||||
}
|
|
||||||
while (dcqs.apply_closure_to_completed_buffer(_worker_id + _worker_id_offset, lower_limit)) {
|
|
||||||
double end_vtime_sec;
|
|
||||||
double elapsed_vtime_sec;
|
|
||||||
int elapsed_vtime_ms;
|
|
||||||
int curr_buffer_num = (int) dcqs.completed_buffers_num();
|
|
||||||
|
|
||||||
if (G1SmoothConcRefine) {
|
|
||||||
end_vtime_sec = os::elapsedVTime();
|
|
||||||
elapsed_vtime_sec = end_vtime_sec - start_vtime_sec;
|
|
||||||
elapsed_vtime_ms = (int) (elapsed_vtime_sec * 1000.0);
|
|
||||||
|
|
||||||
if (curr_buffer_num > prev_buffer_num ||
|
|
||||||
curr_buffer_num > next_threshold) {
|
|
||||||
decreaseInterval(elapsed_vtime_ms);
|
|
||||||
} else if (curr_buffer_num < prev_buffer_num) {
|
|
||||||
increaseInterval(elapsed_vtime_ms);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (_worker_id == 0) {
|
|
||||||
sample_young_list_rs_lengths();
|
if (_worker_id > 0 && curr_buffer_num <= _deactivation_threshold) {
|
||||||
} else if (curr_buffer_num < deactivation_threshold) {
|
|
||||||
// If the number of the buffer has fallen below our threshold
|
// If the number of the buffer has fallen below our threshold
|
||||||
// we should deactivate. The predecessor will reactivate this
|
// we should deactivate. The predecessor will reactivate this
|
||||||
// thread should the number of the buffers cross the threshold again.
|
// thread should the number of the buffers cross the threshold again.
|
||||||
MutexLockerEx x(DirtyCardQ_CBL_mon, Mutex::_no_safepoint_check_flag);
|
|
||||||
deactivate();
|
deactivate();
|
||||||
if (G1TraceConcurrentRefinement) {
|
|
||||||
gclog_or_tty->print_cr("G1-Refine-deactivated worker %d", _worker_id);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we need to activate the next thread.
|
// Check if we need to activate the next thread.
|
||||||
if (curr_buffer_num > next_threshold && _next != NULL && !_next->is_active()) {
|
if (_next != NULL && !_next->is_active() && curr_buffer_num > _next->_threshold) {
|
||||||
MutexLockerEx x(DirtyCardQ_CBL_mon, Mutex::_no_safepoint_check_flag);
|
|
||||||
_next->activate();
|
_next->activate();
|
||||||
DirtyCardQ_CBL_mon->notify_all();
|
|
||||||
if (G1TraceConcurrentRefinement) {
|
|
||||||
gclog_or_tty->print_cr("G1-Refine-activated worker %d", _next->_worker_id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} while (dcqs.apply_closure_to_completed_buffer(_worker_id + _worker_id_offset, cg1r()->green_zone()));
|
||||||
|
|
||||||
if (G1SmoothConcRefine) {
|
// We can exit the loop above while being active if there was a yield request.
|
||||||
prev_buffer_num = curr_buffer_num;
|
if (is_active()) {
|
||||||
_sts.leave();
|
deactivate();
|
||||||
os::sleep(Thread::current(), (jlong) _interval_ms, false);
|
|
||||||
_sts.join();
|
|
||||||
start_vtime_sec = os::elapsedVTime();
|
|
||||||
}
|
|
||||||
n_logs++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_sts.leave();
|
_sts.leave();
|
||||||
|
|
||||||
if (os::supports_vtime()) {
|
if (os::supports_vtime()) {
|
||||||
@ -172,7 +213,6 @@ void ConcurrentG1RefineThread::run() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(_should_terminate, "just checking");
|
assert(_should_terminate, "just checking");
|
||||||
|
|
||||||
terminate();
|
terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,8 +231,8 @@ void ConcurrentG1RefineThread::stop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
MutexLockerEx x(DirtyCardQ_CBL_mon, Mutex::_no_safepoint_check_flag);
|
MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
|
||||||
DirtyCardQ_CBL_mon->notify_all();
|
_monitor->notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -40,42 +40,36 @@ class ConcurrentG1RefineThread: public ConcurrentGCThread {
|
|||||||
// when the number of the rset update buffer crosses a certain threshold. A successor
|
// when the number of the rset update buffer crosses a certain threshold. A successor
|
||||||
// would self-deactivate when the number of the buffers falls below the threshold.
|
// would self-deactivate when the number of the buffers falls below the threshold.
|
||||||
bool _active;
|
bool _active;
|
||||||
ConcurrentG1RefineThread * _next;
|
ConcurrentG1RefineThread* _next;
|
||||||
public:
|
Monitor* _monitor;
|
||||||
virtual void run();
|
ConcurrentG1Refine* _cg1r;
|
||||||
|
|
||||||
bool is_active() { return _active; }
|
int _thread_threshold_step;
|
||||||
void activate() { _active = true; }
|
// This thread activation threshold
|
||||||
void deactivate() { _active = false; }
|
int _threshold;
|
||||||
|
// This thread deactivation threshold
|
||||||
|
int _deactivation_threshold;
|
||||||
|
|
||||||
private:
|
void sample_young_list_rs_lengths();
|
||||||
ConcurrentG1Refine* _cg1r;
|
void run_young_rs_sampling();
|
||||||
|
void wait_for_completed_buffers();
|
||||||
|
|
||||||
double _interval_ms;
|
void set_active(bool x) { _active = x; }
|
||||||
|
bool is_active();
|
||||||
void decreaseInterval(int processing_time_ms) {
|
void activate();
|
||||||
double min_interval_ms = (double) processing_time_ms;
|
void deactivate();
|
||||||
_interval_ms = 0.8 * _interval_ms;
|
|
||||||
if (_interval_ms < min_interval_ms)
|
|
||||||
_interval_ms = min_interval_ms;
|
|
||||||
}
|
|
||||||
void increaseInterval(int processing_time_ms) {
|
|
||||||
double max_interval_ms = 9.0 * (double) processing_time_ms;
|
|
||||||
_interval_ms = 1.1 * _interval_ms;
|
|
||||||
if (max_interval_ms > 0 && _interval_ms > max_interval_ms)
|
|
||||||
_interval_ms = max_interval_ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sleepBeforeNextCycle();
|
|
||||||
|
|
||||||
// For use by G1CollectedHeap, which is a friend.
|
// For use by G1CollectedHeap, which is a friend.
|
||||||
static SuspendibleThreadSet* sts() { return &_sts; }
|
static SuspendibleThreadSet* sts() { return &_sts; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
virtual void run();
|
||||||
// Constructor
|
// Constructor
|
||||||
ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread* next,
|
ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread* next,
|
||||||
int worker_id_offset, int worker_id);
|
int worker_id_offset, int worker_id);
|
||||||
|
|
||||||
|
void initialize();
|
||||||
|
|
||||||
// Printing
|
// Printing
|
||||||
void print() const;
|
void print() const;
|
||||||
void print_on(outputStream* st) const;
|
void print_on(outputStream* st) const;
|
||||||
@ -83,13 +77,10 @@ class ConcurrentG1RefineThread: public ConcurrentGCThread {
|
|||||||
// Total virtual time so far.
|
// Total virtual time so far.
|
||||||
double vtime_accum() { return _vtime_accum; }
|
double vtime_accum() { return _vtime_accum; }
|
||||||
|
|
||||||
ConcurrentG1Refine* cg1r() { return _cg1r; }
|
ConcurrentG1Refine* cg1r() { return _cg1r; }
|
||||||
|
|
||||||
void sample_young_list_rs_lengths();
|
|
||||||
|
|
||||||
// Yield for GC
|
// Yield for GC
|
||||||
void yield();
|
void yield();
|
||||||
|
|
||||||
// shutdown
|
// shutdown
|
||||||
void stop();
|
void stop();
|
||||||
};
|
};
|
||||||
|
@ -760,7 +760,6 @@ void ConcurrentMark::checkpointRootsInitialPost() {
|
|||||||
rp->setup_policy(false); // snapshot the soft ref policy to be used in this cycle
|
rp->setup_policy(false); // snapshot the soft ref policy to be used in this cycle
|
||||||
|
|
||||||
SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
|
SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
|
||||||
satb_mq_set.set_process_completed_threshold(G1SATBProcessCompletedThreshold);
|
|
||||||
satb_mq_set.set_active_all_threads(true);
|
satb_mq_set.set_active_all_threads(true);
|
||||||
|
|
||||||
// update_g1_committed() will be called at the end of an evac pause
|
// update_g1_committed() will be called at the end of an evac pause
|
||||||
|
@ -61,8 +61,8 @@ bool DirtyCardQueue::apply_closure_to_buffer(CardTableEntryClosure* cl,
|
|||||||
#pragma warning( disable:4355 ) // 'this' : used in base member initializer list
|
#pragma warning( disable:4355 ) // 'this' : used in base member initializer list
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
DirtyCardQueueSet::DirtyCardQueueSet() :
|
DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) :
|
||||||
PtrQueueSet(true /*notify_when_complete*/),
|
PtrQueueSet(notify_when_complete),
|
||||||
_closure(NULL),
|
_closure(NULL),
|
||||||
_shared_dirty_card_queue(this, true /*perm*/),
|
_shared_dirty_card_queue(this, true /*perm*/),
|
||||||
_free_ids(NULL),
|
_free_ids(NULL),
|
||||||
@ -77,12 +77,12 @@ size_t DirtyCardQueueSet::num_par_ids() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DirtyCardQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
|
void DirtyCardQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
|
||||||
|
int process_completed_threshold,
|
||||||
int max_completed_queue,
|
int max_completed_queue,
|
||||||
Mutex* lock, PtrQueueSet* fl_owner) {
|
Mutex* lock, PtrQueueSet* fl_owner) {
|
||||||
PtrQueueSet::initialize(cbl_mon, fl_lock, max_completed_queue, fl_owner);
|
PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold,
|
||||||
|
max_completed_queue, fl_owner);
|
||||||
set_buffer_size(G1UpdateBufferSize);
|
set_buffer_size(G1UpdateBufferSize);
|
||||||
set_process_completed_threshold(G1UpdateBufferQueueProcessingThreshold);
|
|
||||||
|
|
||||||
_shared_dirty_card_queue.set_lock(lock);
|
_shared_dirty_card_queue.set_lock(lock);
|
||||||
_free_ids = new FreeIdSet((int) num_par_ids(), _cbl_mon);
|
_free_ids = new FreeIdSet((int) num_par_ids(), _cbl_mon);
|
||||||
}
|
}
|
||||||
@ -154,9 +154,10 @@ bool DirtyCardQueueSet::mut_process_buffer(void** buf) {
|
|||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
DirtyCardQueueSet::CompletedBufferNode*
|
|
||||||
DirtyCardQueueSet::get_completed_buffer_lock(int stop_at) {
|
BufferNode*
|
||||||
CompletedBufferNode* nd = NULL;
|
DirtyCardQueueSet::get_completed_buffer(int stop_at) {
|
||||||
|
BufferNode* nd = NULL;
|
||||||
MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
|
MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
|
||||||
|
|
||||||
if ((int)_n_completed_buffers <= stop_at) {
|
if ((int)_n_completed_buffers <= stop_at) {
|
||||||
@ -166,53 +167,31 @@ DirtyCardQueueSet::get_completed_buffer_lock(int stop_at) {
|
|||||||
|
|
||||||
if (_completed_buffers_head != NULL) {
|
if (_completed_buffers_head != NULL) {
|
||||||
nd = _completed_buffers_head;
|
nd = _completed_buffers_head;
|
||||||
_completed_buffers_head = nd->next;
|
_completed_buffers_head = nd->next();
|
||||||
if (_completed_buffers_head == NULL)
|
if (_completed_buffers_head == NULL)
|
||||||
_completed_buffers_tail = NULL;
|
_completed_buffers_tail = NULL;
|
||||||
_n_completed_buffers--;
|
_n_completed_buffers--;
|
||||||
|
assert(_n_completed_buffers >= 0, "Invariant");
|
||||||
}
|
}
|
||||||
debug_only(assert_completed_buffer_list_len_correct_locked());
|
debug_only(assert_completed_buffer_list_len_correct_locked());
|
||||||
return nd;
|
return nd;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We only do this in contexts where there is no concurrent enqueueing.
|
|
||||||
DirtyCardQueueSet::CompletedBufferNode*
|
|
||||||
DirtyCardQueueSet::get_completed_buffer_CAS() {
|
|
||||||
CompletedBufferNode* nd = _completed_buffers_head;
|
|
||||||
|
|
||||||
while (nd != NULL) {
|
|
||||||
CompletedBufferNode* next = nd->next;
|
|
||||||
CompletedBufferNode* result =
|
|
||||||
(CompletedBufferNode*)Atomic::cmpxchg_ptr(next,
|
|
||||||
&_completed_buffers_head,
|
|
||||||
nd);
|
|
||||||
if (result == nd) {
|
|
||||||
return result;
|
|
||||||
} else {
|
|
||||||
nd = _completed_buffers_head;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(_completed_buffers_head == NULL, "Loop post");
|
|
||||||
_completed_buffers_tail = NULL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DirtyCardQueueSet::
|
bool DirtyCardQueueSet::
|
||||||
apply_closure_to_completed_buffer_helper(int worker_i,
|
apply_closure_to_completed_buffer_helper(int worker_i,
|
||||||
CompletedBufferNode* nd) {
|
BufferNode* nd) {
|
||||||
if (nd != NULL) {
|
if (nd != NULL) {
|
||||||
|
void **buf = BufferNode::make_buffer_from_node(nd);
|
||||||
|
size_t index = nd->index();
|
||||||
bool b =
|
bool b =
|
||||||
DirtyCardQueue::apply_closure_to_buffer(_closure, nd->buf,
|
DirtyCardQueue::apply_closure_to_buffer(_closure, buf,
|
||||||
nd->index, _sz,
|
index, _sz,
|
||||||
true, worker_i);
|
true, worker_i);
|
||||||
void** buf = nd->buf;
|
|
||||||
size_t index = nd->index;
|
|
||||||
delete nd;
|
|
||||||
if (b) {
|
if (b) {
|
||||||
deallocate_buffer(buf);
|
deallocate_buffer(buf);
|
||||||
return true; // In normal case, go on to next buffer.
|
return true; // In normal case, go on to next buffer.
|
||||||
} else {
|
} else {
|
||||||
enqueue_complete_buffer(buf, index, true);
|
enqueue_complete_buffer(buf, index);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -222,40 +201,36 @@ apply_closure_to_completed_buffer_helper(int worker_i,
|
|||||||
|
|
||||||
bool DirtyCardQueueSet::apply_closure_to_completed_buffer(int worker_i,
|
bool DirtyCardQueueSet::apply_closure_to_completed_buffer(int worker_i,
|
||||||
int stop_at,
|
int stop_at,
|
||||||
bool with_CAS)
|
bool during_pause)
|
||||||
{
|
{
|
||||||
CompletedBufferNode* nd = NULL;
|
assert(!during_pause || stop_at == 0, "Should not leave any completed buffers during a pause");
|
||||||
if (with_CAS) {
|
BufferNode* nd = get_completed_buffer(stop_at);
|
||||||
guarantee(stop_at == 0, "Precondition");
|
|
||||||
nd = get_completed_buffer_CAS();
|
|
||||||
} else {
|
|
||||||
nd = get_completed_buffer_lock(stop_at);
|
|
||||||
}
|
|
||||||
bool res = apply_closure_to_completed_buffer_helper(worker_i, nd);
|
bool res = apply_closure_to_completed_buffer_helper(worker_i, nd);
|
||||||
if (res) Atomic::inc(&_processed_buffers_rs_thread);
|
if (res) Atomic::inc(&_processed_buffers_rs_thread);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirtyCardQueueSet::apply_closure_to_all_completed_buffers() {
|
void DirtyCardQueueSet::apply_closure_to_all_completed_buffers() {
|
||||||
CompletedBufferNode* nd = _completed_buffers_head;
|
BufferNode* nd = _completed_buffers_head;
|
||||||
while (nd != NULL) {
|
while (nd != NULL) {
|
||||||
bool b =
|
bool b =
|
||||||
DirtyCardQueue::apply_closure_to_buffer(_closure, nd->buf, 0, _sz,
|
DirtyCardQueue::apply_closure_to_buffer(_closure,
|
||||||
false);
|
BufferNode::make_buffer_from_node(nd),
|
||||||
|
0, _sz, false);
|
||||||
guarantee(b, "Should not stop early.");
|
guarantee(b, "Should not stop early.");
|
||||||
nd = nd->next;
|
nd = nd->next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirtyCardQueueSet::abandon_logs() {
|
void DirtyCardQueueSet::abandon_logs() {
|
||||||
assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
|
assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
|
||||||
CompletedBufferNode* buffers_to_delete = NULL;
|
BufferNode* buffers_to_delete = NULL;
|
||||||
{
|
{
|
||||||
MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
|
MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
|
||||||
while (_completed_buffers_head != NULL) {
|
while (_completed_buffers_head != NULL) {
|
||||||
CompletedBufferNode* nd = _completed_buffers_head;
|
BufferNode* nd = _completed_buffers_head;
|
||||||
_completed_buffers_head = nd->next;
|
_completed_buffers_head = nd->next();
|
||||||
nd->next = buffers_to_delete;
|
nd->set_next(buffers_to_delete);
|
||||||
buffers_to_delete = nd;
|
buffers_to_delete = nd;
|
||||||
}
|
}
|
||||||
_n_completed_buffers = 0;
|
_n_completed_buffers = 0;
|
||||||
@ -263,10 +238,9 @@ void DirtyCardQueueSet::abandon_logs() {
|
|||||||
debug_only(assert_completed_buffer_list_len_correct_locked());
|
debug_only(assert_completed_buffer_list_len_correct_locked());
|
||||||
}
|
}
|
||||||
while (buffers_to_delete != NULL) {
|
while (buffers_to_delete != NULL) {
|
||||||
CompletedBufferNode* nd = buffers_to_delete;
|
BufferNode* nd = buffers_to_delete;
|
||||||
buffers_to_delete = nd->next;
|
buffers_to_delete = nd->next();
|
||||||
deallocate_buffer(nd->buf);
|
deallocate_buffer(BufferNode::make_buffer_from_node(nd));
|
||||||
delete nd;
|
|
||||||
}
|
}
|
||||||
// Since abandon is done only at safepoints, we can safely manipulate
|
// Since abandon is done only at safepoints, we can safely manipulate
|
||||||
// these queues.
|
// these queues.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2001-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -84,11 +84,12 @@ class DirtyCardQueueSet: public PtrQueueSet {
|
|||||||
jint _processed_buffers_rs_thread;
|
jint _processed_buffers_rs_thread;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DirtyCardQueueSet();
|
DirtyCardQueueSet(bool notify_when_complete = true);
|
||||||
|
|
||||||
void initialize(Monitor* cbl_mon, Mutex* fl_lock,
|
void initialize(Monitor* cbl_mon, Mutex* fl_lock,
|
||||||
int max_completed_queue = 0,
|
int process_completed_threshold,
|
||||||
Mutex* lock = NULL, PtrQueueSet* fl_owner = NULL);
|
int max_completed_queue,
|
||||||
|
Mutex* lock, PtrQueueSet* fl_owner = NULL);
|
||||||
|
|
||||||
// The number of parallel ids that can be claimed to allow collector or
|
// The number of parallel ids that can be claimed to allow collector or
|
||||||
// mutator threads to do card-processing work.
|
// mutator threads to do card-processing work.
|
||||||
@ -120,12 +121,13 @@ public:
|
|||||||
// is returned to the completed buffer set, and this call returns false.
|
// is returned to the completed buffer set, and this call returns false.
|
||||||
bool apply_closure_to_completed_buffer(int worker_i = 0,
|
bool apply_closure_to_completed_buffer(int worker_i = 0,
|
||||||
int stop_at = 0,
|
int stop_at = 0,
|
||||||
bool with_CAS = false);
|
bool during_pause = false);
|
||||||
bool apply_closure_to_completed_buffer_helper(int worker_i,
|
|
||||||
CompletedBufferNode* nd);
|
bool apply_closure_to_completed_buffer_helper(int worker_i,
|
||||||
|
BufferNode* nd);
|
||||||
|
|
||||||
|
BufferNode* get_completed_buffer(int stop_at);
|
||||||
|
|
||||||
CompletedBufferNode* get_completed_buffer_CAS();
|
|
||||||
CompletedBufferNode* get_completed_buffer_lock(int stop_at);
|
|
||||||
// Applies the current closure to all completed buffers,
|
// Applies the current closure to all completed buffers,
|
||||||
// non-consumptively.
|
// non-consumptively.
|
||||||
void apply_closure_to_all_completed_buffers();
|
void apply_closure_to_all_completed_buffers();
|
||||||
|
@ -928,6 +928,8 @@ void G1CollectedHeap::do_collection(bool full, bool clear_all_soft_refs,
|
|||||||
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
|
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
|
||||||
TraceTime t(full ? "Full GC (System.gc())" : "Full GC", PrintGC, true, gclog_or_tty);
|
TraceTime t(full ? "Full GC (System.gc())" : "Full GC", PrintGC, true, gclog_or_tty);
|
||||||
|
|
||||||
|
TraceMemoryManagerStats tms(true /* fullGC */);
|
||||||
|
|
||||||
double start = os::elapsedTime();
|
double start = os::elapsedTime();
|
||||||
g1_policy()->record_full_collection_start();
|
g1_policy()->record_full_collection_start();
|
||||||
|
|
||||||
@ -1001,6 +1003,8 @@ void G1CollectedHeap::do_collection(bool full, bool clear_all_soft_refs,
|
|||||||
|
|
||||||
COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
|
COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
|
||||||
|
|
||||||
|
MemoryService::track_memory_usage();
|
||||||
|
|
||||||
if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) {
|
if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) {
|
||||||
HandleMark hm; // Discard invalid handles created during verification
|
HandleMark hm; // Discard invalid handles created during verification
|
||||||
gclog_or_tty->print(" VerifyAfterGC:");
|
gclog_or_tty->print(" VerifyAfterGC:");
|
||||||
@ -1371,6 +1375,7 @@ void G1CollectedHeap::shrink(size_t shrink_bytes) {
|
|||||||
G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) :
|
G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) :
|
||||||
SharedHeap(policy_),
|
SharedHeap(policy_),
|
||||||
_g1_policy(policy_),
|
_g1_policy(policy_),
|
||||||
|
_dirty_card_queue_set(false),
|
||||||
_ref_processor(NULL),
|
_ref_processor(NULL),
|
||||||
_process_strong_tasks(new SubTasksDone(G1H_PS_NumElements)),
|
_process_strong_tasks(new SubTasksDone(G1H_PS_NumElements)),
|
||||||
_bot_shared(NULL),
|
_bot_shared(NULL),
|
||||||
@ -1456,8 +1461,6 @@ jint G1CollectedHeap::initialize() {
|
|||||||
Universe::check_alignment(init_byte_size, HeapRegion::GrainBytes, "g1 heap");
|
Universe::check_alignment(init_byte_size, HeapRegion::GrainBytes, "g1 heap");
|
||||||
Universe::check_alignment(max_byte_size, HeapRegion::GrainBytes, "g1 heap");
|
Universe::check_alignment(max_byte_size, HeapRegion::GrainBytes, "g1 heap");
|
||||||
|
|
||||||
// We allocate this in any case, but only do no work if the command line
|
|
||||||
// param is off.
|
|
||||||
_cg1r = new ConcurrentG1Refine();
|
_cg1r = new ConcurrentG1Refine();
|
||||||
|
|
||||||
// Reserve the maximum.
|
// Reserve the maximum.
|
||||||
@ -1590,18 +1593,20 @@ jint G1CollectedHeap::initialize() {
|
|||||||
|
|
||||||
JavaThread::satb_mark_queue_set().initialize(SATB_Q_CBL_mon,
|
JavaThread::satb_mark_queue_set().initialize(SATB_Q_CBL_mon,
|
||||||
SATB_Q_FL_lock,
|
SATB_Q_FL_lock,
|
||||||
0,
|
G1SATBProcessCompletedThreshold,
|
||||||
Shared_SATB_Q_lock);
|
Shared_SATB_Q_lock);
|
||||||
|
|
||||||
JavaThread::dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon,
|
JavaThread::dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon,
|
||||||
DirtyCardQ_FL_lock,
|
DirtyCardQ_FL_lock,
|
||||||
G1UpdateBufferQueueMaxLength,
|
concurrent_g1_refine()->yellow_zone(),
|
||||||
|
concurrent_g1_refine()->red_zone(),
|
||||||
Shared_DirtyCardQ_lock);
|
Shared_DirtyCardQ_lock);
|
||||||
|
|
||||||
if (G1DeferredRSUpdate) {
|
if (G1DeferredRSUpdate) {
|
||||||
dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon,
|
dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon,
|
||||||
DirtyCardQ_FL_lock,
|
DirtyCardQ_FL_lock,
|
||||||
0,
|
-1, // never trigger processing
|
||||||
|
-1, // no limit on length
|
||||||
Shared_DirtyCardQ_lock,
|
Shared_DirtyCardQ_lock,
|
||||||
&JavaThread::dirty_card_queue_set());
|
&JavaThread::dirty_card_queue_set());
|
||||||
}
|
}
|
||||||
@ -1732,13 +1737,6 @@ size_t G1CollectedHeap::unsafe_max_alloc() {
|
|||||||
return car->free();
|
return car->free();
|
||||||
}
|
}
|
||||||
|
|
||||||
void G1CollectedHeap::collect(GCCause::Cause cause) {
|
|
||||||
// The caller doesn't have the Heap_lock
|
|
||||||
assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock");
|
|
||||||
MutexLocker ml(Heap_lock);
|
|
||||||
collect_locked(cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
void G1CollectedHeap::collect_as_vm_thread(GCCause::Cause cause) {
|
void G1CollectedHeap::collect_as_vm_thread(GCCause::Cause cause) {
|
||||||
assert(Thread::current()->is_VM_thread(), "Precondition#1");
|
assert(Thread::current()->is_VM_thread(), "Precondition#1");
|
||||||
assert(Heap_lock->is_locked(), "Precondition#2");
|
assert(Heap_lock->is_locked(), "Precondition#2");
|
||||||
@ -1755,17 +1753,31 @@ void G1CollectedHeap::collect_as_vm_thread(GCCause::Cause cause) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void G1CollectedHeap::collect(GCCause::Cause cause) {
|
||||||
|
// The caller doesn't have the Heap_lock
|
||||||
|
assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock");
|
||||||
|
|
||||||
void G1CollectedHeap::collect_locked(GCCause::Cause cause) {
|
int gc_count_before;
|
||||||
// Don't want to do a GC until cleanup is completed.
|
|
||||||
wait_for_cleanup_complete();
|
|
||||||
|
|
||||||
// Read the GC count while holding the Heap_lock
|
|
||||||
int gc_count_before = SharedHeap::heap()->total_collections();
|
|
||||||
{
|
{
|
||||||
MutexUnlocker mu(Heap_lock); // give up heap lock, execute gets it back
|
MutexLocker ml(Heap_lock);
|
||||||
VM_G1CollectFull op(gc_count_before, cause);
|
// Read the GC count while holding the Heap_lock
|
||||||
VMThread::execute(&op);
|
gc_count_before = SharedHeap::heap()->total_collections();
|
||||||
|
|
||||||
|
// Don't want to do a GC until cleanup is completed.
|
||||||
|
wait_for_cleanup_complete();
|
||||||
|
} // We give up heap lock; VMThread::execute gets it back below
|
||||||
|
switch (cause) {
|
||||||
|
case GCCause::_scavenge_alot: {
|
||||||
|
// Do an incremental pause, which might sometimes be abandoned.
|
||||||
|
VM_G1IncCollectionPause op(gc_count_before, cause);
|
||||||
|
VMThread::execute(&op);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
// In all other cases, we currently do a full gc.
|
||||||
|
VM_G1CollectFull op(gc_count_before, cause);
|
||||||
|
VMThread::execute(&op);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2119,7 +2131,7 @@ size_t G1CollectedHeap::large_typearray_limit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t G1CollectedHeap::max_capacity() const {
|
size_t G1CollectedHeap::max_capacity() const {
|
||||||
return _g1_committed.byte_size();
|
return g1_reserved_obj_bytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
jlong G1CollectedHeap::millis_since_last_gc() {
|
jlong G1CollectedHeap::millis_since_last_gc() {
|
||||||
@ -2638,6 +2650,8 @@ G1CollectedHeap::do_collection_pause_at_safepoint() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
ResourceMark rm;
|
||||||
|
|
||||||
char verbose_str[128];
|
char verbose_str[128];
|
||||||
sprintf(verbose_str, "GC pause ");
|
sprintf(verbose_str, "GC pause ");
|
||||||
if (g1_policy()->in_young_gc_mode()) {
|
if (g1_policy()->in_young_gc_mode()) {
|
||||||
@ -2649,8 +2663,6 @@ G1CollectedHeap::do_collection_pause_at_safepoint() {
|
|||||||
if (g1_policy()->should_initiate_conc_mark())
|
if (g1_policy()->should_initiate_conc_mark())
|
||||||
strcat(verbose_str, " (initial-mark)");
|
strcat(verbose_str, " (initial-mark)");
|
||||||
|
|
||||||
GCCauseSetter x(this, GCCause::_g1_inc_collection_pause);
|
|
||||||
|
|
||||||
// if PrintGCDetails is on, we'll print long statistics information
|
// if PrintGCDetails is on, we'll print long statistics information
|
||||||
// in the collector policy code, so let's not print this as the output
|
// in the collector policy code, so let's not print this as the output
|
||||||
// is messy if we do.
|
// is messy if we do.
|
||||||
@ -2658,7 +2670,8 @@ G1CollectedHeap::do_collection_pause_at_safepoint() {
|
|||||||
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
|
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
|
||||||
TraceTime t(verbose_str, PrintGC && !PrintGCDetails, true, gclog_or_tty);
|
TraceTime t(verbose_str, PrintGC && !PrintGCDetails, true, gclog_or_tty);
|
||||||
|
|
||||||
ResourceMark rm;
|
TraceMemoryManagerStats tms(false /* fullGC */);
|
||||||
|
|
||||||
assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
|
assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
|
||||||
assert(Thread::current() == VMThread::vm_thread(), "should be in vm thread");
|
assert(Thread::current() == VMThread::vm_thread(), "should be in vm thread");
|
||||||
guarantee(!is_gc_active(), "collection is not reentrant");
|
guarantee(!is_gc_active(), "collection is not reentrant");
|
||||||
@ -2802,6 +2815,22 @@ G1CollectedHeap::do_collection_pause_at_safepoint() {
|
|||||||
_young_list->reset_auxilary_lists();
|
_young_list->reset_auxilary_lists();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (_in_cset_fast_test != NULL) {
|
||||||
|
assert(_in_cset_fast_test_base != NULL, "Since _in_cset_fast_test isn't");
|
||||||
|
FREE_C_HEAP_ARRAY(bool, _in_cset_fast_test_base);
|
||||||
|
// this is more for peace of mind; we're nulling them here and
|
||||||
|
// we're expecting them to be null at the beginning of the next GC
|
||||||
|
_in_cset_fast_test = NULL;
|
||||||
|
_in_cset_fast_test_base = NULL;
|
||||||
|
}
|
||||||
|
// This looks confusing, because the DPT should really be empty
|
||||||
|
// at this point -- since we have not done any collection work,
|
||||||
|
// there should not be any derived pointers in the table to update;
|
||||||
|
// however, there is some additional state in the DPT which is
|
||||||
|
// reset at the end of the (null) "gc" here via the following call.
|
||||||
|
// A better approach might be to split off that state resetting work
|
||||||
|
// into a separate method that asserts that the DPT is empty and call
|
||||||
|
// that here. That is deferred for now.
|
||||||
COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
|
COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2838,6 +2867,8 @@ G1CollectedHeap::do_collection_pause_at_safepoint() {
|
|||||||
|
|
||||||
assert(regions_accounted_for(), "Region leakage.");
|
assert(regions_accounted_for(), "Region leakage.");
|
||||||
|
|
||||||
|
MemoryService::track_memory_usage();
|
||||||
|
|
||||||
if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) {
|
if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) {
|
||||||
HandleMark hm; // Discard invalid handles created during verification
|
HandleMark hm; // Discard invalid handles created during verification
|
||||||
gclog_or_tty->print(" VerifyAfterGC:");
|
gclog_or_tty->print(" VerifyAfterGC:");
|
||||||
@ -4209,10 +4240,11 @@ void G1CollectedHeap::evacuate_collection_set() {
|
|||||||
RedirtyLoggedCardTableEntryFastClosure redirty;
|
RedirtyLoggedCardTableEntryFastClosure redirty;
|
||||||
dirty_card_queue_set().set_closure(&redirty);
|
dirty_card_queue_set().set_closure(&redirty);
|
||||||
dirty_card_queue_set().apply_closure_to_all_completed_buffers();
|
dirty_card_queue_set().apply_closure_to_all_completed_buffers();
|
||||||
JavaThread::dirty_card_queue_set().merge_bufferlists(&dirty_card_queue_set());
|
|
||||||
|
DirtyCardQueueSet& dcq = JavaThread::dirty_card_queue_set();
|
||||||
|
dcq.merge_bufferlists(&dirty_card_queue_set());
|
||||||
assert(dirty_card_queue_set().completed_buffers_num() == 0, "All should be consumed");
|
assert(dirty_card_queue_set().completed_buffers_num() == 0, "All should be consumed");
|
||||||
}
|
}
|
||||||
|
|
||||||
COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
|
COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,7 +692,7 @@ public:
|
|||||||
|
|
||||||
// Reserved (g1 only; super method includes perm), capacity and the used
|
// Reserved (g1 only; super method includes perm), capacity and the used
|
||||||
// portion in bytes.
|
// portion in bytes.
|
||||||
size_t g1_reserved_obj_bytes() { return _g1_reserved.byte_size(); }
|
size_t g1_reserved_obj_bytes() const { return _g1_reserved.byte_size(); }
|
||||||
virtual size_t capacity() const;
|
virtual size_t capacity() const;
|
||||||
virtual size_t used() const;
|
virtual size_t used() const;
|
||||||
// This should be called when we're not holding the heap lock. The
|
// This should be called when we're not holding the heap lock. The
|
||||||
|
@ -1516,8 +1516,30 @@ void G1CollectorPolicy::record_collection_pause_end(bool abandoned) {
|
|||||||
(end_time_sec - _recent_prev_end_times_for_all_gcs_sec->oldest()) * 1000.0;
|
(end_time_sec - _recent_prev_end_times_for_all_gcs_sec->oldest()) * 1000.0;
|
||||||
update_recent_gc_times(end_time_sec, elapsed_ms);
|
update_recent_gc_times(end_time_sec, elapsed_ms);
|
||||||
_recent_avg_pause_time_ratio = _recent_gc_times_ms->sum()/interval_ms;
|
_recent_avg_pause_time_ratio = _recent_gc_times_ms->sum()/interval_ms;
|
||||||
// using 1.01 to account for floating point inaccuracies
|
if (recent_avg_pause_time_ratio() < 0.0 ||
|
||||||
assert(recent_avg_pause_time_ratio() < 1.01, "All GC?");
|
(recent_avg_pause_time_ratio() - 1.0 > 0.0)) {
|
||||||
|
#ifndef PRODUCT
|
||||||
|
// Dump info to allow post-facto debugging
|
||||||
|
gclog_or_tty->print_cr("recent_avg_pause_time_ratio() out of bounds");
|
||||||
|
gclog_or_tty->print_cr("-------------------------------------------");
|
||||||
|
gclog_or_tty->print_cr("Recent GC Times (ms):");
|
||||||
|
_recent_gc_times_ms->dump();
|
||||||
|
gclog_or_tty->print_cr("(End Time=%3.3f) Recent GC End Times (s):", end_time_sec);
|
||||||
|
_recent_prev_end_times_for_all_gcs_sec->dump();
|
||||||
|
gclog_or_tty->print_cr("GC = %3.3f, Interval = %3.3f, Ratio = %3.3f",
|
||||||
|
_recent_gc_times_ms->sum(), interval_ms, recent_avg_pause_time_ratio());
|
||||||
|
// In debug mode, terminate the JVM if the user wants to debug at this point.
|
||||||
|
assert(!G1FailOnFPError, "Debugging data for CR 6898948 has been dumped above");
|
||||||
|
#endif // !PRODUCT
|
||||||
|
// Clip ratio between 0.0 and 1.0, and continue. This will be fixed in
|
||||||
|
// CR 6902692 by redoing the manner in which the ratio is incrementally computed.
|
||||||
|
if (_recent_avg_pause_time_ratio < 0.0) {
|
||||||
|
_recent_avg_pause_time_ratio = 0.0;
|
||||||
|
} else {
|
||||||
|
assert(_recent_avg_pause_time_ratio - 1.0 > 0.0, "Ctl-point invariant");
|
||||||
|
_recent_avg_pause_time_ratio = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (G1PolicyVerbose > 1) {
|
if (G1PolicyVerbose > 1) {
|
||||||
@ -1892,6 +1914,10 @@ void G1CollectorPolicy::record_collection_pause_end(bool abandoned) {
|
|||||||
calculate_young_list_min_length();
|
calculate_young_list_min_length();
|
||||||
calculate_young_list_target_config();
|
calculate_young_list_target_config();
|
||||||
|
|
||||||
|
// Note that _mmu_tracker->max_gc_time() returns the time in seconds.
|
||||||
|
double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSUpdatePauseFractionPercent / 100.0;
|
||||||
|
adjust_concurrent_refinement(update_rs_time, update_rs_processed_buffers, update_rs_time_goal_ms);
|
||||||
|
|
||||||
// </NEW PREDICTION>
|
// </NEW PREDICTION>
|
||||||
|
|
||||||
_target_pause_time_ms = -1.0;
|
_target_pause_time_ms = -1.0;
|
||||||
@ -1899,6 +1925,47 @@ void G1CollectorPolicy::record_collection_pause_end(bool abandoned) {
|
|||||||
|
|
||||||
// <NEW PREDICTION>
|
// <NEW PREDICTION>
|
||||||
|
|
||||||
|
void G1CollectorPolicy::adjust_concurrent_refinement(double update_rs_time,
|
||||||
|
double update_rs_processed_buffers,
|
||||||
|
double goal_ms) {
|
||||||
|
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
||||||
|
ConcurrentG1Refine *cg1r = G1CollectedHeap::heap()->concurrent_g1_refine();
|
||||||
|
|
||||||
|
if (G1AdaptiveConcRefine) {
|
||||||
|
const int k_gy = 3, k_gr = 6;
|
||||||
|
const double inc_k = 1.1, dec_k = 0.9;
|
||||||
|
|
||||||
|
int g = cg1r->green_zone();
|
||||||
|
if (update_rs_time > goal_ms) {
|
||||||
|
g = (int)(g * dec_k); // Can become 0, that's OK. That would mean a mutator-only processing.
|
||||||
|
} else {
|
||||||
|
if (update_rs_time < goal_ms && update_rs_processed_buffers > g) {
|
||||||
|
g = (int)MAX2(g * inc_k, g + 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Change the refinement threads params
|
||||||
|
cg1r->set_green_zone(g);
|
||||||
|
cg1r->set_yellow_zone(g * k_gy);
|
||||||
|
cg1r->set_red_zone(g * k_gr);
|
||||||
|
cg1r->reinitialize_threads();
|
||||||
|
|
||||||
|
int processing_threshold_delta = MAX2((int)(cg1r->green_zone() * sigma()), 1);
|
||||||
|
int processing_threshold = MIN2(cg1r->green_zone() + processing_threshold_delta,
|
||||||
|
cg1r->yellow_zone());
|
||||||
|
// Change the barrier params
|
||||||
|
dcqs.set_process_completed_threshold(processing_threshold);
|
||||||
|
dcqs.set_max_completed_queue(cg1r->red_zone());
|
||||||
|
}
|
||||||
|
|
||||||
|
int curr_queue_size = dcqs.completed_buffers_num();
|
||||||
|
if (curr_queue_size >= cg1r->yellow_zone()) {
|
||||||
|
dcqs.set_completed_queue_padding(curr_queue_size);
|
||||||
|
} else {
|
||||||
|
dcqs.set_completed_queue_padding(0);
|
||||||
|
}
|
||||||
|
dcqs.notify_if_necessary();
|
||||||
|
}
|
||||||
|
|
||||||
double
|
double
|
||||||
G1CollectorPolicy::
|
G1CollectorPolicy::
|
||||||
predict_young_collection_elapsed_time_ms(size_t adjustment) {
|
predict_young_collection_elapsed_time_ms(size_t adjustment) {
|
||||||
@ -2825,8 +2892,15 @@ choose_collection_set() {
|
|||||||
double non_young_start_time_sec;
|
double non_young_start_time_sec;
|
||||||
start_recording_regions();
|
start_recording_regions();
|
||||||
|
|
||||||
guarantee(_target_pause_time_ms > -1.0,
|
guarantee(_target_pause_time_ms > -1.0
|
||||||
|
NOT_PRODUCT(|| Universe::heap()->gc_cause() == GCCause::_scavenge_alot),
|
||||||
"_target_pause_time_ms should have been set!");
|
"_target_pause_time_ms should have been set!");
|
||||||
|
#ifndef PRODUCT
|
||||||
|
if (_target_pause_time_ms <= -1.0) {
|
||||||
|
assert(ScavengeALot && Universe::heap()->gc_cause() == GCCause::_scavenge_alot, "Error");
|
||||||
|
_target_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
assert(_collection_set == NULL, "Precondition");
|
assert(_collection_set == NULL, "Precondition");
|
||||||
|
|
||||||
double base_time_ms = predict_base_elapsed_time_ms(_pending_cards);
|
double base_time_ms = predict_base_elapsed_time_ms(_pending_cards);
|
||||||
@ -2972,7 +3046,3 @@ record_collection_pause_end(bool abandoned) {
|
|||||||
G1CollectorPolicy::record_collection_pause_end(abandoned);
|
G1CollectorPolicy::record_collection_pause_end(abandoned);
|
||||||
assert(assertMarkedBytesDataOK(), "Marked regions not OK at pause end.");
|
assert(assertMarkedBytesDataOK(), "Marked regions not OK at pause end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Local Variables: ***
|
|
||||||
// c-indentation-style: gnu ***
|
|
||||||
// End: ***
|
|
||||||
|
@ -316,6 +316,10 @@ private:
|
|||||||
bool verify_young_ages(HeapRegion* head, SurvRateGroup *surv_rate_group);
|
bool verify_young_ages(HeapRegion* head, SurvRateGroup *surv_rate_group);
|
||||||
#endif // PRODUCT
|
#endif // PRODUCT
|
||||||
|
|
||||||
|
void adjust_concurrent_refinement(double update_rs_time,
|
||||||
|
double update_rs_processed_buffers,
|
||||||
|
double goal_ms);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
double _pause_time_target_ms;
|
double _pause_time_target_ms;
|
||||||
double _recorded_young_cset_choice_time_ms;
|
double _recorded_young_cset_choice_time_ms;
|
||||||
|
@ -86,12 +86,22 @@ void G1MMUTrackerQueue::add_pause(double start, double end, bool gc_thread) {
|
|||||||
// increase the array size (:-)
|
// increase the array size (:-)
|
||||||
// remove the oldest entry (this might allow more GC time for
|
// remove the oldest entry (this might allow more GC time for
|
||||||
// the time slice than what's allowed)
|
// the time slice than what's allowed)
|
||||||
// concolidate the two entries with the minimum gap between them
|
// consolidate the two entries with the minimum gap between them
|
||||||
// (this mighte allow less GC time than what's allowed)
|
// (this might allow less GC time than what's allowed)
|
||||||
guarantee(0, "array full, currently we can't recover");
|
guarantee(NOT_PRODUCT(ScavengeALot ||) G1ForgetfulMMUTracker,
|
||||||
|
"array full, currently we can't recover unless +G1ForgetfulMMUTracker");
|
||||||
|
// In the case where ScavengeALot is true, such overflow is not
|
||||||
|
// uncommon; in such cases, we can, without much loss of precision
|
||||||
|
// or performance (we are GC'ing most of the time anyway!),
|
||||||
|
// simply overwrite the oldest entry in the tracker: this
|
||||||
|
// is also the behaviour when G1ForgetfulMMUTracker is enabled.
|
||||||
|
_head_index = trim_index(_head_index + 1);
|
||||||
|
assert(_head_index == _tail_index, "Because we have a full circular buffer");
|
||||||
|
_tail_index = trim_index(_tail_index + 1);
|
||||||
|
} else {
|
||||||
|
_head_index = trim_index(_head_index + 1);
|
||||||
|
++_no_entries;
|
||||||
}
|
}
|
||||||
_head_index = trim_index(_head_index + 1);
|
|
||||||
++_no_entries;
|
|
||||||
_array[_head_index] = G1MMUTrackerQueueElem(start, end);
|
_array[_head_index] = G1MMUTrackerQueueElem(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,10 @@ private:
|
|||||||
// The array is of fixed size and I don't think we'll need more than
|
// The array is of fixed size and I don't think we'll need more than
|
||||||
// two or three entries with the current behaviour of G1 pauses.
|
// two or three entries with the current behaviour of G1 pauses.
|
||||||
// If the array is full, an easy fix is to look for the pauses with
|
// If the array is full, an easy fix is to look for the pauses with
|
||||||
// the shortest gap between them and concolidate them.
|
// the shortest gap between them and consolidate them.
|
||||||
|
// For now, we have taken the expedient alternative of forgetting
|
||||||
|
// the oldest entry in the event that +G1ForgetfulMMUTracker, thus
|
||||||
|
// potentially violating MMU specs for some time thereafter.
|
||||||
|
|
||||||
G1MMUTrackerQueueElem _array[QueueLength];
|
G1MMUTrackerQueueElem _array[QueueLength];
|
||||||
int _head_index;
|
int _head_index;
|
||||||
|
@ -85,7 +85,7 @@
|
|||||||
diagnostic(bool, G1SummarizeZFStats, false, \
|
diagnostic(bool, G1SummarizeZFStats, false, \
|
||||||
"Summarize zero-filling info") \
|
"Summarize zero-filling info") \
|
||||||
\
|
\
|
||||||
develop(bool, G1TraceConcurrentRefinement, false, \
|
diagnostic(bool, G1TraceConcurrentRefinement, false, \
|
||||||
"Trace G1 concurrent refinement") \
|
"Trace G1 concurrent refinement") \
|
||||||
\
|
\
|
||||||
product(intx, G1MarkStackSize, 2 * 1024 * 1024, \
|
product(intx, G1MarkStackSize, 2 * 1024 * 1024, \
|
||||||
@ -94,19 +94,6 @@
|
|||||||
product(intx, G1MarkRegionStackSize, 1024 * 1024, \
|
product(intx, G1MarkRegionStackSize, 1024 * 1024, \
|
||||||
"Size of the region stack for concurrent marking.") \
|
"Size of the region stack for concurrent marking.") \
|
||||||
\
|
\
|
||||||
develop(bool, G1ConcRefine, true, \
|
|
||||||
"If true, run concurrent rem set refinement for G1") \
|
|
||||||
\
|
|
||||||
develop(intx, G1ConcRefineTargTraversals, 4, \
|
|
||||||
"Number of concurrent refinement we try to achieve") \
|
|
||||||
\
|
|
||||||
develop(intx, G1ConcRefineInitialDelta, 4, \
|
|
||||||
"Number of heap regions of alloc ahead of starting collection " \
|
|
||||||
"pause to start concurrent refinement (initially)") \
|
|
||||||
\
|
|
||||||
develop(bool, G1SmoothConcRefine, true, \
|
|
||||||
"Attempts to smooth out the overhead of concurrent refinement") \
|
|
||||||
\
|
|
||||||
develop(bool, G1ConcZeroFill, true, \
|
develop(bool, G1ConcZeroFill, true, \
|
||||||
"If true, run concurrent zero-filling thread") \
|
"If true, run concurrent zero-filling thread") \
|
||||||
\
|
\
|
||||||
@ -178,13 +165,38 @@
|
|||||||
product(intx, G1UpdateBufferSize, 256, \
|
product(intx, G1UpdateBufferSize, 256, \
|
||||||
"Size of an update buffer") \
|
"Size of an update buffer") \
|
||||||
\
|
\
|
||||||
product(intx, G1UpdateBufferQueueProcessingThreshold, 5, \
|
product(intx, G1ConcRefineYellowZone, 0, \
|
||||||
"Number of enqueued update buffers that will " \
|
"Number of enqueued update buffers that will " \
|
||||||
"trigger concurrent processing") \
|
"trigger concurrent processing. Will be selected ergonomically " \
|
||||||
|
"by default.") \
|
||||||
\
|
\
|
||||||
product(intx, G1UpdateBufferQueueMaxLength, 30, \
|
product(intx, G1ConcRefineRedZone, 0, \
|
||||||
"Maximum number of enqueued update buffers before mutator " \
|
"Maximum number of enqueued update buffers before mutator " \
|
||||||
"threads start processing new ones instead of enqueueing them") \
|
"threads start processing new ones instead of enqueueing them. " \
|
||||||
|
"Will be selected ergonomically by default. Zero will disable " \
|
||||||
|
"concurrent processing.") \
|
||||||
|
\
|
||||||
|
product(intx, G1ConcRefineGreenZone, 0, \
|
||||||
|
"The number of update buffers that are left in the queue by the " \
|
||||||
|
"concurrent processing threads. Will be selected ergonomically " \
|
||||||
|
"by default.") \
|
||||||
|
\
|
||||||
|
product(intx, G1ConcRefineServiceInterval, 300, \
|
||||||
|
"The last concurrent refinement thread wakes up every " \
|
||||||
|
"specified number of milliseconds to do miscellaneous work.") \
|
||||||
|
\
|
||||||
|
product(intx, G1ConcRefineThresholdStep, 0, \
|
||||||
|
"Each time the rset update queue increases by this amount " \
|
||||||
|
"activate the next refinement thread if available. " \
|
||||||
|
"Will be selected ergonomically by default.") \
|
||||||
|
\
|
||||||
|
product(intx, G1RSUpdatePauseFractionPercent, 10, \
|
||||||
|
"A target percentage of time that is allowed to be spend on " \
|
||||||
|
"process RS update buffers during the collection pause.") \
|
||||||
|
\
|
||||||
|
product(bool, G1AdaptiveConcRefine, true, \
|
||||||
|
"Select green, yellow and red zones adaptively to meet the " \
|
||||||
|
"the pause requirements.") \
|
||||||
\
|
\
|
||||||
develop(intx, G1ConcRSLogCacheSize, 10, \
|
develop(intx, G1ConcRSLogCacheSize, 10, \
|
||||||
"Log base 2 of the length of conc RS hot-card cache.") \
|
"Log base 2 of the length of conc RS hot-card cache.") \
|
||||||
@ -242,6 +254,10 @@
|
|||||||
product(bool, G1UseSurvivorSpaces, true, \
|
product(bool, G1UseSurvivorSpaces, true, \
|
||||||
"When true, use survivor space.") \
|
"When true, use survivor space.") \
|
||||||
\
|
\
|
||||||
|
develop(bool, G1FailOnFPError, false, \
|
||||||
|
"When set, G1 will fail when it encounters an FP 'error', " \
|
||||||
|
"so as to allow debugging") \
|
||||||
|
\
|
||||||
develop(bool, G1FixedTenuringThreshold, false, \
|
develop(bool, G1FixedTenuringThreshold, false, \
|
||||||
"When set, G1 will not adjust the tenuring threshold") \
|
"When set, G1 will not adjust the tenuring threshold") \
|
||||||
\
|
\
|
||||||
@ -252,6 +268,9 @@
|
|||||||
"If non-0 is the size of the G1 survivor space, " \
|
"If non-0 is the size of the G1 survivor space, " \
|
||||||
"otherwise SurvivorRatio is used to determine the size") \
|
"otherwise SurvivorRatio is used to determine the size") \
|
||||||
\
|
\
|
||||||
|
product(bool, G1ForgetfulMMUTracker, false, \
|
||||||
|
"If the MMU tracker's memory is full, forget the oldest entry") \
|
||||||
|
\
|
||||||
product(uintx, G1HeapRegionSize, 0, \
|
product(uintx, G1HeapRegionSize, 0, \
|
||||||
"Size of the G1 regions.") \
|
"Size of the G1 regions.") \
|
||||||
\
|
\
|
||||||
|
@ -64,8 +64,8 @@ void PtrQueue::enqueue_known_active(void* ptr) {
|
|||||||
while (_index == 0) {
|
while (_index == 0) {
|
||||||
handle_zero_index();
|
handle_zero_index();
|
||||||
}
|
}
|
||||||
assert(_index > 0, "postcondition");
|
|
||||||
|
|
||||||
|
assert(_index > 0, "postcondition");
|
||||||
_index -= oopSize;
|
_index -= oopSize;
|
||||||
_buf[byte_index_to_index((int)_index)] = ptr;
|
_buf[byte_index_to_index((int)_index)] = ptr;
|
||||||
assert(0 <= _index && _index <= _sz, "Invariant.");
|
assert(0 <= _index && _index <= _sz, "Invariant.");
|
||||||
@ -99,94 +99,110 @@ void** PtrQueueSet::allocate_buffer() {
|
|||||||
assert(_sz > 0, "Didn't set a buffer size.");
|
assert(_sz > 0, "Didn't set a buffer size.");
|
||||||
MutexLockerEx x(_fl_owner->_fl_lock, Mutex::_no_safepoint_check_flag);
|
MutexLockerEx x(_fl_owner->_fl_lock, Mutex::_no_safepoint_check_flag);
|
||||||
if (_fl_owner->_buf_free_list != NULL) {
|
if (_fl_owner->_buf_free_list != NULL) {
|
||||||
void** res = _fl_owner->_buf_free_list;
|
void** res = BufferNode::make_buffer_from_node(_fl_owner->_buf_free_list);
|
||||||
_fl_owner->_buf_free_list = (void**)_fl_owner->_buf_free_list[0];
|
_fl_owner->_buf_free_list = _fl_owner->_buf_free_list->next();
|
||||||
_fl_owner->_buf_free_list_sz--;
|
_fl_owner->_buf_free_list_sz--;
|
||||||
// Just override the next pointer with NULL, just in case we scan this part
|
|
||||||
// of the buffer.
|
|
||||||
res[0] = NULL;
|
|
||||||
return res;
|
return res;
|
||||||
} else {
|
} else {
|
||||||
return NEW_C_HEAP_ARRAY(void*, _sz);
|
// Allocate space for the BufferNode in front of the buffer.
|
||||||
|
char *b = NEW_C_HEAP_ARRAY(char, _sz + BufferNode::aligned_size());
|
||||||
|
return BufferNode::make_buffer_from_block(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PtrQueueSet::deallocate_buffer(void** buf) {
|
void PtrQueueSet::deallocate_buffer(void** buf) {
|
||||||
assert(_sz > 0, "Didn't set a buffer size.");
|
assert(_sz > 0, "Didn't set a buffer size.");
|
||||||
MutexLockerEx x(_fl_owner->_fl_lock, Mutex::_no_safepoint_check_flag);
|
MutexLockerEx x(_fl_owner->_fl_lock, Mutex::_no_safepoint_check_flag);
|
||||||
buf[0] = (void*)_fl_owner->_buf_free_list;
|
BufferNode *node = BufferNode::make_node_from_buffer(buf);
|
||||||
_fl_owner->_buf_free_list = buf;
|
node->set_next(_fl_owner->_buf_free_list);
|
||||||
|
_fl_owner->_buf_free_list = node;
|
||||||
_fl_owner->_buf_free_list_sz++;
|
_fl_owner->_buf_free_list_sz++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PtrQueueSet::reduce_free_list() {
|
void PtrQueueSet::reduce_free_list() {
|
||||||
|
assert(_fl_owner == this, "Free list reduction is allowed only for the owner");
|
||||||
// For now we'll adopt the strategy of deleting half.
|
// For now we'll adopt the strategy of deleting half.
|
||||||
MutexLockerEx x(_fl_lock, Mutex::_no_safepoint_check_flag);
|
MutexLockerEx x(_fl_lock, Mutex::_no_safepoint_check_flag);
|
||||||
size_t n = _buf_free_list_sz / 2;
|
size_t n = _buf_free_list_sz / 2;
|
||||||
while (n > 0) {
|
while (n > 0) {
|
||||||
assert(_buf_free_list != NULL, "_buf_free_list_sz must be wrong.");
|
assert(_buf_free_list != NULL, "_buf_free_list_sz must be wrong.");
|
||||||
void** head = _buf_free_list;
|
void* b = BufferNode::make_block_from_node(_buf_free_list);
|
||||||
_buf_free_list = (void**)_buf_free_list[0];
|
_buf_free_list = _buf_free_list->next();
|
||||||
FREE_C_HEAP_ARRAY(void*,head);
|
FREE_C_HEAP_ARRAY(char, b);
|
||||||
|
_buf_free_list_sz --;
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PtrQueueSet::enqueue_complete_buffer(void** buf, size_t index, bool ignore_max_completed) {
|
void PtrQueue::handle_zero_index() {
|
||||||
// I use explicit locking here because there's a bailout in the middle.
|
assert(0 == _index, "Precondition.");
|
||||||
_cbl_mon->lock_without_safepoint_check();
|
// This thread records the full buffer and allocates a new one (while
|
||||||
|
// holding the lock if there is one).
|
||||||
Thread* thread = Thread::current();
|
if (_buf != NULL) {
|
||||||
assert( ignore_max_completed ||
|
if (_lock) {
|
||||||
thread->is_Java_thread() ||
|
locking_enqueue_completed_buffer(_buf);
|
||||||
SafepointSynchronize::is_at_safepoint(),
|
} else {
|
||||||
"invariant" );
|
if (qset()->process_or_enqueue_complete_buffer(_buf)) {
|
||||||
ignore_max_completed = ignore_max_completed || !thread->is_Java_thread();
|
// Recycle the buffer. No allocation.
|
||||||
|
_sz = qset()->buffer_size();
|
||||||
if (!ignore_max_completed && _max_completed_queue > 0 &&
|
_index = _sz;
|
||||||
_n_completed_buffers >= (size_t) _max_completed_queue) {
|
return;
|
||||||
_cbl_mon->unlock();
|
}
|
||||||
bool b = mut_process_buffer(buf);
|
|
||||||
if (b) {
|
|
||||||
deallocate_buffer(buf);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, go ahead and enqueue the buffer. Must reaquire the lock.
|
|
||||||
_cbl_mon->lock_without_safepoint_check();
|
|
||||||
}
|
}
|
||||||
|
// Reallocate the buffer
|
||||||
|
_buf = qset()->allocate_buffer();
|
||||||
|
_sz = qset()->buffer_size();
|
||||||
|
_index = _sz;
|
||||||
|
assert(0 <= _index && _index <= _sz, "Invariant.");
|
||||||
|
}
|
||||||
|
|
||||||
// Here we still hold the _cbl_mon.
|
bool PtrQueueSet::process_or_enqueue_complete_buffer(void** buf) {
|
||||||
CompletedBufferNode* cbn = new CompletedBufferNode;
|
if (Thread::current()->is_Java_thread()) {
|
||||||
cbn->buf = buf;
|
// We don't lock. It is fine to be epsilon-precise here.
|
||||||
cbn->next = NULL;
|
if (_max_completed_queue == 0 || _max_completed_queue > 0 &&
|
||||||
cbn->index = index;
|
_n_completed_buffers >= _max_completed_queue + _completed_queue_padding) {
|
||||||
|
bool b = mut_process_buffer(buf);
|
||||||
|
if (b) {
|
||||||
|
// True here means that the buffer hasn't been deallocated and the caller may reuse it.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// The buffer will be enqueued. The caller will have to get a new one.
|
||||||
|
enqueue_complete_buffer(buf);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PtrQueueSet::enqueue_complete_buffer(void** buf, size_t index) {
|
||||||
|
MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
|
||||||
|
BufferNode* cbn = BufferNode::new_from_buffer(buf);
|
||||||
|
cbn->set_index(index);
|
||||||
if (_completed_buffers_tail == NULL) {
|
if (_completed_buffers_tail == NULL) {
|
||||||
assert(_completed_buffers_head == NULL, "Well-formedness");
|
assert(_completed_buffers_head == NULL, "Well-formedness");
|
||||||
_completed_buffers_head = cbn;
|
_completed_buffers_head = cbn;
|
||||||
_completed_buffers_tail = cbn;
|
_completed_buffers_tail = cbn;
|
||||||
} else {
|
} else {
|
||||||
_completed_buffers_tail->next = cbn;
|
_completed_buffers_tail->set_next(cbn);
|
||||||
_completed_buffers_tail = cbn;
|
_completed_buffers_tail = cbn;
|
||||||
}
|
}
|
||||||
_n_completed_buffers++;
|
_n_completed_buffers++;
|
||||||
|
|
||||||
if (!_process_completed &&
|
if (!_process_completed && _process_completed_threshold >= 0 &&
|
||||||
_n_completed_buffers >= _process_completed_threshold) {
|
_n_completed_buffers >= _process_completed_threshold) {
|
||||||
_process_completed = true;
|
_process_completed = true;
|
||||||
if (_notify_when_complete)
|
if (_notify_when_complete)
|
||||||
_cbl_mon->notify_all();
|
_cbl_mon->notify();
|
||||||
}
|
}
|
||||||
debug_only(assert_completed_buffer_list_len_correct_locked());
|
debug_only(assert_completed_buffer_list_len_correct_locked());
|
||||||
_cbl_mon->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PtrQueueSet::completed_buffers_list_length() {
|
int PtrQueueSet::completed_buffers_list_length() {
|
||||||
int n = 0;
|
int n = 0;
|
||||||
CompletedBufferNode* cbn = _completed_buffers_head;
|
BufferNode* cbn = _completed_buffers_head;
|
||||||
while (cbn != NULL) {
|
while (cbn != NULL) {
|
||||||
n++;
|
n++;
|
||||||
cbn = cbn->next;
|
cbn = cbn->next();
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
@ -197,7 +213,7 @@ void PtrQueueSet::assert_completed_buffer_list_len_correct() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PtrQueueSet::assert_completed_buffer_list_len_correct_locked() {
|
void PtrQueueSet::assert_completed_buffer_list_len_correct_locked() {
|
||||||
guarantee((size_t)completed_buffers_list_length() == _n_completed_buffers,
|
guarantee(completed_buffers_list_length() == _n_completed_buffers,
|
||||||
"Completed buffer length is wrong.");
|
"Completed buffer length is wrong.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,12 +222,8 @@ void PtrQueueSet::set_buffer_size(size_t sz) {
|
|||||||
_sz = sz * oopSize;
|
_sz = sz * oopSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PtrQueueSet::set_process_completed_threshold(size_t sz) {
|
// Merge lists of buffers. Notify the processing threads.
|
||||||
_process_completed_threshold = sz;
|
// The source queue is emptied as a result. The queues
|
||||||
}
|
|
||||||
|
|
||||||
// Merge lists of buffers. Notify waiting threads if the length of the list
|
|
||||||
// exceeds threshold. The source queue is emptied as a result. The queues
|
|
||||||
// must share the monitor.
|
// must share the monitor.
|
||||||
void PtrQueueSet::merge_bufferlists(PtrQueueSet *src) {
|
void PtrQueueSet::merge_bufferlists(PtrQueueSet *src) {
|
||||||
assert(_cbl_mon == src->_cbl_mon, "Should share the same lock");
|
assert(_cbl_mon == src->_cbl_mon, "Should share the same lock");
|
||||||
@ -223,7 +235,7 @@ void PtrQueueSet::merge_bufferlists(PtrQueueSet *src) {
|
|||||||
} else {
|
} else {
|
||||||
assert(_completed_buffers_head != NULL, "Well formedness");
|
assert(_completed_buffers_head != NULL, "Well formedness");
|
||||||
if (src->_completed_buffers_head != NULL) {
|
if (src->_completed_buffers_head != NULL) {
|
||||||
_completed_buffers_tail->next = src->_completed_buffers_head;
|
_completed_buffers_tail->set_next(src->_completed_buffers_head);
|
||||||
_completed_buffers_tail = src->_completed_buffers_tail;
|
_completed_buffers_tail = src->_completed_buffers_tail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -236,31 +248,13 @@ void PtrQueueSet::merge_bufferlists(PtrQueueSet *src) {
|
|||||||
assert(_completed_buffers_head == NULL && _completed_buffers_tail == NULL ||
|
assert(_completed_buffers_head == NULL && _completed_buffers_tail == NULL ||
|
||||||
_completed_buffers_head != NULL && _completed_buffers_tail != NULL,
|
_completed_buffers_head != NULL && _completed_buffers_tail != NULL,
|
||||||
"Sanity");
|
"Sanity");
|
||||||
|
}
|
||||||
|
|
||||||
if (!_process_completed &&
|
void PtrQueueSet::notify_if_necessary() {
|
||||||
_n_completed_buffers >= _process_completed_threshold) {
|
MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
|
||||||
|
if (_n_completed_buffers >= _process_completed_threshold || _max_completed_queue == 0) {
|
||||||
_process_completed = true;
|
_process_completed = true;
|
||||||
if (_notify_when_complete)
|
if (_notify_when_complete)
|
||||||
_cbl_mon->notify_all();
|
_cbl_mon->notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge free lists of the two queues. The free list of the source
|
|
||||||
// queue is emptied as a result. The queues must share the same
|
|
||||||
// mutex that guards free lists.
|
|
||||||
void PtrQueueSet::merge_freelists(PtrQueueSet* src) {
|
|
||||||
assert(_fl_lock == src->_fl_lock, "Should share the same lock");
|
|
||||||
MutexLockerEx x(_fl_lock, Mutex::_no_safepoint_check_flag);
|
|
||||||
if (_buf_free_list != NULL) {
|
|
||||||
void **p = _buf_free_list;
|
|
||||||
while (*p != NULL) {
|
|
||||||
p = (void**)*p;
|
|
||||||
}
|
|
||||||
*p = src->_buf_free_list;
|
|
||||||
} else {
|
|
||||||
_buf_free_list = src->_buf_free_list;
|
|
||||||
}
|
|
||||||
_buf_free_list_sz += src->_buf_free_list_sz;
|
|
||||||
src->_buf_free_list = NULL;
|
|
||||||
src->_buf_free_list_sz = 0;
|
|
||||||
}
|
|
||||||
|
@ -27,8 +27,10 @@
|
|||||||
// the addresses of modified old-generation objects. This type supports
|
// the addresses of modified old-generation objects. This type supports
|
||||||
// this operation.
|
// this operation.
|
||||||
|
|
||||||
class PtrQueueSet;
|
// The definition of placement operator new(size_t, void*) in the <new>.
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
class PtrQueueSet;
|
||||||
class PtrQueue VALUE_OBJ_CLASS_SPEC {
|
class PtrQueue VALUE_OBJ_CLASS_SPEC {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -77,7 +79,7 @@ public:
|
|||||||
else enqueue_known_active(ptr);
|
else enqueue_known_active(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void handle_zero_index();
|
void handle_zero_index();
|
||||||
void locking_enqueue_completed_buffer(void** buf);
|
void locking_enqueue_completed_buffer(void** buf);
|
||||||
|
|
||||||
void enqueue_known_active(void* ptr);
|
void enqueue_known_active(void* ptr);
|
||||||
@ -126,34 +128,65 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class BufferNode {
|
||||||
|
size_t _index;
|
||||||
|
BufferNode* _next;
|
||||||
|
public:
|
||||||
|
BufferNode() : _index(0), _next(NULL) { }
|
||||||
|
BufferNode* next() const { return _next; }
|
||||||
|
void set_next(BufferNode* n) { _next = n; }
|
||||||
|
size_t index() const { return _index; }
|
||||||
|
void set_index(size_t i) { _index = i; }
|
||||||
|
|
||||||
|
// Align the size of the structure to the size of the pointer
|
||||||
|
static size_t aligned_size() {
|
||||||
|
static const size_t alignment = round_to(sizeof(BufferNode), sizeof(void*));
|
||||||
|
return alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BufferNode is allocated before the buffer.
|
||||||
|
// The chunk of memory that holds both of them is a block.
|
||||||
|
|
||||||
|
// Produce a new BufferNode given a buffer.
|
||||||
|
static BufferNode* new_from_buffer(void** buf) {
|
||||||
|
return new (make_block_from_buffer(buf)) BufferNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following are the required conversion routines:
|
||||||
|
static BufferNode* make_node_from_buffer(void** buf) {
|
||||||
|
return (BufferNode*)make_block_from_buffer(buf);
|
||||||
|
}
|
||||||
|
static void** make_buffer_from_node(BufferNode *node) {
|
||||||
|
return make_buffer_from_block(node);
|
||||||
|
}
|
||||||
|
static void* make_block_from_node(BufferNode *node) {
|
||||||
|
return (void*)node;
|
||||||
|
}
|
||||||
|
static void** make_buffer_from_block(void* p) {
|
||||||
|
return (void**)((char*)p + aligned_size());
|
||||||
|
}
|
||||||
|
static void* make_block_from_buffer(void** p) {
|
||||||
|
return (void*)((char*)p - aligned_size());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// A PtrQueueSet represents resources common to a set of pointer queues.
|
// A PtrQueueSet represents resources common to a set of pointer queues.
|
||||||
// In particular, the individual queues allocate buffers from this shared
|
// In particular, the individual queues allocate buffers from this shared
|
||||||
// set, and return completed buffers to the set.
|
// set, and return completed buffers to the set.
|
||||||
// All these variables are are protected by the TLOQ_CBL_mon. XXX ???
|
// All these variables are are protected by the TLOQ_CBL_mon. XXX ???
|
||||||
class PtrQueueSet VALUE_OBJ_CLASS_SPEC {
|
class PtrQueueSet VALUE_OBJ_CLASS_SPEC {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
class CompletedBufferNode: public CHeapObj {
|
|
||||||
public:
|
|
||||||
void** buf;
|
|
||||||
size_t index;
|
|
||||||
CompletedBufferNode* next;
|
|
||||||
CompletedBufferNode() : buf(NULL),
|
|
||||||
index(0), next(NULL){ }
|
|
||||||
};
|
|
||||||
|
|
||||||
Monitor* _cbl_mon; // Protects the fields below.
|
Monitor* _cbl_mon; // Protects the fields below.
|
||||||
CompletedBufferNode* _completed_buffers_head;
|
BufferNode* _completed_buffers_head;
|
||||||
CompletedBufferNode* _completed_buffers_tail;
|
BufferNode* _completed_buffers_tail;
|
||||||
size_t _n_completed_buffers;
|
int _n_completed_buffers;
|
||||||
size_t _process_completed_threshold;
|
int _process_completed_threshold;
|
||||||
volatile bool _process_completed;
|
volatile bool _process_completed;
|
||||||
|
|
||||||
// This (and the interpretation of the first element as a "next"
|
// This (and the interpretation of the first element as a "next"
|
||||||
// pointer) are protected by the TLOQ_FL_lock.
|
// pointer) are protected by the TLOQ_FL_lock.
|
||||||
Mutex* _fl_lock;
|
Mutex* _fl_lock;
|
||||||
void** _buf_free_list;
|
BufferNode* _buf_free_list;
|
||||||
size_t _buf_free_list_sz;
|
size_t _buf_free_list_sz;
|
||||||
// Queue set can share a freelist. The _fl_owner variable
|
// Queue set can share a freelist. The _fl_owner variable
|
||||||
// specifies the owner. It is set to "this" by default.
|
// specifies the owner. It is set to "this" by default.
|
||||||
@ -170,6 +203,7 @@ protected:
|
|||||||
// Maximum number of elements allowed on completed queue: after that,
|
// Maximum number of elements allowed on completed queue: after that,
|
||||||
// enqueuer does the work itself. Zero indicates no maximum.
|
// enqueuer does the work itself. Zero indicates no maximum.
|
||||||
int _max_completed_queue;
|
int _max_completed_queue;
|
||||||
|
int _completed_queue_padding;
|
||||||
|
|
||||||
int completed_buffers_list_length();
|
int completed_buffers_list_length();
|
||||||
void assert_completed_buffer_list_len_correct_locked();
|
void assert_completed_buffer_list_len_correct_locked();
|
||||||
@ -191,9 +225,12 @@ public:
|
|||||||
// Because of init-order concerns, we can't pass these as constructor
|
// Because of init-order concerns, we can't pass these as constructor
|
||||||
// arguments.
|
// arguments.
|
||||||
void initialize(Monitor* cbl_mon, Mutex* fl_lock,
|
void initialize(Monitor* cbl_mon, Mutex* fl_lock,
|
||||||
int max_completed_queue = 0,
|
int process_completed_threshold,
|
||||||
|
int max_completed_queue,
|
||||||
PtrQueueSet *fl_owner = NULL) {
|
PtrQueueSet *fl_owner = NULL) {
|
||||||
_max_completed_queue = max_completed_queue;
|
_max_completed_queue = max_completed_queue;
|
||||||
|
_process_completed_threshold = process_completed_threshold;
|
||||||
|
_completed_queue_padding = 0;
|
||||||
assert(cbl_mon != NULL && fl_lock != NULL, "Init order issue?");
|
assert(cbl_mon != NULL && fl_lock != NULL, "Init order issue?");
|
||||||
_cbl_mon = cbl_mon;
|
_cbl_mon = cbl_mon;
|
||||||
_fl_lock = fl_lock;
|
_fl_lock = fl_lock;
|
||||||
@ -208,14 +245,17 @@ public:
|
|||||||
void deallocate_buffer(void** buf);
|
void deallocate_buffer(void** buf);
|
||||||
|
|
||||||
// Declares that "buf" is a complete buffer.
|
// Declares that "buf" is a complete buffer.
|
||||||
void enqueue_complete_buffer(void** buf, size_t index = 0,
|
void enqueue_complete_buffer(void** buf, size_t index = 0);
|
||||||
bool ignore_max_completed = false);
|
|
||||||
|
// To be invoked by the mutator.
|
||||||
|
bool process_or_enqueue_complete_buffer(void** buf);
|
||||||
|
|
||||||
bool completed_buffers_exist_dirty() {
|
bool completed_buffers_exist_dirty() {
|
||||||
return _n_completed_buffers > 0;
|
return _n_completed_buffers > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool process_completed_buffers() { return _process_completed; }
|
bool process_completed_buffers() { return _process_completed; }
|
||||||
|
void set_process_completed(bool x) { _process_completed = x; }
|
||||||
|
|
||||||
bool active() { return _all_active; }
|
bool active() { return _all_active; }
|
||||||
|
|
||||||
@ -226,15 +266,24 @@ public:
|
|||||||
// Get the buffer size.
|
// Get the buffer size.
|
||||||
size_t buffer_size() { return _sz; }
|
size_t buffer_size() { return _sz; }
|
||||||
|
|
||||||
// Set the number of completed buffers that triggers log processing.
|
// Get/Set the number of completed buffers that triggers log processing.
|
||||||
void set_process_completed_threshold(size_t sz);
|
void set_process_completed_threshold(int sz) { _process_completed_threshold = sz; }
|
||||||
|
int process_completed_threshold() const { return _process_completed_threshold; }
|
||||||
|
|
||||||
// Must only be called at a safe point. Indicates that the buffer free
|
// Must only be called at a safe point. Indicates that the buffer free
|
||||||
// list size may be reduced, if that is deemed desirable.
|
// list size may be reduced, if that is deemed desirable.
|
||||||
void reduce_free_list();
|
void reduce_free_list();
|
||||||
|
|
||||||
size_t completed_buffers_num() { return _n_completed_buffers; }
|
int completed_buffers_num() { return _n_completed_buffers; }
|
||||||
|
|
||||||
void merge_bufferlists(PtrQueueSet* src);
|
void merge_bufferlists(PtrQueueSet* src);
|
||||||
void merge_freelists(PtrQueueSet* src);
|
|
||||||
|
void set_max_completed_queue(int m) { _max_completed_queue = m; }
|
||||||
|
int max_completed_queue() { return _max_completed_queue; }
|
||||||
|
|
||||||
|
void set_completed_queue_padding(int padding) { _completed_queue_padding = padding; }
|
||||||
|
int completed_queue_padding() { return _completed_queue_padding; }
|
||||||
|
|
||||||
|
// Notify the consumer if the number of buffers crossed the threshold
|
||||||
|
void notify_if_necessary();
|
||||||
};
|
};
|
||||||
|
@ -67,9 +67,9 @@ SATBMarkQueueSet::SATBMarkQueueSet() :
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
void SATBMarkQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
|
void SATBMarkQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
|
||||||
int max_completed_queue,
|
int process_completed_threshold,
|
||||||
Mutex* lock) {
|
Mutex* lock) {
|
||||||
PtrQueueSet::initialize(cbl_mon, fl_lock, max_completed_queue);
|
PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold, -1);
|
||||||
_shared_satb_queue.set_lock(lock);
|
_shared_satb_queue.set_lock(lock);
|
||||||
if (ParallelGCThreads > 0) {
|
if (ParallelGCThreads > 0) {
|
||||||
_par_closures = NEW_C_HEAP_ARRAY(ObjectClosure*, ParallelGCThreads);
|
_par_closures = NEW_C_HEAP_ARRAY(ObjectClosure*, ParallelGCThreads);
|
||||||
@ -122,12 +122,12 @@ void SATBMarkQueueSet::par_iterate_closure_all_threads(int worker) {
|
|||||||
|
|
||||||
bool SATBMarkQueueSet::apply_closure_to_completed_buffer_work(bool par,
|
bool SATBMarkQueueSet::apply_closure_to_completed_buffer_work(bool par,
|
||||||
int worker) {
|
int worker) {
|
||||||
CompletedBufferNode* nd = NULL;
|
BufferNode* nd = NULL;
|
||||||
{
|
{
|
||||||
MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
|
MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
|
||||||
if (_completed_buffers_head != NULL) {
|
if (_completed_buffers_head != NULL) {
|
||||||
nd = _completed_buffers_head;
|
nd = _completed_buffers_head;
|
||||||
_completed_buffers_head = nd->next;
|
_completed_buffers_head = nd->next();
|
||||||
if (_completed_buffers_head == NULL) _completed_buffers_tail = NULL;
|
if (_completed_buffers_head == NULL) _completed_buffers_tail = NULL;
|
||||||
_n_completed_buffers--;
|
_n_completed_buffers--;
|
||||||
if (_n_completed_buffers == 0) _process_completed = false;
|
if (_n_completed_buffers == 0) _process_completed = false;
|
||||||
@ -135,9 +135,9 @@ bool SATBMarkQueueSet::apply_closure_to_completed_buffer_work(bool par,
|
|||||||
}
|
}
|
||||||
ObjectClosure* cl = (par ? _par_closures[worker] : _closure);
|
ObjectClosure* cl = (par ? _par_closures[worker] : _closure);
|
||||||
if (nd != NULL) {
|
if (nd != NULL) {
|
||||||
ObjPtrQueue::apply_closure_to_buffer(cl, nd->buf, 0, _sz);
|
void **buf = BufferNode::make_buffer_from_node(nd);
|
||||||
deallocate_buffer(nd->buf);
|
ObjPtrQueue::apply_closure_to_buffer(cl, buf, 0, _sz);
|
||||||
delete nd;
|
deallocate_buffer(buf);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -145,13 +145,13 @@ bool SATBMarkQueueSet::apply_closure_to_completed_buffer_work(bool par,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SATBMarkQueueSet::abandon_partial_marking() {
|
void SATBMarkQueueSet::abandon_partial_marking() {
|
||||||
CompletedBufferNode* buffers_to_delete = NULL;
|
BufferNode* buffers_to_delete = NULL;
|
||||||
{
|
{
|
||||||
MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
|
MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
|
||||||
while (_completed_buffers_head != NULL) {
|
while (_completed_buffers_head != NULL) {
|
||||||
CompletedBufferNode* nd = _completed_buffers_head;
|
BufferNode* nd = _completed_buffers_head;
|
||||||
_completed_buffers_head = nd->next;
|
_completed_buffers_head = nd->next();
|
||||||
nd->next = buffers_to_delete;
|
nd->set_next(buffers_to_delete);
|
||||||
buffers_to_delete = nd;
|
buffers_to_delete = nd;
|
||||||
}
|
}
|
||||||
_completed_buffers_tail = NULL;
|
_completed_buffers_tail = NULL;
|
||||||
@ -159,10 +159,9 @@ void SATBMarkQueueSet::abandon_partial_marking() {
|
|||||||
DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
|
DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
|
||||||
}
|
}
|
||||||
while (buffers_to_delete != NULL) {
|
while (buffers_to_delete != NULL) {
|
||||||
CompletedBufferNode* nd = buffers_to_delete;
|
BufferNode* nd = buffers_to_delete;
|
||||||
buffers_to_delete = nd->next;
|
buffers_to_delete = nd->next();
|
||||||
deallocate_buffer(nd->buf);
|
deallocate_buffer(BufferNode::make_buffer_from_node(nd));
|
||||||
delete nd;
|
|
||||||
}
|
}
|
||||||
assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
|
assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
|
||||||
// So we can safely manipulate these queues.
|
// So we can safely manipulate these queues.
|
||||||
|
@ -60,8 +60,8 @@ public:
|
|||||||
SATBMarkQueueSet();
|
SATBMarkQueueSet();
|
||||||
|
|
||||||
void initialize(Monitor* cbl_mon, Mutex* fl_lock,
|
void initialize(Monitor* cbl_mon, Mutex* fl_lock,
|
||||||
int max_completed_queue = 0,
|
int process_completed_threshold,
|
||||||
Mutex* lock = NULL);
|
Mutex* lock);
|
||||||
|
|
||||||
static void handle_zero_index_for_thread(JavaThread* t);
|
static void handle_zero_index_for_thread(JavaThread* t);
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ void VM_G1CollectFull::doit() {
|
|||||||
void VM_G1IncCollectionPause::doit() {
|
void VM_G1IncCollectionPause::doit() {
|
||||||
JvmtiGCForAllocationMarker jgcm;
|
JvmtiGCForAllocationMarker jgcm;
|
||||||
G1CollectedHeap* g1h = G1CollectedHeap::heap();
|
G1CollectedHeap* g1h = G1CollectedHeap::heap();
|
||||||
GCCauseSetter x(g1h, GCCause::_g1_inc_collection_pause);
|
GCCauseSetter x(g1h, _gc_cause);
|
||||||
g1h->do_collection_pause_at_safepoint();
|
g1h->do_collection_pause_at_safepoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,8 +68,9 @@ class VM_G1CollectForAllocation: public VM_GC_Operation {
|
|||||||
|
|
||||||
class VM_G1IncCollectionPause: public VM_GC_Operation {
|
class VM_G1IncCollectionPause: public VM_GC_Operation {
|
||||||
public:
|
public:
|
||||||
VM_G1IncCollectionPause(int gc_count_before) :
|
VM_G1IncCollectionPause(int gc_count_before,
|
||||||
VM_GC_Operation(gc_count_before) {}
|
GCCause::Cause gc_cause = GCCause::_g1_inc_collection_pause) :
|
||||||
|
VM_GC_Operation(gc_count_before) { _gc_cause = gc_cause; }
|
||||||
virtual VMOp_Type type() const { return VMOp_G1IncCollectionPause; }
|
virtual VMOp_Type type() const { return VMOp_G1IncCollectionPause; }
|
||||||
virtual void doit();
|
virtual void doit();
|
||||||
virtual const char* name() const {
|
virtual const char* name() const {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user